import type { ElementType } from "react"; import { create } from "zustand"; import { persist } from "zustand/middleware"; import { ArrowRightDoubleIcon, CameraLensIcon, Folder03Icon, Happy01Icon, HeadphonesIcon, MagicWand05Icon, TextIcon, Settings01Icon, } from "@hugeicons/core-free-icons"; import { HugeiconsIcon, type IconSvgElement } from "@hugeicons/react"; import { effectsRegistry } from "@/effects"; export const TAB_KEYS = [ "media", "sounds", "text", "stickers", "effects", "lens", "transitions", "settings", ] as const; export type Tab = (typeof TAB_KEYS)[number]; const createHugeiconsIcon = ({ icon }: { icon: IconSvgElement }) => ({ className }: { className?: string }) => ( ); export const tabs = { media: { icon: createHugeiconsIcon({ icon: Folder03Icon }), label: "Media", }, sounds: { icon: createHugeiconsIcon({ icon: HeadphonesIcon }), label: "Sounds", }, text: { icon: createHugeiconsIcon({ icon: TextIcon }), label: "Text", }, stickers: { icon: createHugeiconsIcon({ icon: Happy01Icon }), label: "Stickers", }, effects: { icon: createHugeiconsIcon({ icon: MagicWand05Icon }), label: "Effects", }, lens: { icon: createHugeiconsIcon({ icon: CameraLensIcon }), label: "Lens", }, transitions: { icon: createHugeiconsIcon({ icon: ArrowRightDoubleIcon }), label: "Transitions", }, settings: { icon: createHugeiconsIcon({ icon: Settings01Icon }), label: "Settings", }, } satisfies Record< Tab, { icon: ElementType<{ className?: string }>; label: string } >; export type MediaViewMode = "grid" | "list"; export type MediaSortKey = "name" | "type" | "duration" | "size"; export type MediaSortOrder = "asc" | "desc"; export function getDefaultEffectsTab(): Tab { const hasLensEffects = effectsRegistry .getAll() .some((definition) => definition.category === "lens"); return hasLensEffects ? "lens" : "effects"; } interface AssetsPanelStore { activeTab: Tab; setActiveTab: (tab: Tab) => void; highlightMediaId: string | null; requestRevealMedia: (mediaId: string) => void; clearHighlight: () => void; /* Media */ mediaViewMode: MediaViewMode; setMediaViewMode: (mode: MediaViewMode) => void; mediaSortBy: MediaSortKey; mediaSortOrder: MediaSortOrder; setMediaSort: (args: { key: MediaSortKey; order: MediaSortOrder }) => void; } export const useAssetsPanelStore = create()( persist( (set) => ({ activeTab: "media", setActiveTab: (tab) => set({ activeTab: tab }), highlightMediaId: null, requestRevealMedia: (mediaId) => set({ activeTab: "media", highlightMediaId: mediaId }), clearHighlight: () => set({ highlightMediaId: null }), mediaViewMode: "grid", setMediaViewMode: (mode) => set({ mediaViewMode: mode }), mediaSortBy: "name", mediaSortOrder: "asc", setMediaSort: ({ key, order }) => set({ mediaSortBy: key, mediaSortOrder: order }), }), { name: "assets-panel", partialize: (state) => ({ mediaViewMode: state.mediaViewMode, mediaSortBy: state.mediaSortBy, mediaSortOrder: state.mediaSortOrder, }), }, ), );