diff --git a/frontend/src/components/GraphCanvas.svelte b/frontend/src/components/GraphCanvas.svelte index 2f9cbcd..a8248a6 100644 --- a/frontend/src/components/GraphCanvas.svelte +++ b/frontend/src/components/GraphCanvas.svelte @@ -12,6 +12,7 @@ setAutoPin, setAutoDisconnect, saveProfile, loadProfile, deleteProfile, setNodeVolume, setNodeMute, + setAlias, createNullSink, createLoopback, loadModule, getQuantum, setQuantum, } from '../lib/stores'; @@ -29,6 +30,8 @@ let contextMenu = $state<{ x: number; y: number; linkId: number; outputPortId: number; inputPortId: number; pinned: boolean } | null>(null); let nodeContextMenu = $state<{ x: number; y: number; nodeId: number; nodeName: string } | null>(null); let showPropsDialog = $state(null); // node ID or null + let renameDialog = $state<{ pwName: string } | null>(null); + let renameInput = $state(''); // Filters let showAudio = $state(true); @@ -128,6 +131,11 @@ return nodeName; } + // Return custom alias, otherwise nick, otherwise PW name + function displayName(nd: { name: string; nick: string }): string { + return $patchbay.aliases?.[nd.name] || nd.nick || nd.name; + } + // Build computed layout let graphNodes = $derived.by(() => { const n = $nodes; @@ -593,7 +601,7 @@ - {nd.nick || nd.name} + {displayName(nd)} [{nd.node_type}] @@ -680,8 +688,13 @@ {#if nodeContextMenu}
@@ -730,6 +743,31 @@ {/if} {/if} + + {#if renameDialog} +
+
+ Rename Node + +
+
+

{renameDialog.pwName}

+
+ { if (e.key === 'Enter') { setAlias(renameDialog!.pwName, renameInput); renameDialog = null; } }} + /> +
+
+ + +
+
+
+ {/if} + {#if showHideDialog}
diff --git a/frontend/src/lib/stores.ts b/frontend/src/lib/stores.ts index 2247f68..0e4304e 100644 --- a/frontend/src/lib/stores.ts +++ b/frontend/src/lib/stores.ts @@ -19,6 +19,7 @@ export const patchbay = writable({ pinned_connections: [], hide_rules: [], merge_rules: [], + aliases: {}, }); // Port/node lookups @@ -82,7 +83,7 @@ export async function initGraph() { if (res.ok) { const data = await res.json(); if (data && data.profiles) { - patchbay.set(data as PatchbayState); + patchbay.set({ ...data, aliases: data.aliases ?? {} } as PatchbayState); } } } catch {} @@ -357,6 +358,20 @@ export function deleteProfile(name: string) { savePatchbayState(); } +// Node aliases (custom display names, keyed by PW node name) +export function setAlias(pwName: string, alias: string) { + patchbay.update(pb => { + const aliases = { ...pb.aliases }; + if (alias.trim()) { + aliases[pwName] = alias.trim(); + } else { + delete aliases[pwName]; // empty string = remove alias + } + return { ...pb, aliases }; + }); + savePatchbayState(); +} + // Volume control export async function setNodeVolume(nodeId: number, volume: number) { try { diff --git a/frontend/src/lib/types.ts b/frontend/src/lib/types.ts index df832a5..ad7b92a 100644 --- a/frontend/src/lib/types.ts +++ b/frontend/src/lib/types.ts @@ -85,4 +85,5 @@ export interface PatchbayState { pinned_connections: number[]; hide_rules: string[]; merge_rules: string[]; + aliases: Record; // PW node name → custom display name }