Replace idle toasts with pane border + titlebar badge
Old behaviour: every pane fired orch.notify("X is idle") after 5s of
silence, stacking up to N toasts that took ages to dismiss.
New behaviour:
- LeafPane tracks its own isIdle state locally and reports up via
orch.reportLeafIdle(leafId, idle).
- App aggregates into a Set<NodeId> and renders "N idle" in red after
the "N panes" count in the titlebar (hidden when zero).
- The pane itself gets a red border (.leaf.idle) — but active and
broadcasting borders still take precedence, so the focus indicator
isn't masked by idle status.
- The pane's "alive" status text in the toolbar swaps to red "idle"
while it's quiet (reverts to "alive" the moment output arrives).
- Idle clears immediately on the next byte of output (no 1-second lag)
AND when the pane unmounts (cleanup effect).
No more flood of toasts.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
c93ebddfa5
commit
d9ddf52699
5 changed files with 71 additions and 15 deletions
21
src/App.tsx
21
src/App.tsx
|
|
@ -239,6 +239,19 @@ export default function App() {
|
|||
setNotifications((ns) => ns.filter((n) => n.id !== id));
|
||||
}, []);
|
||||
|
||||
// ---- per-pane idle aggregation (replaces toast spam) --------------------
|
||||
const [idleLeafIds, setIdleLeafIds] = useState<Set<NodeId>>(() => new Set());
|
||||
const reportLeafIdle = useCallback((leafId: NodeId, idle: boolean) => {
|
||||
setIdleLeafIds((prev) => {
|
||||
if (idle && prev.has(leafId)) return prev;
|
||||
if (!idle && !prev.has(leafId)) return prev;
|
||||
const next = new Set(prev);
|
||||
if (idle) next.add(leafId);
|
||||
else next.delete(leafId);
|
||||
return next;
|
||||
});
|
||||
}, []);
|
||||
|
||||
// ---- header-drag swap ---------------------------------------------------
|
||||
const [dragSourceId, setDragSourceId] = useState<NodeId | null>(null);
|
||||
const [dragOverId, setDragOverId] = useState<NodeId | null>(null);
|
||||
|
|
@ -283,6 +296,7 @@ export default function App() {
|
|||
beginHeaderDrag,
|
||||
setHeaderDragOver,
|
||||
endHeaderDrag,
|
||||
reportLeafIdle,
|
||||
}),
|
||||
[
|
||||
activeLeafId,
|
||||
|
|
@ -301,6 +315,7 @@ export default function App() {
|
|||
beginHeaderDrag,
|
||||
setHeaderDragOver,
|
||||
endHeaderDrag,
|
||||
reportLeafIdle,
|
||||
],
|
||||
);
|
||||
|
||||
|
|
@ -443,6 +458,12 @@ export default function App() {
|
|||
|
||||
<span className="layout-info">
|
||||
{leafCount(tree)} pane{leafCount(tree) === 1 ? "" : "s"}
|
||||
{idleLeafIds.size > 0 && (
|
||||
<span className="idle-info" title="Panes that haven't produced output recently">
|
||||
{" · "}
|
||||
{idleLeafIds.size} idle
|
||||
</span>
|
||||
)}
|
||||
</span>
|
||||
</header>
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue