feat(offline): implicit net-state model, two-tier version gate, unified lobby #249
Reference in New Issue
Block a user
Delete Branch "feature/android-native"
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?
Lands the offline-model redesign (ANDROID_PLAN.md O1-O7): the explicit offline toggle is replaced by a single detected net-state machine, the lobby is unified, and a two-tier client-version gate is added. Contour-safe (both version vars empty => dormant; the wire change is additive), so web/pwa/vk/tg behaviour is unchanged and no new CI variables are required. O1 net-state reducer (test-first); O2 store + wiring (+@capacitor/network); O3 remove the offline toggle; O4 two-tier gate (hard -> offline Update/Play-offline notice; soft GATEWAY_RECOMMENDED_CLIENT_VERSION -> X-Update-Recommended nudge); O5 unified lobby (closes G-step-0); O6 create flows (with-friends segment + dict guard); O7 docs. The manual android-build CI workflow is disabled for now (renamed .disabled). Tests: gateway go green, svelte-check 0/0, vitest 617, e2e 122/122 (chromium + webkit).
Add @capacitor/{core,android,app,cli,assets} to ui/, a capacitor.config.ts (appId ru.eruditgame.app, appName Эрудит, webDir dist — bundle model, no server.url), and the generated ui/android/ Gradle project (tracked; build outputs and the machine-specific local.properties gitignored, keystore patterns un-commented so signing material can never be committed). Wire the Android hardware Back button in ui/src/lib/native.ts behind a dynamic @capacitor/app import (web/mock bundles never load it), called from App.svelte onMount and reusing routeDepth for the navigation-root check. Whitelist sharp in pnpm-workspace.yaml for @capacitor/assets icon generation. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>Native (Capacitor) cold boot with no cached session now enters as a device-local guest in auto-offline mode and lands straight in the lobby (never /login), so the app opens and plays local vs_ai / hotseat with the APK's bundled dictionaries and zero network. When the gateway becomes reachable, reconcileServerGuest silently mints + adopts a server guest and clears the auto-offline, lighting up online features. Web / PWA / Telegram / VK are byte-for-byte unchanged. - transport: exec gains { silent, allowOffline } so background reconciliation bypasses the offline kill switch (like the reachability probe) and never raises the terminal update overlay (a too-old client stays a local guest); new authGuestSilent on the client interface, the real transport and the mock. - app: native no-session boot branch; reconcileServerGuest fired at boot, by the recovery poll and the online event; the poll routes the session-less guest through reconciliation, since checkReachable needs a token it lacks. - native: initNativeShell tolerates a missing Capacitor bridge. - e2e: new native.spec.ts (inject window.androidBridge; boot -> offline lobby, local vs_ai move, reconcile -> online, hotseat start) + playwright.config bundles the dawgs into dist-e2e/dict for the loader's bundled tier.fa4dc2412atoa8f78c7880a8f78c7880to872804e02e872804e02eto14918cc94f14918cc94fto2d1fadb50c