summaryrefslogtreecommitdiff
path: root/apps/web/src/stores
diff options
context:
space:
mode:
authorMaze Winther <mazewinther@gmail.com>2025-09-01 22:15:32 +0200
committerMaze Winther <mazewinther@gmail.com>2025-09-01 22:15:32 +0200
commitd8f446580c2636e87aa39c00b1565406c56f9343 (patch)
treed538f50f10d114bc6d5843efb27cc38cd4d39328 /apps/web/src/stores
parentb84e699e9c4f0a56685697f46f52af86479a1265 (diff)
downloadopencut-d8f446580c2636e87aa39c00b1565406c56f9343.tar.gz
feat: remove default background scene and add scene management
Diffstat (limited to 'apps/web/src/stores')
-rw-r--r--apps/web/src/stores/project-store.ts8
-rw-r--r--apps/web/src/stores/scene-store.ts113
2 files changed, 85 insertions, 36 deletions
diff --git a/apps/web/src/stores/project-store.ts b/apps/web/src/stores/project-store.ts
index 0c67be9f..c58f7309 100644
--- a/apps/web/src/stores/project-store.ts
+++ b/apps/web/src/stores/project-store.ts
@@ -4,7 +4,7 @@ import { storageService } from "@/lib/storage/storage-service";
import { toast } from "sonner";
import { useMediaStore } from "./media-store";
import { useTimelineStore } from "./timeline-store";
-import { createBackgroundScene, useSceneStore } from "./scene-store";
+import { useSceneStore } from "./scene-store";
import { generateUUID } from "@/lib/utils";
import { CanvasSize, CanvasMode } from "@/types/editor";
@@ -14,9 +14,8 @@ export const DEFAULT_FPS = 30;
export function createMainScene(): Scene {
return {
id: generateUUID(),
- name: "Main scene",
+ name: "Main Scene",
isMain: true,
- isBackground: false,
createdAt: new Date(),
updatedAt: new Date(),
};
@@ -24,7 +23,6 @@ export function createMainScene(): Scene {
const createDefaultProject = (name: string): TProject => {
const mainScene = createMainScene();
- const backgroundScene = createBackgroundScene();
return {
id: generateUUID(),
@@ -32,7 +30,7 @@ const createDefaultProject = (name: string): TProject => {
thumbnail: "",
createdAt: new Date(),
updatedAt: new Date(),
- scenes: [mainScene, backgroundScene],
+ scenes: [mainScene],
currentSceneId: mainScene.id,
backgroundColor: "#000000",
backgroundType: "color",
diff --git a/apps/web/src/stores/scene-store.ts b/apps/web/src/stores/scene-store.ts
index 1b789427..a9f65a49 100644
--- a/apps/web/src/stores/scene-store.ts
+++ b/apps/web/src/stores/scene-store.ts
@@ -9,29 +9,17 @@ export function getMainScene({ scenes }: { scenes: Scene[] }): Scene | null {
return scenes.find((scene) => scene.isMain) || null;
}
-export function getBackgroundScene({
- scenes,
-}: {
- scenes: Scene[];
-}): Scene | null {
- return scenes.find((scene) => scene.isBackground) || null;
-}
-
-export function createBackgroundScene(): Scene {
- return {
- id: generateUUID(),
- name: "Background",
- isMain: false,
- isBackground: true,
- createdAt: new Date(),
- updatedAt: new Date(),
- };
-}
-
-function ensureBackgroundScene({ scenes }: { scenes: Scene[] }): Scene[] {
- const hasBackground = scenes.some((scene) => scene.isBackground);
- if (!hasBackground) {
- return [...scenes, createBackgroundScene()];
+function ensureMainScene(scenes: Scene[]): Scene[] {
+ const hasMain = scenes.some((scene) => scene.isMain);
+ if (!hasMain) {
+ const mainScene: Scene = {
+ id: generateUUID(),
+ name: "Main scene",
+ isMain: true,
+ createdAt: new Date(),
+ updatedAt: new Date(),
+ };
+ return [mainScene, ...scenes];
}
return scenes;
}
@@ -49,6 +37,7 @@ interface SceneStore {
name: string;
isMain: boolean;
}) => Promise<string>;
+ deleteScene: ({ sceneId }: { sceneId: string }) => Promise<void>;
renameScene: ({
sceneId,
name,
@@ -115,6 +104,62 @@ export const useSceneStore = create<SceneStore>((set, get) => ({
}
},
+ deleteScene: async ({ sceneId }: { sceneId: string }) => {
+ const { scenes, currentScene } = get();
+ const sceneToDelete = scenes.find((s) => s.id === sceneId);
+
+ if (!sceneToDelete) {
+ throw new Error("Scene not found");
+ }
+
+ if (sceneToDelete.isMain) {
+ throw new Error("Cannot delete main scene");
+ }
+
+ const updatedScenes = scenes.filter((s) => s.id !== sceneId);
+
+ // Determine new current scene if we're deleting the current one
+ let newCurrentScene = currentScene;
+ if (currentScene?.id === sceneId) {
+ newCurrentScene = getMainScene({ scenes: updatedScenes });
+ }
+
+ // Update project
+ const projectStore = useProjectStore.getState();
+ const { activeProject } = projectStore;
+
+ if (!activeProject) {
+ throw new Error("No active project");
+ }
+
+ const updatedProject = {
+ ...activeProject,
+ scenes: updatedScenes,
+ updatedAt: new Date(),
+ };
+
+ try {
+ await storageService.saveProject({ project: updatedProject });
+ useProjectStore.setState({ activeProject: updatedProject });
+ set({
+ scenes: updatedScenes,
+ currentScene: newCurrentScene,
+ });
+
+ // If we switched scenes, load the new scene's timeline
+ if (newCurrentScene && newCurrentScene.id !== currentScene?.id) {
+ const timelineStore = useTimelineStore.getState();
+ await timelineStore.loadProjectTimeline({
+ projectId: activeProject.id,
+ sceneId: newCurrentScene.id,
+ });
+ }
+ } catch (error) {
+ console.error("Failed to delete scene:", error);
+ throw error;
+ }
+ },
+
renameScene: async ({ sceneId, name }: { sceneId: string; name: string }) => {
const { scenes } = get();
const updatedScenes = scenes.map((scene) =>
@@ -226,7 +271,7 @@ export const useSceneStore = create<SceneStore>((set, get) => ({
scenes: Scene[];
currentSceneId?: string;
}) => {
- const ensuredScenes = ensureBackgroundScene({ scenes });
+ const ensuredScenes = ensureMainScene(scenes);
const currentScene = currentSceneId
? ensuredScenes.find((s) => s.id === currentSceneId)
: null;
@@ -241,19 +286,25 @@ export const useSceneStore = create<SceneStore>((set, get) => ({
if (ensuredScenes.length > scenes.length) {
const projectStore = useProjectStore.getState();
const { activeProject } = projectStore;
-
+
if (activeProject) {
const updatedProject = {
...activeProject,
scenes: ensuredScenes,
updatedAt: new Date(),
};
-
- storageService.saveProject({ project: updatedProject }).then(() => {
- useProjectStore.setState({ activeProject: updatedProject });
- }).catch(error => {
- console.error("Failed to save project with background scene:", error);
- });
+
+ storageService
+ .saveProject({ project: updatedProject })
+ .then(() => {
+ useProjectStore.setState({ activeProject: updatedProject });
+ })
+ .catch((error) => {
+ console.error(
+ "Failed to save project with background scene:",
+ error
+ );
+ });
}
}
},