mirror of
https://github.com/OpenCut-app/OpenCut.git
synced 2026-07-13 21:52:53 +02:00
feat: masks, properties refactor, shaders, storage migrations, and more
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
import type { ShortcutKey } from "@/types/keybinding";
|
||||
import type { ShortcutKey } from "@/lib/actions/keybinding";
|
||||
|
||||
export type TActionCategory =
|
||||
| "playback"
|
||||
@@ -7,7 +7,8 @@ export type TActionCategory =
|
||||
| "selection"
|
||||
| "history"
|
||||
| "timeline"
|
||||
| "controls";
|
||||
| "controls"
|
||||
| "assets";
|
||||
|
||||
export interface TActionDefinition {
|
||||
description: string;
|
||||
@@ -114,10 +115,14 @@ export const ACTIONS = {
|
||||
category: "selection",
|
||||
defaultShortcuts: ["ctrl+a"],
|
||||
},
|
||||
"cancel-interaction": {
|
||||
description: "Cancel current interaction",
|
||||
category: "controls",
|
||||
defaultShortcuts: ["escape"],
|
||||
},
|
||||
"deselect-all": {
|
||||
description: "Deselect all elements",
|
||||
category: "selection",
|
||||
defaultShortcuts: ["escape"],
|
||||
},
|
||||
"duplicate-selected": {
|
||||
description: "Duplicate selected element",
|
||||
@@ -146,11 +151,25 @@ export const ACTIONS = {
|
||||
category: "history",
|
||||
defaultShortcuts: ["ctrl+shift+z", "ctrl+y"],
|
||||
},
|
||||
"remove-media-asset": {
|
||||
description: "Remove media asset",
|
||||
category: "assets",
|
||||
args: { projectId: "string", assetId: "string" },
|
||||
},
|
||||
"remove-media-assets": {
|
||||
description: "Remove media assets",
|
||||
category: "assets",
|
||||
args: { projectId: "string", assetIds: "string[]" },
|
||||
},
|
||||
} as const satisfies Record<string, TActionDefinition>;
|
||||
|
||||
export type TAction = keyof typeof ACTIONS;
|
||||
|
||||
export function getActionDefinition({ action }: { action: TAction }): TActionDefinition {
|
||||
export function getActionDefinition({
|
||||
action,
|
||||
}: {
|
||||
action: TAction;
|
||||
}): TActionDefinition {
|
||||
return ACTIONS[action];
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,79 @@
|
||||
import type { TActionWithOptionalArgs } from "./types";
|
||||
|
||||
/**
|
||||
* Alt is also regarded as macOS OPTION (⌥) key
|
||||
* Ctrl is also regarded as macOS COMMAND (⌘) key (NOTE: this differs from HTML Keyboard spec where COMMAND is Meta key!)
|
||||
*/
|
||||
export type ModifierKeys =
|
||||
| "ctrl"
|
||||
| "alt"
|
||||
| "shift"
|
||||
| "ctrl+shift"
|
||||
| "alt+shift"
|
||||
| "ctrl+alt"
|
||||
| "ctrl+alt+shift";
|
||||
|
||||
export type Key =
|
||||
| "a"
|
||||
| "b"
|
||||
| "c"
|
||||
| "d"
|
||||
| "e"
|
||||
| "f"
|
||||
| "g"
|
||||
| "h"
|
||||
| "i"
|
||||
| "j"
|
||||
| "k"
|
||||
| "l"
|
||||
| "m"
|
||||
| "n"
|
||||
| "o"
|
||||
| "p"
|
||||
| "q"
|
||||
| "r"
|
||||
| "s"
|
||||
| "t"
|
||||
| "u"
|
||||
| "v"
|
||||
| "w"
|
||||
| "x"
|
||||
| "y"
|
||||
| "z"
|
||||
| "0"
|
||||
| "1"
|
||||
| "2"
|
||||
| "3"
|
||||
| "4"
|
||||
| "5"
|
||||
| "6"
|
||||
| "7"
|
||||
| "8"
|
||||
| "9"
|
||||
| "up"
|
||||
| "down"
|
||||
| "left"
|
||||
| "right"
|
||||
| "/"
|
||||
| "?"
|
||||
| "."
|
||||
| "enter"
|
||||
| "tab"
|
||||
| "space"
|
||||
| "escape"
|
||||
| "esc"
|
||||
| "backspace"
|
||||
| "delete"
|
||||
| "home"
|
||||
| "end";
|
||||
/* eslint-enable */
|
||||
|
||||
export type ModifierBasedShortcutKey = `${ModifierKeys}+${Key}`;
|
||||
// Singular keybindings (these will be disabled when an input-ish area has been focused)
|
||||
export type SingleCharacterShortcutKey = `${Key}`;
|
||||
|
||||
export type ShortcutKey = ModifierBasedShortcutKey | SingleCharacterShortcutKey;
|
||||
|
||||
export type KeybindingConfig = {
|
||||
[key in ShortcutKey]?: TActionWithOptionalArgs;
|
||||
};
|
||||
@@ -57,5 +57,30 @@ export const invokeAction: InvokeActionFunc = <A extends TAction>(
|
||||
args?: TArgOfAction<A>,
|
||||
trigger?: TInvocationTrigger,
|
||||
) => {
|
||||
boundActions[action]?.forEach((handler) => handler(args, trigger));
|
||||
if (trigger === "keypress") {
|
||||
// #region agent log
|
||||
fetch("http://127.0.0.1:7245/ingest/669b22f8-172b-4e65-aa3f-1c702ede83f7", {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
"X-Debug-Session-Id": "3997d9",
|
||||
},
|
||||
body: JSON.stringify({
|
||||
sessionId: "3997d9",
|
||||
runId: "initial",
|
||||
hypothesisId: "H4",
|
||||
location: "actions/registry.ts:invokeAction",
|
||||
message: "Action invoked from keypress",
|
||||
data: {
|
||||
action,
|
||||
handlerCount: boundActions[action]?.length ?? 0,
|
||||
},
|
||||
timestamp: Date.now(),
|
||||
}),
|
||||
}).catch(() => {});
|
||||
// #endregion
|
||||
}
|
||||
boundActions[action]?.forEach((handler) => {
|
||||
handler(args, trigger);
|
||||
});
|
||||
};
|
||||
|
||||
@@ -8,6 +8,8 @@ export type TActionArgsMap = {
|
||||
"seek-backward": { seconds: number } | undefined;
|
||||
"jump-forward": { seconds: number } | undefined;
|
||||
"jump-backward": { seconds: number } | undefined;
|
||||
"remove-media-asset": { projectId: string; assetId: string };
|
||||
"remove-media-assets": { projectId: string; assetIds: string[] };
|
||||
};
|
||||
|
||||
type TKeysWithValueUndefined<T> = {
|
||||
|
||||
Reference in New Issue
Block a user