From 3e89d2998588f8e35c524e523ba2ee853f0f6475 Mon Sep 17 00:00:00 2001 From: Maze Winther Date: Mon, 20 Apr 2026 11:31:17 +0200 Subject: refactor: restructure files to their domains, new preview overlay system, and dep graph --- apps/web/src/timeline/track-element-update.ts | 147 ++++++++++++++++++++++++++ 1 file changed, 147 insertions(+) create mode 100644 apps/web/src/timeline/track-element-update.ts (limited to 'apps/web/src/timeline/track-element-update.ts') diff --git a/apps/web/src/timeline/track-element-update.ts b/apps/web/src/timeline/track-element-update.ts new file mode 100644 index 00000000..7d86a4e8 --- /dev/null +++ b/apps/web/src/timeline/track-element-update.ts @@ -0,0 +1,147 @@ +import type { SceneTracks, TimelineElement, TimelineTrack } from "@/timeline"; + +export function findTrackInSceneTracks({ + tracks, + trackId, +}: { + tracks: SceneTracks; + trackId: string; +}): TimelineTrack | null { + if (tracks.main.id === trackId) { + return tracks.main; + } + + return ( + tracks.overlay.find((track) => track.id === trackId) ?? + tracks.audio.find((track) => track.id === trackId) ?? + null + ); +} + +export function updateTrackInSceneTracks({ + tracks, + trackId, + update, +}: { + tracks: SceneTracks; + trackId: string; + update: (track: TTrack) => TTrack; +}): SceneTracks { + if (tracks.main.id === trackId) { + return { + ...tracks, + main: update(tracks.main), + }; + } + + const overlayTrackIndex = tracks.overlay.findIndex((track) => track.id === trackId); + if (overlayTrackIndex >= 0) { + return { + ...tracks, + overlay: tracks.overlay.map((track, index) => + index === overlayTrackIndex ? update(track) : track, + ), + }; + } + + const audioTrackIndex = tracks.audio.findIndex((track) => track.id === trackId); + if (audioTrackIndex >= 0) { + return { + ...tracks, + audio: tracks.audio.map((track, index) => + index === audioTrackIndex ? update(track) : track, + ), + }; + } + + return tracks; +} + +function updateElementInTrack({ + track, + elementId, + update, + elementPredicate, +}: { + track: TTrack; + elementId: string; + update: (element: TimelineElement) => TimelineElement; + elementPredicate?: (element: TimelineElement) => boolean; +}): TTrack { + const nextElements = track.elements.map((element) => { + if (element.id !== elementId) { + return element; + } + if (elementPredicate && !elementPredicate(element)) { + return element; + } + return update(element); + }); + + return { + ...track, + elements: nextElements, + } as TTrack; +} + +export function updateElementInSceneTracks({ + tracks, + trackId, + elementId, + update, + elementPredicate, +}: { + tracks: SceneTracks; + trackId: string; + elementId: string; + update: (element: TimelineElement) => TimelineElement; + elementPredicate?: (element: TimelineElement) => boolean; +}): SceneTracks { + if (tracks.main.id === trackId) { + return { + ...tracks, + main: updateElementInTrack({ + track: tracks.main, + elementId, + update, + elementPredicate, + }), + }; + } + + const overlayTrackIndex = tracks.overlay.findIndex((track) => track.id === trackId); + if (overlayTrackIndex >= 0) { + return { + ...tracks, + overlay: tracks.overlay.map((track, index) => + index === overlayTrackIndex + ? updateElementInTrack({ + track, + elementId, + update, + elementPredicate, + }) + : track, + ), + }; + } + + const audioTrackIndex = tracks.audio.findIndex((track) => track.id === trackId); + if (audioTrackIndex >= 0) { + return { + ...tracks, + audio: tracks.audio.map((track, index) => + index === audioTrackIndex + ? updateElementInTrack({ + track, + elementId, + update, + elementPredicate, + }) + : track, + ), + }; + } + + return tracks; +} -- cgit v1.3.1