mirror of
https://github.com/OpenCut-app/OpenCut.git
synced 2026-07-13 21:52:53 +02:00
move logic to zustand store
This commit is contained in:
@@ -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);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -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 = [
|
||||||
|
|||||||
Reference in New Issue
Block a user