From 7f214fc2d48648e4fb8d17597af502f99a585245 Mon Sep 17 00:00:00 2001 From: joren Date: Mon, 30 Mar 2026 01:17:10 +0200 Subject: [PATCH] feat: Split toggle - show input/output as separate nodes - Toggle button next to 'Merge Nodes' in toolbar - When active: skips merge rules, each PipeWire node shown separately - Green=output, red=input (no confusing duplex merging) - Defaults to off (merged mode) --- frontend/src/components/GraphCanvas.svelte | 35 ++++++++++++---------- 1 file changed, 19 insertions(+), 16 deletions(-) diff --git a/frontend/src/components/GraphCanvas.svelte b/frontend/src/components/GraphCanvas.svelte index c0f7ab0..391bf72 100644 --- a/frontend/src/components/GraphCanvas.svelte +++ b/frontend/src/components/GraphCanvas.svelte @@ -42,6 +42,7 @@ let showProfileDialog = $state(false); let showRuleDialog = $state(false); let showVirtualMenu = $state(false); + let splitNodes = $state(false); let showNetworkDialog = $state<{ type: string } | null>(null); let netHost = $state('127.0.0.1'); let netPort = $state('4713'); @@ -138,25 +139,26 @@ // Filter hidden nodes let visible = n.filter(nd => !isNodeHidden(nd.name)); - // Merge nodes by prefix - const merged = new Map(); - for (const nd of visible) { - const mergedName = getMergedName(nd.name); - const existing = merged.get(mergedName); - if (existing) { - existing.port_ids = [...new Set([...existing.port_ids, ...nd.port_ids])]; - existing.name = mergedName; - // If merged node has both input and output ports, mark as duplex - const mergedInPorts = existing.port_ids.map(pid => portMap.get(pid)).filter((p): p is Port => !!p && p.mode === 'input'); - const mergedOutPorts = existing.port_ids.map(pid => portMap.get(pid)).filter((p): p is Port => !!p && p.mode === 'output'); - if (mergedInPorts.length > 0 && mergedOutPorts.length > 0) { - existing.mode = 'duplex'; + // Merge nodes by prefix (unless split mode) + if (!splitNodes) { + const merged = new Map(); + for (const nd of visible) { + const mergedName = getMergedName(nd.name); + const existing = merged.get(mergedName); + if (existing) { + existing.port_ids = [...new Set([...existing.port_ids, ...nd.port_ids])]; + existing.name = mergedName; + const mergedInPorts = existing.port_ids.map(pid => portMap.get(pid)).filter((p): p is Port => !!p && p.mode === 'input'); + const mergedOutPorts = existing.port_ids.map(pid => portMap.get(pid)).filter((p): p is Port => !!p && p.mode === 'output'); + if (mergedInPorts.length > 0 && mergedOutPorts.length > 0) { + existing.mode = 'duplex'; + } + } else { + merged.set(mergedName, { ...nd, name: mergedName }); } - } else { - merged.set(mergedName, { ...nd, name: mergedName }); } + visible = Array.from(merged.values()); } - visible = Array.from(merged.values()); const out = visible.filter(nd => nd.mode === 'output'); const inp = visible.filter(nd => nd.mode === 'input'); @@ -464,6 +466,7 @@ +