flutter pub get rejects "2026.05.11.0+1" — it requires strict
MAJOR.MINOR.PATCH+BUILD with no leading zeros. Use 2026.5.11+1
as the local default; CI's --build-name="${TAG#v}" still injects
the full 4-part tag for release builds, so production APKs report
the tag verbatim while local dev builds get a sensible recent value.
Update banner showing on identical versions:
- pubspec.yaml was stuck at the placeholder 0.1.0+1, so
PackageInfo.version returned "0.1.0" while the server reported the
actual release tag (e.g. "2026.05.10.1"). Comparison correctly said
"newer" → banner always showed.
- Bump pubspec to 2026.05.11.0+1 so the local default matches the
release cadence even before CI overrides it.
- Update flutter.yml release step to pass --build-name="${TAG#v}" so
every tagged APK reports the tag as its PackageInfo.version. Future
releases stop drifting from pubspec.
- Rewrite isVersionNewer to do component-wise int comparison with
zero-padding: pub_semver.Version.parse rejects 4-part date versions
like "2026.05.10.1", at which point the old code fell back to
string inequality and treated "2026.05.10" as newer than itself
vs "2026.05.10.0". Drop the pub_semver import (no longer used).
Lock-screen play/pause not responding:
- PlaybackState only listed MediaAction.seek in systemActions, which
on Android 13+ means tapping the lock-screen play/pause button
doesn't route back to the AudioHandler. Add play, pause,
skipToNext, skipToPrevious to the set.
- Add androidCompactActionIndices: [0, 1, 2] so the compact
notification view explicitly maps the three buttons.
Album art being smaller than the lock-screen frame is upstream of
this commit — the cover-cache writes whatever pixel dimensions the
server returns. If the server's /api/albums/<id>/cover returns small
thumbnails for these albums, the lock screen renders them at that
size. Worth a separate look at the server cover-emit path.
Already a transitive dep via flutter_secure_storage and flutter_cache_manager.
Promoting to direct so we can import it from album_cover_cache (next
commit) for the lock-screen artwork cache directory.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
shared/fabledsword.tokens.json mirrors web/src/lib/styles/tokens.json;
assets/error-copy.json mirrors the web's error-code copy table;
assets/svg/album-fallback.svg mirrors the web placeholder. Together
these give Flutter the same visual + copy starting point as the SPA.
tool/gen_tokens.dart emits lib/theme/tokens.dart from the JSON; the
generated file is committed so CI can verify the JSON and the Dart
file haven't drifted (gate added in Task 21).
tool/sync_shared.sh mkdirs the shared/ + assets/ destinations before
copying so the script works on a fresh checkout (the original
plan-text shape only mkdir'd assets/svg).
pubspec.yaml assets block uncommented now that the three asset paths
exist on disk.
iOS + Android targets only; desktop disabled (per spec, Tauri-wrapped
SvelteKit handles desktop in v1.1). Riverpod + dio + just_audio +
audio_service + go_router pinned in pubspec. Smoke test confirms the
ProviderScope wiring boots a Material app.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>