diff --git a/src/App.css b/src/App.css index eab9bdd..702340e 100644 --- a/src/App.css +++ b/src/App.css @@ -47,6 +47,15 @@ color: #cce6ff; border-color: #2a5a8c; } +.palette-btn.bcast-all.on { + background: #4a3010; + color: #f0c060; + border-color: #c98a1f; +} +.palette-btn.bcast-all.on.partial { + background: #2a2010; + color: #c98a1f; +} .preset-btn { min-width: 28px; text-align: center; diff --git a/src/App.tsx b/src/App.tsx index 5174ceb..7a4b5ef 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -21,6 +21,7 @@ import { changeDistro, changeLabel, toggleBroadcast as toggleBroadcastInTree, + setAllBroadcast, serialize, deserialize, presetSingle, @@ -282,6 +283,29 @@ export default function App() { [paletteOpen, tree], ); + // ---- global broadcast state (derived from tree) ------------------------- + const broadcastStats = useMemo(() => { + let on = 0; + let total = 0; + for (const leaf of walkLeaves(tree)) { + total++; + if (leaf.broadcast) on++; + } + return { on, total }; + }, [tree]); + + const toggleBroadcastAll = useCallback(() => { + // If any pane is broadcasting, turn them all off. Otherwise turn them all on. + setTree((t) => setAllBroadcast(t, broadcastStats.on === 0)); + }, [broadcastStats.on]); + + const broadcastBtnLabel = + broadcastStats.on === 0 + ? "📡 all off" + : broadcastStats.on === broadcastStats.total + ? "📡 all on" + : `📡 ${broadcastStats.on}/${broadcastStats.total}`; + const onPalettePick = useCallback((leafId: string) => { setActiveLeafId(leafId); setPaletteOpen(false); @@ -321,6 +345,20 @@ export default function App() { + +