diff options
| author | Maze Winther <mazewinther@gmail.com> | 2026-04-07 04:41:27 +0200 |
|---|---|---|
| committer | Maze Winther <mazewinther@gmail.com> | 2026-04-07 04:41:27 +0200 |
| commit | cbd1b8212370c67b34a70dccd21bd82de72fead2 (patch) | |
| tree | d97cbee2aae22c22b59c59a50e9f8a6af0ae8ccf /apps/web/src/services/storage/migrations/transformers | |
| parent | 4f7d401a974047d37673ee8e3840dceaaddc295c (diff) | |
| download | opencut-cbd1b8212370c67b34a70dccd21bd82de72fead2.tar.gz | |
refactor: structured track layout per scene
Diffstat (limited to 'apps/web/src/services/storage/migrations/transformers')
| -rw-r--r-- | apps/web/src/services/storage/migrations/transformers/v23-to-v24.ts | 113 |
1 files changed, 113 insertions, 0 deletions
diff --git a/apps/web/src/services/storage/migrations/transformers/v23-to-v24.ts b/apps/web/src/services/storage/migrations/transformers/v23-to-v24.ts new file mode 100644 index 00000000..710d4dc1 --- /dev/null +++ b/apps/web/src/services/storage/migrations/transformers/v23-to-v24.ts @@ -0,0 +1,113 @@ +import type { MigrationResult, ProjectRecord } from "./types"; +import { getProjectId, isRecord } from "./utils"; + +export function transformProjectV23ToV24({ + project, +}: { + project: ProjectRecord; +}): MigrationResult<ProjectRecord> { + if (!getProjectId({ project })) { + return { project, skipped: true, reason: "no project id" }; + } + + const version = project.version; + if (typeof version !== "number") { + return { project, skipped: true, reason: "invalid version" }; + } + if (version >= 24) { + return { project, skipped: true, reason: "already v24" }; + } + if (version !== 23) { + return { project, skipped: true, reason: "not v23" }; + } + + return { + project: { + ...migrateProject({ project }), + version: 24, + }, + skipped: false, + }; +} + +function migrateProject({ + project, +}: { + project: ProjectRecord; +}): ProjectRecord { + if (!Array.isArray(project.scenes)) { + return project; + } + + return { + ...project, + scenes: project.scenes.map((scene) => migrateScene({ scene })), + }; +} + +function migrateScene({ scene }: { scene: unknown }): unknown { + if (!isRecord(scene) || !Array.isArray(scene.tracks)) { + return scene; + } + + const mainTrack = findMainTrack({ tracks: scene.tracks }); + if (!mainTrack) { + return scene; + } + + return { + ...scene, + tracks: { + overlay: scene.tracks + .filter((track) => track !== mainTrack) + .map((track) => migrateTrack({ track })) + .filter( + (track): track is ProjectRecord => + isRecord(track) && track.type !== "audio", + ), + main: migrateTrack({ track: mainTrack }), + audio: scene.tracks + .map((track) => migrateTrack({ track })) + .filter( + (track): track is ProjectRecord => + isRecord(track) && track.type === "audio", + ), + }, + }; +} + +function findMainTrack({ + tracks, +}: { + tracks: unknown[]; +}): ProjectRecord | null { + for (const track of tracks) { + if (!isRecord(track)) { + continue; + } + if (track.type === "video" && track.isMain === true) { + return track; + } + } + + for (const track of tracks) { + if (!isRecord(track)) { + continue; + } + if (track.type === "video") { + return track; + } + } + + return null; +} + +function migrateTrack({ track }: { track: unknown }): unknown { + if (!isRecord(track)) { + return track; + } + + const nextTrack = { ...track }; + delete nextTrack.isMain; + return nextTrack; +} |
