# Actions System Actions are the trigger layer for user-initiated operations. They connect keyboard shortcuts, UI buttons, and context menus to editor functionality. ## Adding a New Action ### 1. Define the action — `src/lib/actions/definitions.ts` Add an entry to the `ACTIONS` object: ```typescript "my-action": { description: "What it does", category: "editing", // playback | navigation | editing | selection | history | timeline | controls defaultShortcuts: ["ctrl+m"], // optional args: { someValue: "number" }, // optional, only if it takes args }, ``` **If your shortcut uses a special key** (not a letter/digit), check `getPressedKey` in `src/stores/keybindings-store.ts` and add a case if it's missing: ```typescript if (key === "escape") return "escape"; ``` **If your action has a `defaultShortcuts`**, also add a keybindings migration so existing users get it (keybindings are persisted in localStorage — new defaults only apply to fresh installs): 1. Create `src/stores/keybindings/migrations/vN-to-vN+1.ts`: ```typescript export function vNToVN1({ state }: { state: unknown }): unknown { const s = state as { keybindings: Record; isCustomized: boolean }; const keybindings = { ...s.keybindings }; if (!keybindings["my-key"]) { keybindings["my-key"] = "my-action"; } return { ...s, keybindings }; } ``` 2. Register it in `src/stores/keybindings/migrations/index.ts` and bump `CURRENT_VERSION`. ### 2. Register the handler — `src/hooks/actions/use-editor-actions.ts` ```typescript useActionHandler( "my-action", () => { editor.timeline.doSomething(); }, undefined, // isActive: MutableRefObject | boolean | undefined ); ``` ### 3. Register arg types (if needed) — `src/lib/actions/types.ts` Only required if your action accepts arguments: ```typescript export type TActionArgsMap = { // ...existing actions... "my-action": { someValue: number } | undefined; // | undefined = optional args }; ``` ## Invoking Actions Use `invokeAction` for any user-triggered operation (buttons, context menus, etc.): ```typescript import { invokeAction } from "@/lib/actions"; invokeAction("my-action"); invokeAction("seek-forward", { seconds: 5 }); ``` Avoid calling `editor.xxx()` directly from UI components — that bypasses the action layer (toasts, validation feedback, keybinding support). ## The `isActive` parameter The third argument to `useActionHandler` controls when the handler is active: - `undefined` — always active - `true` / `false` — statically enabled/disabled - `MutableRefObject` — reactive, toggled at runtime (e.g. only active when a panel is focused)