From ff4e5df44cf50759ef1215795decf801643e484d Mon Sep 17 00:00:00 2001 From: Kingkor Roy Tirtho Date: Sat, 9 Jul 2022 02:19:27 +0600 Subject: [PATCH] High Constrast color scheme support added Download button shows done if already downloaded Search TextField design improved --- lib/components/Player/PlayerQueue.dart | 21 +++++--- lib/components/Search/Search.dart | 40 ++++++-------- .../Settings/ColorSchemePickerDialog.dart | 18 +++++++ .../Shared/DownloadTrackButton.dart | 53 ++++++++++++++----- lib/components/Shared/PlaybuttonCard.dart | 10 ++-- 5 files changed, 95 insertions(+), 47 deletions(-) diff --git a/lib/components/Player/PlayerQueue.dart b/lib/components/Player/PlayerQueue.dart index bbac3229..54cee194 100644 --- a/lib/components/Player/PlayerQueue.dart +++ b/lib/components/Player/PlayerQueue.dart @@ -5,6 +5,7 @@ import 'package:flutter_hooks/flutter_hooks.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:scroll_to_index/scroll_to_index.dart'; import 'package:spotube/components/Shared/NotFound.dart'; +import 'package:spotube/components/Shared/SpotubeMarqueeText.dart'; import 'package:spotube/components/Shared/TrackTile.dart'; import 'package:spotube/helpers/image-to-url-string.dart'; import 'package:spotube/helpers/zero-pad-num-str.dart'; @@ -48,6 +49,9 @@ class PlayerQueue extends HookConsumerWidget { return null; }, []); + var titleStyle = Theme.of(context).textTheme.headline4?.copyWith( + fontWeight: FontWeight.bold, + ); return BackdropFilter( filter: ImageFilter.blur( sigmaX: 12.0, @@ -76,12 +80,17 @@ class PlayerQueue extends HookConsumerWidget { borderRadius: BorderRadius.circular(20), ), ), - Text( - "Queue (${playback.playlist?.name})", - style: Theme.of(context).textTheme.headline4?.copyWith( - fontWeight: FontWeight.bold, - ), - overflow: TextOverflow.ellipsis, + Text("Queue", style: titleStyle), + Padding( + padding: const EdgeInsets.symmetric(horizontal: 8.0), + child: Text( + playback.playlist?.name ?? "", + overflow: TextOverflow.ellipsis, + style: Theme.of(context) + .textTheme + .bodyText1 + ?.copyWith(fontWeight: FontWeight.bold), + ), ), const SizedBox(height: 10), Flexible( diff --git a/lib/components/Search/Search.dart b/lib/components/Search/Search.dart index e46dbde1..8b53d204 100644 --- a/lib/components/Search/Search.dart +++ b/lib/components/Search/Search.dart @@ -43,36 +43,30 @@ class Search extends HookConsumerWidget { color: Theme.of(context).backgroundColor, child: Column( children: [ - Padding( + Container( padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 10), - child: Row( - children: [ - Expanded( - child: TextField( - controller: controller, - decoration: - const InputDecoration(hintText: "Search..."), - onSubmitted: (value) { + color: Theme.of(context).backgroundColor, + child: Expanded( + child: TextField( + controller: controller, + decoration: InputDecoration( + isDense: true, + suffix: ElevatedButton( + child: const Icon(Icons.search_rounded), + onPressed: () { ref.read(searchTermStateProvider.notifier).state = controller.value.text; }, ), + hintStyle: const TextStyle(height: 2), + hintText: "Search...", ), - const SizedBox(width: 5), - MaterialButton( - elevation: 3, - splashColor: Theme.of(context).primaryColor, - padding: const EdgeInsets.symmetric(vertical: 21), - color: Theme.of(context).primaryColor, - textColor: Colors.white, - child: const Icon(Icons.search_rounded), - onPressed: () { - ref.read(searchTermStateProvider.notifier).state = - controller.value.text; - }, - ), - ], + onSubmitted: (value) { + ref.read(searchTermStateProvider.notifier).state = + controller.value.text; + }, + ), ), ), searchSnapshot.when( diff --git a/lib/components/Settings/ColorSchemePickerDialog.dart b/lib/components/Settings/ColorSchemePickerDialog.dart index 7ec221ed..f96620d2 100644 --- a/lib/components/Settings/ColorSchemePickerDialog.dart +++ b/lib/components/Settings/ColorSchemePickerDialog.dart @@ -3,6 +3,23 @@ import 'package:flutter_hooks/flutter_hooks.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:spotube/provider/UserPreferences.dart'; +final highContrast = MaterialColor( + const Color.fromARGB(255, 104, 104, 104).value, + const { + 50: Colors.white, + 100: Color.fromARGB(255, 233, 233, 233), + 200: Color.fromARGB(255, 224, 219, 219), + 300: Color.fromARGB(255, 207, 207, 207), + 400: Color.fromARGB(255, 146, 146, 146), + 500: Color.fromARGB(255, 104, 104, 104), + 600: Color.fromARGB(255, 78, 78, 78), + 700: Color.fromARGB(255, 61, 61, 61), + 800: Color.fromARGB(255, 27, 27, 27), + 850: Color.fromARGB(255, 20, 20, 20), + 900: Colors.black, + }, +); + final colorsMap = { "Red": Colors.red, "Pink": Colors.pink, @@ -23,6 +40,7 @@ final colorsMap = { "Brown": Colors.brown, "BlueGrey": Colors.blueGrey, "Grey": Colors.grey, + "HighContrast": highContrast, }; enum ColorSchemeType { diff --git a/lib/components/Shared/DownloadTrackButton.dart b/lib/components/Shared/DownloadTrackButton.dart index 125ab68b..d5c2fbf3 100644 --- a/lib/components/Shared/DownloadTrackButton.dart +++ b/lib/components/Shared/DownloadTrackButton.dart @@ -29,8 +29,29 @@ class DownloadTrackButton extends HookConsumerWidget { final status = useState(TrackStatus.idle); YoutubeExplode yt = useMemoized(() => YoutubeExplode()); + final outputFile = useState(null); + final downloadFolder = useState(null); + String fileName = + "${track?.name} - ${artistsToString(track?.artists ?? [])}"; + + useEffect(() { + (() async { + downloadFolder.value = path.join( + Platform.isAndroid + ? "/storage/emulated/0/Download" + : (await path_provider.getDownloadsDirectory())!.path, + "Spotube"); + + outputFile.value = + File(path.join(downloadFolder.value!, "$fileName.mp3")); + }()); + return null; + }, [fileName, track]); + final _downloadTrack = useCallback(() async { - if (track == null) return; + if (track == null || + outputFile.value == null || + downloadFolder.value == null) return; if ((kIsMobile) && !await Permission.storage.isGranted && !await Permission.storage.isPermanentlyDenied) { @@ -47,18 +68,10 @@ class DownloadTrackButton extends HookConsumerWidget { StreamManifest manifest = await yt.videos.streamsClient .getManifest((track as SpotubeTrack).ytTrack.url); - String downloadFolder = path.join( - Platform.isAndroid - ? "/storage/emulated/0/Download" - : (await path_provider.getDownloadsDirectory())!.path, - "Spotube"); - String fileName = - "${track?.name} - ${artistsToString(track?.artists ?? [])}"; - File outputFile = File(path.join(downloadFolder, "$fileName.mp3")); File outputLyricsFile = - File(path.join(downloadFolder, "$fileName-lyrics.txt")); + File(path.join(downloadFolder.value!, "$fileName-lyrics.txt")); - if (await outputFile.exists()) { + if (await outputFile.value!.exists()) { final shouldReplace = await showDialog( context: context, builder: (context) { @@ -113,9 +126,11 @@ class DownloadTrackButton extends HookConsumerWidget { }, ); - if (!await outputFile.exists()) await outputFile.create(recursive: true); + if (!await outputFile.value!.exists()) { + await outputFile.value!.create(recursive: true); + } - IOSink outputFileStream = outputFile.openWrite(); + IOSink outputFileStream = outputFile.value!.openWrite(); await audioStream.pipe(outputFileStream); await outputFileStream.flush(); await outputFileStream.close().then((value) async { @@ -157,12 +172,20 @@ class DownloadTrackButton extends HookConsumerWidget { yt, preferences.saveTrackLyrics, playback.track, + outputFile.value, + downloadFolder.value, + fileName ]); useEffect(() { return () => yt.close(); }, []); + final outputFileExists = useMemoized( + () => outputFile.value?.existsSync() == true, + [outputFile.value, status.value, track], + ); + if (status.value == TrackStatus.downloading) { return const SizedBox( child: CircularProgressIndicator.adaptive( @@ -175,7 +198,9 @@ class DownloadTrackButton extends HookConsumerWidget { return const Icon(Icons.download_done_rounded); } return IconButton( - icon: const Icon(Icons.download_rounded), + icon: Icon( + outputFileExists ? Icons.download_done_rounded : Icons.download_rounded, + ), onPressed: track != null && track is SpotubeTrack ? _downloadTrack : null, ); } diff --git a/lib/components/Shared/PlaybuttonCard.dart b/lib/components/Shared/PlaybuttonCard.dart index 5183e631..3e5830c1 100644 --- a/lib/components/Shared/PlaybuttonCard.dart +++ b/lib/components/Shared/PlaybuttonCard.dart @@ -29,6 +29,7 @@ class PlaybuttonCard extends StatelessWidget { margin: margin, child: InkWell( onTap: onTap, + borderRadius: BorderRadius.circular(8), child: ConstrainedBox( constraints: const BoxConstraints(maxWidth: 200), child: Ink( @@ -37,10 +38,11 @@ class PlaybuttonCard extends StatelessWidget { borderRadius: BorderRadius.circular(8), boxShadow: [ BoxShadow( - blurRadius: 10, - offset: const Offset(0, 3), - spreadRadius: 5, - color: Theme.of(context).shadowColor) + blurRadius: 10, + offset: const Offset(0, 3), + spreadRadius: 5, + color: Theme.of(context).shadowColor, + ) ], ), child: Column(