summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--apps/web/src/components/editor/media-panel/views/stickers.tsx41
-rw-r--r--apps/web/src/stores/stickers-store.ts53
2 files changed, 56 insertions, 38 deletions
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<string | null>(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<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);
+ 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<void>;
searchStickers: (query: string) => Promise<void>;
downloadSticker: (iconName: string) => Promise<File | null>;
+ addStickerToTimeline: (iconName: string) => Promise<void>;
addToRecentStickers: (iconName: string) => void;
clearRecentStickers: () => void;
@@ -58,6 +66,7 @@ export const useStickersStore = create<StickersStore>((set, get) => ({
isLoadingCollection: false,
isSearching: false,
isDownloading: false,
+ addingSticker: null,
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) => {
set((state) => {
const recent = [