mirror of
https://github.com/OpenCut-app/OpenCut.git
synced 2026-07-13 21:52:53 +02:00
chore: normalize line endings
This commit is contained in:
+85
-85
@@ -1,85 +1,85 @@
|
||||
# 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<string, string>; 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> | 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<boolean>` — reactive, toggled at runtime (e.g. only active when a panel is focused)
|
||||
# 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<string, string>; 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> | 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<boolean>` — reactive, toggled at runtime (e.g. only active when a panel is focused)
|
||||
|
||||
Reference in New Issue
Block a user