mirror of
https://github.com/OpenCut-app/OpenCut.git
synced 2026-07-13 21:52:53 +02:00
fix: scenes now load properly
This commit is contained in:
@@ -88,11 +88,27 @@ export function ScenesMigrator({ children }: { children: React.ReactNode }) {
|
|||||||
|
|
||||||
const migrateLegacyProject = async (project: TProject) => {
|
const migrateLegacyProject = async (project: TProject) => {
|
||||||
try {
|
try {
|
||||||
const mainScene = createMainScene();
|
const mainScene: Scene = {
|
||||||
|
id: generateUUID(),
|
||||||
|
name: "Main Scene",
|
||||||
|
isMain: true,
|
||||||
|
isBackground: false,
|
||||||
|
createdAt: new Date(),
|
||||||
|
updatedAt: new Date(),
|
||||||
|
};
|
||||||
|
|
||||||
|
const backgroundScene: Scene = {
|
||||||
|
id: generateUUID(),
|
||||||
|
name: "Background",
|
||||||
|
isMain: false,
|
||||||
|
isBackground: true,
|
||||||
|
createdAt: new Date(),
|
||||||
|
updatedAt: new Date(),
|
||||||
|
};
|
||||||
|
|
||||||
const migratedProject: TProject = {
|
const migratedProject: TProject = {
|
||||||
...project,
|
...project,
|
||||||
scenes: [mainScene],
|
scenes: [mainScene, backgroundScene],
|
||||||
currentSceneId: mainScene.id,
|
currentSceneId: mainScene.id,
|
||||||
updatedAt: new Date(),
|
updatedAt: new Date(),
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -78,6 +78,7 @@ class StorageService {
|
|||||||
id: scene.id,
|
id: scene.id,
|
||||||
name: scene.name,
|
name: scene.name,
|
||||||
isMain: scene.isMain,
|
isMain: scene.isMain,
|
||||||
|
isBackground: scene.isBackground,
|
||||||
createdAt: scene.createdAt.toISOString(),
|
createdAt: scene.createdAt.toISOString(),
|
||||||
updatedAt: scene.updatedAt.toISOString(),
|
updatedAt: scene.updatedAt.toISOString(),
|
||||||
}));
|
}));
|
||||||
@@ -113,12 +114,13 @@ class StorageService {
|
|||||||
id: scene.id,
|
id: scene.id,
|
||||||
name: scene.name,
|
name: scene.name,
|
||||||
isMain: scene.isMain,
|
isMain: scene.isMain,
|
||||||
|
isBackground: scene.isBackground || false, // Default for legacy scenes
|
||||||
createdAt: new Date(scene.createdAt),
|
createdAt: new Date(scene.createdAt),
|
||||||
updatedAt: new Date(scene.updatedAt),
|
updatedAt: new Date(scene.updatedAt),
|
||||||
})) || [];
|
})) || [];
|
||||||
|
|
||||||
// Convert back to TProject format
|
// Convert back to TProject format
|
||||||
return {
|
const project = {
|
||||||
id: serializedProject.id,
|
id: serializedProject.id,
|
||||||
name: serializedProject.name,
|
name: serializedProject.name,
|
||||||
thumbnail: serializedProject.thumbnail,
|
thumbnail: serializedProject.thumbnail,
|
||||||
@@ -134,6 +136,7 @@ class StorageService {
|
|||||||
canvasSize: serializedProject.canvasSize,
|
canvasSize: serializedProject.canvasSize,
|
||||||
canvasMode: serializedProject.canvasMode,
|
canvasMode: serializedProject.canvasMode,
|
||||||
};
|
};
|
||||||
|
return project;
|
||||||
}
|
}
|
||||||
|
|
||||||
async loadAllProjects(): Promise<TProject[]> {
|
async loadAllProjects(): Promise<TProject[]> {
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import { storageService } from "@/lib/storage/storage-service";
|
|||||||
import { toast } from "sonner";
|
import { toast } from "sonner";
|
||||||
import { useMediaStore } from "./media-store";
|
import { useMediaStore } from "./media-store";
|
||||||
import { useTimelineStore } from "./timeline-store";
|
import { useTimelineStore } from "./timeline-store";
|
||||||
import { useSceneStore } from "./scene-store";
|
import { createBackgroundScene, useSceneStore } from "./scene-store";
|
||||||
import { generateUUID } from "@/lib/utils";
|
import { generateUUID } from "@/lib/utils";
|
||||||
import { CanvasSize, CanvasMode } from "@/types/editor";
|
import { CanvasSize, CanvasMode } from "@/types/editor";
|
||||||
|
|
||||||
@@ -16,6 +16,7 @@ export function createMainScene(): Scene {
|
|||||||
id: generateUUID(),
|
id: generateUUID(),
|
||||||
name: "Main scene",
|
name: "Main scene",
|
||||||
isMain: true,
|
isMain: true,
|
||||||
|
isBackground: false,
|
||||||
createdAt: new Date(),
|
createdAt: new Date(),
|
||||||
updatedAt: new Date(),
|
updatedAt: new Date(),
|
||||||
};
|
};
|
||||||
@@ -23,13 +24,15 @@ export function createMainScene(): Scene {
|
|||||||
|
|
||||||
const createDefaultProject = (name: string): TProject => {
|
const createDefaultProject = (name: string): TProject => {
|
||||||
const mainScene = createMainScene();
|
const mainScene = createMainScene();
|
||||||
|
const backgroundScene = createBackgroundScene();
|
||||||
|
|
||||||
return {
|
return {
|
||||||
id: generateUUID(),
|
id: generateUUID(),
|
||||||
name,
|
name,
|
||||||
thumbnail: "",
|
thumbnail: "",
|
||||||
createdAt: new Date(),
|
createdAt: new Date(),
|
||||||
updatedAt: new Date(),
|
updatedAt: new Date(),
|
||||||
scenes: [mainScene],
|
scenes: [mainScene, backgroundScene],
|
||||||
currentSceneId: mainScene.id,
|
currentSceneId: mainScene.id,
|
||||||
backgroundColor: "#000000",
|
backgroundColor: "#000000",
|
||||||
backgroundType: "color",
|
backgroundType: "color",
|
||||||
@@ -226,15 +229,19 @@ export const useProjectStore = create<ProjectStore>((set, get) => ({
|
|||||||
if (project) {
|
if (project) {
|
||||||
set({ activeProject: project });
|
set({ activeProject: project });
|
||||||
|
|
||||||
|
let currentScene = null;
|
||||||
if (project.scenes && project.scenes.length > 0) {
|
if (project.scenes && project.scenes.length > 0) {
|
||||||
sceneStore.initializeScenes({
|
sceneStore.initializeScenes({
|
||||||
scenes: project.scenes,
|
scenes: project.scenes,
|
||||||
currentSceneId: project.currentSceneId,
|
currentSceneId: project.currentSceneId,
|
||||||
});
|
});
|
||||||
|
// Get current scene directly from project data (don't rely on store state)
|
||||||
|
currentScene =
|
||||||
|
project.scenes.find((s) => s.id === project.currentSceneId) ||
|
||||||
|
project.scenes.find((s) => s.isMain) ||
|
||||||
|
project.scenes[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
const currentScene = sceneStore.currentScene;
|
|
||||||
|
|
||||||
await Promise.all([
|
await Promise.all([
|
||||||
mediaStore.loadProjectMedia(id),
|
mediaStore.loadProjectMedia(id),
|
||||||
timelineStore.loadProjectTimeline({
|
timelineStore.loadProjectTimeline({
|
||||||
|
|||||||
@@ -9,6 +9,33 @@ export function getMainScene({ scenes }: { scenes: Scene[] }): Scene | null {
|
|||||||
return scenes.find((scene) => scene.isMain) || 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()];
|
||||||
|
}
|
||||||
|
return scenes;
|
||||||
|
}
|
||||||
|
|
||||||
interface SceneStore {
|
interface SceneStore {
|
||||||
// Current scene state
|
// Current scene state
|
||||||
currentScene: Scene | null;
|
currentScene: Scene | null;
|
||||||
@@ -58,6 +85,7 @@ export const useSceneStore = create<SceneStore>((set, get) => ({
|
|||||||
id: generateUUID(),
|
id: generateUUID(),
|
||||||
name,
|
name,
|
||||||
isMain,
|
isMain,
|
||||||
|
isBackground: false,
|
||||||
createdAt: new Date(),
|
createdAt: new Date(),
|
||||||
updatedAt: new Date(),
|
updatedAt: new Date(),
|
||||||
};
|
};
|
||||||
@@ -198,16 +226,36 @@ export const useSceneStore = create<SceneStore>((set, get) => ({
|
|||||||
scenes: Scene[];
|
scenes: Scene[];
|
||||||
currentSceneId?: string;
|
currentSceneId?: string;
|
||||||
}) => {
|
}) => {
|
||||||
|
const ensuredScenes = ensureBackgroundScene({ scenes });
|
||||||
const currentScene = currentSceneId
|
const currentScene = currentSceneId
|
||||||
? scenes.find((s) => s.id === currentSceneId)
|
? ensuredScenes.find((s) => s.id === currentSceneId)
|
||||||
: null;
|
: null;
|
||||||
|
|
||||||
const fallbackScene = getMainScene({ scenes });
|
const fallbackScene = getMainScene({ scenes: ensuredScenes });
|
||||||
|
|
||||||
set({
|
set({
|
||||||
scenes,
|
scenes: ensuredScenes,
|
||||||
currentScene: currentScene || fallbackScene,
|
currentScene: currentScene || fallbackScene,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
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);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
clearScenes: () => {
|
clearScenes: () => {
|
||||||
|
|||||||
@@ -260,6 +260,15 @@ export const useTimelineStore = create<TimelineStore>((set, get) => {
|
|||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("Failed to auto-save timeline:", error);
|
console.error("Failed to auto-save timeline:", error);
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
console.warn(
|
||||||
|
"Auto-save skipped - missing activeProject or currentScene:",
|
||||||
|
{
|
||||||
|
hasProject: !!activeProject,
|
||||||
|
hasScene: !!currentScene,
|
||||||
|
sceneName: currentScene?.name,
|
||||||
|
}
|
||||||
|
);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ export interface Scene {
|
|||||||
id: string;
|
id: string;
|
||||||
name: string;
|
name: string;
|
||||||
isMain: boolean;
|
isMain: boolean;
|
||||||
|
isBackground: boolean;
|
||||||
createdAt: Date;
|
createdAt: Date;
|
||||||
updatedAt: Date;
|
updatedAt: Date;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user