mirror of
https://github.com/Ark0N/Codeman.git
synced 2026-10-06 15:39:41 +02:00
feat(web): make a dead connection unmistakable instead of a red dot
Opening Codeman with nothing reachable (phone off the tailnet, VPN down, server stopped) rendered a normal-looking UI: the service worker serves the cached app shell, every /api call fails, and the only tell was an 8px red dot in the header corner. On a phone that reads as "there are no sessions". Two surfaces, chosen by whether there is anything worth looking at: - Full-screen overlay while no server state has loaded this page load. It names the host, lists the three things to check (network, VPN/Tailscale, server), counts down to the next retry, and offers "Retry now" plus "Show cached view" to demote itself to the banner. - Non-blocking banner once state HAS loaded, so a mid-session drop leaves the terminal scrollback readable. A 2.5s grace keeps a COM deploy (SSE is back in ~200ms) from flashing the banner every release; navigator.onLine === false skips the grace, since the device saying "no network" is never a blip. Retry re-arms the terminal WebSocket as well as SSE: planWsReconnect can give up outright, and the SSE backoff caps at 30s, so waiting it out is not always an option. The decision is pure (computeConnectionLossUi in constants.js, unit-tested in a node VM like the WS reconnect policy); app.js only writes the DOM.
This commit is contained in:
@@ -2872,3 +2872,47 @@ html:is([data-skin="paper-gray"], [data-skin="solarized-light"], [data-skin="cat
|
||||
padding: 4px 7px;
|
||||
}
|
||||
}
|
||||
|
||||
/* ============================================================================
|
||||
Connection loss: phone sizing
|
||||
The banner sits in normal flow directly under the fixed header (the container
|
||||
already reserves that space), so it needs the same safe-area padding as the
|
||||
other banners. The overlay is fixed and handles its own insets.
|
||||
============================================================================ */
|
||||
@media (max-width: 430px) {
|
||||
.offline-banner {
|
||||
padding: 0.4rem 0.5rem;
|
||||
padding-left: calc(0.5rem + var(--safe-area-left));
|
||||
padding-right: calc(0.5rem + var(--safe-area-right));
|
||||
font-size: 0.7rem;
|
||||
gap: 0.4rem;
|
||||
}
|
||||
|
||||
/* The countdown is the first thing to go when the bar gets tight. The
|
||||
wording plus the Retry button carry the message on their own. */
|
||||
.offline-banner-detail {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.offline-banner-retry {
|
||||
padding: 0.25rem 0.5rem;
|
||||
margin-left: auto;
|
||||
}
|
||||
|
||||
.offline-overlay-card {
|
||||
padding: 22px 18px 18px;
|
||||
}
|
||||
|
||||
.offline-overlay-title {
|
||||
font-size: 1.05rem;
|
||||
}
|
||||
|
||||
.offline-overlay-actions {
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.offline-overlay-btn {
|
||||
width: 100%;
|
||||
padding: 0.65rem 1rem;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user