v2.53.1 — LOW-1: Willkommen-zurück-Dialog nur bei >24h Offline (24h-Check)
This commit is contained in:
@@ -267,6 +267,10 @@ class _CloudScreenState extends State<CloudScreen>
|
||||
/// „Willkommen zurück! Seit letztem Sync: +8 neue · −3 gelöscht · ⭐5“
|
||||
void _zeigeKonfliktReport(SyncBericht bericht) {
|
||||
if (!mounted) return;
|
||||
// LOW-1: „Willkommen zurück!“ nur zeigen, wenn der letzte Sync mehr als
|
||||
// 24h zurückliegt (oder noch nie gesynct) — sonst Dialog-Flut bei jedem
|
||||
// Sync mit Änderungen. Basis ist der letzterSync-Stand VOR diesem Lauf.
|
||||
if (!bericht.nachLangerPause()) return;
|
||||
final titel = 'Willkommen zurück!';
|
||||
final zeilen = <String>[
|
||||
'Seit deinem letzten Sync:',
|
||||
|
||||
@@ -35,11 +35,17 @@ class SyncBericht {
|
||||
/// Menschlich lesbare Änderungszeilen („+ Neuer Song: …“, „− Gelöscht: …“).
|
||||
final List<String> details;
|
||||
|
||||
/// Letzter Sync-ZEITPUNKT VOR diesem Lauf (Snapshot vor listSongs,
|
||||
/// MED-1) — Basis für den 24h-Check des „Willkommen zurück!“-Dialogs
|
||||
/// (LOW-1). null = noch nie gesynct (Erst-Sync) → Dialog zeigen.
|
||||
final DateTime? letzterSyncVorher;
|
||||
|
||||
const SyncBericht({
|
||||
required this.neueSongs,
|
||||
required this.geloeschteSongs,
|
||||
required this.favoritenGeaendert,
|
||||
this.details = const [],
|
||||
this.letzterSyncVorher,
|
||||
});
|
||||
|
||||
bool get hatAenderungen =>
|
||||
@@ -54,6 +60,16 @@ class SyncBericht {
|
||||
];
|
||||
return teile.join(' · ');
|
||||
}
|
||||
|
||||
/// LOW-1: „Willkommen zurück!“-Dialog nur nach längerer Pause zeigen —
|
||||
/// letzter Sync mehr als 24h zurück (oder noch nie gesynct). [jetzt]
|
||||
/// injizierbar für Tests.
|
||||
bool nachLangerPause({DateTime? jetzt}) {
|
||||
final vorher = letzterSyncVorher;
|
||||
if (vorher == null) return true;
|
||||
final j = jetzt ?? DateTime.now();
|
||||
return j.difference(vorher) > const Duration(hours: 24);
|
||||
}
|
||||
}
|
||||
|
||||
/// Zentraler Cloud-Sync (Sprint D, v2.52.2).
|
||||
@@ -487,6 +503,10 @@ class SyncService {
|
||||
geloeschteSongs: geloeschteSongs,
|
||||
favoritenGeaendert: favoritenGeaendert,
|
||||
details: [...neueDetails, ...loeschDetails, ...favoritenDetails],
|
||||
// LOW-1: 24h-Check des „Willkommen zurück!“-Dialogs gegen den
|
||||
// letzterSync-Stand VOR diesem Sync (MED-1-Snapshot) — nicht gegen
|
||||
// den frisch persistierten, sonst wäre die Pause immer 0.
|
||||
letzterSyncVorher: letzterSync,
|
||||
);
|
||||
if (bericht.hatAenderungen) {
|
||||
onBericht?.call(bericht);
|
||||
|
||||
@@ -103,6 +103,32 @@ void main() {
|
||||
expect(bericht.details, hasLength(2));
|
||||
expect(bericht.details.first, '+ Neuer Song: A');
|
||||
});
|
||||
|
||||
test('nachLangerPause: letzterSyncVorher null (Erst-Sync) → true', () {
|
||||
const bericht = SyncBericht(
|
||||
neueSongs: 1, geloeschteSongs: 0, favoritenGeaendert: 0);
|
||||
expect(bericht.nachLangerPause(jetzt: DateTime(2026, 8, 5, 12)), isTrue);
|
||||
});
|
||||
|
||||
test('nachLangerPause: < 24h seit letztem Sync → false', () {
|
||||
final bericht = SyncBericht(
|
||||
neueSongs: 1,
|
||||
geloeschteSongs: 0,
|
||||
favoritenGeaendert: 0,
|
||||
letzterSyncVorher: DateTime(2026, 8, 5, 11, 0),
|
||||
);
|
||||
expect(bericht.nachLangerPause(jetzt: DateTime(2026, 8, 5, 12)), isFalse);
|
||||
});
|
||||
|
||||
test('nachLangerPause: > 24h seit letztem Sync → true', () {
|
||||
final bericht = SyncBericht(
|
||||
neueSongs: 1,
|
||||
geloeschteSongs: 0,
|
||||
favoritenGeaendert: 0,
|
||||
letzterSyncVorher: DateTime(2026, 8, 3, 10, 0),
|
||||
);
|
||||
expect(bericht.nachLangerPause(jetzt: DateTime(2026, 8, 5, 12)), isTrue);
|
||||
});
|
||||
});
|
||||
|
||||
group('songAusServerMap (MED-2: Server-Listeneintrag → lokaler Song)', () {
|
||||
|
||||
Reference in New Issue
Block a user