summaryrefslogtreecommitdiff
path: root/apps/web/src/lib/commands/timeline/clipboard/paste.ts
diff options
context:
space:
mode:
authorMaze Winther <mazewinther@gmail.com>2026-02-08 01:51:25 +0100
committerMaze Winther <mazewinther@gmail.com>2026-02-08 01:51:25 +0100
commit9b5fd6eb077a3fb2380f42414b65405030a01fcd (patch)
tree91d56e1c71e9a876afb1ae39fe4644ed8d5accee /apps/web/src/lib/commands/timeline/clipboard/paste.ts
parent00cf7f6ab7b35616290cfeab06256a14f6d4beba (diff)
downloadopencut-9b5fd6eb077a3fb2380f42414b65405030a01fcd.tar.gz
feat: ensure elements on main track starts at 0
Diffstat (limited to 'apps/web/src/lib/commands/timeline/clipboard/paste.ts')
-rw-r--r--apps/web/src/lib/commands/timeline/clipboard/paste.ts27
1 files changed, 25 insertions, 2 deletions
diff --git a/apps/web/src/lib/commands/timeline/clipboard/paste.ts b/apps/web/src/lib/commands/timeline/clipboard/paste.ts
index 9c979790..39feb8ce 100644
--- a/apps/web/src/lib/commands/timeline/clipboard/paste.ts
+++ b/apps/web/src/lib/commands/timeline/clipboard/paste.ts
@@ -10,6 +10,8 @@ import { wouldElementOverlap } from "@/lib/timeline/element-utils";
import {
buildEmptyTrack,
getHighestInsertIndexForTrack,
+ isMainTrack,
+ enforceMainTrackStart,
} from "@/lib/timeline/track-utils";
export class PasteCommand extends Command {
@@ -65,11 +67,32 @@ export class PasteCommand extends Command {
if (resolvedTargetIndex >= 0) {
const targetTrack = updatedTracks[resolvedTargetIndex];
+ let adjustedElements = elementsToAdd;
+
+ if (isMainTrack(targetTrack)) {
+ 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) {
+ adjustedElements = elementsToAdd.map((element) => ({
+ ...element,
+ startTime: Math.max(0, element.startTime + delta),
+ }));
+ }
+ }
+
updatedTracks[resolvedTargetIndex] = {
...targetTrack,
- elements: [...targetTrack.elements, ...elementsToAdd],
+ elements: [...targetTrack.elements, ...adjustedElements],
} as TimelineTrack;
- for (const element of elementsToAdd) {
+ for (const element of adjustedElements) {
this.pastedElements.push({
trackId: targetTrack.id,
elementId: element.id,