summaryrefslogtreecommitdiff
path: root/apps/web/src/core/managers/project-manager.ts
diff options
context:
space:
mode:
authorMaze Winther <mazewinther@gmail.com>2026-03-25 16:47:22 +0100
committerMaze Winther <mazewinther@gmail.com>2026-03-29 15:48:22 +0200
commit8db3bead13441a5882d8689dfc6a9f09c82375d9 (patch)
treee9d0cafa93904ffcbec3188c37961bcc16c6422d /apps/web/src/core/managers/project-manager.ts
parent39ea298a9ccba3104c549c0ca079c231981811f5 (diff)
downloadopencut-8db3bead13441a5882d8689dfc6a9f09c82375d9.tar.gz
feat: masks, properties refactor, shaders, storage migrations, and more
Diffstat (limited to 'apps/web/src/core/managers/project-manager.ts')
-rw-r--r--apps/web/src/core/managers/project-manager.ts49
1 files changed, 31 insertions, 18 deletions
diff --git a/apps/web/src/core/managers/project-manager.ts b/apps/web/src/core/managers/project-manager.ts
index 05889a94..f84a25e3 100644
--- a/apps/web/src/core/managers/project-manager.ts
+++ b/apps/web/src/core/managers/project-manager.ts
@@ -6,8 +6,8 @@ import type {
TProjectSortOption,
TProjectSettings,
TTimelineViewState,
-} from "@/types/project";
-import type { ExportOptions, ExportResult, ExportState } from "@/types/export";
+} from "@/lib/project/types";
+import type { ExportOptions, ExportResult, ExportState } from "@/lib/export";
import { storageService } from "@/services/storage/service";
import { toast } from "sonner";
import { generateUUID } from "@/utils/id";
@@ -26,9 +26,9 @@ import {
runStorageMigrations,
type MigrationProgress,
} from "@/services/storage/migrations";
-import { DEFAULT_TIMELINE_VIEW_STATE } from "@/constants/timeline-constants";
import { loadFonts } from "@/lib/fonts/google-fonts";
-import { collectFontFamilies } from "@/lib/timeline/element-utils";
+import { DEFAULTS } from "@/lib/timeline/defaults";
+import { getElementFontFamilies } from "@/lib/timeline/element-utils";
export interface MigrationState {
isMigrating: boolean;
@@ -94,6 +94,8 @@ export class ProjectManager {
settings: {
fps: DEFAULT_FPS,
canvasSize: DEFAULT_CANVAS_SIZE,
+ canvasSizeMode: "preset",
+ lastCustomCanvasSize: null,
originalCanvasSize: null,
background: {
type: "color",
@@ -155,7 +157,9 @@ export class ProjectManager {
await this.editor.media.loadProjectMedia({ projectId: id });
const allTracks = (project.scenes ?? []).flatMap((scene) => scene.tracks);
- await loadFonts({ families: collectFontFamilies({ tracks: allTracks }) });
+ await loadFonts({
+ families: getElementFontFamilies({ tracks: allTracks }),
+ });
if (!project.metadata.thumbnail) {
const didUpdateThumbnail = await this.updateThumbnailFromTimeline();
@@ -239,14 +243,21 @@ export class ProjectManager {
this.notify();
}
- await this.ensureStorageMigrations();
try {
- const metadata = await storageService.loadAllProjectsMetadata();
- this.savedProjects = metadata;
- this.notify();
+ await this.ensureStorageMigrations();
+ try {
+ const metadata = await storageService.loadAllProjectsMetadata();
+ this.savedProjects = metadata;
+ this.notify();
+ } catch (error) {
+ console.error("Failed to load projects:", error);
+ } finally {
+ this.isLoading = false;
+ this.isInitialized = true;
+ this.notify();
+ }
} catch (error) {
- console.error("Failed to load projects:", error);
- } finally {
+ console.error("Failed to run migrations:", error);
this.isLoading = false;
this.isInitialized = true;
this.notify();
@@ -495,10 +506,12 @@ export class ProjectManager {
}
async prepareExit(): Promise<void> {
+ console.log("prepareExit", this.active);
if (!this.active) return;
try {
const didUpdateThumbnail = await this.updateThumbnailFromTimeline();
+ console.log("didUpdateThumbnail", didUpdateThumbnail);
if (didUpdateThumbnail) {
await this.editor.save.flush();
}
@@ -571,7 +584,7 @@ export class ProjectManager {
}
getTimelineViewState(): TTimelineViewState {
- return this.active?.timelineViewState ?? DEFAULT_TIMELINE_VIEW_STATE;
+ return this.active?.timelineViewState ?? DEFAULTS.timeline.viewState;
}
setTimelineViewState({ viewState }: { viewState: TTimelineViewState }): void {
@@ -581,6 +594,7 @@ export class ProjectManager {
timelineViewState: viewState ?? undefined,
};
this.editor.save.markDirty();
+ this.notify();
}
getSavedProjects(): TProjectMetadata[] {
@@ -615,15 +629,12 @@ export class ProjectManager {
const tracks = this.editor.timeline.getTracks();
const mediaAssets = this.editor.media.getAssets();
const duration = this.editor.timeline.getTotalDuration();
-
- if (duration === 0) return false;
-
const { canvasSize, background } = this.active.settings;
const scene = buildScene({
tracks,
mediaAssets,
- duration,
+ duration: duration || 1,
canvasSize,
background,
});
@@ -656,7 +667,7 @@ export class ProjectManager {
);
if (index !== -1) {
- this.savedProjects[index] = project.metadata;
+ this.savedProjects = this.savedProjects.with(index, project.metadata);
} else {
this.savedProjects = [project.metadata, ...this.savedProjects];
}
@@ -665,6 +676,8 @@ export class ProjectManager {
}
private notify(): void {
- this.listeners.forEach((fn) => fn());
+ this.listeners.forEach((fn) => {
+ fn();
+ });
}
}