feat(offline): implicit net-state model, two-tier version gate, unified lobby
CI / changes (pull_request) Successful in 2s
CI / unit (pull_request) Successful in 10s
CI / integration (pull_request) Successful in 21s
CI / ui (pull_request) Successful in 1m14s
CI / conformance (pull_request) Successful in 12s
CI / gate (pull_request) Successful in 0s
CI / deploy (pull_request) Failing after 22s
CI / changes (pull_request) Successful in 2s
CI / unit (pull_request) Successful in 10s
CI / integration (pull_request) Successful in 21s
CI / ui (pull_request) Successful in 1m14s
CI / conformance (pull_request) Successful in 12s
CI / gate (pull_request) Successful in 0s
CI / deploy (pull_request) Failing after 22s
Land the offline-model redesign (ANDROID_PLAN.md O1-O7): replace the explicit offline toggle with a single detected net-state machine, unify the lobby, and add a two-tier client-version gate. Contour-safe: both version vars empty => dormant, and the wire change is additive, so web/pwa/vk/tg behaviour is unchanged unless the gate is deliberately configured. O1 pure net-state reducer (test-first). O2 reactive store + event wiring (connection/offline become thin shims; +@capacitor/network). O3 remove the offline toggle + migrate the pref. O4 two-tier gate: hard update_required degrades to an offline Update/Play-offline notice (not terminal); soft GATEWAY_RECOMMENDED_CLIENT_VERSION -> X-Update-Recommended nudge. O5 unified lobby (device-local + greyed-from-cache server games; self-set identity; closes G-step-0). O6 create flows (with-friends online/offline segment + offline dict guard). O7 docs (ARCHITECTURE, FUNCTIONAL +_ru, TESTING, deploy/README). Also disable the manual android-build CI workflow for now (rename to .disabled); the Android APK release comes later. Tests: gateway go green, svelte-check 0/0, vitest 617, e2e 122/122 (chromium + webkit).
This commit is contained in:
@@ -63,15 +63,18 @@ test.describe('native offline-first', () => {
|
||||
expect(await page.locator('[data-cell].filled').count()).toBeGreaterThan(3);
|
||||
}).toPass({ timeout: 15000 });
|
||||
|
||||
// Back to the lobby, then the network returns: reconciliation silently mints + adopts a server
|
||||
// guest and clears the auto-offline, so online lights up — the offline tint drops, the seeded
|
||||
// online game (vs Ann) appears and the Stats tab re-enables. (The local vs_ai game stays
|
||||
// device-only, so the online lobby list no longer shows it — that is the intended split.)
|
||||
// Back to the lobby (still offline): the device-local vs_ai game (🤖) is listed. Then the network
|
||||
// returns: reconciliation silently mints + adopts a server guest and clears the auto-offline, so
|
||||
// online lights up — the offline tint drops, the seeded online game (vs Ann) appears and Stats
|
||||
// re-enables. The local game STAYS visible in the unified lobby alongside the server games — a
|
||||
// reconciled guest keeps its device-local games (this closes G-step-0).
|
||||
await page.getByRole('button', { name: /Back|Назад/i }).click();
|
||||
await expect(page.locator('button.tab').nth(2)).toBeVisible();
|
||||
await expect(page.locator('.rowwrap').filter({ hasText: '🤖' })).toBeVisible(); // the local vs_ai game, listed while offline
|
||||
await page.evaluate(() => (window as unknown as { __native: { reconcile(): void } }).__native.reconcile());
|
||||
await expect(page.locator('header.nav.offline')).toHaveCount(0);
|
||||
await expect(page.getByText('Ann', { exact: false }).first()).toBeVisible({ timeout: 15000 });
|
||||
await expect(page.locator('.rowwrap').filter({ hasText: '🤖' })).toBeVisible(); // still listed online — the reconciled guest keeps it (G-step-0)
|
||||
await expect(page.locator('button.tab').nth(1)).toBeEnabled();
|
||||
|
||||
// The native sign-in surface is guest + email only: on Profile the Telegram + VK LINK buttons are
|
||||
|
||||
Reference in New Issue
Block a user