summaryrefslogtreecommitdiff
path: root/apps/web/src/core/managers/timeline-manager.ts
diff options
context:
space:
mode:
Diffstat (limited to 'apps/web/src/core/managers/timeline-manager.ts')
-rw-r--r--apps/web/src/core/managers/timeline-manager.ts53
1 files changed, 51 insertions, 2 deletions
diff --git a/apps/web/src/core/managers/timeline-manager.ts b/apps/web/src/core/managers/timeline-manager.ts
index ad9f7792..c8ac5a79 100644
--- a/apps/web/src/core/managers/timeline-manager.ts
+++ b/apps/web/src/core/managers/timeline-manager.ts
@@ -23,12 +23,14 @@ import {
PasteCommand,
UpdateElementStartTimeCommand,
MoveElementCommand,
+ TracksSnapshotCommand,
} from "@/lib/commands/timeline";
-import { BatchCommand } from "@/lib/commands";
+import { BatchCommand, PreviewTracker } from "@/lib/commands";
import type { InsertElementParams } from "@/lib/commands/timeline/element/insert-element";
export class TimelineManager {
private listeners = new Set<() => void>();
+ private previewTracker = new PreviewTracker<TimelineTrack[]>();
constructor(private editor: EditorCore) {}
@@ -214,7 +216,8 @@ export class TimelineManager {
({ trackId, elementId, updates: elementUpdates }) =>
new UpdateElementCommand(trackId, elementId, elementUpdates),
);
- const command = commands.length === 1 ? commands[0] : new BatchCommand(commands);
+ const command =
+ commands.length === 1 ? commands[0] : new BatchCommand(commands);
if (pushHistory) {
this.editor.command.execute({ command });
} else {
@@ -222,6 +225,52 @@ export class TimelineManager {
}
}
+ isPreviewActive(): boolean {
+ return this.previewTracker.isActive();
+ }
+
+ previewElements({
+ updates,
+ }: {
+ updates: Array<{
+ trackId: string;
+ elementId: string;
+ updates: Partial<Record<string, unknown>>;
+ }>;
+ }): void {
+ const tracks = this.getTracks();
+ this.previewTracker.begin({ state: tracks });
+
+ let updatedTracks = tracks;
+ for (const { trackId, elementId, updates: elementUpdates } of updates) {
+ updatedTracks = updatedTracks.map((track) => {
+ if (track.id !== trackId) return track;
+ const newElements = track.elements.map((element) =>
+ element.id === elementId
+ ? { ...element, ...elementUpdates }
+ : element,
+ );
+ return { ...track, elements: newElements } as TimelineTrack;
+ });
+ }
+ this.updateTracks(updatedTracks);
+ }
+
+ commitPreview(): void {
+ const snapshot = this.previewTracker.end();
+ if (snapshot === null) return;
+ const currentTracks = this.getTracks();
+ const command = new TracksSnapshotCommand(snapshot, currentTracks);
+ this.editor.command.push({ command });
+ }
+
+ discardPreview(): void {
+ const snapshot = this.previewTracker.end();
+ if (snapshot !== null) {
+ this.updateTracks(snapshot);
+ }
+ }
+
duplicateElements({
elements,
}: {