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/hooks/use-editor.ts | |
| parent | 5a2aaf3601b6b050603f51e487a31fb07862a21f (diff) | |
| download | opencut-2272598d420cf078aaa3928246bfa3a414f6eddb.tar.gz | |
feat: clipboard with keyframe paste
Made-with: Cursor
Diffstat (limited to 'apps/web/src/hooks/use-editor.ts')
| -rw-r--r-- | apps/web/src/hooks/use-editor.ts | 117 |
1 files changed, 59 insertions, 58 deletions
diff --git a/apps/web/src/hooks/use-editor.ts b/apps/web/src/hooks/use-editor.ts index bafa6cf7..1a5ca8ae 100644 --- a/apps/web/src/hooks/use-editor.ts +++ b/apps/web/src/hooks/use-editor.ts @@ -1,58 +1,59 @@ -import { useCallback, useMemo, useRef, useSyncExternalStore } from "react";
-import { EditorCore } from "@/core";
-
-function isShallowEqual(a: unknown, b: unknown): boolean {
- if (Object.is(a, b)) return true;
- if (!Array.isArray(a) || !Array.isArray(b)) return false;
- if (a.length !== b.length) return false;
- return a.every((item, i) => Object.is(item, b[i]));
-}
-
-const subscribeNone = () => () => {};
-
-export function useEditor(): EditorCore;
-export function useEditor<T>(selector: (editor: EditorCore) => T): T;
-export function useEditor<T>(
- selector?: (editor: EditorCore) => T,
-): EditorCore | T {
- const editor = useMemo(() => EditorCore.getInstance(), []);
- const selectorRef = useRef(selector);
- selectorRef.current = selector;
-
- const snapshotCacheRef = useRef<unknown>(undefined);
-
- const subscribeAll = useCallback(
- (onChange: () => void) => {
- const unsubscribers = [
- editor.playback.subscribe(onChange),
- editor.timeline.subscribe(onChange),
- editor.scenes.subscribe(onChange),
- editor.project.subscribe(onChange),
- editor.media.subscribe(onChange),
- editor.renderer.subscribe(onChange),
- editor.selection.subscribe(onChange),
- ];
- return () => {
- unsubscribers.forEach((unsubscribe) => {
- unsubscribe();
- });
- };
- },
- [editor],
- );
-
- const getSnapshot = useCallback(() => {
- const next = selectorRef.current ? selectorRef.current(editor) : editor;
- if (isShallowEqual(snapshotCacheRef.current, next)) {
- return snapshotCacheRef.current;
- }
- snapshotCacheRef.current = next;
- return next;
- }, [editor]);
-
- return useSyncExternalStore(
- selector ? subscribeAll : subscribeNone,
- getSnapshot,
- getSnapshot,
- ) as EditorCore | T;
-}
+import { useCallback, useMemo, useRef, useSyncExternalStore } from "react"; +import { EditorCore } from "@/core"; + +function isShallowEqual(a: unknown, b: unknown): boolean { + if (Object.is(a, b)) return true; + if (!Array.isArray(a) || !Array.isArray(b)) return false; + if (a.length !== b.length) return false; + return a.every((item, i) => Object.is(item, b[i])); +} + +const subscribeNone = () => () => {}; + +export function useEditor(): EditorCore; +export function useEditor<T>(selector: (editor: EditorCore) => T): T; +export function useEditor<T>( + selector?: (editor: EditorCore) => T, +): EditorCore | T { + const editor = useMemo(() => EditorCore.getInstance(), []); + const selectorRef = useRef(selector); + selectorRef.current = selector; + + const snapshotCacheRef = useRef<unknown>(undefined); + + const subscribeAll = useCallback( + (onChange: () => void) => { + const unsubscribers = [ + editor.playback.subscribe(onChange), + editor.timeline.subscribe(onChange), + editor.scenes.subscribe(onChange), + editor.project.subscribe(onChange), + editor.media.subscribe(onChange), + editor.renderer.subscribe(onChange), + editor.selection.subscribe(onChange), + editor.clipboard.subscribe(onChange), + ]; + return () => { + unsubscribers.forEach((unsubscribe) => { + unsubscribe(); + }); + }; + }, + [editor], + ); + + const getSnapshot = useCallback(() => { + const next = selectorRef.current ? selectorRef.current(editor) : editor; + if (isShallowEqual(snapshotCacheRef.current, next)) { + return snapshotCacheRef.current; + } + snapshotCacheRef.current = next; + return next; + }, [editor]); + + return useSyncExternalStore( + selector ? subscribeAll : subscribeNone, + getSnapshot, + getSnapshot, + ) as EditorCore | T; +} |
