summaryrefslogtreecommitdiff
path: root/apps/web/src/hooks/actions/use-editor-actions.ts
diff options
context:
space:
mode:
Diffstat (limited to 'apps/web/src/hooks/actions/use-editor-actions.ts')
-rw-r--r--apps/web/src/hooks/actions/use-editor-actions.ts312
1 files changed, 312 insertions, 0 deletions
diff --git a/apps/web/src/hooks/actions/use-editor-actions.ts b/apps/web/src/hooks/actions/use-editor-actions.ts
new file mode 100644
index 00000000..d1ff6c92
--- /dev/null
+++ b/apps/web/src/hooks/actions/use-editor-actions.ts
@@ -0,0 +1,312 @@
+"use client";
+
+import { useTimelineStore } from "@/stores/timeline-store";
+import { useActionHandler } from "@/hooks/actions/use-action-handler";
+import { useEditor } from "../use-editor";
+import { useElementSelection } from "../timeline/element/use-element-selection";
+import { getElementsAtTime } from "@/lib/timeline";
+
+export function useEditorActions() {
+ const editor = useEditor();
+ const activeProject = editor.project.getActive();
+ const { selectedElements, setElementSelection } = useElementSelection();
+ const { clipboard, setClipboard, toggleSnapping } = useTimelineStore();
+
+ useActionHandler(
+ "toggle-play",
+ () => {
+ editor.playback.toggle();
+ },
+ undefined,
+ );
+
+ useActionHandler(
+ "stop-playback",
+ () => {
+ if (editor.playback.getIsPlaying()) {
+ editor.playback.toggle();
+ }
+ editor.playback.seek({ time: 0 });
+ },
+ undefined,
+ );
+
+ useActionHandler(
+ "seek-forward",
+ (args) => {
+ const seconds = args?.seconds ?? 1;
+ editor.playback.seek({
+ time: Math.min(
+ editor.timeline.getTotalDuration(),
+ editor.playback.getCurrentTime() + seconds,
+ ),
+ });
+ },
+ undefined,
+ );
+
+ useActionHandler(
+ "seek-backward",
+ (args) => {
+ const seconds = args?.seconds ?? 1;
+ editor.playback.seek({
+ time: Math.max(0, editor.playback.getCurrentTime() - seconds),
+ });
+ },
+ undefined,
+ );
+
+ useActionHandler(
+ "frame-step-forward",
+ () => {
+ const fps = activeProject.settings.fps;
+ editor.playback.seek({
+ time: Math.min(
+ editor.timeline.getTotalDuration(),
+ editor.playback.getCurrentTime() + 1 / fps,
+ ),
+ });
+ },
+ undefined,
+ );
+
+ useActionHandler(
+ "frame-step-backward",
+ () => {
+ const fps = activeProject.settings.fps;
+ editor.playback.seek({
+ time: Math.max(0, editor.playback.getCurrentTime() - 1 / fps),
+ });
+ },
+ undefined,
+ );
+
+ useActionHandler(
+ "jump-forward",
+ (args) => {
+ const seconds = args?.seconds ?? 5;
+ editor.playback.seek({
+ time: Math.min(
+ editor.timeline.getTotalDuration(),
+ editor.playback.getCurrentTime() + seconds,
+ ),
+ });
+ },
+ undefined,
+ );
+
+ useActionHandler(
+ "jump-backward",
+ (args) => {
+ const seconds = args?.seconds ?? 5;
+ editor.playback.seek({
+ time: Math.max(0, editor.playback.getCurrentTime() - seconds),
+ });
+ },
+ undefined,
+ );
+
+ useActionHandler(
+ "goto-start",
+ () => {
+ editor.playback.seek({ time: 0 });
+ },
+ undefined,
+ );
+
+ useActionHandler(
+ "goto-end",
+ () => {
+ editor.playback.seek({ time: editor.timeline.getTotalDuration() });
+ },
+ undefined,
+ );
+
+ useActionHandler(
+ "split",
+ () => {
+ const currentTime = editor.playback.getCurrentTime();
+ const elementsToSplit =
+ selectedElements.length > 0
+ ? selectedElements
+ : getElementsAtTime({
+ tracks: editor.timeline.getTracks(),
+ time: currentTime,
+ });
+
+ if (elementsToSplit.length === 0) return;
+
+ editor.timeline.splitElements({
+ elements: elementsToSplit,
+ splitTime: currentTime,
+ });
+ },
+ undefined,
+ );
+
+ useActionHandler(
+ "split-left",
+ () => {
+ const currentTime = editor.playback.getCurrentTime();
+ const elementsToSplit =
+ selectedElements.length > 0
+ ? selectedElements
+ : getElementsAtTime({
+ tracks: editor.timeline.getTracks(),
+ time: currentTime,
+ });
+
+ if (elementsToSplit.length === 0) return;
+
+ editor.timeline.splitElements({
+ elements: elementsToSplit,
+ splitTime: currentTime,
+ retainSide: "right",
+ });
+ },
+ undefined,
+ );
+
+ useActionHandler(
+ "split-right",
+ () => {
+ const currentTime = editor.playback.getCurrentTime();
+ const elementsToSplit =
+ selectedElements.length > 0
+ ? selectedElements
+ : getElementsAtTime({
+ tracks: editor.timeline.getTracks(),
+ time: currentTime,
+ });
+
+ if (elementsToSplit.length === 0) return;
+
+ editor.timeline.splitElements({
+ elements: elementsToSplit,
+ splitTime: currentTime,
+ retainSide: "left",
+ });
+ },
+ undefined,
+ );
+
+ useActionHandler(
+ "delete-selected",
+ () => {
+ if (selectedElements.length === 0) {
+ return;
+ }
+ editor.timeline.deleteElements({
+ elements: selectedElements,
+ });
+ },
+ undefined,
+ );
+
+ useActionHandler(
+ "select-all",
+ () => {
+ const allElements = editor.timeline.getTracks().flatMap((track) =>
+ track.elements.map((element) => ({
+ trackId: track.id,
+ elementId: element.id,
+ })),
+ );
+ setElementSelection({ elements: allElements });
+ },
+ undefined,
+ );
+
+ useActionHandler(
+ "duplicate-selected",
+ () => {
+ editor.timeline.duplicateElements({
+ elements: selectedElements,
+ });
+ },
+ undefined,
+ );
+
+ useActionHandler(
+ "toggle-elements-muted-selected",
+ () => {
+ editor.timeline.toggleElementsMuted({ elements: selectedElements });
+ },
+ undefined,
+ );
+
+ useActionHandler(
+ "toggle-elements-visibility-selected",
+ () => {
+ editor.timeline.toggleElementsVisibility({ elements: selectedElements });
+ },
+ undefined,
+ );
+
+ useActionHandler(
+ "toggle-bookmark",
+ () => {
+ editor.scenes.toggleBookmark({ time: editor.playback.getCurrentTime() });
+ },
+ undefined,
+ );
+
+ useActionHandler(
+ "copy-selected",
+ () => {
+ if (selectedElements.length === 0) return;
+
+ const results = editor.timeline.getElementsWithTracks({
+ elements: selectedElements,
+ });
+ const items = results.map(({ track, element }) => {
+ const { ...elementWithoutId } = element;
+ return {
+ trackId: track.id,
+ trackType: track.type,
+ element: elementWithoutId,
+ };
+ });
+
+ setClipboard({ items });
+ },
+ undefined,
+ );
+
+ useActionHandler(
+ "paste-copied",
+ () => {
+ if (!clipboard?.items.length) return;
+
+ editor.timeline.pasteAtTime({
+ time: editor.playback.getCurrentTime(),
+ clipboardItems: clipboard.items,
+ });
+ },
+ undefined,
+ );
+
+ useActionHandler(
+ "toggle-snapping",
+ () => {
+ toggleSnapping();
+ },
+ undefined,
+ );
+
+ useActionHandler(
+ "undo",
+ () => {
+ editor.command.undo();
+ },
+ undefined,
+ );
+
+ useActionHandler(
+ "redo",
+ () => {
+ editor.command.redo();
+ },
+ undefined,
+ );
+}