feat: masks, properties refactor, shaders, storage migrations, and more

This commit is contained in:
Maze Winther
2026-03-29 15:48:22 +02:00
parent 39ea298a9c
commit 8db3bead13
690 changed files with 35618 additions and 7337 deletions
+23 -4
View File
@@ -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];
}
+79
View File
@@ -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;
};
+26 -1
View File
@@ -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);
});
};
+2
View File
@@ -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> = {