From 14183781dd3f1e16c121e78ad637a326de7b5dcf Mon Sep 17 00:00:00 2001 From: Kingkor Roy Tirtho Date: Sun, 4 Jun 2023 16:34:37 +0600 Subject: [PATCH] feat: repeat button all 3 mode and disable player controls when track is fetching --- lib/components/player/player_controls.dart | 40 +++++++++++++------ lib/main.dart | 26 +++++++----- lib/models/spotube_track.dart | 3 ++ .../proxy_playlist/next_fetcher_mixin.dart | 23 ++++++----- .../proxy_playlist_provider.dart | 2 +- 5 files changed, 60 insertions(+), 34 deletions(-) diff --git a/lib/components/player/player_controls.dart b/lib/components/player/player_controls.dart index 50f73efa9..d6a9424f3 100644 --- a/lib/components/player/player_controls.dart +++ b/lib/components/player/player_controls.dart @@ -197,7 +197,7 @@ class PlayerControls extends HookConsumerWidget { : context.l10n.shuffle_playlist, icon: const Icon(SpotubeIcons.shuffle), style: shuffled ? activeButtonStyle : buttonStyle, - onPressed: playlist.isFetching + onPressed: playlist.isFetching == true || buffering ? null : () { if (shuffled) { @@ -212,7 +212,9 @@ class PlayerControls extends HookConsumerWidget { tooltip: context.l10n.previous_track, icon: const Icon(SpotubeIcons.skipBack), style: buttonStyle, - onPressed: playlistNotifier.previous, + onPressed: playlist.isFetching == true || buffering + ? null + : playlistNotifier.previous, ), IconButton( tooltip: playing @@ -242,7 +244,9 @@ class PlayerControls extends HookConsumerWidget { tooltip: context.l10n.next_track, icon: const Icon(SpotubeIcons.skipForward), style: buttonStyle, - onPressed: playlistNotifier.next, + onPressed: playlist.isFetching == true || buffering + ? null + : playlistNotifier.next, ), StreamBuilder( stream: audioPlayer.loopModeStream, @@ -251,24 +255,34 @@ class PlayerControls extends HookConsumerWidget { return IconButton( tooltip: loopMode == PlaybackLoopMode.one ? context.l10n.loop_track - : context.l10n.repeat_playlist, + : loopMode == PlaybackLoopMode.all + ? context.l10n.repeat_playlist + : null, icon: Icon( loopMode == PlaybackLoopMode.one ? SpotubeIcons.repeatOne : SpotubeIcons.repeat, ), - style: loopMode == PlaybackLoopMode.one + style: loopMode == PlaybackLoopMode.one || + loopMode == PlaybackLoopMode.all ? activeButtonStyle : buttonStyle, - onPressed: playlist.isFetching + onPressed: playlist.isFetching == true || buffering ? null - : () { - if (loopMode == PlaybackLoopMode.one) { - audioPlayer - .setLoopMode(PlaybackLoopMode.all); - } else { - audioPlayer - .setLoopMode(PlaybackLoopMode.one); + : () async { + switch (await audioPlayer.loopMode) { + case PlaybackLoopMode.all: + audioPlayer + .setLoopMode(PlaybackLoopMode.one); + break; + case PlaybackLoopMode.one: + audioPlayer + .setLoopMode(PlaybackLoopMode.none); + break; + case PlaybackLoopMode.none: + audioPlayer + .setLoopMode(PlaybackLoopMode.all); + break; } }, ); diff --git a/lib/main.dart b/lib/main.dart index 55629a69f..4b4cbc7cf 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -119,19 +119,25 @@ Future main(List rawArgs) async { enableApplicationParameters: false, ), FileHandler(await getLogsPath(), printLogs: false), + SnackbarHandler(const Duration(seconds: 3)), ], ), - releaseConfig: CatcherOptions(SilentReportMode(), [ - if (arguments["verbose"] ?? false) - ConsoleHandler( - enableDeviceParameters: false, - enableApplicationParameters: false, + releaseConfig: CatcherOptions( + SilentReportMode(), + [ + if (arguments["verbose"] ?? false) + ConsoleHandler( + enableDeviceParameters: false, + enableApplicationParameters: false, + ), + ToastHandler(), + FileHandler( + await getLogsPath(), + printLogs: false, ), - FileHandler( - await getLogsPath(), - printLogs: false, - ), - ]), + SnackbarHandler(const Duration(seconds: 3)), + ], + ), runAppFunction: () { runApp( DevicePreview( diff --git a/lib/models/spotube_track.dart b/lib/models/spotube_track.dart index da0d49449..7b597a047 100644 --- a/lib/models/spotube_track.dart +++ b/lib/models/spotube_track.dart @@ -120,6 +120,9 @@ class SpotubeTrack extends Track { ytVideo = await PipedSpotube.client.streams(matchedCachedTrack.youtubeId); } else { siblings = await fetchSiblings(track); + if (siblings.isEmpty) { + throw Exception("Failed to find any results for ${track.name}"); + } ytVideo = await PipedSpotube.client.streams(siblings.first.id); await MatchedTrack.box.put( diff --git a/lib/provider/proxy_playlist/next_fetcher_mixin.dart b/lib/provider/proxy_playlist/next_fetcher_mixin.dart index 947b5c074..d32afaf8f 100644 --- a/lib/provider/proxy_playlist/next_fetcher_mixin.dart +++ b/lib/provider/proxy_playlist/next_fetcher_mixin.dart @@ -1,5 +1,5 @@ -import 'package:catcher/catcher.dart'; import 'package:collection/collection.dart'; +import 'package:flutter/foundation.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:spotify/spotify.dart'; import 'package:spotube/models/local_track.dart'; @@ -105,15 +105,18 @@ mixin NextFetcher on StateNotifier { /// This method must be called after any playback operation as /// it can increase the latency Future storeTrack(Track track, SpotubeTrack spotubeTrack) async { - if (track is! SpotubeTrack) { - await supabase - .insertTrack( - MatchedTrack( - youtubeId: spotubeTrack.ytTrack.id, - spotifyId: spotubeTrack.id!, - ), - ) - .catchError(Catcher.reportCheckedError); + try { + if (track is! SpotubeTrack) { + await supabase.insertTrack( + MatchedTrack( + youtubeId: spotubeTrack.ytTrack.id, + spotifyId: spotubeTrack.id!, + ), + ); + } + } catch (e, stackTrace) { + debugPrint(e.toString()); + debugPrintStack(stackTrace: stackTrace); } } } diff --git a/lib/provider/proxy_playlist/proxy_playlist_provider.dart b/lib/provider/proxy_playlist/proxy_playlist_provider.dart index 99cf65bc0..7efcfb7d3 100644 --- a/lib/provider/proxy_playlist/proxy_playlist_provider.dart +++ b/lib/provider/proxy_playlist/proxy_playlist_provider.dart @@ -218,7 +218,7 @@ class ProxyPlaylistNotifier extends PersistedStateNotifier }) async { tracks = blacklist.filter(tracks).toList() as List; final addableTrack = await SpotubeTrack.fetchFromTrack( - tracks.elementAt(initialIndex), + tracks.elementAtOrNull(initialIndex) ?? tracks.first, preferences, );