diff options
| author | ryu <ryumacodes@gmail.com> | 2025-08-07 19:37:06 +0500 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-08-07 19:37:06 +0500 |
| commit | e71788014d137a74f10420601451ddfbb84701bb (patch) | |
| tree | 2c08f7fbbc7537b12935e842981830aed976ce87 /apps/web/src/lib/storage | |
| parent | 6412158003f295a350fc66800796f30c8f3c534b (diff) | |
| parent | d022a78ae2330665e7d763fdc6e831a71f3b9ea1 (diff) | |
| download | opencut-e71788014d137a74f10420601451ddfbb84701bb.tar.gz | |
Merge branch 'main' into feat/timeline-return-to-start
Diffstat (limited to 'apps/web/src/lib/storage')
| -rw-r--r-- | apps/web/src/lib/storage/storage-service.ts | 96 | ||||
| -rw-r--r-- | apps/web/src/lib/storage/types.ts | 2 |
2 files changed, 98 insertions, 0 deletions
diff --git a/apps/web/src/lib/storage/storage-service.ts b/apps/web/src/lib/storage/storage-service.ts index 0037dbdb..98001591 100644 --- a/apps/web/src/lib/storage/storage-service.ts +++ b/apps/web/src/lib/storage/storage-service.ts @@ -9,9 +9,11 @@ import { TimelineData, } from "./types"; import { TimelineTrack } from "@/types/timeline"; +import { SavedSoundsData, SavedSound, SoundEffect } from "@/types/sounds"; class StorageService { private projectsAdapter: IndexedDBAdapter<SerializedProject>; + private savedSoundsAdapter: IndexedDBAdapter<SavedSoundsData>; private config: StorageConfig; constructor() { @@ -19,6 +21,7 @@ class StorageService { projectsDb: "video-editor-projects", mediaDb: "video-editor-media", timelineDb: "video-editor-timelines", + savedSoundsDb: "video-editor-saved-sounds", version: 1, }; @@ -27,6 +30,12 @@ class StorageService { "projects", this.config.version ); + + this.savedSoundsAdapter = new IndexedDBAdapter<SavedSoundsData>( + this.config.savedSoundsDb, + "saved-sounds", + this.config.version + ); } // Helper to get project-specific media adapters @@ -63,6 +72,8 @@ class StorageService { backgroundColor: project.backgroundColor, backgroundType: project.backgroundType, blurIntensity: project.blurIntensity, + bookmarks: project.bookmarks, + fps: project.fps, }; await this.projectsAdapter.set(project.id, serializedProject); @@ -83,6 +94,8 @@ class StorageService { backgroundColor: serializedProject.backgroundColor, backgroundType: serializedProject.backgroundType, blurIntensity: serializedProject.blurIntensity, + bookmarks: serializedProject.bookmarks, + fps: serializedProject.fps, }; } @@ -260,6 +273,89 @@ class StorageService { }; } + async loadSavedSounds(): Promise<SavedSoundsData> { + try { + const savedSoundsData = await this.savedSoundsAdapter.get("user-sounds"); + return ( + savedSoundsData || { + sounds: [], + lastModified: new Date().toISOString(), + } + ); + } catch (error) { + console.error("Failed to load saved sounds:", error); + return { sounds: [], lastModified: new Date().toISOString() }; + } + } + + async saveSoundEffect(soundEffect: SoundEffect): Promise<void> { + try { + const currentData = await this.loadSavedSounds(); + + // Check if sound is already saved + if (currentData.sounds.some((sound) => sound.id === soundEffect.id)) { + return; // Already saved + } + + const savedSound: SavedSound = { + id: soundEffect.id, + name: soundEffect.name, + username: soundEffect.username, + previewUrl: soundEffect.previewUrl, + downloadUrl: soundEffect.downloadUrl, + duration: soundEffect.duration, + tags: soundEffect.tags, + license: soundEffect.license, + savedAt: new Date().toISOString(), + }; + + const updatedData: SavedSoundsData = { + sounds: [...currentData.sounds, savedSound], + lastModified: new Date().toISOString(), + }; + + await this.savedSoundsAdapter.set("user-sounds", updatedData); + } catch (error) { + console.error("Failed to save sound effect:", error); + throw error; + } + } + + async removeSavedSound(soundId: number): Promise<void> { + try { + const currentData = await this.loadSavedSounds(); + + const updatedData: SavedSoundsData = { + sounds: currentData.sounds.filter((sound) => sound.id !== soundId), + lastModified: new Date().toISOString(), + }; + + await this.savedSoundsAdapter.set("user-sounds", updatedData); + } catch (error) { + console.error("Failed to remove saved sound:", error); + throw error; + } + } + + async isSoundSaved(soundId: number): Promise<boolean> { + try { + const currentData = await this.loadSavedSounds(); + return currentData.sounds.some((sound) => sound.id === soundId); + } catch (error) { + console.error("Failed to check if sound is saved:", error); + return false; + } + } + + async clearSavedSounds(): Promise<void> { + try { + await this.savedSoundsAdapter.remove("user-sounds"); + } catch (error) { + console.error("Failed to clear saved sounds:", error); + throw error; + } + } + // Check browser support isOPFSSupported(): boolean { return OPFSAdapter.isSupported(); diff --git a/apps/web/src/lib/storage/types.ts b/apps/web/src/lib/storage/types.ts index b662c164..127b1690 100644 --- a/apps/web/src/lib/storage/types.ts +++ b/apps/web/src/lib/storage/types.ts @@ -30,6 +30,7 @@ export interface StorageConfig { projectsDb: string; mediaDb: string; timelineDb: string; + savedSoundsDb: string; version: number; } @@ -37,6 +38,7 @@ export interface StorageConfig { export type SerializedProject = Omit<TProject, "createdAt" | "updatedAt"> & { createdAt: string; updatedAt: string; + bookmarks?: number[]; }; // Extend FileSystemDirectoryHandle with missing async iterator methods |
