versionCode 5. public_html/ changed, so the service worker cache goes to
bgclock-v20.
Confirmed on device: a turn left running well past the delay, force-quit and
reopened, now comes back with the time it had actually spent.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
versionCode 4. public_html/ changed, so the service worker cache goes to
bgclock-v19 — without it an installed web user would keep serving the old page
from cache indefinitely.
The five store screenshots are untouched: the ring only exists while a finger
is on the button, and none of them shows that.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
versionCode 3. public_html/ changed this time, so the service worker cache is
bumped to bgclock-v18 — without it an installed web user would keep serving
the old page from cache indefinitely.
Nothing to do in fdroiddata. The recipe landed with the 1.0 submission and
carries UpdateCheckMode: Tags and AutoUpdateMode: Version, so their bot finds
this tag, resolves it to a commit hash and writes the build entry itself.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
versionCode 2. The one user-visible change since 1.0 is the navigation bar
staying on screen; public_html/ is untouched, so the service worker cache
keeps its name and no web user sees a different page.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
fdroidserver forces its own build-tools version into app builds, but that
rewrite only matches files ending .gradle — not .gradle.kts. So the pin
would have survived onto their buildserver, and if it could not get
build-tools 36.0.0 the build would fail rather than fall back. AGP picks
its own default instead. Clean rebuild is unaffected: still builds, still
zero permissions.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
A single Activity holding one WebView, in Java rather than Kotlin — for
~120 lines of setup Kotlin would only add its Gradle plugin, its stdlib
in the APK and a third version to keep aligned with Gradle and AGP. One
dependency: androidx.webkit 1.16.0.
The assets are served from https://appassets.androidplatform.net through
WebViewAssetLoader rather than file://. That is the part that matters: an
https origin is a secure context, and localStorage — which holds every
setting and the match in progress — is blocked on file://, so a saved
game would silently vanish. Confirmed on device: force-quit mid-match and
everything comes back.
public_html stays the only copy of the web app. A task syncs it into the
assets at build time, so the browser version and the app version cannot
drift; the APK's index.html hashes identical to the working tree. sw.js
is left out on purpose — it is cache-first, and a service-worker cache
outlives an app upgrade, so it would serve a stale index.html with no way
to clear it. The APK is the cache now.
Three web APIs don't exist in a WebView, so the Activity supplies them:
FLAG_KEEP_SCREEN_ON for navigator.wakeLock, native immersive mode for
requestFullscreen(), and LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES so the
panels' env(safe-area-inset-*) has something to report. textZoom is
pinned to 100: the layout is built on clamp() and vw, and a large system
font would scale the text inside it.
The manifest declares no permissions whatsoever.
Wiring note: AGP 9 refuses a Provider in sourceSets.assets.srcDir, since
it can't tell generated from static directories. The sync is a task with
a DirectoryProperty output, attached via androidComponents.onVariants,
which is the supported path and carries the task dependency.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>