de-duplicate code

This commit is contained in:
Maze Winther 2026-01-28 15:12:14 +01:00
parent 9de4cee572
commit 6d19841abf
4 changed files with 111 additions and 107 deletions

View File

@ -905,6 +905,28 @@ element-utils.ts
iconName: string;
startTime: number;
}): CreateStickerElement
export function buildVideoElement({
mediaId,
name,
duration,
startTime,
}: {
mediaId: string;
name: string;
duration: number;
startTime: number;
}): CreateVideoElement
export function buildImageElement({
mediaId,
name,
duration,
startTime,
}: {
mediaId: string;
name: string;
duration: number;
startTime: number;
}): CreateImageElement
export function buildUploadAudioElement({
mediaId,
name,

View File

@ -29,6 +29,11 @@ import { useEditor } from "@/hooks/use-editor";
import { useFileUpload } from "@/hooks/use-file-upload";
import { useRevealItem } from "@/hooks/use-reveal-item";
import { processMediaAssets } from "@/lib/media/processing";
import {
buildImageElement,
buildUploadAudioElement,
buildVideoElement,
} from "@/lib/timeline/element-utils";
import { useAssetsPanelStore } from "@/stores/assets-panel-store";
import type { MediaAsset } from "@/types/assets";
import type { CreateTimelineElement } from "@/types/timeline";
@ -644,45 +649,26 @@ function createElementFromMedia({
switch (asset.type) {
case "video":
return {
type: "video",
name: asset.name,
return buildVideoElement({
mediaId: asset.id,
startTime,
name: asset.name,
duration,
trimStart: 0,
trimEnd: 0,
muted: false,
hidden: false,
transform: { scale: 1, position: { x: 0, y: 0 }, rotate: 0 },
opacity: 1,
};
startTime,
});
case "image":
return {
type: "image",
name: asset.name,
return buildImageElement({
mediaId: asset.id,
startTime,
name: asset.name,
duration,
trimStart: 0,
trimEnd: 0,
hidden: false,
transform: { scale: 1, position: { x: 0, y: 0 }, rotate: 0 },
opacity: 1,
};
startTime,
});
case "audio":
return {
type: "audio",
sourceType: "upload",
name: asset.name,
return buildUploadAudioElement({
mediaId: asset.id,
startTime,
name: asset.name,
duration,
trimStart: 0,
trimEnd: 0,
volume: 1,
muted: false,
};
startTime,
});
default:
throw new Error(`Unsupported media type: ${asset.type}`);
}

View File

@ -7,6 +7,9 @@ import { snapTimeToFrame } from "@/lib/time";
import {
buildTextElement,
buildStickerElement,
buildUploadAudioElement,
buildVideoElement,
buildImageElement,
} from "@/lib/timeline/element-utils";
import { computeDropTarget } from "@/lib/timeline/drop-utils";
import { getDragData, hasDragData } from "@/lib/drag-data";
@ -261,62 +264,32 @@ export function useTimelineDragDrop({
if (dragData.mediaType === "audio") {
editor.timeline.insertElement({
placement: { mode: "explicit", trackId },
element: {
type: "audio",
sourceType: "upload",
element: buildUploadAudioElement({
mediaId: mediaAsset.id,
name: mediaAsset.name,
duration,
startTime: target.xPosition,
trimStart: 0,
trimEnd: 0,
volume: 1,
muted: false,
},
}),
});
} else if (dragData.mediaType === "video") {
editor.timeline.insertElement({
placement: { mode: "explicit", trackId },
element: {
type: "video",
element: buildVideoElement({
mediaId: mediaAsset.id,
name: mediaAsset.name,
duration,
startTime: target.xPosition,
trimStart: 0,
trimEnd: 0,
transform: {
scale: 1,
position: {
x: 0,
y: 0,
},
rotate: 0,
},
opacity: 1,
},
}),
});
} else {
editor.timeline.insertElement({
placement: { mode: "explicit", trackId },
element: {
type: "image",
element: buildImageElement({
mediaId: mediaAsset.id,
name: mediaAsset.name,
duration,
startTime: target.xPosition,
trimStart: 0,
trimEnd: 0,
transform: {
scale: 1,
position: {
x: 0,
y: 0,
},
rotate: 0,
},
opacity: 1,
},
}),
});
}
},
@ -377,63 +350,33 @@ export function useTimelineDragDrop({
if (added.type === "audio") {
editor.timeline.insertElement({
placement: { mode: "explicit", trackId },
element: {
type: "audio",
sourceType: "upload",
element: buildUploadAudioElement({
mediaId: added.id,
name: added.name,
duration,
startTime: dropTarget.xPosition,
trimStart: 0,
trimEnd: 0,
volume: 1,
buffer: new AudioBuffer({ length: 1, sampleRate: 44100 }),
muted: false,
},
}),
});
} else if (added.type === "video") {
editor.timeline.insertElement({
placement: { mode: "explicit", trackId },
element: {
type: "video",
element: buildVideoElement({
mediaId: added.id,
name: added.name,
duration,
startTime: dropTarget.xPosition,
trimStart: 0,
trimEnd: 0,
transform: {
scale: 1,
position: {
x: 0,
y: 0,
},
rotate: 0,
},
opacity: 1,
},
}),
});
} else {
editor.timeline.insertElement({
placement: { mode: "explicit", trackId },
element: {
type: "image",
element: buildImageElement({
mediaId: added.id,
name: added.name,
duration,
startTime: dropTarget.xPosition,
trimStart: 0,
trimEnd: 0,
transform: {
scale: 1,
position: {
x: 0,
y: 0,
},
rotate: 0,
},
opacity: 1,
},
}),
});
}
}
@ -486,10 +429,10 @@ export function useTimelineDragDrop({
}
},
[
dropTarget,
executeTextDrop,
executeStickerDrop,
executeMediaDrop,
dropTarget,
executeTextDrop,
executeStickerDrop,
executeMediaDrop,
executeFileDrop,
containerRef,
],

View File

@ -2,6 +2,8 @@ import { DEFAULT_TEXT_ELEMENT } from "@/constants/text-constants";
import { TIMELINE_CONSTANTS } from "@/constants/timeline-constants";
import type {
CreateTimelineElement,
CreateVideoElement,
CreateImageElement,
CreateStickerElement,
CreateUploadAudioElement,
CreateLibraryAudioElement,
@ -165,6 +167,57 @@ export function buildStickerElement({
};
}
export function buildVideoElement({
mediaId,
name,
duration,
startTime,
}: {
mediaId: string;
name: string;
duration: number;
startTime: number;
}): CreateVideoElement {
return {
type: "video",
mediaId,
name,
duration,
startTime,
trimStart: 0,
trimEnd: 0,
muted: false,
hidden: false,
transform: { scale: 1, position: { x: 0, y: 0 }, rotate: 0 },
opacity: 1,
};
}
export function buildImageElement({
mediaId,
name,
duration,
startTime,
}: {
mediaId: string;
name: string;
duration: number;
startTime: number;
}): CreateImageElement {
return {
type: "image",
mediaId,
name,
duration,
startTime,
trimStart: 0,
trimEnd: 0,
hidden: false,
transform: { scale: 1, position: { x: 0, y: 0 }, rotate: 0 },
opacity: 1,
};
}
export function buildUploadAudioElement({
mediaId,
name,