872804e02e
CI / changes (pull_request) Successful in 2s
CI / unit (pull_request) Successful in 10s
CI / integration (pull_request) Successful in 19s
CI / ui (pull_request) Successful in 1m13s
CI / conformance (pull_request) Successful in 10s
CI / gate (pull_request) Successful in 0s
CI / deploy (pull_request) Failing after 20s
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, the wire change is additive, so web/pwa/vk/tg behaviour is unchanged unless the gate is deliberately configured. O1 net-state reducer (test-first). O2 store + wiring (connection/offline 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. Wire the version gate through the deploy: GATEWAY_MIN_CLIENT_VERSION + GATEWAY_RECOMMENDED_CLIENT_VERSION are plain (unprefixed) Gitea vars, passed via compose + ci.yaml (test) + prod-deploy.yaml + write-prod-env.sh (prod) + .env.example, so the gate is live when set (a test-contour commit-hash version fails open; empty => dormant). Disable the manual android-build CI workflow for now (rename .disabled). Bump the app bundle budget 127->130 KB for the added always-loaded wiring. Tests: gateway go green (incl. two-tier gate over a real HTTP handler), compose --no-interpolate confirms the gateway env, svelte-check 0/0, vitest 617, e2e 122/122 (chromium + webkit).
57 lines
1.7 KiB
Svelte
57 lines
1.7 KiB
Svelte
<script lang="ts">
|
||
// The soft "update available" nudge (the soft version tier). A non-blocking banner: play continues.
|
||
// Shown only while online — the hard "update required" notice is an offline state, so it naturally
|
||
// supersedes this — and only until the user dismisses it for the session. Rendered at the bottom of
|
||
// the lobby (above the tab bar), so it never covers a game in progress.
|
||
import { netState } from '../lib/netstate.svelte';
|
||
import { updateRecommended, dismissUpdateNudge, openUpdate } from '../lib/update.svelte';
|
||
import { t } from '../lib/i18n/index.svelte';
|
||
|
||
const show = $derived(netState.online && updateRecommended.active && !updateRecommended.dismissed);
|
||
</script>
|
||
|
||
{#if show}
|
||
<div class="nudge" role="status">
|
||
<span class="msg">{t('update.available')}</span>
|
||
<button class="upd" type="button" onclick={openUpdate}>{t('update.action')}</button>
|
||
<button class="x" type="button" onclick={dismissUpdateNudge} aria-label={t('common.close')}>×</button>
|
||
</div>
|
||
{/if}
|
||
|
||
<style>
|
||
.nudge {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 0.6rem;
|
||
padding: 0.5rem 0.9rem;
|
||
border-top: 1px solid var(--border);
|
||
background: var(--surface);
|
||
color: var(--text);
|
||
font-size: 0.9rem;
|
||
}
|
||
.msg {
|
||
flex: 1 1 auto;
|
||
min-width: 0;
|
||
}
|
||
.upd {
|
||
flex: 0 0 auto;
|
||
font: inherit;
|
||
padding: 0.3rem 0.8rem;
|
||
border: 1px solid var(--accent);
|
||
border-radius: var(--radius-sm);
|
||
background: var(--accent);
|
||
color: var(--accent-text);
|
||
cursor: pointer;
|
||
}
|
||
.x {
|
||
flex: 0 0 auto;
|
||
font-size: 1.2rem;
|
||
line-height: 1;
|
||
padding: 0.2rem 0.4rem;
|
||
border: none;
|
||
background: transparent;
|
||
color: var(--text-muted);
|
||
cursor: pointer;
|
||
}
|
||
</style>
|