diff options
| author | Maze Winther <mazewinther@gmail.com> | 2026-04-13 04:40:56 +0200 |
|---|---|---|
| committer | Maze Winther <mazewinther@gmail.com> | 2026-04-13 05:03:10 +0200 |
| commit | 2272598d420cf078aaa3928246bfa3a414f6eddb (patch) | |
| tree | b52460a2e3576c9e517ef8a9dd86959a68f31b69 /apps/web/src/core/managers | |
| parent | 5a2aaf3601b6b050603f51e487a31fb07862a21f (diff) | |
| download | opencut-2272598d420cf078aaa3928246bfa3a414f6eddb.tar.gz | |
feat: clipboard with keyframe paste
Made-with: Cursor
Diffstat (limited to 'apps/web/src/core/managers')
| -rw-r--r-- | apps/web/src/core/managers/clipboard-manager.ts | 81 |
1 files changed, 81 insertions, 0 deletions
diff --git a/apps/web/src/core/managers/clipboard-manager.ts b/apps/web/src/core/managers/clipboard-manager.ts new file mode 100644 index 00000000..b19343df --- /dev/null +++ b/apps/web/src/core/managers/clipboard-manager.ts @@ -0,0 +1,81 @@ +import type { EditorCore } from "@/core"; +import { + buildPasteClipboardCommand, + copyClipboardEntry, + type ClipboardEntry, + type CopyContext, + type PasteContext, +} from "@/lib/clipboard"; + +export class ClipboardManager { + private entry: ClipboardEntry | null = null; + private listeners = new Set<() => void>(); + + constructor(private editor: EditorCore) {} + + getEntry(): ClipboardEntry | null { + return this.entry; + } + + hasEntry(): boolean { + return this.entry !== null; + } + + copy(): boolean { + const entry = copyClipboardEntry({ + context: this.getCopyContext(), + }); + if (!entry) { + return false; + } + + this.entry = entry; + this.notify(); + return true; + } + + paste({ time }: { time?: number } = {}): boolean { + if (!this.entry) { + return false; + } + + const command = buildPasteClipboardCommand({ + entry: this.entry, + context: this.getPasteContext({ time }), + }); + if (!command) { + return false; + } + + this.editor.command.execute({ command }); + return true; + } + + subscribe(listener: () => void): () => void { + this.listeners.add(listener); + return () => this.listeners.delete(listener); + } + + private getCopyContext(): CopyContext { + return { + editor: this.editor, + selectedElements: this.editor.selection.getSelectedElements(), + selectedKeyframes: this.editor.selection.getSelectedKeyframes(), + }; + } + + private getPasteContext({ time }: { time?: number }): PasteContext { + return { + editor: this.editor, + selectedElements: this.editor.selection.getSelectedElements(), + selectedKeyframes: this.editor.selection.getSelectedKeyframes(), + time: time ?? this.editor.playback.getCurrentTime(), + }; + } + + private notify(): void { + this.listeners.forEach((listener) => { + listener(); + }); + } +} |
