mirror of
https://github.com/OpenCut-app/OpenCut.git
synced 2026-07-13 21:52:53 +02:00
feat: masks, properties refactor, shaders, storage migrations, and more
This commit is contained in:
@@ -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();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user