mirror of
https://github.com/zarzet/SpotiFLAC-Mobile.git
synced 2026-07-30 15:58:51 +02:00
feat(download): preserve quality variants
This commit is contained in:
@@ -4,8 +4,10 @@ import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:spotiflac_android/l10n/l10n.dart';
|
||||
import 'package:spotiflac_android/models/track.dart';
|
||||
import 'package:spotiflac_android/providers/library_collections_provider.dart';
|
||||
import 'package:spotiflac_android/providers/settings_provider.dart';
|
||||
import 'package:spotiflac_android/services/cover_cache_manager.dart';
|
||||
import 'package:spotiflac_android/widgets/playlist_picker_sheet.dart';
|
||||
import 'package:spotiflac_android/widgets/track_detail_actions.dart';
|
||||
import 'package:spotiflac_android/utils/clickable_metadata.dart';
|
||||
|
||||
class TrackCollectionQuickActions extends ConsumerWidget {
|
||||
@@ -64,6 +66,9 @@ class _TrackOptionsSheet extends ConsumerWidget {
|
||||
final isInWishlist = ref.watch(
|
||||
libraryCollectionsProvider.select((state) => state.isInWishlist(track)),
|
||||
);
|
||||
final allowQualityVariants = ref.watch(
|
||||
settingsProvider.select((settings) => settings.allowQualityVariants),
|
||||
);
|
||||
|
||||
return SafeArea(
|
||||
child: ConstrainedBox(
|
||||
@@ -163,6 +168,25 @@ class _TrackOptionsSheet extends ConsumerWidget {
|
||||
color: colorScheme.outlineVariant.withValues(alpha: 0.5),
|
||||
),
|
||||
|
||||
if (allowQualityVariants)
|
||||
_OptionTile(
|
||||
icon: Icons.download_outlined,
|
||||
title: context.l10n.trackOptionDownloadQualityVariant,
|
||||
onTap: () {
|
||||
final rootContext = Navigator.of(
|
||||
context,
|
||||
rootNavigator: true,
|
||||
).context;
|
||||
Navigator.pop(context);
|
||||
downloadSingleTrack(
|
||||
rootContext,
|
||||
ref,
|
||||
track,
|
||||
forceQualityPicker: true,
|
||||
);
|
||||
},
|
||||
),
|
||||
|
||||
_OptionTile(
|
||||
icon: isLoved ? Icons.favorite : Icons.favorite_border,
|
||||
iconColor: isLoved ? colorScheme.error : null,
|
||||
|
||||
@@ -19,6 +19,7 @@ void downloadSingleTrack(
|
||||
String? recommendedService,
|
||||
String? playlistName,
|
||||
int? playlistPosition,
|
||||
bool forceQualityPicker = false,
|
||||
}) {
|
||||
final settings = ref.read(settingsProvider);
|
||||
|
||||
@@ -29,7 +30,7 @@ void downloadSingleTrack(
|
||||
);
|
||||
}
|
||||
|
||||
if (settings.askQualityBeforeDownload) {
|
||||
if (settings.askQualityBeforeDownload || forceQualityPicker) {
|
||||
DownloadServicePicker.show(
|
||||
context,
|
||||
trackName: track.name,
|
||||
@@ -115,9 +116,7 @@ void showQueuedSnackbar(BuildContext context, int added, int skipped) {
|
||||
final message = skipped > 0
|
||||
? context.l10n.discographySkippedDownloaded(added, skipped)
|
||||
: context.l10n.snackbarAddedTracksToQueue(added);
|
||||
ScaffoldMessenger.of(
|
||||
context,
|
||||
).showSnackBar(SnackBar(content: Text(message)));
|
||||
ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text(message)));
|
||||
}
|
||||
|
||||
/// Shared batch "add to queue" flow for detail screens: skips tracks already
|
||||
@@ -139,18 +138,24 @@ Future<void> queueTracksSkippingDownloaded(
|
||||
}) async {
|
||||
if (tracks.isEmpty) return;
|
||||
|
||||
final settings = ref.read(settingsProvider);
|
||||
final skipExisting =
|
||||
settings.deduplicateDownloads && !settings.allowQualityVariants;
|
||||
final historyLookups = tracks
|
||||
.map(historyLookupForTrack)
|
||||
.toList(growable: false);
|
||||
final existingHistoryKeys = await ref.read(
|
||||
downloadHistoryBatchExistsProvider(
|
||||
HistoryBatchLookupRequest(historyLookups),
|
||||
).future,
|
||||
);
|
||||
final existingHistoryKeys = skipExisting
|
||||
? await ref.read(
|
||||
downloadHistoryBatchExistsProvider(
|
||||
HistoryBatchLookupRequest(historyLookups),
|
||||
).future,
|
||||
)
|
||||
: const <String>{};
|
||||
if (!context.mounted) return;
|
||||
final settings = ref.read(settingsProvider);
|
||||
final localLibState =
|
||||
(settings.localLibraryEnabled && settings.localLibraryShowDuplicates)
|
||||
(skipExisting &&
|
||||
settings.localLibraryEnabled &&
|
||||
settings.localLibraryShowDuplicates)
|
||||
? ref.read(localLibraryProvider)
|
||||
: null;
|
||||
final tracksToQueue = <Track>[];
|
||||
@@ -158,9 +163,9 @@ Future<void> queueTracksSkippingDownloaded(
|
||||
|
||||
for (var i = 0; i < tracks.length; i++) {
|
||||
final track = tracks[i];
|
||||
final isInHistory = existingHistoryKeys.contains(
|
||||
historyLookups[i].lookupKey,
|
||||
);
|
||||
final isInHistory =
|
||||
skipExisting &&
|
||||
existingHistoryKeys.contains(historyLookups[i].lookupKey);
|
||||
final isInLocal =
|
||||
localLibState?.existsInLibrary(
|
||||
isrc: track.isrc,
|
||||
@@ -187,7 +192,7 @@ Future<void> queueTracksSkippingDownloaded(
|
||||
return;
|
||||
}
|
||||
|
||||
if (settings.askQualityBeforeDownload) {
|
||||
if (settings.askQualityBeforeDownload || settings.allowQualityVariants) {
|
||||
DownloadServicePicker.show(
|
||||
context,
|
||||
trackName: '${tracksToQueue.length} tracks',
|
||||
|
||||
Reference in New Issue
Block a user