import locales from "@blitzkit/i18n/locales.json"; import { literals } from "@blitzkit/i18n/src/literals"; import { Flex, Text } from "@radix-ui/themes"; import fuzzysort from "fuzzysort"; import { times } from "lodash-es"; import { useMemo, useState } from "react"; import { api } from "../../core/blitzkit/api"; import { useLocale } from "../../hooks/useLocale"; import { Gallery } from "../../stores/gallery"; import type { MaybeSkeletonComponentProps } from "../../types/maybeSkeletonComponentProps"; import { InlineSkeleton } from "../InlineSkeleton"; import { GalleryCard } from "./Card"; export interface Avatar { name: string; id: string; } const gallery = await api.galleryDefinitions(); const DEFAULT_LOADED = 42; const PREVIEW_COUNT = 28; export function GalleryList({ skeleton }: MaybeSkeletonComponentProps) { const search = Gallery.use((state) => state.search); const [loadedCards, setLoadedCards] = useState(DEFAULT_LOADED); const { locale, strings } = useLocale(); const filtered = useMemo(() => { setLoadedCards(DEFAULT_LOADED); if (search === undefined) { return gallery.avatars; } else { return fuzzysort .go(search, gallery.avatars, { keys: [ ...locales.supported.map( (supported) => `name.locales.${supported.locale}`, ), "id", ], }) .map((result) => result.obj); } }, [search]); return ( <> {skeleton ? ( ) : ( literals(strings.website.tools.gallery.search.results, { count: filtered.length.toLocaleString(locale), }) )} {!skeleton && filtered .slice(0, loadedCards) .map((avatar) => )} {times( skeleton ? DEFAULT_LOADED + PREVIEW_COUNT : Math.min(PREVIEW_COUNT, filtered.length - loadedCards), (index) => ( setLoadedCards((state) => state + 2)} /> ), )} ); }