perf(downloads): enqueue selected playlists in one update

This commit is contained in:
zarzet committed 2026-10-08 09:27:26 +07:00
1 parent 2ded1cff68
commit e01ec99c5e
6 files changed
+586 -47

No files matched your search

+13
View File
@@ -5,6 +5,19 @@ part 'download_item.g.dart';
const Object _downloadItemUnset = Object();
/// Tracks that share playlist naming and album-artist normalization rules.
class DownloadQueueBatch {
final List<Track> tracks;
final String? playlistName;
final List<int?>? playlistPositions;
const DownloadQueueBatch({
required this.tracks,
this.playlistName,
this.playlistPositions,
});
}
enum DownloadStatus {
queued,
downloading,
+59 -33
View File
@@ -975,42 +975,68 @@ class DownloadQueueNotifier extends Notifier<DownloadQueueState> {
String? playlistName,
List<int?>? playlistPositions,
}) {
addBatchesToQueue(
[
DownloadQueueBatch(
tracks: tracks,
playlistName: playlistName,
playlistPositions: playlistPositions,
),
],
service,
qualityOverride: qualityOverride,
);
}
/// Publishes several independent album/playlist batches together. Keep each
/// group's artist normalization, batch flag and playlist positions separate.
void addBatchesToQueue(
List<DownloadQueueBatch> batches,
String service, {
String? qualityOverride,
}) {
if (batches.isEmpty) return;
final settings = ref.read(settingsProvider);
updateSettings(settings);
String? normalizedService;
final takenIds = state.items.map((item) => item.id).toSet();
final shouldAssignPlaylistPositions =
playlistName != null && playlistName.trim().isNotEmpty;
final normalizedTracks = normalizeBatchAlbumArtists(tracks);
final fromBatch = normalizedTracks.length > 1;
final newItems = normalizedTracks.asMap().entries.map((entry) {
final track = entry.value;
final index = entry.key;
final explicitPosition =
playlistPositions != null &&
index < playlistPositions.length &&
(playlistPositions[index] ?? 0) > 0
? playlistPositions[index]
: null;
final id = _newQueueItemId(track, takenIds: takenIds);
takenIds.add(id);
return DownloadItem(
id: id,
track: track,
service: _normalizeQueuedService(service),
createdAt: DateTime.now(),
qualityOverride: qualityOverride,
playlistName: playlistName,
playlistPosition:
explicitPosition ??
(shouldAssignPlaylistPositions ? index + 1 : null),
fromBatch: fromBatch,
preserveQualityVariant: settings.allowQualityVariants,
networkDownloadFolder: settings.networkDownloadFolder,
);
}).toList();
final newItems = <DownloadItem>[];
for (final batch in batches) {
final playlistName = batch.playlistName;
final playlistPositions = batch.playlistPositions;
final shouldAssignPlaylistPositions =
playlistName != null && playlistName.trim().isNotEmpty;
final normalizedTracks = normalizeBatchAlbumArtists(batch.tracks);
final fromBatch = normalizedTracks.length > 1;
for (var index = 0; index < normalizedTracks.length; index++) {
final track = normalizedTracks[index];
final explicitPosition =
playlistPositions != null &&
index < playlistPositions.length &&
(playlistPositions[index] ?? 0) > 0
? playlistPositions[index]
: null;
final id = _newQueueItemId(track, takenIds: takenIds);
takenIds.add(id);
newItems.add(
DownloadItem(
id: id,
track: track,
service: normalizedService ??= _normalizeQueuedService(service),
createdAt: DateTime.now(),
qualityOverride: qualityOverride,
playlistName: playlistName,
playlistPosition:
explicitPosition ??
(shouldAssignPlaylistPositions ? index + 1 : null),
fromBatch: fromBatch,
preserveQualityVariant: settings.allowQualityVariants,
networkDownloadFolder: settings.networkDownloadFolder,
),
);
}
}
state = state.copyWith(items: [...state.items, ...newItems]);
state = _withSettings(settings, items: [...state.items, ...newItems]);
_saveQueueToStorage();
if (!state.isProcessing) {
+11 -9
View File
@@ -263,15 +263,17 @@ extension _QueueTabSelectionActions on _QueueTabState {
}
return;
}
for (final playlist in selectedPlaylists) {
final tracks = playlist.tracks.map((e) => e.track).toList();
queueNotifier.addMultipleToQueue(
tracks,
svc,
qualityOverride: qualityOverride,
playlistName: playlist.name,
);
}
queueNotifier.addBatchesToQueue(
[
for (final playlist in selectedPlaylists)
DownloadQueueBatch(
tracks: playlist.tracks.map((entry) => entry.track).toList(),
playlistName: playlist.name,
),
],
svc,
qualityOverride: qualityOverride,
);
}
if (settings.askQualityBeforeDownload || settings.allowQualityVariants) {