summaryrefslogtreecommitdiff
path: root/apps/web/src/stores/project-store.ts
diff options
context:
space:
mode:
authormelad <meladnaieem@yahoo.com>2025-07-31 13:50:22 +0300
committerGitHub <noreply@github.com>2025-07-31 12:50:22 +0200
commitf255ccb818358b90edd0c1bc1f3a690dc1e729ac (patch)
tree8c2a0503d591d24edaa6cd0eeea5f152397f6bd3 /apps/web/src/stores/project-store.ts
parentb229d94a8da7b258f1b49867e8cee225d5feb735 (diff)
downloadopencut-f255ccb818358b90edd0c1bc1f3a690dc1e729ac.tar.gz
feat: add hide or show for media elements, mute or unmute for audio elements (#500)
* feat: create external tools section (#493) * feat: create external tools section * fix: better wording * Feature, added hide or show for media elements, mute or unmute for audio elements both effective on timeline and preview panel, with overlay icon for indicating so and state storing, * Minor UI vertical separator between magnifier and other buttons * fixed the AbortError issue in the AudioWaveform component. The error was occurring because of a race condition during cleanup when the component unmounts. * feat: implement bookmarking functionality in the timeline and project storage - Added bookmark management methods in the project store for toggling and checking bookmarks. - Updated the timeline component to display bookmark markers and integrate bookmark actions in the context menu. - Enhanced the storage service to handle bookmarks in project serialization and deserialization. - Updated project types to include bookmarks as an array of numbers. --------- Co-authored-by: Dominik K. <dominik@koch-bautechnik.de> Co-authored-by: Maze Winther <mazewinther@gmail.com>
Diffstat (limited to 'apps/web/src/stores/project-store.ts')
-rw-r--r--apps/web/src/stores/project-store.ts97
1 files changed, 97 insertions, 0 deletions
diff --git a/apps/web/src/stores/project-store.ts b/apps/web/src/stores/project-store.ts
index 7bb38039..69aca3ec 100644
--- a/apps/web/src/stores/project-store.ts
+++ b/apps/web/src/stores/project-store.ts
@@ -27,6 +27,11 @@ interface ProjectStore {
options?: { backgroundColor?: string; blurIntensity?: number }
) => Promise<void>;
updateProjectFps: (fps: number) => Promise<void>;
+
+ // Bookmark methods
+ toggleBookmark: (time: number) => Promise<void>;
+ isBookmarked: (time: number) => boolean;
+ removeBookmark: (time: number) => Promise<void>;
getFilteredAndSortedProjects: (
searchQuery: string,
@@ -39,6 +44,97 @@ export const useProjectStore = create<ProjectStore>((set, get) => ({
savedProjects: [],
isLoading: true,
isInitialized: false,
+
+ // Implementation of bookmark methods
+ toggleBookmark: async (time: number) => {
+ const { activeProject } = get();
+ if (!activeProject) return;
+
+ // Round time to the nearest frame
+ const fps = activeProject.fps || 30;
+ const frameTime = Math.round(time * fps) / fps;
+
+ const bookmarks = activeProject.bookmarks || [];
+ let updatedBookmarks: number[];
+
+ // Check if already bookmarked
+ const bookmarkIndex = bookmarks.findIndex(
+ bookmark => Math.abs(bookmark - frameTime) < 0.001
+ );
+
+ if (bookmarkIndex !== -1) {
+ // Remove bookmark
+ updatedBookmarks = bookmarks.filter((_, i) => i !== bookmarkIndex);
+ } else {
+ // Add bookmark
+ updatedBookmarks = [...bookmarks, frameTime].sort((a, b) => a - b);
+ }
+
+ const updatedProject = {
+ ...activeProject,
+ bookmarks: updatedBookmarks,
+ updatedAt: new Date(),
+ };
+
+ try {
+ await storageService.saveProject(updatedProject);
+ set({ activeProject: updatedProject });
+ await get().loadAllProjects(); // Refresh the list
+ } catch (error) {
+ console.error("Failed to update project bookmarks:", error);
+ toast.error("Failed to update bookmarks", {
+ description: "Please try again",
+ });
+ }
+ },
+
+ isBookmarked: (time: number) => {
+ const { activeProject } = get();
+ if (!activeProject || !activeProject.bookmarks) return false;
+
+ // Round time to the nearest frame
+ const fps = activeProject.fps || 30;
+ const frameTime = Math.round(time * fps) / fps;
+
+ return activeProject.bookmarks.some(
+ bookmark => Math.abs(bookmark - frameTime) < 0.001
+ );
+ },
+
+ removeBookmark: async (time: number) => {
+ const { activeProject } = get();
+ if (!activeProject || !activeProject.bookmarks) return;
+
+ // Round time to the nearest frame
+ const fps = activeProject.fps || 30;
+ const frameTime = Math.round(time * fps) / fps;
+
+ const updatedBookmarks = activeProject.bookmarks.filter(
+ bookmark => Math.abs(bookmark - frameTime) >= 0.001
+ );
+
+ if (updatedBookmarks.length === activeProject.bookmarks.length) {
+ // No bookmark found to remove
+ return;
+ }
+
+ const updatedProject = {
+ ...activeProject,
+ bookmarks: updatedBookmarks,
+ updatedAt: new Date(),
+ };
+
+ try {
+ await storageService.saveProject(updatedProject);
+ set({ activeProject: updatedProject });
+ await get().loadAllProjects(); // Refresh the list
+ } catch (error) {
+ console.error("Failed to update project bookmarks:", error);
+ toast.error("Failed to remove bookmark", {
+ description: "Please try again",
+ });
+ }
+ },
createNewProject: async (name: string) => {
const newProject: TProject = {
@@ -50,6 +146,7 @@ export const useProjectStore = create<ProjectStore>((set, get) => ({
backgroundColor: "#000000",
backgroundType: "color",
blurIntensity: 8,
+ bookmarks: [],
};
set({ activeProject: newProject });