summaryrefslogtreecommitdiff
path: root/apps/web/src/stores
diff options
context:
space:
mode:
authorSimon Orzel <simonorzel@gmail.com>2025-07-20 13:12:16 +0200
committerSimon Orzel <simonorzel@gmail.com>2025-07-20 13:12:16 +0200
commit061624ab588afff18073ae62fbac425c1aa5cf3a (patch)
treea508634ecf5a32c26389a687cee922e0610da1d2 /apps/web/src/stores
parentafa8f426fbe8617980d848cdda977f2ab47b5e4e (diff)
downloadopencut-061624ab588afff18073ae62fbac425c1aa5cf3a.tar.gz
feat(web): adds project preview images and cleans up duplicated code by making more composible project card
Diffstat (limited to 'apps/web/src/stores')
-rw-r--r--apps/web/src/stores/timeline-store.ts37
1 files changed, 37 insertions, 0 deletions
diff --git a/apps/web/src/stores/timeline-store.ts b/apps/web/src/stores/timeline-store.ts
index 6e48f7cd..25a56943 100644
--- a/apps/web/src/stores/timeline-store.ts
+++ b/apps/web/src/stores/timeline-store.ts
@@ -158,6 +158,7 @@ interface TimelineStore {
// Computed values
getTotalDuration: () => number;
+ getProjectThumbnail: (projectId: string) => Promise<string | null>;
// History actions
undo: () => void;
@@ -1159,6 +1160,42 @@ export const useTimelineStore = create<TimelineStore>((set, get) => {
return Math.max(...trackEndTimes, 0);
},
+ getProjectThumbnail: async (projectId) => {
+ try {
+ const tracks = await storageService.loadTimeline(projectId);
+ const mediaItems = await storageService.loadAllMediaItems(projectId);
+
+ if (!tracks || !mediaItems.length) return null;
+
+ const firstMediaElement = tracks
+ .flatMap((track) => track.elements)
+ .filter((element) => element.type === "media")
+ .sort((a, b) => a.startTime - b.startTime)[0];
+
+ if (!firstMediaElement) return null;
+
+ const mediaItem = mediaItems.find(
+ (item) => item.id === firstMediaElement.mediaId,
+ );
+ if (!mediaItem) return null;
+
+ if (mediaItem.type === "video" && mediaItem.file) {
+ const { generateVideoThumbnail } = await import(
+ "@/stores/media-store"
+ );
+ const { thumbnailUrl } = await generateVideoThumbnail(mediaItem.file);
+ return thumbnailUrl;
+ } else if (mediaItem.type === "image" && mediaItem.url) {
+ return mediaItem.url;
+ }
+
+ return null;
+ } catch (error) {
+ console.error("Failed to get project thumbnail:", error);
+ return null;
+ }
+ },
+
redo: () => {
const { redoStack } = get();
if (redoStack.length === 0) return;