mirror of
https://github.com/OpenCut-app/OpenCut.git
synced 2026-07-13 21:52:53 +02:00
refactor: structured track layout per scene
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
import { Command, type CommandResult } from "@/lib/commands/base-command";
|
||||
import type { TrackType, TimelineTrack } from "@/lib/timeline";
|
||||
import type { SceneTracks, TrackType } from "@/lib/timeline";
|
||||
import { generateUUID } from "@/utils/id";
|
||||
import { EditorCore } from "@/core";
|
||||
import {
|
||||
@@ -9,7 +9,7 @@ import {
|
||||
|
||||
export class AddTrackCommand extends Command {
|
||||
private trackId: string;
|
||||
private savedState: TimelineTrack[] | null = null;
|
||||
private savedState: SceneTracks | null = null;
|
||||
|
||||
constructor(
|
||||
private type: TrackType,
|
||||
@@ -21,21 +21,28 @@ export class AddTrackCommand extends Command {
|
||||
|
||||
execute(): CommandResult | undefined {
|
||||
const editor = EditorCore.getInstance();
|
||||
this.savedState = editor.timeline.getTracks();
|
||||
this.savedState = editor.scenes.getActiveScene().tracks;
|
||||
|
||||
const newTrack: TimelineTrack = buildEmptyTrack({
|
||||
id: this.trackId,
|
||||
type: this.type,
|
||||
});
|
||||
|
||||
const updatedTracks = [...(this.savedState || [])];
|
||||
const insertIndex =
|
||||
this.index ??
|
||||
getDefaultInsertIndexForTrack({
|
||||
tracks: updatedTracks,
|
||||
tracks: this.savedState,
|
||||
trackType: this.type,
|
||||
});
|
||||
updatedTracks.splice(insertIndex, 0, newTrack);
|
||||
|
||||
const updatedTracks =
|
||||
this.type === "audio"
|
||||
? buildAudioTrackState({
|
||||
tracks: this.savedState,
|
||||
insertIndex,
|
||||
trackId: this.trackId,
|
||||
})
|
||||
: buildOverlayTrackState({
|
||||
tracks: this.savedState,
|
||||
insertIndex,
|
||||
trackId: this.trackId,
|
||||
trackType: this.type,
|
||||
});
|
||||
|
||||
editor.timeline.updateTracks(updatedTracks);
|
||||
return undefined;
|
||||
@@ -52,3 +59,60 @@ export class AddTrackCommand extends Command {
|
||||
return this.trackId;
|
||||
}
|
||||
}
|
||||
|
||||
function buildAudioTrackState({
|
||||
tracks,
|
||||
insertIndex,
|
||||
trackId,
|
||||
}: {
|
||||
tracks: SceneTracks;
|
||||
insertIndex: number;
|
||||
trackId: string;
|
||||
}): SceneTracks {
|
||||
const audioInsertIndex = Math.max(
|
||||
0,
|
||||
insertIndex - tracks.overlay.length - 1,
|
||||
);
|
||||
const newTrack = buildEmptyTrack({
|
||||
id: trackId,
|
||||
type: "audio",
|
||||
});
|
||||
return {
|
||||
...tracks,
|
||||
audio: [
|
||||
...tracks.audio.slice(0, audioInsertIndex),
|
||||
newTrack,
|
||||
...tracks.audio.slice(audioInsertIndex),
|
||||
],
|
||||
};
|
||||
}
|
||||
|
||||
function buildOverlayTrackState({
|
||||
tracks,
|
||||
insertIndex,
|
||||
trackId,
|
||||
trackType,
|
||||
}: {
|
||||
tracks: SceneTracks;
|
||||
insertIndex: number;
|
||||
trackId: string;
|
||||
trackType: Exclude<TrackType, "audio">;
|
||||
}): SceneTracks {
|
||||
const overlayInsertIndex = Math.min(insertIndex, tracks.overlay.length);
|
||||
const newTrack =
|
||||
trackType === "video"
|
||||
? buildEmptyTrack({ id: trackId, type: "video" })
|
||||
: trackType === "text"
|
||||
? buildEmptyTrack({ id: trackId, type: "text" })
|
||||
: trackType === "graphic"
|
||||
? buildEmptyTrack({ id: trackId, type: "graphic" })
|
||||
: buildEmptyTrack({ id: trackId, type: "effect" });
|
||||
return {
|
||||
...tracks,
|
||||
overlay: [
|
||||
...tracks.overlay.slice(0, overlayInsertIndex),
|
||||
newTrack,
|
||||
...tracks.overlay.slice(overlayInsertIndex),
|
||||
],
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user