← back to Desktop Dotbar
dotbar: surface Arrange outcome on the button instead of swallowing errors
534bea84c634e89aacfa96e7a6fce5bf25040f5e · 2026-09-16 11:54:30 -0700 · Steve Abrams
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MtzMyVz6sH79QSHLZzQMEZ
Files touched
Diff
commit 534bea84c634e89aacfa96e7a6fce5bf25040f5e
Author: Steve Abrams <steve@designerwallcoverings.com>
Date: Wed Sep 16 11:54:30 2026 -0700
dotbar: surface Arrange outcome on the button instead of swallowing errors
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MtzMyVz6sH79QSHLZzQMEZ
---
public/index.html | 19 ++++++++++++++-----
1 file changed, 14 insertions(+), 5 deletions(-)
diff --git a/public/index.html b/public/index.html
index 8951a88..68758cd 100644
--- a/public/index.html
+++ b/public/index.html
@@ -75,7 +75,7 @@
<div id="panel"></div>
<script>
const BAR_H = 48, PANEL_H = 360;
-let openColor = null, data = null, _miss = 0, curBarH = BAR_H, arranging = false;
+let openColor = null, data = null, _miss = 0, curBarH = BAR_H, arranging = false, arrangeMsg = '';
// The four needs-Steve states pulse; green/pink stay solid (Steve 2026-09-15 dot-flash directive).
const WAIT = new Set(['lightblue','orange','purple','yellow']);
@@ -101,7 +101,7 @@ function renderBar(){
}
const sp = document.createElement('div'); sp.id='spacer'; bar.appendChild(sp);
const meta = document.createElement('div'); meta.id='meta';
- meta.innerHTML = `<button class="arrbtn${arranging?' busy':''}" title="re-tile every screen into the grid now" onclick="arrange()">${arranging?'⧉ Arranging…':'⧉ Arrange'}</button>`
+ meta.innerHTML = `<button class="arrbtn${arranging?' busy':''}" title="re-tile every screen into the grid now" onclick="arrange()">${arranging?'⧉ Arranging…':(arrangeMsg?('⧉ '+arrangeMsg):'⧉ Arrange')}</button>`
+ `<span><b>${data.total}</b> live</span>`
+ `<span class="icobtn" title="refresh" onclick="tick()">⟳</span>`
+ `<span class="icobtn" title="quit bar" onclick="(window.dotbar&&window.dotbar.quit)&&window.dotbar.quit()">✕</span>`;
@@ -141,9 +141,18 @@ async function reveal(tty){
// into the grid. Shows a busy state on the button until the (multi-pass, converging) run returns.
async function arrange(){
if (arranging) return;
- arranging = true; renderBar();
- try { await fetch('/api/arrange', { method:'POST' }); } catch(e){}
- arranging = false; renderBar();
+ arrangeMsg = ''; arranging = true; renderBar();
+ // Surface the outcome on the button instead of swallowing it — an invisible failure (the old
+ // `catch(e){}`) is exactly why "the button does nothing" was undiagnosable. Show moved-count on
+ // success, or the server err / HTTP status / "no server" on failure.
+ let msg;
+ try {
+ const r = await fetch('/api/arrange', { method:'POST' });
+ const j = await r.json().catch(() => null);
+ msg = (j && j.ok) ? `moved ${j.moved || 0}` : ('✗ ' + ((j && j.err) || ('HTTP ' + r.status)));
+ } catch (e) { msg = '✗ ' + ((e && e.message) || 'no server'); }
+ arranging = false; arrangeMsg = msg; renderBar();
+ clearTimeout(window._arrTimer); window._arrTimer = setTimeout(() => { arrangeMsg = ''; renderBar(); }, 2200);
tick(); // refresh counts/labels once windows have settled
}
← 2f67aa2 dotbar: render a strip on EVERY display (Arrange button reac
·
back to Desktop Dotbar
·
wire arrange bar to master router 8db4601 →