feat: upgrade Gallery

This commit is contained in:
TrèsAbhi committed 2025-09-01 22:58:26 -05:00
1 parent 96482d4268
commit d33990bdb4
5 files changed
+35 -45

No files matched your search

@@ -1,15 +1,15 @@
import locales from '@blitzkit/i18n/locales.json'; import locales from "@blitzkit/i18n/locales.json";
import { literals } from '@blitzkit/i18n/src/literals'; import { literals } from "@blitzkit/i18n/src/literals";
import { Flex, Text } from '@radix-ui/themes'; import { Flex, Text } from "@radix-ui/themes";
import fuzzysort from 'fuzzysort'; import fuzzysort from "fuzzysort";
import { times } from 'lodash-es'; import { times } from "lodash-es";
import { useMemo, useState } from 'react'; import { useMemo, useState } from "react";
import { awaitableGallery } from '../../core/awaitables/gallery'; import { awaitableGallery } from "../../core/awaitables/gallery";
import { useLocale } from '../../hooks/useLocale'; import { useLocale } from "../../hooks/useLocale";
import { GalleryEphemeral } from '../../stores/galleryEphemeral'; import { Gallery } from "../../stores/gallery";
import type { MaybeSkeletonComponentProps } from '../../types/maybeSkeletonComponentProps'; import type { MaybeSkeletonComponentProps } from "../../types/maybeSkeletonComponentProps";
import { InlineSkeleton } from '../InlineSkeleton'; import { InlineSkeleton } from "../InlineSkeleton";
import { GalleryCard } from './Card'; import { GalleryCard } from "./Card";
export interface Avatar { export interface Avatar {
name: string; name: string;
@@ -22,7 +22,7 @@ const DEFAULT_LOADED = 42;
const PREVIEW_COUNT = 28; const PREVIEW_COUNT = 28;
export function GalleryList({ skeleton }: MaybeSkeletonComponentProps) { export function GalleryList({ skeleton }: MaybeSkeletonComponentProps) {
const search = GalleryEphemeral.use((state) => state.search); const search = Gallery.use((state) => state.search);
const [loadedCards, setLoadedCards] = useState(DEFAULT_LOADED); const [loadedCards, setLoadedCards] = useState(DEFAULT_LOADED);
const { locale, strings } = useLocale(); const { locale, strings } = useLocale();
const filtered = useMemo(() => { const filtered = useMemo(() => {
@@ -35,9 +35,9 @@ export function GalleryList({ skeleton }: MaybeSkeletonComponentProps) {
.go(search, gallery.avatars, { .go(search, gallery.avatars, {
keys: [ keys: [
...locales.supported.map( ...locales.supported.map(
(supported) => `name.locales.${supported.locale}`, (supported) => `name.locales.${supported.locale}`
), ),
'id', "id",
], ],
}) })
.map((result) => result.obj); .map((result) => result.obj);
@@ -72,7 +72,7 @@ export function GalleryList({ skeleton }: MaybeSkeletonComponentProps) {
skeleton skeleton
onIntersection={() => setLoadedCards((state) => state + 2)} onIntersection={() => setLoadedCards((state) => state + 2)}
/> />
), )
)} )}
</Flex> </Flex>
</> </>
@@ -1,13 +1,12 @@
import { MagnifyingGlassIcon } from '@radix-ui/react-icons'; import { MagnifyingGlassIcon } from "@radix-ui/react-icons";
import { TextField } from '@radix-ui/themes'; import { TextField } from "@radix-ui/themes";
import { useRef } from 'react'; import { useRef } from "react";
import { useLocale } from '../../hooks/useLocale'; import { useLocale } from "../../hooks/useLocale";
import { GalleryEphemeral } from '../../stores/galleryEphemeral'; import { Gallery } from "../../stores/gallery";
import type { MaybeSkeletonComponentProps } from '../../types/maybeSkeletonComponentProps'; import type { MaybeSkeletonComponentProps } from "../../types/maybeSkeletonComponentProps";
export function GallerySearch({ skeleton }: MaybeSkeletonComponentProps) { export function GallerySearch({ skeleton }: MaybeSkeletonComponentProps) {
const input = useRef<HTMLInputElement>(null); const input = useRef<HTMLInputElement>(null);
const mutateGalleryEphemeral = GalleryEphemeral.useMutation();
const { strings } = useLocale(); const { strings } = useLocale();
return ( return (
@@ -17,7 +16,7 @@ export function GallerySearch({ skeleton }: MaybeSkeletonComponentProps) {
placeholder={strings.website.tools.gallery.search.hint} placeholder={strings.website.tools.gallery.search.hint}
ref={input} ref={input}
onChange={(event) => { onChange={(event) => {
mutateGalleryEphemeral((draft) => { Gallery.mutate((draft) => {
const trimmed = event.target.value.trim(); const trimmed = event.target.value.trim();
draft.search = trimmed.length === 0 ? undefined : trimmed; draft.search = trimmed.length === 0 ? undefined : trimmed;
}); });
@@ -1,12 +1,11 @@
import { GalleryList } from '../../../components/Gallery/List'; import { GalleryList } from "../../../components/Gallery/List";
import { GallerySearch } from '../../../components/Gallery/Search'; import { GallerySearch } from "../../../components/Gallery/Search";
import { PageWrapper } from '../../../components/PageWrapper'; import { PageWrapper } from "../../../components/PageWrapper";
import { import {
LocaleProvider, LocaleProvider,
type LocaleAcceptorProps, type LocaleAcceptorProps,
} from '../../../hooks/useLocale'; } from "../../../hooks/useLocale";
import { GalleryEphemeral } from '../../../stores/galleryEphemeral'; import type { MaybeSkeletonComponentProps } from "../../../types/maybeSkeletonComponentProps";
import type { MaybeSkeletonComponentProps } from '../../../types/maybeSkeletonComponentProps';
export function Page({ export function Page({
locale, locale,
@@ -22,10 +21,8 @@ export function Page({
function Content({ skeleton }: MaybeSkeletonComponentProps) { function Content({ skeleton }: MaybeSkeletonComponentProps) {
return ( return (
<PageWrapper maxWidth="80rem" color="gold"> <PageWrapper maxWidth="80rem" color="gold">
<GalleryEphemeral.Provider>
<GallerySearch skeleton={skeleton} /> <GallerySearch skeleton={skeleton} />
<GalleryList skeleton={skeleton} /> <GalleryList skeleton={skeleton} />
</GalleryEphemeral.Provider>
</PageWrapper> </PageWrapper>
); );
} }
+7
View File
@@ -0,0 +1,7 @@
import { Varuna } from "varuna";
interface Gallery {
search?: string;
}
export const Gallery = new Varuna<Gallery>({});
@@ -1,13 +0,0 @@
import { create } from 'zustand';
import { subscribeWithSelector } from 'zustand/middleware';
import { createContextualStore } from '../core/zustand/createContextualStore';
interface GalleryEphemeral {
search?: string;
}
export const GalleryEphemeral = createContextualStore(() => {
return create<GalleryEphemeral>()(
subscribeWithSelector<GalleryEphemeral>(() => ({})),
);
});