fix: replace download multiple pops and add translations

This commit is contained in:
Kingkor Roy Tirtho 2023-06-08 09:03:18 +06:00
parent 6752adc939
commit 4a21249ee3
4 changed files with 71 additions and 25 deletions

View File

@ -2,6 +2,7 @@ import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:spotify/spotify.dart'; import 'package:spotify/spotify.dart';
import 'package:spotube/extensions/context.dart';
final replaceDownloadedFileState = StateProvider<bool?>((ref) => null); final replaceDownloadedFileState = StateProvider<bool?>((ref) => null);
@ -14,13 +15,14 @@ class ReplaceDownloadedDialog extends ConsumerWidget {
Widget build(BuildContext context, ref) { Widget build(BuildContext context, ref) {
final groupValue = ref.watch(replaceDownloadedFileState); final groupValue = ref.watch(replaceDownloadedFileState);
final theme = Theme.of(context); final theme = Theme.of(context);
final replaceAll = ref.watch(replaceDownloadedFileState);
return AlertDialog( return AlertDialog(
title: Text("Track ${track.name} Already Exists"), title: Text(context.l10n.track_exists(track.name ?? "")),
content: Column( content: Column(
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
children: [ children: [
const Text("Do you want to replace the already downloaded track?"), Text(context.l10n.do_you_want_to_replace),
RadioListTile<bool>( RadioListTile<bool>(
dense: true, dense: true,
contentPadding: EdgeInsets.zero, contentPadding: EdgeInsets.zero,
@ -29,10 +31,10 @@ class ReplaceDownloadedDialog extends ConsumerWidget {
groupValue: groupValue, groupValue: groupValue,
onChanged: (value) { onChanged: (value) {
if (value != null) { if (value != null) {
ref.read(replaceDownloadedFileState.notifier).state = value; ref.read(replaceDownloadedFileState.notifier).state = true;
} }
}, },
title: const Text("Replace all downloaded tracks"), title: Text(context.l10n.replace_downloaded_tracks),
), ),
RadioListTile<bool>( RadioListTile<bool>(
dense: true, dense: true,
@ -42,25 +44,29 @@ class ReplaceDownloadedDialog extends ConsumerWidget {
groupValue: groupValue, groupValue: groupValue,
onChanged: (value) { onChanged: (value) {
if (value != null) { if (value != null) {
ref.read(replaceDownloadedFileState.notifier).state = value; ref.read(replaceDownloadedFileState.notifier).state = false;
} }
}, },
title: const Text("Skip downloading all downloaded tracks"), title: Text(context.l10n.skip_download_tracks),
), ),
], ],
), ),
actions: [ actions: [
OutlinedButton( OutlinedButton(
child: const Text("No"), onPressed: replaceAll == true
onPressed: () { ? null
: () {
Navigator.pop(context, false); Navigator.pop(context, false);
}, },
child: Text(context.l10n.skip),
), ),
FilledButton( FilledButton(
child: const Text("Yes"), onPressed: replaceAll == false
onPressed: () { ? null
: () {
Navigator.pop(context, true); Navigator.pop(context, true);
}, },
child: Text(context.l10n.replace),
), ),
], ],
); );

View File

@ -185,5 +185,11 @@
"something_went_wrong": "Something went wrong", "something_went_wrong": "Something went wrong",
"piped_instance": "Piped Server Instance", "piped_instance": "Piped Server Instance",
"piped_description": "The Piped server instance to use for track matching\nSome of them might not work well. So use at your own risk", "piped_description": "The Piped server instance to use for track matching\nSome of them might not work well. So use at your own risk",
"generate_playlist": "Generate Playlist" "generate_playlist": "Generate Playlist",
"track_exists": "Track {track} already exists",
"replace_downloaded_tracks": "Replace all downloaded tracks",
"skip_download_tracks": "Skip downloading all downloaded tracks",
"do_you_want_to_replace": "Do you want to replace the existing track??",
"replace": "Replace",
"skip": "Skip"
} }

View File

@ -1,3 +1,5 @@
import 'dart:async';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
import 'package:flutter_hooks/flutter_hooks.dart'; import 'package:flutter_hooks/flutter_hooks.dart';
@ -9,7 +11,6 @@ import 'package:spotube/components/root/sidebar.dart';
import 'package:spotube/components/root/spotube_navigation_bar.dart'; import 'package:spotube/components/root/spotube_navigation_bar.dart';
import 'package:spotube/hooks/use_update_checker.dart'; import 'package:spotube/hooks/use_update_checker.dart';
import 'package:spotube/provider/download_manager_provider.dart'; import 'package:spotube/provider/download_manager_provider.dart';
import 'package:spotube/provider/authentication_provider.dart';
const rootPaths = { const rootPaths = {
0: "/", 0: "/",
@ -29,19 +30,38 @@ class RootApp extends HookConsumerWidget {
Widget build(BuildContext context, ref) { Widget build(BuildContext context, ref) {
final index = useState(0); final index = useState(0);
final isMounted = useIsMounted(); final isMounted = useIsMounted();
final auth = ref.watch(AuthenticationNotifier.provider); final showingDialogCompleter = useRef(Completer()..complete());
final downloader = ref.watch(downloadManagerProvider.notifier); final downloader = ref.watch(downloadManagerProvider.notifier);
useEffect(() { useEffect(() {
downloader.onFileExists = (track) async { downloader.onFileExists = (track) async {
if (!isMounted()) return false; if (!isMounted()) return false;
return await showDialog<bool>(
if (!showingDialogCompleter.value.isCompleted) {
await showingDialogCompleter.value.future;
}
final replaceAll = ref.read(replaceDownloadedFileState);
if (replaceAll != null) return replaceAll;
showingDialogCompleter.value = Completer();
if (context.mounted) {
final result = await showDialog<bool>(
context: context, context: context,
builder: (context) => ReplaceDownloadedDialog( builder: (context) => ReplaceDownloadedDialog(
track: track, track: track,
), ),
) ?? ) ??
false; false;
showingDialogCompleter.value.complete();
return result;
}
// it'll never reach here as root_app is always mounted
return false;
}; };
return null; return null;
}, [downloader]); }, [downloader]);

View File

@ -49,6 +49,12 @@ class DownloadManagerProvider extends StateNotifier<List<SpotubeTrack>> {
if (update.status == TaskStatus.complete) { if (update.status == TaskStatus.complete) {
final track = final track =
state.firstWhere((element) => element.id == update.task.taskId); state.firstWhere((element) => element.id == update.task.taskId);
// resetting the replace downloaded file state on queue completion
if (state.last == track) {
ref.read(replaceDownloadedFileState.notifier).state = null;
}
state = state state = state
.where((element) => element.id != update.task.taskId) .where((element) => element.id != update.task.taskId)
.toList(); .toList();
@ -141,6 +147,9 @@ class DownloadManagerProvider extends StateNotifier<List<SpotubeTrack>> {
final file = File(_getPathForTrack(track)); final file = File(_getPathForTrack(track));
if (file.existsSync() && if (file.existsSync() &&
(replaceFileGlobal ?? await onFileExists?.call(track)) != true) { (replaceFileGlobal ?? await onFileExists?.call(track)) != true) {
if (state.isEmpty) {
ref.read(replaceDownloadedFileState.notifier).state = null;
}
return null; return null;
} }
@ -159,6 +168,11 @@ class DownloadManagerProvider extends StateNotifier<List<SpotubeTrack>> {
} }
return enqueue(e); return enqueue(e);
})); }));
if (tasks.isEmpty) {
ref.read(replaceDownloadedFileState.notifier).state = null;
}
return tasks.whereType<Task>().toList(); return tasks.whereType<Task>().toList();
} }