From 38dea70f3aca452e64859eef17c2fa5e4499cbf4 Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Sat, 17 Oct 2026 01:07:41 +0000 Subject: [PATCH 01/23] Fix icons, send targets, and group add/remove. Replace the placeholder action icon with the laboratory mark, choose groups and decks directly in the property inspector, and keep group add/remove from being overwritten. Bump the plugin to 0.1.1.0. Co-authored-by: Shugo Kawamura --- Cargo.lock | 4 +- Cargo.toml | 2 +- crates/hyperdeck-plugin/src/state.rs | 1 + pi/package-lock.json | 4 +- pi/package.json | 2 +- pi/public/assets/caret.svg | 3 + pi/public/assets/check.svg | 3 + pi/public/assets/rcheck.svg | 3 + pi/src/App.tsx | 165 ++++++++++------- pi/src/Configuration.tsx | 169 ++++++++++++------ .../images/icon.png | Bin 209 -> 5776 bytes .../images/icon@2x.png | Bin 405 -> 11239 bytes .../manifest.json | 2 +- 13 files changed, 232 insertions(+), 126 deletions(-) create mode 100644 pi/public/assets/caret.svg create mode 100644 pi/public/assets/check.svg create mode 100644 pi/public/assets/rcheck.svg diff --git a/Cargo.lock b/Cargo.lock index bdd24e0..777c86c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -730,7 +730,7 @@ dependencies = [ [[package]] name = "hyperdeck-plugin" -version = "0.1.0" +version = "0.1.1" dependencies = [ "anyhow", "base64 0.22.1", @@ -746,7 +746,7 @@ dependencies = [ [[package]] name = "hyperdeck-pool" -version = "0.1.0" +version = "0.1.1" dependencies = [ "hyperdeck-tokio", "serde", diff --git a/Cargo.toml b/Cargo.toml index b9acaba..350c398 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -3,7 +3,7 @@ resolver = "3" members = ["crates/hyperdeck-pool", "crates/hyperdeck-plugin"] [workspace.package] -version = "0.1.0" +version = "0.1.1" edition = "2024" rust-version = "1.99" license = "MIT OR Apache-2.0" diff --git a/crates/hyperdeck-plugin/src/state.rs b/crates/hyperdeck-plugin/src/state.rs index 69aed20..d5cbda7 100644 --- a/crates/hyperdeck-plugin/src/state.rs +++ b/crates/hyperdeck-plugin/src/state.rs @@ -150,6 +150,7 @@ impl AppState { ); drop(keys); self.refresh_key(context).await; + self.mark_catalog_open().await; } /// Forget a key that left the profile. diff --git a/pi/package-lock.json b/pi/package-lock.json index 22ac855..138a768 100644 --- a/pi/package-lock.json +++ b/pi/package-lock.json @@ -1,12 +1,12 @@ { "name": "hyperdeck-property-inspector", - "version": "0.1.0", + "version": "0.1.1", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "hyperdeck-property-inspector", - "version": "0.1.0", + "version": "0.1.1", "dependencies": { "@mikanseilaboratory/streamdeck-pi-client": "0.1.0", "react": "^18.3.1", diff --git a/pi/package.json b/pi/package.json index 980da66..9454f6b 100644 --- a/pi/package.json +++ b/pi/package.json @@ -1,7 +1,7 @@ { "name": "hyperdeck-property-inspector", "private": true, - "version": "0.1.0", + "version": "0.1.1", "type": "module", "scripts": { "dev": "vite", diff --git a/pi/public/assets/caret.svg b/pi/public/assets/caret.svg new file mode 100644 index 0000000..932fff4 --- /dev/null +++ b/pi/public/assets/caret.svg @@ -0,0 +1,3 @@ + + + diff --git a/pi/public/assets/check.svg b/pi/public/assets/check.svg new file mode 100644 index 0000000..bbfec96 --- /dev/null +++ b/pi/public/assets/check.svg @@ -0,0 +1,3 @@ + + + diff --git a/pi/public/assets/rcheck.svg b/pi/public/assets/rcheck.svg new file mode 100644 index 0000000..c01a443 --- /dev/null +++ b/pi/public/assets/rcheck.svg @@ -0,0 +1,3 @@ + + + diff --git a/pi/src/App.tsx b/pi/src/App.tsx index fd703fb..a215dfd 100644 --- a/pi/src/App.tsx +++ b/pi/src/App.tsx @@ -136,11 +136,14 @@ export function App() { useEffect(() => { for (const listener of listenersRef.current) listener(statuses); + }, [statuses]); + + useEffect(() => { const child = configWindowRef.current; if (child && !child.closed && child.opener === window) { - child.refreshHyperdeckConfig?.(settingsRef.current, statuses); + child.refreshHyperdeckConfig?.(settingsRef.current, statusRef.current); } - }, [statuses, global.settings]); + }, [global.settings]); useEffect(() => { send({ type: "ready" }); @@ -237,69 +240,78 @@ function TargetPicker({ value: TargetSelector; onChange: (value: TargetSelector) => void; }) { - const mode = value.kind === "group" ? "group" : value.kind === "instances" ? "instances" : "all"; + const [preferMultiple, setPreferMultiple] = useState(value.kind === "instances" && value.ids.length !== 1); + useEffect(() => { + if (value.kind !== "instances") setPreferMultiple(false); + }, [value]); + const mode = preferMultiple ? "multiple" : targetMode(value); + const selected = value.kind === "instances" ? value.ids : []; + const missingGroup = value.kind === "group" && !groups.some((group) => group.id === value.id); + const missingInstance = + value.kind === "instances" && value.ids.length === 1 && !instances.some((instance) => instance.id === value.ids[0]); return ( <> -
+
Send to
- {value.kind === "group" && ( -
-
Group
- -
- )} - {value.kind === "instances" && - instances.map((instance) => { - const status = statuses.find((item) => item.id === instance.id)?.status?.kind; - return ( -
-
{status ?? ""}
-
- + {mode === "multiple" && ( +
+
Decks
+
+ {instances.length === 0 && No decks yet} + {instances.map((instance) => { + const id = `target-${instance.id}`; + const on = selected.includes(instance.id); + const status = statuses.find((item) => item.id === instance.id)?.status?.kind; + return ( +
{ - const ids = event.target.checked - ? [...value.ids, instance.id] - : value.ids.filter((id) => id !== instance.id); + checked={on} + onChange={() => { + const ids = on ? selected.filter((item) => item !== instance.id) : [...selected, instance.id]; onChange({ kind: "instances", ids }); }} /> -
-
- ); - })} +
+ ); + })} +
+
+ )} ); } @@ -324,7 +336,8 @@ function Fields({ const shared = settings.common?.sharedParams !== false; const targeted = targetedIds(instances, groups, target); const [editor, setEditor] = useState(targeted[0] ?? ""); - const params = shared ? settings.shared : settings.params?.[editor] ?? settings.shared; + const activeEditor = targeted.includes(editor) ? editor : (targeted[0] ?? ""); + const params = shared ? settings.shared : settings.params?.[activeEditor] ?? settings.shared; const clips = uniqueClips(decks); const update = (patch: Partial) => { setSettings((previous) => { @@ -335,7 +348,7 @@ function Fields({ ...previous, params: { ...previous.params, - [editor]: { ...(previous.params?.[editor] ?? previous.shared), ...patch } + [activeEditor]: { ...(previous.params?.[activeEditor] ?? previous.shared), ...patch } } }; }); @@ -343,7 +356,7 @@ function Fields({ return ( <> {!shared && ( - + {targeted.map((id) => (
@@ -229,47 +253,70 @@ function InstanceCard({ function Groups({ instances, groups, + ready, setGroups }: { instances: InstanceConfig[]; groups: TargetGroup[]; - setGroups: (groups: TargetGroup[]) => void; + ready: boolean; + setGroups: (recipe: (groups: TargetGroup[]) => TargetGroup[]) => void; }) { return ( <>
Groups
- {groups.map((group, index) => ( -
-