summaryrefslogtreecommitdiff
path: root/apps/web/src/lib/commands/timeline/clipboard
diff options
context:
space:
mode:
authorMaze Winther <mazewinther@gmail.com>2026-04-22 14:36:51 +0200
committerMaze Winther <mazewinther@gmail.com>2026-04-22 14:36:51 +0200
commitf1b45b4328cff6a016720ce7b38b87ac2992dc2d (patch)
tree16b816caa0ecf9f7ae680d7f440667ecd57b748d /apps/web/src/lib/commands/timeline/clipboard
parent7428dc75cfef15481ad747806e81309a5a99e3a9 (diff)
downloadopencut-f1b45b4328cff6a016720ce7b38b87ac2992dc2d.tar.gz
chore: remove stale files
Diffstat (limited to 'apps/web/src/lib/commands/timeline/clipboard')
-rw-r--r--apps/web/src/lib/commands/timeline/clipboard/paste.ts193
1 files changed, 0 insertions, 193 deletions
diff --git a/apps/web/src/lib/commands/timeline/clipboard/paste.ts b/apps/web/src/lib/commands/timeline/clipboard/paste.ts
deleted file mode 100644
index 58199a94..00000000
--- a/apps/web/src/lib/commands/timeline/clipboard/paste.ts
+++ /dev/null
@@ -1,193 +0,0 @@
-import {
- Command,
- createElementSelectionResult,
- type CommandResult,
-} from "@/lib/commands/base-command";
-import { EditorCore } from "@/core";
-import type { SceneTracks, TimelineElement } from "@/lib/timeline";
-import type { ElementClipboardItem } from "@/lib/clipboard";
-import { generateUUID } from "@/utils/id";
-import {
- applyPlacement,
- resolveTrackPlacement,
- enforceMainTrackStart,
-} from "@/lib/timeline/placement";
-import { cloneAnimations } from "@/lib/animation";
-
-export class PasteCommand extends Command {
- private savedState: SceneTracks | null = null;
- private pastedElements: { trackId: string; elementId: string }[] = [];
- private readonly time: number;
- private readonly clipboardItems: ElementClipboardItem[];
-
- constructor({
- time,
- clipboardItems,
- }: {
- time: number;
- clipboardItems: ElementClipboardItem[];
- }) {
- super();
- this.time = time;
- this.clipboardItems = clipboardItems;
- }
-
- execute(): CommandResult | undefined {
- if (this.clipboardItems.length === 0) return undefined;
-
- const editor = EditorCore.getInstance();
- this.savedState = editor.scenes.getActiveScene().tracks;
- this.pastedElements = [];
-
- const minStart = Math.min(
- ...this.clipboardItems.map((item) => item.element.startTime),
- );
-
- let updatedTracks = this.savedState;
- const itemsByTrackId = groupClipboardItemsByTrackId({
- clipboardItems: this.clipboardItems,
- });
-
- for (const [trackId, items] of itemsByTrackId) {
- const elementsToAdd = buildPastedElements({
- items,
- minStart,
- time: this.time,
- });
-
- if (elementsToAdd.length === 0) {
- continue;
- }
-
- const trackType = items[0].trackType;
- const sourceTrackIndex = [
- ...updatedTracks.overlay,
- updatedTracks.main,
- ...updatedTracks.audio,
- ].findIndex((track) => track.id === trackId);
- const placementResult = resolveTrackPlacement({
- tracks: updatedTracks,
- trackType,
- timeSpans: elementsToAdd.map((element) => ({
- startTime: element.startTime,
- duration: element.duration,
- })),
- strategy: { type: "aboveSource", sourceTrackIndex },
- });
- if (!placementResult) {
- continue;
- }
-
- let elementsForPlacement = elementsToAdd;
- if (placementResult.kind === "existingTrack") {
- const targetTrack =
- placementResult.trackIndex < updatedTracks.overlay.length
- ? updatedTracks.overlay[placementResult.trackIndex]
- : placementResult.trackIndex === updatedTracks.overlay.length
- ? updatedTracks.main
- : updatedTracks.audio[
- placementResult.trackIndex - updatedTracks.overlay.length - 1
- ];
- if (targetTrack?.id === updatedTracks.main.id) {
- const earliestElement = elementsToAdd.reduce((earliest, element) =>
- element.startTime < earliest.startTime ? element : earliest,
- );
- const adjustedEarliestStartTime = enforceMainTrackStart({
- tracks: updatedTracks,
- targetTrackId: targetTrack.id,
- requestedStartTime: earliestElement.startTime,
- });
- const delta = adjustedEarliestStartTime - earliestElement.startTime;
-
- if (delta !== 0) {
- elementsForPlacement = elementsToAdd.map((element) => ({
- ...element,
- startTime: Math.max(0, element.startTime + delta),
- }));
- }
- }
- }
-
- const applied = applyPlacement({
- tracks: updatedTracks,
- placementResult,
- elements: elementsForPlacement,
- });
- if (!applied) {
- continue;
- }
-
- updatedTracks = applied.updatedTracks;
-
- for (const element of elementsForPlacement) {
- this.pastedElements.push({
- trackId: applied.targetTrackId,
- elementId: element.id,
- });
- }
- }
-
- editor.timeline.updateTracks(updatedTracks);
-
- if (this.pastedElements.length > 0) {
- return createElementSelectionResult(this.pastedElements);
- }
- return undefined;
- }
-
- undo(): void {
- if (this.savedState) {
- const editor = EditorCore.getInstance();
- editor.timeline.updateTracks(this.savedState);
- }
- }
-
- getPastedElements(): { trackId: string; elementId: string }[] {
- return this.pastedElements;
- }
-}
-
-function groupClipboardItemsByTrackId({
- clipboardItems,
-}: {
- clipboardItems: ElementClipboardItem[];
-}): Map<string, ElementClipboardItem[]> {
- const groupedItems = new Map<string, ElementClipboardItem[]>();
-
- for (const item of clipboardItems) {
- const existingItems = groupedItems.get(item.trackId) ?? [];
- groupedItems.set(item.trackId, [...existingItems, item]);
- }
-
- return groupedItems;
-}
-
-function buildPastedElements({
- items,
- minStart,
- time,
-}: {
- items: ElementClipboardItem[];
- minStart: number;
- time: number;
-}): TimelineElement[] {
- const elementsToAdd: TimelineElement[] = [];
-
- for (const item of items) {
- const relativeOffset = item.element.startTime - minStart;
- const startTime = Math.max(0, time + relativeOffset);
- const newElementId = generateUUID();
-
- elementsToAdd.push({
- ...item.element,
- id: newElementId,
- startTime,
- animations: cloneAnimations({
- animations: item.element.animations,
- shouldRegenerateKeyframeIds: true,
- }),
- } as TimelineElement);
- }
-
- return elementsToAdd;
-}