This commit is contained in:
ponzischeme89
2026-08-24 09:16:19 +12:00
parent 30155e1c5f
commit 067395a362
38 changed files with 104 additions and 60756 deletions
+4 -24
View File
@@ -145,9 +145,8 @@ Android identifies an app by
applicationId **plus** signing key, so a changed key forces every user to uninstall and
reinstall.
Every version bump is also a publish operation: update the version and changelog together,
commit the complete release, and push it to GitHub. Never leave a bumped version only in the
local working tree.
Every version bump is also a publish operation: commit the complete release and push it to
GitHub. Never leave a bumped version only in the local working tree.
For direct TV deployment without publishing a release, `deploy-tv.ps1` builds and verifies
the signed release, connects over wireless ADB, installs it with `-r`, and launches the
@@ -159,23 +158,6 @@ pass `-Device host:port` when Android rotates the wireless-debugging port.
URL is a static manifest, anything else is a Gitea host. `resolveApkUrl` lets a manifest
use a relative `apkUrl`. Both are unit-tested in `UpdateSourceTest`.
**`CHANGELOG.md` is the version history the TV shows.** It is read into
`BuildConfig.CHANGELOG_TEXT` at build time the way `LICENSE` and `NOTICE` are, parsed by
the pure `parseChangelog` in `ui/settings/VersionHistory.kt`, and rendered by Settings →
About as one collapsible release per entry. So a release edits one file and the history
stays readable offline. Keep the `## <version> — <date>` / `- bullet` shape; anything else
in the file is skipped as prose, and a bullet wrapped onto a second line is rejoined.
**An update is acknowledged once with a toast.** `ui/whatsnew/whatsNewDecision` compares the
running build with `Settings.whatsNewSeenVersion`, and `AppRoot` briefly says “Memby has been
updated to version …” over the launcher before recording it. The record is device state,
deliberately not a synced preference: what is new is a property of the APK on *this* set.
Two quiet cases matter: a **fresh install** has not updated from anything, so setup records
the current build without announcing it; and a signed-out set with an older record waits
until somebody signs in, because the notice belongs over the launcher. The changelog is no
longer part of this decision — release history remains available in Settings → About, while
local or unreleased builds still receive the same one-time update acknowledgement.
**Forced updates are server-controlled.** `server/internal/appupdate` decides `none` /
`optional` / `mandatory` from the client's `X-Memby-Version` header against an
operator-set policy (admin page → App updates). `HomeViewModel.checkForAppUpdate` runs on
@@ -2636,8 +2618,7 @@ logo. Things to preserve:
`-isation` (personalise, synchronisation, organise), `-our` (colour, favourite, behaviour),
`-re` (centre, theatre), **licence** the noun and *license* the verb, **programme** for a
broadcast, and grey, catalogue, cancelled, labelled, travelling. This covers on-screen copy
in Kotlin and `res/values/strings.xml`, `CHANGELOG.md` (which the TV renders twice — Settings
→ About and the what's-new panel), the admin console, the release landing page in
in Kotlin and `res/values/strings.xml`, the admin console, the release landing page in
`dist/template/`, every string the gateway sends the client to display (row titles, alert
`label`s, the preference and feature catalogues, error messages), and this repository's own
prose and comments.
@@ -2942,8 +2923,7 @@ seen"), not feature names.
**Up out of the top of a page returns to the page list.** Nothing sits above a pane's first
control, so that press did nothing at all on every page — and a remote that stops responding
is not read as a list that has run out. About is where it was reported, its pane being a
changelog long enough that walking back up it is the ordinary way to leave. The escape is an
is not read as a list that has run out. The escape is an
`onKeyEvent` on the content column that makes the move the default handler would have made
and falls back to the rail only when it fails, so a page's own vertical navigation is
untouched: `focusProperties { up = … }` is inherited by every row and would take that