From 3d67b065f57585ced95c1135a50a2c237845d1d7 Mon Sep 17 00:00:00 2001 From: Maze Winther Date: Mon, 1 Sep 2025 22:19:55 +0200 Subject: refactor: remove success toast --- apps/web/src/components/editor/media-panel/views/stickers.tsx | 2 -- 1 file changed, 2 deletions(-) (limited to 'apps/web/src/components/editor/media-panel/views/stickers.tsx') diff --git a/apps/web/src/components/editor/media-panel/views/stickers.tsx b/apps/web/src/components/editor/media-panel/views/stickers.tsx index 41afe285..c30acee0 100644 --- a/apps/web/src/components/editor/media-panel/views/stickers.tsx +++ b/apps/web/src/components/editor/media-panel/views/stickers.tsx @@ -308,8 +308,6 @@ function StickersContentView({ category }: { category: StickerCategory }) { if (!added) throw new Error("Sticker not in media store"); addElementAtTime(added, currentTime); - - toast.success(`Added "${iconName}" to timeline`); } catch (error) { console.error("Failed to add sticker:", error); toast.error("Failed to add sticker to timeline"); -- cgit v1.3.1 From c5480d307cd6b959c21aee4f1de7a2c3b9010d7d Mon Sep 17 00:00:00 2001 From: Maze Winther Date: Mon, 1 Sep 2025 23:01:15 +0200 Subject: refactor: make stickers use panel base view --- .../editor/media-panel/views/stickers.tsx | 97 +++++++++------------- apps/web/src/components/editor/panel-base-view.tsx | 6 ++ 2 files changed, 43 insertions(+), 60 deletions(-) (limited to 'apps/web/src/components/editor/media-panel/views/stickers.tsx') diff --git a/apps/web/src/components/editor/media-panel/views/stickers.tsx b/apps/web/src/components/editor/media-panel/views/stickers.tsx index c30acee0..b6c64bd0 100644 --- a/apps/web/src/components/editor/media-panel/views/stickers.tsx +++ b/apps/web/src/components/editor/media-panel/views/stickers.tsx @@ -20,8 +20,7 @@ import { import { toast } from "sonner"; import { Button } from "@/components/ui/button"; import { ScrollArea } from "@/components/ui/scroll-area"; -import { Tabs, TabsList, TabsTrigger, TabsContent } from "@/components/ui/tabs"; -import { Separator } from "@/components/ui/separator"; +import { PanelBaseView as BaseView } from "@/components/editor/panel-base-view"; import { Tooltip, TooltipContent, @@ -48,63 +47,41 @@ export function StickersView() { const { selectedCategory, setSelectedCategory } = useStickersStore(); return ( -
- { - if (["all", "general", "brands", "emoji"].includes(v)) { - setSelectedCategory(v as StickerCategory); - } - }} - className="flex flex-col h-full" - > -
- - - - All - - - - Icons - - - - Brands - - - - Emoji - - -
- - - - - - - - - - - - - -
-
+ { + if (["all", "general", "brands", "emoji"].includes(v)) { + setSelectedCategory(v as StickerCategory); + } + }} + tabs={[ + { + value: "all", + label: "All", + icon: , + content: , + }, + { + value: "general", + label: "Icons", + icon: , + content: , + }, + { + value: "brands", + label: "Brands", + icon: , + content: , + }, + { + value: "emoji", + label: "Emoji", + icon: , + content: , + }, + ]} + className="flex flex-col h-full p-0 overflow-hidden" + /> ); } @@ -361,7 +338,7 @@ function StickersContentView({ category }: { category: StickerCategory }) { }, [isInCollection]); return ( -
+
{tabs.map((tab) => ( + {tab.icon ? ( + + {tab.icon} + + ) : null} {tab.label} ))} -- cgit v1.3.1 From 42cf851d635e006c8dda11e09d9b52d07d1afcd2 Mon Sep 17 00:00:00 2001 From: Maze Winther Date: Mon, 1 Sep 2025 23:02:57 +0200 Subject: disable back animation --- apps/web/src/components/editor/media-panel/views/stickers.tsx | 1 + apps/web/src/components/ui/input-with-back.tsx | 4 +++- 2 files changed, 4 insertions(+), 1 deletion(-) (limited to 'apps/web/src/components/editor/media-panel/views/stickers.tsx') diff --git a/apps/web/src/components/editor/media-panel/views/stickers.tsx b/apps/web/src/components/editor/media-panel/views/stickers.tsx index b6c64bd0..0d293242 100644 --- a/apps/web/src/components/editor/media-panel/views/stickers.tsx +++ b/apps/web/src/components/editor/media-panel/views/stickers.tsx @@ -358,6 +358,7 @@ function StickersContentView({ category }: { category: StickerCategory }) { } value={localSearchQuery} onChange={setLocalSearchQuery} + disableAnimation={true} />
diff --git a/apps/web/src/components/ui/input-with-back.tsx b/apps/web/src/components/ui/input-with-back.tsx index ea225c14..cae9f8c9 100644 --- a/apps/web/src/components/ui/input-with-back.tsx +++ b/apps/web/src/components/ui/input-with-back.tsx @@ -12,6 +12,7 @@ interface InputWithBackProps { placeholder?: string; value?: string; onChange?: (value: string) => void; + disableAnimation?: boolean; } export function InputWithBack({ @@ -20,12 +21,13 @@ export function InputWithBack({ placeholder = "Search anything", value, onChange, + disableAnimation = false, }: InputWithBackProps) { const [containerRef, setContainerRef] = useState(null); const [buttonOffset, setButtonOffset] = useState(-60); const smoothTransition = { - duration: 0.35, + duration: disableAnimation ? 0 : 0.35, ease: [0.25, 0.1, 0.25, 1] as const, }; -- cgit v1.3.1 From f7ef8d7f38af0f049288a58787bc7b9f931599df Mon Sep 17 00:00:00 2001 From: Maze Winther Date: Mon, 1 Sep 2025 23:17:48 +0200 Subject: move logic to zustand store --- .../editor/media-panel/views/stickers.tsx | 41 ++--------------- apps/web/src/stores/stickers-store.ts | 53 ++++++++++++++++++++++ 2 files changed, 56 insertions(+), 38 deletions(-) (limited to 'apps/web/src/components/editor/media-panel/views/stickers.tsx') diff --git a/apps/web/src/components/editor/media-panel/views/stickers.tsx b/apps/web/src/components/editor/media-panel/views/stickers.tsx index 0d293242..f67450cc 100644 --- a/apps/web/src/components/editor/media-panel/views/stickers.tsx +++ b/apps/web/src/components/editor/media-panel/views/stickers.tsx @@ -181,12 +181,12 @@ function StickersContentView({ category }: { category: StickerCategory }) { setSelectedCollection, loadCollections, searchStickers, - downloadSticker, + addStickerToTimeline, clearRecentStickers, setSelectedCategory, + addingSticker, } = useStickersStore(); - const [addingSticker, setAddingSticker] = useState(null); const [localSearchQuery, setLocalSearchQuery] = useState(searchQuery); const [collectionsToShow, setCollectionsToShow] = useState(20); const [showCollectionItems, setShowCollectionItems] = useState(false); @@ -250,46 +250,11 @@ function StickersContentView({ category }: { category: StickerCategory }) { }, [localSearchQuery]); const handleAddSticker = async (iconName: string) => { - if (!activeProject) { - toast.error("No active project"); - return; - } - - setAddingSticker(iconName); - try { - const file = await downloadSticker(iconName); - - if (!file) { - throw new Error("Failed to download sticker"); - } - - const mediaItem: Omit = { - name: iconName.replace(":", "-"), - type: "image", - file, - url: URL.createObjectURL(file), - width: 200, - height: 200, - duration: TIMELINE_CONSTANTS.DEFAULT_IMAGE_DURATION, - ephemeral: false, - }; - - await addMediaFile(activeProject.id, mediaItem); - - const added = useMediaStore - .getState() - .mediaFiles.find( - (m) => m.url === mediaItem.url && m.name === mediaItem.name - ); - if (!added) throw new Error("Sticker not in media store"); - - addElementAtTime(added, currentTime); + await addStickerToTimeline(iconName); } catch (error) { console.error("Failed to add sticker:", error); toast.error("Failed to add sticker to timeline"); - } finally { - setAddingSticker(null); } }; diff --git a/apps/web/src/stores/stickers-store.ts b/apps/web/src/stores/stickers-store.ts index da8b926b..c7c9ef98 100644 --- a/apps/web/src/stores/stickers-store.ts +++ b/apps/web/src/stores/stickers-store.ts @@ -9,6 +9,12 @@ import { type CollectionInfo, type IconSearchResult, } from "@/lib/iconify-api"; +import { useProjectStore } from "@/stores/project-store"; +import { useMediaStore } from "@/stores/media-store"; +import { useTimelineStore } from "@/stores/timeline-store"; +import { usePlaybackStore } from "@/stores/playback-store"; +import { TIMELINE_CONSTANTS } from "@/constants/timeline-constants"; +import type { MediaFile } from "@/types/media"; export type StickerCategory = "all" | "general" | "brands" | "emoji"; @@ -26,6 +32,7 @@ interface StickersStore { isLoadingCollection: boolean; isSearching: boolean; isDownloading: boolean; + addingSticker: string | null; setSearchQuery: (query: string) => void; setSelectedCategory: (category: StickerCategory) => void; @@ -36,6 +43,7 @@ interface StickersStore { loadCollection: (prefix: string) => Promise; searchStickers: (query: string) => Promise; downloadSticker: (iconName: string) => Promise; + addStickerToTimeline: (iconName: string) => Promise; addToRecentStickers: (iconName: string) => void; clearRecentStickers: () => void; @@ -58,6 +66,7 @@ export const useStickersStore = create((set, get) => ({ isLoadingCollection: false, isSearching: false, isDownloading: false, + addingSticker: null, setSearchQuery: (query) => set({ searchQuery: query }), @@ -162,6 +171,50 @@ export const useStickersStore = create((set, get) => ({ } }, + addStickerToTimeline: async (iconName: string) => { + set({ addingSticker: iconName }); + try { + const { activeProject } = useProjectStore.getState(); + if (!activeProject) { + throw new Error("No active project"); + } + + const file = await get().downloadSticker(iconName); + if (!file) { + throw new Error("Failed to download sticker"); + } + + const mediaItem: Omit = { + name: iconName.replace(":", "-"), + type: "image", + file, + url: URL.createObjectURL(file), + width: 200, + height: 200, + duration: TIMELINE_CONSTANTS.DEFAULT_IMAGE_DURATION, + ephemeral: false, + }; + + const { addMediaFile } = useMediaStore.getState(); + await addMediaFile(activeProject.id, mediaItem); + + const added = useMediaStore + .getState() + .mediaFiles.find( + (m) => m.url === mediaItem.url && m.name === mediaItem.name + ); + if (!added) { + throw new Error("Sticker not in media store"); + } + + const { currentTime } = usePlaybackStore.getState(); + const { addElementAtTime } = useTimelineStore.getState(); + addElementAtTime(added, currentTime); + } finally { + set({ addingSticker: null }); + } + }, + addToRecentStickers: (iconName: string) => { set((state) => { const recent = [ -- cgit v1.3.1