Beta UI fixes batch: backdrop-click closes dialogs, 1970 dates, refresh loses current folder, peering panel "p.peers is not iterable" #171
Labels
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference: Cordy/Cairn#171
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Four clear UI fixes from Nikola's dogfood notes (2026-08-10), one surface, one PR:
<dialog>windows; users instinctively click the page behind to dismiss. Native<dialog>reports backdrop clicks as clicks on the dialog element itself — one delegated handler covers every dialog, present and future.scopedeliberately reports the Unix epoch as the stable ModTime for synthetic overlay directories — correct server-side, wrong to display. The UI renders an em dash for epoch mtimes instead of a fake date.location.hashon navigation and restore it on boot — which also gives every folder a shareable deep link for free.peerRefreshiterates the peers list without a null-guard; an empty registry serves{"peers": null}and the raw exception lands in the status line. Guard the shape and never surface a raw JS error to the operator.Shipped in v0.6.1 (PR #181), live on the dogfood.
<dialog>— a native dialog reports backdrop clicks with the dialog element itself as the event target, so the handler is four lines and covers future dialogs automatically.fmtTimereturns an em dash for any timestamp ≤ epoch; the server keeps reporting the stable epoch ModTime for synthetic dirs (correct for caching/sorting), the UI just stops pretending it's a date.load(path)mirrors the path intolocation.hash(history.replaceState, no history spam); boot prefers a valid hash over Personal. Side effect as designed: folder URLs are now shareable deep links.p.peers is not iterable:{"peers": null}/{"keys": null}from an empty registry are normalized to[]at the parse site, so no render code can trip and no raw JS error can reach the panel's status line.Verify on
.249(hard refresh to pick up the new UI): click outside any dialog; check the Spaces root's Modified column; navigate into a folder and hit F5; open the Peering panel with a fresh eye on the message line.Post-mortem addendum: v0.6.1 shipped broken, v0.6.2 fixes it — verified live in the browser.
The S1 splice (epoch-dash) was applied via
re.sub, whose replacement-template engine leaves unknown escapes like\"as literal backslash+quote. The emitted JS readreturn \"—\";— a SyntaxError at the top of the first inline script block, which killed the entire UI (no views, no data,MI is not definedcascade). My post-conditions verified five of the six splices; the one regex splice was exactly the one without an emitted-text check. Nikola noticed immediately; browser console confirmed the failure in one look.Fixes, both shipped in v0.6.2:
<script>block and runsnode --checkon each before committing — a shipped UI can no longer contain unparseable JS, from any future splice or hand edit. (Worth folding intovalidate.ymlpermanently; noting for the next CI touch.)Lessons recorded: never route splice text through
re.sub's template engine when the payload contains escapes — build replacements with plain string ops; and every splice, regex or anchored, asserts on the emitted text. Verified on the dogfood via browser: zero console errors, all views render,#/homehash routing active, dash mtimes on folders visible.