v2.53 — Tombstone-Sync + Konflikt-Report (Sprint E): deleted_at, lokal nachgezogene Löschungen, Willkommen-zurück-Dialog
This commit is contained in:
@@ -118,6 +118,7 @@ class _CloudScreenState extends State<CloudScreen>
|
||||
_berechneNaechstenSync();
|
||||
};
|
||||
_sync.onSyncEnde = _syncEnde;
|
||||
_sync.onBericht = _zeigeKonfliktReport;
|
||||
// Verbindung stellt der CloudService beim App-Start her (MeloHome.initState).
|
||||
// Hier nur Settings laden + Serverdaten, sobald der Service verbunden ist.
|
||||
_ladeSettings();
|
||||
@@ -262,6 +263,109 @@ class _CloudScreenState extends State<CloudScreen>
|
||||
}
|
||||
}
|
||||
|
||||
/// Konflikt-Report (Sprint E): Zusammenfassung nach langem Offline-Sync.
|
||||
/// „Willkommen zurück! Seit letztem Sync: +8 neue · −3 gelöscht · ⭐5“
|
||||
void _zeigeKonfliktReport(SyncBericht bericht) {
|
||||
if (!mounted) return;
|
||||
final titel = 'Willkommen zurück!';
|
||||
final zeilen = <String>[
|
||||
'Seit deinem letzten Sync:',
|
||||
if (bericht.neueSongs > 0) '➕ ${bericht.neueSongs} neue Songs',
|
||||
if (bericht.geloeschteSongs > 0) '🗑️ ${bericht.geloeschteSongs} gelöscht',
|
||||
if (bericht.favoritenGeaendert > 0)
|
||||
'⭐ ${bericht.favoritenGeaendert} Favoriten geändert',
|
||||
];
|
||||
showDialog<void>(
|
||||
context: context,
|
||||
barrierDismissible: true,
|
||||
builder: (ctx) => AlertDialog(
|
||||
backgroundColor: MeloTheme.dunkel1,
|
||||
title: Text(titel,
|
||||
style: const TextStyle(color: Colors.white, fontSize: 18)),
|
||||
content: SingleChildScrollView(
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: zeilen
|
||||
.map((z) => Padding(
|
||||
padding: const EdgeInsets.symmetric(vertical: 3),
|
||||
child: Text(z,
|
||||
style: const TextStyle(
|
||||
color: MeloTheme.textSekundaer,
|
||||
fontSize: 14)),
|
||||
))
|
||||
.toList(),
|
||||
),
|
||||
),
|
||||
actions: [
|
||||
TextButton(
|
||||
onPressed: () {
|
||||
Navigator.pop(ctx);
|
||||
if (bericht.details.isNotEmpty) {
|
||||
_zeigeReportDetails(bericht);
|
||||
}
|
||||
},
|
||||
child: const Text('Details',
|
||||
style: TextStyle(color: MeloTheme.rot)),
|
||||
),
|
||||
TextButton(
|
||||
onPressed: () => Navigator.pop(ctx),
|
||||
child: const Text('OK',
|
||||
style: TextStyle(color: Colors.white)),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
void _zeigeReportDetails(SyncBericht bericht) {
|
||||
if (!mounted) return;
|
||||
showModalBottomSheet<void>(
|
||||
context: context,
|
||||
backgroundColor: MeloTheme.dunkel1,
|
||||
builder: (ctx) => SafeArea(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(16),
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
const Text('Änderungen',
|
||||
style: TextStyle(
|
||||
color: Colors.white,
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.bold)),
|
||||
const SizedBox(height: 12),
|
||||
Flexible(
|
||||
child: ListView(
|
||||
shrinkWrap: true,
|
||||
children: bericht.details
|
||||
.map((d) => Padding(
|
||||
padding: const EdgeInsets.symmetric(vertical: 4),
|
||||
child: Text(d,
|
||||
style: const TextStyle(
|
||||
color: MeloTheme.textSekundaer,
|
||||
fontSize: 13)),
|
||||
))
|
||||
.toList(),
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 12),
|
||||
SizedBox(
|
||||
width: double.infinity,
|
||||
child: TextButton(
|
||||
onPressed: () => Navigator.pop(ctx),
|
||||
child: const Text('Schließen',
|
||||
style: TextStyle(color: MeloTheme.rot)),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
// ─── 📜 Sync-Historie (fürs Dashboard) ───
|
||||
|
||||
static const _historieKey = 'cloud_sync_history';
|
||||
|
||||
Reference in New Issue
Block a user