feat(update): tell sideloaded installs that a newer version exists (#179)
AGE-110: 64% of 30d-active users sit on v0.4.10 and 0.2% on the newest build, so a client-side fix (the AGE-105 Sentry noise gate) reaches almost nobody. Play hygiene fixes one channel; the direct APK, the self-hosted F-Droid repo and third-party mirrors have no update mechanism at all — a device installed from a downloaded APK has literally no way to learn a newer version exists. - src/lib/update-check-policy.ts: pure, node --test'able decision logic — numeric version compare (a string compare puts 0.4.10 BEFORE 0.4.9, i.e. it would have told the largest stale cohort it was current), a 24h check throttle that survives a backwards clock, per-version dismissal, and a cached last-known-latest so the affordance survives between checks - src/lib/update-check.ts: Android-only runtime wiring. One unauthenticated GET per 24h to the GitHub releases API (every non-Play channel is downstream of a GitHub release; expo-updates cannot replace a native binary, which is what this cohort needs). Never throws. - UpdateBanner on the sessions list: one dismissible strip, no modal. "Not now" sticks for that version only. - Settings "Version" row showed a hard-coded "1.0.0" for every build ever shipped. It now shows the real version, plus "0.4.10 -> 0.4.14" when an update exists (ignoreDismissed: dismissal silences the banner, not the place a user goes to check). - en/zh-Hans strings, catalog parity kept. Tests: 19 new cases in update-check-policy.test.ts; full suite 300 pass, tsc --noEmit clean. Co-authored-by: engineer <engineer@macbookpro.lan> Co-authored-by: Paperclip <noreply@paperclip.ing>
This commit is contained in:
@@ -27,6 +27,7 @@ import type BottomSheet from "@gorhom/bottom-sheet"
|
||||
import type { Session, Project } from "../../src/lib/sdk"
|
||||
import { DirectorySwitcher, DirectoryBrowserSheet } from "../../src/components/chat"
|
||||
import { groupByDirectory } from "../../src/lib/session-grouping"
|
||||
import { UpdateBanner } from "../../src/components/UpdateBanner"
|
||||
import { nameOf } from "../../src/lib/path-utils"
|
||||
import { SETUP_GUIDE_URL } from "../../src/lib/links"
|
||||
|
||||
@@ -548,6 +549,8 @@ export default function SessionsScreen() {
|
||||
</View>
|
||||
)}
|
||||
|
||||
<UpdateBanner isDark={isDark} />
|
||||
|
||||
<FlatList
|
||||
data={rows}
|
||||
keyExtractor={(row) => (row.type === "header" ? `dir:${row.directory}` : row.session.id)}
|
||||
|
||||
Reference in New Issue
Block a user