mirror of
https://github.com/zarzet/SpotiFLAC-Mobile.git
synced 2026-10-20 22:41:38 +02:00
refactor(services): clarify misleading names and drop a no-op rethrow
Remove the try/catch that only rethrew in the library scan helper, rename the history loader that schedules a microtask, and fix two comments.
This commit is contained in:
1 parent
019257541b
commit
6879df4917
3 files changed
+63
-64
No files matched your search
@@ -118,11 +118,11 @@ class DownloadHistoryNotifier extends Notifier<DownloadHistoryState> {
|
||||
@override
|
||||
DownloadHistoryState build() {
|
||||
ref.onDispose(() => _indexBumpTimer?.cancel());
|
||||
_loadFromDatabaseSync();
|
||||
_scheduleLoadFromDatabase();
|
||||
return DownloadHistoryState();
|
||||
}
|
||||
|
||||
void _loadFromDatabaseSync() {
|
||||
void _scheduleLoadFromDatabase() {
|
||||
if (_isLoaded) return;
|
||||
_isLoaded = true;
|
||||
Future.microtask(() async {
|
||||
|
||||
@@ -52,7 +52,8 @@ class HistoryBatchLookupRequest {
|
||||
const HistoryBatchLookupRequest(this.tracks);
|
||||
|
||||
/// An immutable request whose hash is computed only once. Use for lists
|
||||
/// retained across widget builds; the legacy constructor remains available.
|
||||
/// retained across widget builds; the const constructor recomputes the hash
|
||||
/// on every use.
|
||||
factory HistoryBatchLookupRequest.snapshot(
|
||||
Iterable<HistoryLookupRequest> tracks,
|
||||
) = _HistoryBatchLookupSnapshot;
|
||||
@@ -339,6 +340,8 @@ class HistoryDatabase {
|
||||
return (value ?? '').trim().toLowerCase();
|
||||
}
|
||||
|
||||
/// Returns '' for an empty track name, unlike [LibraryDatabase.matchKeyFor],
|
||||
/// which returns '|artist' in that case.
|
||||
static String matchKeyFor(String? trackName, String? artistName) {
|
||||
final track = normalizeLookupText(trackName);
|
||||
if (track.isEmpty) return '';
|
||||
|
||||
@@ -2479,68 +2479,64 @@ class PlatformBridge {
|
||||
'${scanDir.path}${Platform.pathSeparator}'
|
||||
'library_scan_${hash.toRadixString(16).padLeft(8, '0')}.ndjson',
|
||||
);
|
||||
try {
|
||||
if (isCancelled?.call() == true) {
|
||||
throw StateError('Library scan cancelled before native scan');
|
||||
}
|
||||
if (forceFullScan) {
|
||||
// An explicit rescan must not resume metadata from an earlier attempt.
|
||||
for (final file in [output, File('${output.path}.state')]) {
|
||||
if (await file.exists()) await file.delete();
|
||||
}
|
||||
// Preserve covers referenced by the current DB until ingestion succeeds.
|
||||
// Fresh paths bypass native disk and Flutter image caches together.
|
||||
final covers = Directory('${scanDir.path}/library_covers');
|
||||
await covers.create(recursive: true);
|
||||
final freshCovers = await covers.createTemp('full_scan_');
|
||||
await setLibraryCoverCacheDir(freshCovers.path);
|
||||
}
|
||||
if (isCancelled?.call() == true) {
|
||||
throw StateError('Library scan cancelled before native scan');
|
||||
}
|
||||
final result = await _channel.invokeMethod(method, {
|
||||
...arguments,
|
||||
'output_path': output.path,
|
||||
});
|
||||
if (result is! Map) {
|
||||
throw FormatException('$method returned ${result.runtimeType}');
|
||||
}
|
||||
if (result['cancelled'] == true) {
|
||||
throw FormatException('$method returned a cancelled partial scan');
|
||||
}
|
||||
final errors = result['error_count'];
|
||||
if (errors is! num ||
|
||||
!errors.isFinite ||
|
||||
errors < 0 ||
|
||||
errors != errors.toInt()) {
|
||||
throw FormatException('$method returned an invalid error count');
|
||||
}
|
||||
final pathValue = result['path'];
|
||||
final countValue = result['count'];
|
||||
if (pathValue is! String || pathValue.trim().isEmpty) {
|
||||
throw FormatException('$method returned an invalid output path');
|
||||
}
|
||||
if (countValue is! num ||
|
||||
!countValue.isFinite ||
|
||||
countValue < 0 ||
|
||||
countValue != countValue.toInt()) {
|
||||
throw FormatException('$method returned an invalid row count');
|
||||
}
|
||||
final path = pathValue;
|
||||
final count = countValue.toInt();
|
||||
final file = File(path);
|
||||
if (!await file.exists()) {
|
||||
throw FormatException('$method did not create its output file');
|
||||
}
|
||||
return LibraryScanNDJSONFile(
|
||||
file: file,
|
||||
expectedCount: count,
|
||||
errorCount: errors.toInt(),
|
||||
);
|
||||
} catch (_) {
|
||||
// Keep partial output; native SAF scan resumes from its sidecar.
|
||||
rethrow;
|
||||
// Partial output is kept on failure; native SAF scan resumes from its sidecar.
|
||||
if (isCancelled?.call() == true) {
|
||||
throw StateError('Library scan cancelled before native scan');
|
||||
}
|
||||
if (forceFullScan) {
|
||||
// An explicit rescan must not resume metadata from an earlier attempt.
|
||||
for (final file in [output, File('${output.path}.state')]) {
|
||||
if (await file.exists()) await file.delete();
|
||||
}
|
||||
// Preserve covers referenced by the current DB until ingestion succeeds.
|
||||
// Fresh paths bypass native disk and Flutter image caches together.
|
||||
final covers = Directory('${scanDir.path}/library_covers');
|
||||
await covers.create(recursive: true);
|
||||
final freshCovers = await covers.createTemp('full_scan_');
|
||||
await setLibraryCoverCacheDir(freshCovers.path);
|
||||
}
|
||||
if (isCancelled?.call() == true) {
|
||||
throw StateError('Library scan cancelled before native scan');
|
||||
}
|
||||
final result = await _channel.invokeMethod(method, {
|
||||
...arguments,
|
||||
'output_path': output.path,
|
||||
});
|
||||
if (result is! Map) {
|
||||
throw FormatException('$method returned ${result.runtimeType}');
|
||||
}
|
||||
if (result['cancelled'] == true) {
|
||||
throw FormatException('$method returned a cancelled partial scan');
|
||||
}
|
||||
final errors = result['error_count'];
|
||||
if (errors is! num ||
|
||||
!errors.isFinite ||
|
||||
errors < 0 ||
|
||||
errors != errors.toInt()) {
|
||||
throw FormatException('$method returned an invalid error count');
|
||||
}
|
||||
final pathValue = result['path'];
|
||||
final countValue = result['count'];
|
||||
if (pathValue is! String || pathValue.trim().isEmpty) {
|
||||
throw FormatException('$method returned an invalid output path');
|
||||
}
|
||||
if (countValue is! num ||
|
||||
!countValue.isFinite ||
|
||||
countValue < 0 ||
|
||||
countValue != countValue.toInt()) {
|
||||
throw FormatException('$method returned an invalid row count');
|
||||
}
|
||||
final path = pathValue;
|
||||
final count = countValue.toInt();
|
||||
final file = File(path);
|
||||
if (!await file.exists()) {
|
||||
throw FormatException('$method did not create its output file');
|
||||
}
|
||||
return LibraryScanNDJSONFile(
|
||||
file: file,
|
||||
expectedCount: count,
|
||||
errorCount: errors.toInt(),
|
||||
);
|
||||
}
|
||||
|
||||
static Future<Map<String, dynamic>> scanSafTreeIncremental(
|
||||
|
||||
Reference in new issue
Block a user