diff --git a/ui/src/lib/app.svelte.ts b/ui/src/lib/app.svelte.ts index 6d751ea..49ab6aa 100644 --- a/ui/src/lib/app.svelte.ts +++ b/ui/src/lib/app.svelte.ts @@ -57,7 +57,6 @@ import { import type { CoachSeries } from './coachmark'; import { connection, reportOffline, reportOnline, resetConnection, checkReachable } from './connection.svelte'; import { offlineMode, setOfflineMode } from './offline.svelte'; -import { netlog } from './netdiag.svelte'; // TEMP diagnostic import { shouldBootOffline } from './offline'; import { isConnectionCode } from './retry'; import { clearGameCache, getCachedGame, setCachedGame } from './gamecache'; @@ -604,15 +603,9 @@ export function scheduleRecovery(delayMs: number): void { recoveryTimer = null; if (!offlineMode.active || !offlineMode.auto) return; const interfaceUp = typeof navigator === 'undefined' || navigator.onLine; - netlog(`poll tick: navOnline=${interfaceUp}`); // TEMP diagnostic - if (interfaceUp) { - const reachable = await checkReachable(BOOT_REACHABILITY_TIMEOUT_MS); - netlog(`checkReachable=${reachable}`); // TEMP diagnostic - if (reachable && offlineMode.active && offlineMode.auto) { - setOfflineMode(false); - netlog('-> RETURNED ONLINE'); // TEMP diagnostic - return; - } + if (interfaceUp && (await checkReachable(BOOT_REACHABILITY_TIMEOUT_MS))) { + if (offlineMode.active && offlineMode.auto) setOfflineMode(false); + return; } scheduleRecovery(4000); }, delayMs); @@ -621,17 +614,14 @@ export function scheduleRecovery(delayMs: number): void { export function initNetworkReactivity(): void { if (typeof window === 'undefined' || import.meta.env.MODE === 'mock') return; window.addEventListener('offline', () => { - netlog(`offline EVENT (active=${offlineMode.active})`); // TEMP diagnostic if (!offlineMode.active) { setOfflineMode(true, false); // auto (session) - netlog('-> auto-offline; poll started'); // TEMP diagnostic scheduleRecovery(4000); // poll for the network to return } }); // The online event, when it fires, just kicks an immediate reachability check; the poll above is // the reliable fallback for platforms where it does not fire. window.addEventListener('online', () => { - netlog(`online EVENT (active=${offlineMode.active} auto=${offlineMode.auto})`); // TEMP diagnostic if (offlineMode.active && offlineMode.auto) scheduleRecovery(0); }); } diff --git a/ui/src/lib/netdiag.svelte.ts b/ui/src/lib/netdiag.svelte.ts deleted file mode 100644 index d1a487c..0000000 --- a/ui/src/lib/netdiag.svelte.ts +++ /dev/null @@ -1,38 +0,0 @@ -// TEMPORARY network diagnostic — REMOVE before release. A live view of the online/offline signals so -// we can pinpoint where the auto-offline -> online transition breaks. Rendered by a panel in -// Lobby.svelte. Skipped in the mock build. - -let entries = $state([]); -let navOnline = $state(typeof navigator !== 'undefined' ? navigator.onLine : true); - -export const netdiag = { - /** entries is the newest-first ring buffer of timestamped diagnostic lines. */ - get entries(): string[] { - return entries; - }, - /** navOnline is the live navigator.onLine value (the property itself is not reactive). */ - get navOnline(): boolean { - return navOnline; - }, -}; - -/** netlog appends a timestamped diagnostic line (kept to the last 24). */ -export function netlog(msg: string): void { - const t = new Date().toLocaleTimeString(); - entries = [`${t} ${msg}`, ...entries].slice(0, 24); - if (typeof navigator !== 'undefined') navOnline = navigator.onLine; -} - -// A 1 s heartbeat keeps navigator.onLine live in the panel and logs when it flips — so a flight-mode -// toggle is visible even if the online/offline events never fire (the exact thing we are chasing). -if (typeof window !== 'undefined' && import.meta.env.MODE !== 'mock') { - let last = typeof navigator !== 'undefined' ? navigator.onLine : true; - setInterval(() => { - const now = typeof navigator !== 'undefined' ? navigator.onLine : true; - navOnline = now; - if (now !== last) { - last = now; - netlog(`navigator.onLine -> ${now}`); - } - }, 1000); -} diff --git a/ui/src/lib/offline.svelte.ts b/ui/src/lib/offline.svelte.ts index dd2d5d5..544e4a7 100644 --- a/ui/src/lib/offline.svelte.ts +++ b/ui/src/lib/offline.svelte.ts @@ -36,6 +36,7 @@ export const offlineMode = { */ export function setOfflineMode(on: boolean, persist = true): void { active = on; + auto = on && !persist; // a non-persisted offline is auto-detected; a persisted one is deliberate if (persist) saveOfflinePref(on); } diff --git a/ui/src/screens/Lobby.svelte b/ui/src/screens/Lobby.svelte index 60ac74b..1cd9405 100644 --- a/ui/src/screens/Lobby.svelte +++ b/ui/src/screens/Lobby.svelte @@ -6,7 +6,6 @@ import Modal from '../components/Modal.svelte'; import { app, handleError, refreshFeedbackBadge, seedChatUnread } from '../lib/app.svelte'; import { connection } from '../lib/connection.svelte'; - import { netdiag } from '../lib/netdiag.svelte'; // TEMP diagnostic import { gateway } from '../lib/gateway'; import { navigate } from '../lib/router.svelte'; import { t } from '../lib/i18n/index.svelte'; @@ -259,15 +258,6 @@ } - -
-
- nav.onLine={String(netdiag.navOnline)} · offline={String(offlineMode.active)} · auto={String(offlineMode.auto)} · conn.online={String(connection.online)} -
- {#each netdiag.entries as e, i (i)}
{e}
{/each} -
-
{#if invitations.length}