feat: the app tells when sync fails, and when it is too old

Published apps can't be made to update, so the app now notices when it
no longer matches the server: the server names the oldest app build it
works with (instance.info's minimumAppBuild), asked before the first
sync of each launch, and the sync engine's refusal of differing synced
tables counts the same. Either way the app says "update the app; if it
is up to date, the server needs an update" in a banner on Home and in
the new Sync card in Settings, and what the person does meanwhile stays
on the device.

The Sync card shows where sync stands since the app started (syncing,
everything synced, sync failing, with the last completion and failure)
and offers Sync now. While the last sync failed, a dot sits on the
Profile tab and the Settings cog. One sync that goes through clears it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
This commit is contained in:
Tizian 「ティツィアーン」 2026-10-03 23:26:47 +02:00
commit e35ce5c81d
Signed by: raisondetredev
GPG key ID: 07F6FCF405488B64

View file

@ -860,6 +860,57 @@ class AppLocalizationsEn extends AppLocalizations {
@override
String get settingsAbout => 'About Halkyon Learn';
@override
String get syncTitle => 'Sync';
@override
String get syncStateSyncing => 'Syncing…';
@override
String get syncStateSynced => 'Everything synced';
@override
String get syncStateNotYet => 'Not synced yet';
@override
String get syncStateFailing => 'Sync is failing';
@override
String syncStateMismatch(String server) {
return 'This app can\'t sync with $server';
}
@override
String get syncMismatchDetail =>
'Update the app. If it is up to date, the server needs an update. What you do meanwhile stays on this device and syncs afterwards.';
@override
String syncLastCompleted(String time) {
return 'Last completed at $time';
}
@override
String get syncNoRunYet => 'No sync has completed since the app started';
@override
String syncLastFailed(String time) {
return 'Last attempt failed at $time';
}
@override
String get syncNow => 'Sync now';
@override
String get syncTroubleLabel => 'Sync needs attention';
@override
String syncMismatchBanner(String server) {
return 'This app can\'t sync with $server any more. Update it to keep syncing.';
}
@override
String get syncMismatchMore => 'More';
@override
String get tagsReadFailed => 'Couldn\'t read the tags.';