renderStatus() only rewrote the status TextView, so the 'Last sync cursor'
line kept its launch-time value until the next onResume - on a fresh install a
successful sync still displayed 'never'. It now delegates to refreshStatus()
which refreshes both lines.
Chrome on Android 16/17 refuses to reach LAN addresses without the local
network permission, surfacing as ERR_LOCAL_NETWORK_PERMISSION_MISSING (or a
generic 'site can't be reached'), which looks like a dead server. Also removes
the now-stale 'python3 -m http.server 8080' instructions, since that server is
no longer running and its URL returns connection refused.
- MainActivity: the periodic safety-net worker sits in ENQUEUED between runs,
so observing it reset the status line to 'Syncing…' forever. Only a RUNNING
periodic job now counts; one-shot ENQUEUED still shows progress.
- FileBrowserActivity: the action-bar subtitle counted files only, so folders
with no files displayed '0 items'. It now reads e.g. '4 folders · 1 file'.
Native Kotlin Android app (single Activity + WorkManager worker) that copies
photos newer than a stored cursor to //192.168.123.2/photo/Home as
decade/year/month, deduping by filename and NAS file size.
- SMB2/3 via smbj; transparently reconnects when the server drops an idle
session (previously surfaced as "DiskShare has already been closed")
- MediaStore cursor store, incremental uploads, size-aware dedupe
- "Phone files" / "NAS files" browser: grid, thumbnails, full-screen preview
- Release signing read from keystore.properties (never committed)