import { useEffect, useState } from "preact/hooks" import styled from "styled-components" import { Theme, generateVariables } from '../../../context/Theme' import { dispatch } from "../../../redux" export const fetchManifest = (): Promise => fetch(`//bree.dev/revolt-themes/manifest.json`).then(res => res.json()) export const fetchTheme = (slug: string): Promise => fetch(`//bree.dev/revolt-themes/theme_${slug}.json`).then(res => res.json()) interface ThemeMetadata { name: string, creator: string, description: string } type Manifest = { generated: string, themes: Record } // TODO: ability to preview / display the settings set like in the appearance pane const ThemeInfo = styled.div` display: grid; grid: "preview name creator" min-content "preview desc desc" 1fr / 200px 1fr 1fr; gap: 0.5rem 1rem; padding: 0.5rem; border-radius: var(--border-radius); background: var(--secondary-background); &[data-loaded] { .preview { opacity: 1; } } .preview { grid-area: preview; aspect-ratio: 323 / 202; display: grid; grid: 1fr / 1fr; align-items: center; justify-content: center; text-align: center; cursor: pointer; background-color: var(--secondary-background); border-radius: var(--border-radius); overflow: hidden; opacity: 0; transition: 0.25s opacity; > * { grid-area: 1 / 1; } svg { height: 100%; width: 100%; object-fit: contain; } } .name { grid-area: name; } .creator { grid-area: creator; justify-self: end; } .description { grid-area: desc; } ` const ThemeList = styled.div` display: grid; gap: 1rem; ` import previewPath from '../assets/preview.svg' const ThemedSVG = styled.svg<{ theme: Theme }>` ${props => props.theme && generateVariables(props.theme)} ` type ThemePreviewProps = Omit, "as"> & { slug?: string, theme?: Theme onThemeLoaded?: (theme: Theme) => void }; const ThemePreview = ({ theme, ...props }: ThemePreviewProps) => { return } export function ThemeShop() { // setThemeList is for adding more / lazy loading in the future const [themeList, setThemeList] = useState<[string, ThemeMetadata][] | null>(null); const [themeData, setThemeData] = useState>({}); async function fetchThemeList() { const manifest = await fetchManifest() setThemeList(Object.entries(manifest.themes)) } async function getTheme(slug: string) { const theme = await fetchTheme(slug); setThemeData(data => ({ ...data, [slug]: theme })) } useEffect(() => { fetchThemeList() }, []) useEffect(() => { themeList?.forEach(([slug]) => { getTheme(slug) }) }, [themeList]) return ( {themeList?.map(([slug, theme]) => { return
{theme.name}
{/* Maybe id's of the users should be included as well / instead? */}
@{theme.creator}
{theme.description}
dispatch({ type: "SETTINGS_SET_THEME", theme: { custom: themeData[slug], } })} />
})}
) }