From 83bb86a1fa717a4057cffe1f87097b10dab6d257 Mon Sep 17 00:00:00 2001 From: Dustin Date: Wed, 5 Aug 2026 11:26:00 +0200 Subject: [PATCH] =?UTF-8?q?v2.53.1=20=E2=80=94=20LOW-1:=20Willkommen-zur?= =?UTF-8?q?=C3=BCck-Dialog=20nur=20bei=20>24h=20Offline=20(24h-Check)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/screens/cloud_screen.dart | 4 ++++ lib/services/sync_service.dart | 20 ++++++++++++++++++++ test/sync_service_test.dart | 26 ++++++++++++++++++++++++++ 3 files changed, 50 insertions(+) diff --git a/lib/screens/cloud_screen.dart b/lib/screens/cloud_screen.dart index 6c4b52f..6c7b7f1 100644 --- a/lib/screens/cloud_screen.dart +++ b/lib/screens/cloud_screen.dart @@ -267,6 +267,10 @@ class _CloudScreenState extends State /// „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 = [ 'Seit deinem letzten Sync:', diff --git a/lib/services/sync_service.dart b/lib/services/sync_service.dart index de2d933..07d49b2 100644 --- a/lib/services/sync_service.dart +++ b/lib/services/sync_service.dart @@ -35,11 +35,17 @@ class SyncBericht { /// Menschlich lesbare Änderungszeilen („+ Neuer Song: …“, „− Gelöscht: …“). final List 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); diff --git a/test/sync_service_test.dart b/test/sync_service_test.dart index 32b8dde..13ca243 100644 --- a/test/sync_service_test.dart +++ b/test/sync_service_test.dart @@ -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)', () {