mirror of
https://github.com/zarzet/SpotiFLAC-Mobile.git
synced 2026-10-11 02:08:44 +02:00
refactor(library): share the track selection bar and delete action
The Library list's multi-select toolbar (FLAC upgrade, re-enrich, convert, ReplayGain add/remove, delete) becomes LibraryTrackSelectionBar, and its delete flow becomes deleteLibraryTracks. The Library list renders and behaves as before; other screens can now offer the same actions.
This commit is contained in:
1 parent
a549671c4e
commit
86cf860288
5 files changed
+210
-172
No files matched your search
@@ -16,6 +16,7 @@ import 'package:spotiflac_android/services/library_database.dart';
|
||||
import 'package:spotiflac_android/services/local_track_redownload_service.dart';
|
||||
import 'package:spotiflac_android/services/platform_bridge.dart';
|
||||
import 'package:spotiflac_android/utils/ffmpeg_reenrich.dart';
|
||||
import 'package:spotiflac_android/utils/file_access.dart';
|
||||
import 'package:spotiflac_android/utils/int_utils.dart';
|
||||
import 'package:spotiflac_android/utils/lyrics_metadata_helper.dart';
|
||||
import 'package:spotiflac_android/utils/string_utils.dart';
|
||||
@@ -508,3 +509,63 @@ Future<({List<Track> tracks, int skipped})> matchLocalTracksForFlac(
|
||||
}
|
||||
return (tracks: tracks, skipped: skipped);
|
||||
}
|
||||
|
||||
/// Confirms, then deletes the files behind [selected] and removes their
|
||||
/// history or local-index rows. Files that cannot be deleted keep their rows.
|
||||
Future<void> deleteLibraryTracks(
|
||||
BuildContext context,
|
||||
WidgetRef ref,
|
||||
List<UnifiedLibraryItem> selected, {
|
||||
required bool Function() isActive,
|
||||
required VoidCallback onComplete,
|
||||
}) async {
|
||||
if (selected.isEmpty) return;
|
||||
final confirmed = await showAppDialog<bool>(
|
||||
context: context,
|
||||
builder: (ctx) => AppAlertDialog(
|
||||
title: Text(context.l10n.dialogDeleteSelectedTitle),
|
||||
content: Text(context.l10n.dialogDeleteSelectedMessage(selected.length)),
|
||||
actions: [
|
||||
AppDialogAction(
|
||||
isDefault: true,
|
||||
onPressed: () => Navigator.pop(ctx, false),
|
||||
child: Text(context.l10n.dialogCancel),
|
||||
),
|
||||
AppDialogAction(
|
||||
filled: true,
|
||||
isDestructive: true,
|
||||
onPressed: () => Navigator.pop(ctx, true),
|
||||
style: FilledButton.styleFrom(
|
||||
backgroundColor: Theme.of(context).colorScheme.error,
|
||||
),
|
||||
child: Text(context.l10n.dialogDelete),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
if (confirmed != true || !isActive() || !context.mounted) return;
|
||||
|
||||
final historyNotifier = ref.read(downloadHistoryProvider.notifier);
|
||||
final messenger = ScaffoldMessenger.of(context);
|
||||
final l10n = context.l10n;
|
||||
var deletedCount = 0;
|
||||
for (final item in selected) {
|
||||
final cleanPath = DownloadedEmbeddedCoverResolver.cleanFilePath(
|
||||
item.filePath,
|
||||
);
|
||||
if (!await deleteFile(cleanPath)) continue;
|
||||
if (item.source == LibraryItemSource.downloaded) {
|
||||
historyNotifier.removeFromHistory(item.historyItem!.id);
|
||||
} else {
|
||||
await LibraryDatabase.instance.deleteByPath(item.filePath);
|
||||
}
|
||||
deletedCount++;
|
||||
}
|
||||
if (selected.any((item) => item.source == LibraryItemSource.local)) {
|
||||
ref.read(localLibraryProvider.notifier).reloadFromStorage();
|
||||
}
|
||||
onComplete();
|
||||
messenger.showSnackBar(
|
||||
SnackBar(content: Text(l10n.snackbarDeletedTracks(deletedCount))),
|
||||
);
|
||||
}
|
||||
Reference in new issue
Block a user