Files
Melo/lib/library/auto_scan.dart
T
Hermes (Server)andClaude Opus 5 15e3d44453 Automatische Erkennung: neue Dateien auf dem Geraet und neue Alben am Server
- AutoScan: beim Zurueckkehren in die App wird die Zahl der Musikdateien
  mit der Bibliothek verglichen; nur bei Abweichung laeuft ein Scan, und
  hoechstens alle 5 Minuten. Gleich viele Loeschungen wie Neuzugaenge
  bleiben unbemerkt - dafuer gibt es den Scan von Hand.
- ServerNeuheiten: meldet neu auf Navidrome aufgetauchte Alben im
  Online-Tab. Der erste Abruf meldet bewusst nichts, sonst waere die ganze
  Sammlung "neu"; er nutzt die ohnehin geladenen Alben statt eines zweiten
  Serveraufrufs.
- Neu: MeloDb.countSongs(), countAndroidMediaStoreSongs().

189 Tests gruen, flutter analyze ohne Befund.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018NLW1q1hzEC9goDQ1dJ98d
2026-08-20 19:19:04 +02:00

62 lines
1.9 KiB
Dart

import 'package:flutter/foundation.dart';
/// Erkennt von allein, wenn sich der Musikbestand des Geräts geändert hat —
/// etwa weil Dateien per Kabel übertragen oder heruntergeladen wurden — und
/// stößt dann einen Scan an.
///
/// Bewusst nur ein Zählvergleich: der Scan selbst ist der teure Teil und soll
/// nicht bei jedem Wechsel in den Vordergrund laufen. Werden gleich viele
/// Titel gelöscht wie hinzugefügt, merkt das erst der nächste Scan von Hand.
class AutoScan {
AutoScan({
required this.geraeteAnzahl,
required this.bekannteAnzahl,
required this.scanne,
this.mindestAbstand = const Duration(minutes: 5),
DateTime Function()? jetzt,
}) : _jetzt = jetzt ?? DateTime.now;
/// Wie viele Musikdateien das Gerät meldet.
final Future<int> Function() geraeteAnzahl;
/// Wie viele Titel die Bibliothek kennt.
final Future<int> Function() bekannteAnzahl;
final Future<void> Function() scanne;
/// So lange wird nach einer Prüfung gar nicht erst wieder gezählt.
final Duration mindestAbstand;
final DateTime Function() _jetzt;
DateTime? _zuletzt;
bool _laeuft = false;
/// Prüft, ob sich etwas geändert hat, und scannt gegebenenfalls.
/// Gibt zurück, ob ein Scan angestoßen wurde.
Future<bool> pruefe() async {
if (_laeuft) return false;
final jetzt = _jetzt();
final zuletzt = _zuletzt;
if (zuletzt != null && jetzt.difference(zuletzt) < mindestAbstand) {
return false;
}
_zuletzt = jetzt;
_laeuft = true;
try {
final auf = await geraeteAnzahl();
final bekannt = await bekannteAnzahl();
if (auf == bekannt) return false;
await scanne();
return true;
} catch (e) {
// Kein Grund, die App zu stören — der Knopf zum Scannen bleibt ja da.
debugPrint('Automatische Erkennung fehlgeschlagen: $e');
return false;
} finally {
_laeuft = false;
}
}
}