From 2272598d420cf078aaa3928246bfa3a414f6eddb Mon Sep 17 00:00:00 2001 From: Maze Winther Date: Mon, 13 Apr 2026 04:40:56 +0200 Subject: feat: clipboard with keyframe paste Made-with: Cursor --- apps/web/src/hooks/actions/use-editor-actions.ts | 43 +++++++----------------- 1 file changed, 12 insertions(+), 31 deletions(-) (limited to 'apps/web/src/hooks/actions') diff --git a/apps/web/src/hooks/actions/use-editor-actions.ts b/apps/web/src/hooks/actions/use-editor-actions.ts index be04a7d3..1c4735bb 100644 --- a/apps/web/src/hooks/actions/use-editor-actions.ts +++ b/apps/web/src/hooks/actions/use-editor-actions.ts @@ -7,10 +7,7 @@ import { useEditor } from "../use-editor"; import { useElementSelection } from "../timeline/element/use-element-selection"; import { TICKS_PER_SECOND } from "@/lib/wasm"; import { useKeyframeSelection } from "../timeline/element/use-keyframe-selection"; -import { - getElementsAtTime, - hasMediaId, -} from "@/lib/timeline"; +import { getElementsAtTime, hasMediaId } from "@/lib/timeline"; import { cancelInteraction } from "@/lib/cancel-interaction"; import { invokeAction } from "@/lib/actions"; import { canToggleSourceAudio } from "@/lib/timeline/audio-separation"; @@ -24,8 +21,6 @@ export function useEditorActions() { const editor = useEditor(); const { selectedElements, setElementSelection } = useElementSelection(); const { selectedKeyframes, clearKeyframeSelection } = useKeyframeSelection(); - const clipboard = useTimelineStore((s) => s.clipboard); - const setClipboard = useTimelineStore((s) => s.setClipboard); const toggleSnapping = useTimelineStore((s) => s.toggleSnapping); const rippleEditingEnabled = useTimelineStore((s) => s.rippleEditingEnabled); const toggleRippleEditing = useTimelineStore((s) => s.toggleRippleEditing); @@ -111,7 +106,9 @@ export function useEditorActions() { "frame-step-forward", () => { const fps = editor.project.getActive().settings.fps; - const ticksPerFrame = Math.round(TICKS_PER_SECOND * fps.denominator / fps.numerator); + const ticksPerFrame = Math.round( + (TICKS_PER_SECOND * fps.denominator) / fps.numerator, + ); editor.playback.seek({ time: Math.min( editor.timeline.getTotalDuration(), @@ -126,7 +123,9 @@ export function useEditorActions() { "frame-step-backward", () => { const fps = editor.project.getActive().settings.fps; - const ticksPerFrame = Math.round(TICKS_PER_SECOND * fps.denominator / fps.numerator); + const ticksPerFrame = Math.round( + (TICKS_PER_SECOND * fps.denominator) / fps.numerator, + ); editor.playback.seek({ time: Math.max(0, editor.playback.getCurrentTime() - ticksPerFrame), }); @@ -294,8 +293,9 @@ export function useEditorActions() { } return ( - editor.media.getAssets().find((asset) => asset.id === element.mediaId) ?? - null + editor.media + .getAssets() + .find((asset) => asset.id === element.mediaId) ?? null ); })(); if (!canToggleSourceAudio(selectedElement.element, mediaAsset)) { @@ -387,21 +387,7 @@ export function useEditorActions() { useActionHandler( "copy-selected", () => { - if (selectedElements.length === 0) return; - - const results = editor.timeline.getElementsWithTracks({ - elements: selectedElements, - }); - const items = results.map(({ track, element }) => { - const { id: _, ...elementWithoutId } = element; - return { - trackId: track.id, - trackType: track.type, - element: elementWithoutId, - }; - }); - - setClipboard({ items }); + editor.clipboard.copy(); }, undefined, ); @@ -409,12 +395,7 @@ export function useEditorActions() { useActionHandler( "paste-copied", () => { - if (!clipboard?.items.length) return; - - editor.timeline.pasteAtTime({ - time: editor.playback.getCurrentTime(), - clipboardItems: clipboard.items, - }); + editor.clipboard.paste(); }, undefined, ); -- cgit v1.3.1