fix: scenes now load properly

This commit is contained in:
Maze Winther
2025-09-01 17:18:00 +02:00
parent e2bd8d1e09
commit af1964cf11
6 changed files with 479 additions and 395 deletions
@@ -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(),
}; };
+4 -1
View File
@@ -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[]> {
+11 -4
View File
@@ -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({
+51 -3
View File
@@ -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: () => {
+9
View File
@@ -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,
}
);
} }
}; };
+1
View File
@@ -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;
} }