Was-ist-neu-Bericht als In-App-Dialog nach dem Abgleich
This commit is contained in:
+19
-2
@@ -30,6 +30,7 @@ import 'services/sync_service.dart';
|
|||||||
import 'services/yt_download_service.dart';
|
import 'services/yt_download_service.dart';
|
||||||
import 'services/yt_search_service.dart';
|
import 'services/yt_search_service.dart';
|
||||||
import 'settings/app_settings.dart';
|
import 'settings/app_settings.dart';
|
||||||
|
import 'shared/sync_bericht_dialog.dart';
|
||||||
import 'shared/theme.dart';
|
import 'shared/theme.dart';
|
||||||
|
|
||||||
late final MeloAudioHandler _handler;
|
late final MeloAudioHandler _handler;
|
||||||
@@ -177,7 +178,7 @@ class _HomeShellState extends State<HomeShell> with WidgetsBindingObserver {
|
|||||||
WidgetsBinding.instance.addObserver(this);
|
WidgetsBinding.instance.addObserver(this);
|
||||||
// Beim Start einmal mit dem Server abgleichen — neue Titel von anderen
|
// Beim Start einmal mit dem Server abgleichen — neue Titel von anderen
|
||||||
// Geräten sind dann sofort da.
|
// Geräten sind dann sofort da.
|
||||||
context.read<SyncService>().automatisch();
|
unawaited(_gleicheAbUndZeigeBericht());
|
||||||
unawaited(context.read<LibraryService>().ensureStartupPermissions());
|
unawaited(context.read<LibraryService>().ensureStartupPermissions());
|
||||||
unawaited(_pruefeGeteilteAdresse());
|
unawaited(_pruefeGeteilteAdresse());
|
||||||
}
|
}
|
||||||
@@ -205,13 +206,29 @@ class _HomeShellState extends State<HomeShell> with WidgetsBindingObserver {
|
|||||||
// auf dem Gerät wie am Server.
|
// auf dem Gerät wie am Server.
|
||||||
if (state == AppLifecycleState.resumed) {
|
if (state == AppLifecycleState.resumed) {
|
||||||
if (Platform.isAndroid) _autoScan.pruefe();
|
if (Platform.isAndroid) _autoScan.pruefe();
|
||||||
context.read<SyncService>().automatisch();
|
unawaited(_gleicheAbUndZeigeBericht());
|
||||||
// Ein zweites Teilen startet die App nicht neu (singleTop), sondern
|
// Ein zweites Teilen startet die App nicht neu (singleTop), sondern
|
||||||
// bringt sie nur nach vorn — deshalb auch hier nachsehen.
|
// bringt sie nur nach vorn — deshalb auch hier nachsehen.
|
||||||
unawaited(_pruefeGeteilteAdresse());
|
unawaited(_pruefeGeteilteAdresse());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Gleicht ab und zeigt danach höchstens einmal den „Was ist neu"-Bericht.
|
||||||
|
Future<void> _gleicheAbUndZeigeBericht() async {
|
||||||
|
final sync = context.read<SyncService>();
|
||||||
|
await sync.automatisch();
|
||||||
|
if (!mounted) return;
|
||||||
|
final bericht = sync.bericht;
|
||||||
|
if (bericht == null) return;
|
||||||
|
// Zuerst quittieren: ein zweites Zurückkehren in die App soll denselben
|
||||||
|
// Bericht nicht erneut zeigen.
|
||||||
|
sync.berichtGesehen();
|
||||||
|
await showDialog<void>(
|
||||||
|
context: context,
|
||||||
|
builder: (_) => SyncBerichtDialog(bericht: bericht),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final tabs = <Widget>[
|
final tabs = <Widget>[
|
||||||
|
|||||||
@@ -0,0 +1,35 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
import '../services/sync_service.dart';
|
||||||
|
|
||||||
|
/// „Willkommen zurück" — was sich seit dem letzten erfolgreichen Abgleich
|
||||||
|
/// getan hat. Rein in-App, ohne Benachrichtigungs-Kanal und ohne neue
|
||||||
|
/// Abhängigkeit.
|
||||||
|
class SyncBerichtDialog extends StatelessWidget {
|
||||||
|
const SyncBerichtDialog({super.key, required this.bericht});
|
||||||
|
|
||||||
|
final SyncBericht bericht;
|
||||||
|
|
||||||
|
static String textFuer(SyncBericht b) {
|
||||||
|
if (b.istLeer) return 'Nichts Neues seit dem letzten Abgleich.';
|
||||||
|
final teile = <String>[];
|
||||||
|
if (b.neueSongs > 0) teile.add('${b.neueSongs} neue Titel');
|
||||||
|
if (b.geloeschte > 0) teile.add('${b.geloeschte} entfernt');
|
||||||
|
if (b.favoriten > 0) teile.add('${b.favoriten} Favoriten geändert');
|
||||||
|
return '${teile.join(' · ')}.';
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return AlertDialog(
|
||||||
|
title: const Text('Willkommen zurück!'),
|
||||||
|
content: Text(textFuer(bericht)),
|
||||||
|
actions: [
|
||||||
|
FilledButton(
|
||||||
|
onPressed: () => Navigator.of(context).pop(),
|
||||||
|
child: const Text('Alles klar'),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_test/flutter_test.dart';
|
||||||
|
import 'package:melo/services/sync_service.dart';
|
||||||
|
import 'package:melo/shared/sync_bericht_dialog.dart';
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
Future<void> zeige(WidgetTester tester, SyncBericht bericht) async {
|
||||||
|
await tester.pumpWidget(MaterialApp(
|
||||||
|
home: Scaffold(body: SyncBerichtDialog(bericht: bericht)),
|
||||||
|
));
|
||||||
|
await tester.pump();
|
||||||
|
}
|
||||||
|
|
||||||
|
testWidgets('nennt neue und entfernte Titel', (tester) async {
|
||||||
|
await zeige(
|
||||||
|
tester,
|
||||||
|
const SyncBericht(neueSongs: 3, geloeschte: 1, favoriten: 0),
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(find.text('Willkommen zurück!'), findsOneWidget);
|
||||||
|
expect(find.textContaining('3 neue Titel'), findsOneWidget);
|
||||||
|
expect(find.textContaining('1 entfernt'), findsOneWidget);
|
||||||
|
});
|
||||||
|
|
||||||
|
testWidgets('ohne Änderungen sagt er das auch', (tester) async {
|
||||||
|
await zeige(
|
||||||
|
tester,
|
||||||
|
const SyncBericht(neueSongs: 0, geloeschte: 0, favoriten: 0),
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(find.textContaining('Nichts Neues'), findsOneWidget);
|
||||||
|
});
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user