diff options
| author | Maze Winther <mazewinther@gmail.com> | 2026-04-20 11:31:17 +0200 |
|---|---|---|
| committer | Maze Winther <mazewinther@gmail.com> | 2026-04-20 11:31:17 +0200 |
| commit | 3e89d2998588f8e35c524e523ba2ee853f0f6475 (patch) | |
| tree | 57221f96c1259b3b07e3ddf8c1adefc502b9d8eb /apps/web/src/stores/stickers-store.ts | |
| parent | 729d10592f4e802f91c555c309ff3ba4b119f843 (diff) | |
| download | opencut-3e89d2998588f8e35c524e523ba2ee853f0f6475.tar.gz | |
refactor: restructure files to their domains, new preview overlay system, and dep graph
Diffstat (limited to 'apps/web/src/stores/stickers-store.ts')
| -rw-r--r-- | apps/web/src/stores/stickers-store.ts | 238 |
1 files changed, 0 insertions, 238 deletions
diff --git a/apps/web/src/stores/stickers-store.ts b/apps/web/src/stores/stickers-store.ts deleted file mode 100644 index 191050dd..00000000 --- a/apps/web/src/stores/stickers-store.ts +++ /dev/null @@ -1,238 +0,0 @@ -import { create } from "zustand"; -import { persist } from "zustand/middleware"; -import { - browseAll, - browseCategory, - searchAll, - searchStickers as searchStickersFromProviders, -} from "@/lib/stickers"; -import type { StickerBrowseResult, StickerSearchResult } from "@/lib/stickers"; -import { STICKER_CATEGORIES } from "@/lib/stickers/categories"; -import type { StickerCategory } from "@/lib/stickers/types"; -import { registerDefaultStickerProviders } from "@/lib/stickers/providers"; -import { stickersRegistry } from "@/lib/stickers/registry"; -import { parseStickerId } from "@/lib/stickers/sticker-id"; - -const MAX_RECENT_STICKERS = 50; -let browseRequestVersion = 0; - -function isValidStickerId(value: unknown): value is string { - if (typeof value !== "string") { - return false; - } - - try { - const parsed = parseStickerId({ stickerId: value }); - return stickersRegistry.has(parsed.providerId); - } catch { - return false; - } -} - -function sanitizeRecentStickers({ - recentStickers, -}: { - recentStickers: unknown; -}): string[] { - registerDefaultStickerProviders({}); - - if (!Array.isArray(recentStickers)) { - return []; - } - - const sanitized: string[] = []; - for (const stickerId of recentStickers) { - if (!isValidStickerId(stickerId)) { - continue; - } - if (sanitized.includes(stickerId)) { - continue; - } - sanitized.push(stickerId); - if (sanitized.length >= MAX_RECENT_STICKERS) { - break; - } - } - - return sanitized; -} - -type ViewMode = "search" | "browse"; - -interface StickersStore { - searchQuery: string; - selectedCategory: StickerCategory; - viewMode: ViewMode; - searchResults: StickerSearchResult | null; - browseContent: StickerBrowseResult | null; - recentStickers: string[]; - isSearching: boolean; - isBrowsing: boolean; - - setSearchQuery: ({ query }: { query: string }) => void; - setSelectedCategory: ({ category }: { category: StickerCategory }) => void; - searchStickers: ({ query }: { query: string }) => Promise<void>; - browseStickers: () => Promise<void>; - addToRecentStickers: ({ stickerId }: { stickerId: string }) => void; - clearRecentStickers: () => void; -} - -export const useStickersStore = create<StickersStore>()( - persist( - (set, get) => ({ - searchQuery: "", - selectedCategory: "all", - viewMode: "browse", - - searchResults: null, - browseContent: null, - recentStickers: [], - - isSearching: false, - isBrowsing: false, - - setSearchQuery: ({ query }) => set({ searchQuery: query }), - - setSelectedCategory: ({ category }) => { - set({ - selectedCategory: category in STICKER_CATEGORIES ? category : "all", - browseContent: null, - }); - - const query = get().searchQuery.trim(); - if (query) { - void get().searchStickers({ query }); - return; - } - - void get().browseStickers(); - }, - - searchStickers: async ({ query }: { query: string }) => { - const trimmedQuery = query.trim(); - if (!trimmedQuery) { - set({ searchResults: null, viewMode: "browse" }); - await get().browseStickers(); - return; - } - - const category = get().selectedCategory; - const selectedCategory = - category in STICKER_CATEGORIES ? category : "all"; - - set({ isSearching: true, viewMode: "search" }); - try { - if (selectedCategory === "all") { - const browseContent = await searchAll({ query: trimmedQuery }); - set({ browseContent, searchResults: null }); - } else { - const results = await searchStickersFromProviders({ - query: trimmedQuery, - category: selectedCategory, - limit: 100, - }); - set({ searchResults: results }); - } - } catch (error) { - console.error("Search failed:", error); - set({ searchResults: null }); - } finally { - set({ isSearching: false }); - } - }, - - browseStickers: async () => { - const version = ++browseRequestVersion; - const category = get().selectedCategory; - const selectedCategory = - category in STICKER_CATEGORIES ? category : "all"; - - set({ isBrowsing: true, viewMode: "browse" }); - try { - const browseContent = - selectedCategory === "all" - ? await browseAll({ - recentStickers: get().recentStickers, - }) - : await browseCategory({ - category: selectedCategory, - }); - - if (version !== browseRequestVersion) return; - set({ browseContent }); - } catch (error) { - if (version !== browseRequestVersion) return; - console.error("Browse failed:", error); - set({ browseContent: null }); - } finally { - if (version === browseRequestVersion) { - set({ isBrowsing: false }); - } - } - }, - - addToRecentStickers: ({ stickerId }: { stickerId: string }) => { - const sanitizedStickerIds = sanitizeRecentStickers({ - recentStickers: [stickerId], - }); - if (sanitizedStickerIds.length === 0) { - return; - } - - set((state) => { - const recent = [ - sanitizedStickerIds[0], - ...state.recentStickers.filter((s) => s !== sanitizedStickerIds[0]), - ]; - return { - recentStickers: recent.slice(0, MAX_RECENT_STICKERS), - }; - }); - - if (get().viewMode === "browse" && get().selectedCategory === "all") { - void get().browseStickers(); - } - }, - - clearRecentStickers: () => { - set({ recentStickers: [] }); - - if (get().viewMode === "browse" && get().selectedCategory === "all") { - void get().browseStickers(); - } - }, - }), - { - name: "stickers-settings", - version: 1, - migrate: (persistedState) => { - if ( - typeof persistedState === "object" && - persistedState !== null && - "selectedCategory" in persistedState - ) { - const typedState = persistedState as { - selectedCategory?: string; - recentStickers?: string[]; - }; - const category = typedState.selectedCategory ?? "all"; - return { - ...typedState, - selectedCategory: - category in STICKER_CATEGORIES - ? (category as StickerCategory) - : "all", - recentStickers: sanitizeRecentStickers({ - recentStickers: typedState.recentStickers ?? [], - }), - }; - } - return persistedState; - }, - partialize: (state) => ({ - selectedCategory: state.selectedCategory, - recentStickers: state.recentStickers, - }), - }, - ), -); |
