move logic to zustand store

This commit is contained in:
Maze Winther
2025-09-01 23:17:48 +02:00
parent 42cf851d63
commit f7ef8d7f38
2 changed files with 56 additions and 38 deletions
@@ -181,12 +181,12 @@ function StickersContentView({ category }: { category: StickerCategory }) {
setSelectedCollection, setSelectedCollection,
loadCollections, loadCollections,
searchStickers, searchStickers,
downloadSticker, addStickerToTimeline,
clearRecentStickers, clearRecentStickers,
setSelectedCategory, setSelectedCategory,
addingSticker,
} = useStickersStore(); } = useStickersStore();
const [addingSticker, setAddingSticker] = useState<string | null>(null);
const [localSearchQuery, setLocalSearchQuery] = useState(searchQuery); const [localSearchQuery, setLocalSearchQuery] = useState(searchQuery);
const [collectionsToShow, setCollectionsToShow] = useState(20); const [collectionsToShow, setCollectionsToShow] = useState(20);
const [showCollectionItems, setShowCollectionItems] = useState(false); const [showCollectionItems, setShowCollectionItems] = useState(false);
@@ -250,46 +250,11 @@ function StickersContentView({ category }: { category: StickerCategory }) {
}, [localSearchQuery]); }, [localSearchQuery]);
const handleAddSticker = async (iconName: string) => { const handleAddSticker = async (iconName: string) => {
if (!activeProject) {
toast.error("No active project");
return;
}
setAddingSticker(iconName);
try { try {
const file = await downloadSticker(iconName); await addStickerToTimeline(iconName);
if (!file) {
throw new Error("Failed to download sticker");
}
const mediaItem: Omit<MediaFile, "id"> = {
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);
} catch (error) { } catch (error) {
console.error("Failed to add sticker:", error); console.error("Failed to add sticker:", error);
toast.error("Failed to add sticker to timeline"); toast.error("Failed to add sticker to timeline");
} finally {
setAddingSticker(null);
} }
}; };
+53
View File
@@ -9,6 +9,12 @@ import {
type CollectionInfo, type CollectionInfo,
type IconSearchResult, type IconSearchResult,
} from "@/lib/iconify-api"; } 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"; export type StickerCategory = "all" | "general" | "brands" | "emoji";
@@ -26,6 +32,7 @@ interface StickersStore {
isLoadingCollection: boolean; isLoadingCollection: boolean;
isSearching: boolean; isSearching: boolean;
isDownloading: boolean; isDownloading: boolean;
addingSticker: string | null;
setSearchQuery: (query: string) => void; setSearchQuery: (query: string) => void;
setSelectedCategory: (category: StickerCategory) => void; setSelectedCategory: (category: StickerCategory) => void;
@@ -36,6 +43,7 @@ interface StickersStore {
loadCollection: (prefix: string) => Promise<void>; loadCollection: (prefix: string) => Promise<void>;
searchStickers: (query: string) => Promise<void>; searchStickers: (query: string) => Promise<void>;
downloadSticker: (iconName: string) => Promise<File | null>; downloadSticker: (iconName: string) => Promise<File | null>;
addStickerToTimeline: (iconName: string) => Promise<void>;
addToRecentStickers: (iconName: string) => void; addToRecentStickers: (iconName: string) => void;
clearRecentStickers: () => void; clearRecentStickers: () => void;
@@ -58,6 +66,7 @@ export const useStickersStore = create<StickersStore>((set, get) => ({
isLoadingCollection: false, isLoadingCollection: false,
isSearching: false, isSearching: false,
isDownloading: false, isDownloading: false,
addingSticker: null,
setSearchQuery: (query) => set({ searchQuery: query }), setSearchQuery: (query) => set({ searchQuery: query }),
@@ -162,6 +171,50 @@ export const useStickersStore = create<StickersStore>((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<MediaFile, "id"> = {
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) => { addToRecentStickers: (iconName: string) => {
set((state) => { set((state) => {
const recent = [ const recent = [