diff --git a/frontend/src/components/GraphCanvas.svelte b/frontend/src/components/GraphCanvas.svelte index a8248a6..1ffc482 100644 --- a/frontend/src/components/GraphCanvas.svelte +++ b/frontend/src/components/GraphCanvas.svelte @@ -113,13 +113,10 @@ return pt.matrixTransform(ctm.inverse()); } - function isNodeHidden(nodeName: string): boolean { + function isNodeHidden(nd: { name: string; nick: string }): boolean { + const dn = displayName(nd).toLowerCase(); for (const rule of $patchbay.hide_rules) { - try { - if (new RegExp(rule, 'i').test(nodeName)) return true; - } catch { - if (nodeName.toLowerCase().includes(rule.toLowerCase())) return true; - } + if (dn === rule.toLowerCase()) return true; } return false; } @@ -145,7 +142,7 @@ for (const port of p) portMap.set(port.id, port); // Filter hidden nodes - let visible = n.filter(nd => !isNodeHidden(nd.name)); + let visible = n.filter(nd => !isNodeHidden(nd)); // Merge nodes by prefix (unless split mode) if (!splitNodes) { @@ -223,8 +220,8 @@ // Check if both endpoint nodes are visible const outNode = $nodes.find(n => n.id === outPort.node_id); const inNode = $nodes.find(n => n.id === inPort.node_id); - if (outNode && isNodeHidden(outNode.name)) return null; - if (inNode && isNodeHidden(inNode.name)) return null; + if (outNode && isNodeHidden(outNode)) return null; + if (inNode && isNodeHidden(inNode)) return null; const pinned = pb.pinned_connections.includes(link.id); return { ...link, outPort, inPort, pinned }; }).filter(Boolean) as Array; diff --git a/frontend/src/lib/stores.ts b/frontend/src/lib/stores.ts index 0e4304e..f6d86cf 100644 --- a/frontend/src/lib/stores.ts +++ b/frontend/src/lib/stores.ts @@ -322,11 +322,20 @@ export async function saveProfile(name: string) { }); } + const volumes: Record = {}; + const mutes: Record = {}; + for (const n of currentNodes) { + volumes[n.name] = n.volume; + mutes[n.name] = n.mute; + } + const profile: PatchbayProfile = { name, connections, hide_rules: [...pb.hide_rules], merge_rules: [...pb.merge_rules], + volumes, + mutes, }; patchbay.update(pb => ({ @@ -337,11 +346,26 @@ export async function saveProfile(name: string) { savePatchbayState(); } +async function applyProfileVolumes(profile: PatchbayProfile) { + if (!profile.volumes && !profile.mutes) return; + const currentNodes = get_store_value(nodes); + for (const n of currentNodes) { + if (profile.volumes?.[n.name] !== undefined) { + await setNodeVolume(n.id, profile.volumes[n.name]); + } + if (profile.mutes?.[n.name] !== undefined) { + await setNodeMute(n.id, profile.mutes[n.name]); + } + } +} + export function loadProfile(name: string) { patchbay.update(pb => ({ ...pb, active_profile: name })); const pb = get_store_value(patchbay); // Always apply connections when explicitly loading a profile applyPatchbay(pb); + const profile = pb.profiles[name]; + if (profile) applyProfileVolumes(profile); savePatchbayState(); } diff --git a/frontend/src/lib/types.ts b/frontend/src/lib/types.ts index ad7b92a..d59dafb 100644 --- a/frontend/src/lib/types.ts +++ b/frontend/src/lib/types.ts @@ -73,6 +73,8 @@ export interface PatchbayProfile { connections: ConnectionRule[]; hide_rules?: string[]; merge_rules?: string[]; + volumes?: Record; // PW node name → volume (0..1) + mutes?: Record; // PW node name → mute state } export interface PatchbayState {