summaryrefslogtreecommitdiff
path: root/apps/web/src/commands/timeline
diff options
context:
space:
mode:
authorcashmere <cashmere@autistici.org>2026-08-16 06:16:56 +0200
committercashmere <cashmere@autistici.org>2026-08-16 06:16:56 +0200
commitf1043734438c8518a302f698d9ae6583a75f0c14 (patch)
treed3e636a96e6349c1ad17afa7b28c9ffe5c882e37 /apps/web/src/commands/timeline
parent37d22b1e390bd6cea04bf8e15069281ee125cf10 (diff)
downloadopencut-f1043734438c8518a302f698d9ae6583a75f0c14.tar.gz
feat: add transitions, track mixing, and voiceover controls
Diffstat (limited to 'apps/web/src/commands/timeline')
-rw-r--r--apps/web/src/commands/timeline/track/index.ts1
-rw-r--r--apps/web/src/commands/timeline/track/update-track-volume.ts38
2 files changed, 39 insertions, 0 deletions
diff --git a/apps/web/src/commands/timeline/track/index.ts b/apps/web/src/commands/timeline/track/index.ts
index 9d4bd9c3..4aa4ceaf 100644
--- a/apps/web/src/commands/timeline/track/index.ts
+++ b/apps/web/src/commands/timeline/track/index.ts
@@ -2,3 +2,4 @@ export { AddTrackCommand } from "./add-track";
export { RemoveTrackCommand } from "./remove-track";
export { ToggleTrackMuteCommand } from "./toggle-track-mute";
export { ToggleTrackVisibilityCommand } from "./toggle-track-visibility";
+export { UpdateTrackVolumeCommand } from "./update-track-volume";
diff --git a/apps/web/src/commands/timeline/track/update-track-volume.ts b/apps/web/src/commands/timeline/track/update-track-volume.ts
new file mode 100644
index 00000000..ecd7f6ac
--- /dev/null
+++ b/apps/web/src/commands/timeline/track/update-track-volume.ts
@@ -0,0 +1,38 @@
+import { Command, type CommandResult } from "@/commands/base-command";
+import { EditorCore } from "@/core";
+import type { SceneTracks } from "@/timeline";
+import { canTrackHaveAudio, updateTrackInSceneTracks } from "@/timeline";
+import { clampDb } from "@/timeline/audio-state";
+
+export class UpdateTrackVolumeCommand extends Command {
+ private savedState: SceneTracks | null = null;
+
+ constructor({ trackId, volume }: { trackId: string; volume: number }) {
+ super();
+ this.trackId = trackId;
+ this.volume = clampDb(volume);
+ }
+
+ private trackId: string;
+ private volume: number;
+
+ execute(): CommandResult | undefined {
+ const editor = EditorCore.getInstance();
+ this.savedState = editor.scenes.getActiveScene().tracks;
+ const updatedTracks = updateTrackInSceneTracks({
+ tracks: this.savedState,
+ trackId: this.trackId,
+ update: (track) =>
+ canTrackHaveAudio(track) ? { ...track, volume: this.volume } : track,
+ });
+ editor.timeline.updateTracks(updatedTracks);
+ return undefined;
+ }
+
+ undo(): void {
+ if (this.savedState) {
+ const editor = EditorCore.getInstance();
+ editor.timeline.updateTracks(this.savedState);
+ }
+ }
+}