refactor: use provider based is track loading implementation

This commit is contained in:
Kingkor Roy Tirtho 2024-06-24 21:01:09 +06:00
parent a83dd64476
commit 75173e5096
9 changed files with 216 additions and 207 deletions

View File

@ -11,7 +11,7 @@ import 'package:spotube/pages/home/home.dart';
import 'package:spotube/pages/library/library.dart';
import 'package:spotube/pages/lyrics/lyrics.dart';
import 'package:spotube/pages/search/search.dart';
import 'package:spotube/provider/audio_player/audio_player.dart';
import 'package:spotube/provider/audio_player/querying_track_info.dart';
import 'package:spotube/services/audio_player/audio_player.dart';
import 'package:spotube/utils/platform.dart';
@ -96,8 +96,8 @@ class SeekIntent extends Intent {
class SeekAction extends Action<SeekIntent> {
@override
invoke(intent) async {
final playlist = intent.ref.read(audioPlayerProvider.notifier);
if (playlist.isFetching()) {
final isFetchingActiveTrack = intent.ref.read(queryingTrackInfoProvider);
if (isFetchingActiveTrack) {
DirectionalFocusAction().invoke(
DirectionalFocusIntent(
intent.forward ? TraversalDirection.right : TraversalDirection.left,

View File

@ -17,7 +17,7 @@ import 'package:spotube/extensions/constrains.dart';
import 'package:spotube/extensions/duration.dart';
import 'package:spotube/extensions/image.dart';
import 'package:spotube/models/local_track.dart';
import 'package:spotube/provider/audio_player/audio_player.dart';
import 'package:spotube/provider/audio_player/querying_track_info.dart';
import 'package:spotube/provider/audio_player/state.dart';
import 'package:spotube/provider/blacklist_provider.dart';
@ -84,8 +84,7 @@ class TrackTile extends HookConsumerWidget {
},
child: HoverBuilder(
permanentState: isSelected || constrains.smAndDown ? true : null,
builder: (context, isHovering) {
return ListTile(
builder: (context, isHovering) => ListTile(
selected: isSelected,
onTap: () async {
try {
@ -100,8 +99,7 @@ class TrackTile extends HookConsumerWidget {
onLongPress: onLongPress,
enabled: !isBlackListed,
contentPadding: EdgeInsets.zero,
tileColor:
isBlackListed ? theme.colorScheme.errorContainer : null,
tileColor: isBlackListed ? theme.colorScheme.errorContainer : null,
horizontalTitleGap: 12,
leadingAndTrailingTextStyle: theme.textTheme.bodyMedium,
leading: Row(
@ -159,13 +157,13 @@ class TrackTile extends HookConsumerWidget {
data: theme.iconTheme
.copyWith(size: 26, color: Colors.white),
child: Skeleton.ignore(
child: AnimatedSwitcher(
child: Consumer(
builder: (context, ref, _) {
final isFetchingActiveTrack =
ref.watch(queryingTrackInfoProvider);
return AnimatedSwitcher(
duration: const Duration(milliseconds: 300),
child: (isPlaying &&
ref
.watch(audioPlayerProvider
.notifier)
.isFetching()) ||
child: (isPlaying && isFetchingActiveTrack) ||
isLoading.value
? const SizedBox(
width: 26,
@ -183,6 +181,8 @@ class TrackTile extends HookConsumerWidget {
: !isHovering
? const SizedBox.shrink()
: const Icon(SpotubeIcons.play),
);
},
),
),
),
@ -267,8 +267,7 @@ class TrackTile extends HookConsumerWidget {
),
],
),
);
},
),
),
);
});

View File

@ -10,6 +10,7 @@ import 'package:spotube/extensions/image.dart';
import 'package:spotube/extensions/track.dart';
import 'package:spotube/models/connect/connect.dart';
import 'package:spotube/pages/album/album.dart';
import 'package:spotube/provider/audio_player/querying_track_info.dart';
import 'package:spotube/provider/connect/connect.dart';
import 'package:spotube/provider/history/history.dart';
import 'package:spotube/provider/audio_player/audio_player.dart';
@ -35,6 +36,7 @@ class AlbumCard extends HookConsumerWidget {
useStream(audioPlayer.playingStream).data ?? audioPlayer.isPlaying;
final playlistNotifier = ref.watch(audioPlayerProvider.notifier);
final historyNotifier = ref.read(playbackHistoryProvider.notifier);
final isFetchingActiveTrack = ref.watch(queryingTrackInfoProvider);
bool isPlaylistPlaying = useMemoized(
() => playlist.containsCollection(album.id!),
@ -59,8 +61,8 @@ class AlbumCard extends HookConsumerWidget {
),
margin: const EdgeInsets.symmetric(horizontal: 10),
isPlaying: isPlaylistPlaying,
isLoading: (isPlaylistPlaying && playlistNotifier.isFetching()) ||
updating.value,
isLoading:
(isPlaylistPlaying && isFetchingActiveTrack) || updating.value,
title: album.name!,
description:
"${album.albumType?.formatted}${album.artists?.asString() ?? ""}",

View File

@ -11,7 +11,7 @@ import 'package:spotube/extensions/context.dart';
import 'package:spotube/extensions/duration.dart';
import 'package:spotube/modules/player/use_progress.dart';
import 'package:spotube/models/logger.dart';
import 'package:spotube/provider/audio_player/audio_player.dart';
import 'package:spotube/provider/audio_player/querying_track_info.dart';
import 'package:spotube/services/audio_player/audio_player.dart';
class PlayerControls extends HookConsumerWidget {
@ -43,8 +43,7 @@ class PlayerControls extends HookConsumerWidget {
SeekIntent: SeekAction(),
},
[]);
ref.watch(audioPlayerProvider);
final playlistNotifier = ref.watch(audioPlayerProvider.notifier);
final isFetchingActiveTrack = ref.watch(queryingTrackInfoProvider);
final playing =
useStream(audioPlayer.playingStream).data ?? audioPlayer.isPlaying;
@ -132,7 +131,7 @@ class PlayerControls extends HookConsumerWidget {
// than total duration. Keeping it resolved
value: progress.value.toDouble(),
secondaryTrackValue: bufferProgress,
onChanged: playlistNotifier.isFetching()
onChanged: isFetchingActiveTrack
? null
: (v) {
progress.value = v;
@ -183,7 +182,7 @@ class PlayerControls extends HookConsumerWidget {
: context.l10n.shuffle_playlist,
icon: const Icon(SpotubeIcons.shuffle),
style: shuffled ? activeButtonStyle : buttonStyle,
onPressed: playlistNotifier.isFetching()
onPressed: isFetchingActiveTrack
? null
: () {
if (shuffled) {
@ -198,7 +197,7 @@ class PlayerControls extends HookConsumerWidget {
tooltip: context.l10n.previous_track,
icon: const Icon(SpotubeIcons.skipBack),
style: buttonStyle,
onPressed: playlistNotifier.isFetching()
onPressed: isFetchingActiveTrack
? null
: audioPlayer.skipToPrevious,
),
@ -206,7 +205,7 @@ class PlayerControls extends HookConsumerWidget {
tooltip: playing
? context.l10n.pause_playback
: context.l10n.resume_playback,
icon: playlistNotifier.isFetching()
icon: isFetchingActiveTrack
? SizedBox(
height: 20,
width: 20,
@ -219,7 +218,7 @@ class PlayerControls extends HookConsumerWidget {
playing ? SpotubeIcons.pause : SpotubeIcons.play,
),
style: resumePauseStyle,
onPressed: playlistNotifier.isFetching()
onPressed: isFetchingActiveTrack
? null
: Actions.handler<PlayPauseIntent>(
context,
@ -230,9 +229,8 @@ class PlayerControls extends HookConsumerWidget {
tooltip: context.l10n.next_track,
icon: const Icon(SpotubeIcons.skipForward),
style: buttonStyle,
onPressed: playlistNotifier.isFetching()
? null
: audioPlayer.skipToNext,
onPressed:
isFetchingActiveTrack ? null : audioPlayer.skipToNext,
),
StreamBuilder<PlaylistMode>(
stream: audioPlayer.loopModeStream,
@ -253,7 +251,7 @@ class PlayerControls extends HookConsumerWidget {
loopMode == PlaylistMode.loop
? activeButtonStyle
: buttonStyle,
onPressed: playlistNotifier.isFetching()
onPressed: isFetchingActiveTrack
? null
: () async {
await audioPlayer.setLoopMode(loopMode);

View File

@ -12,6 +12,7 @@ import 'package:spotube/collections/intents.dart';
import 'package:spotube/modules/player/use_progress.dart';
import 'package:spotube/modules/player/player.dart';
import 'package:spotube/provider/audio_player/audio_player.dart';
import 'package:spotube/provider/audio_player/querying_track_info.dart';
import 'package:spotube/services/audio_player/audio_player.dart';
class PlayerOverlay extends HookConsumerWidget {
@ -24,7 +25,7 @@ class PlayerOverlay extends HookConsumerWidget {
@override
Widget build(BuildContext context, ref) {
final playlistNotifier = ref.watch(audioPlayerProvider.notifier);
final isFetchingActiveTrack = ref.watch(queryingTrackInfoProvider);
final playlist = ref.watch(audioPlayerProvider);
final canShow = playlist.activeTrack != null;
@ -127,14 +128,14 @@ class PlayerOverlay extends HookConsumerWidget {
SpotubeIcons.skipBack,
color: textColor,
),
onPressed: playlistNotifier.isFetching()
onPressed: isFetchingActiveTrack
? null
: audioPlayer.skipToPrevious,
),
Consumer(
builder: (context, ref, _) {
return IconButton(
icon: playlistNotifier.isFetching()
icon: isFetchingActiveTrack
? const SizedBox(
height: 20,
width: 20,
@ -158,7 +159,7 @@ class PlayerOverlay extends HookConsumerWidget {
SpotubeIcons.skipForward,
color: textColor,
),
onPressed: playlistNotifier.isFetching()
onPressed: isFetchingActiveTrack
? null
: audioPlayer.skipToNext,
),

View File

@ -16,6 +16,7 @@ import 'package:spotube/extensions/duration.dart';
import 'package:spotube/hooks/utils/use_debounce.dart';
import 'package:spotube/models/database/database.dart';
import 'package:spotube/provider/audio_player/audio_player.dart';
import 'package:spotube/provider/audio_player/querying_track_info.dart';
import 'package:spotube/provider/server/active_sourced_track.dart';
import 'package:spotube/provider/user_preferences/user_preferences_provider.dart';
@ -54,7 +55,7 @@ class SiblingTracksSheet extends HookConsumerWidget {
Widget build(BuildContext context, ref) {
final theme = Theme.of(context);
final playlist = ref.watch(audioPlayerProvider);
final playlistNotifier = ref.watch(audioPlayerProvider.notifier);
final isFetchingActiveTrack = ref.watch(queryingTrackInfoProvider);
final preferences = ref.watch(userPreferencesProvider);
final isSearching = useState(false);
@ -130,7 +131,7 @@ class SiblingTracksSheet extends HookConsumerWidget {
]);
final siblings = useMemoized(
() => playlistNotifier.isFetching()
() => isFetchingActiveTrack
? [
(activeTrack as SourcedTrack).sourceInfo,
...activeTrack.siblings,
@ -176,12 +177,12 @@ class SiblingTracksSheet extends HookConsumerWidget {
Text("${sourceInfo.artist}"),
],
),
enabled: !playlistNotifier.isFetching(),
selected: !playlistNotifier.isFetching() &&
enabled: !isFetchingActiveTrack,
selected: !isFetchingActiveTrack &&
sourceInfo.id == (activeTrack as SourcedTrack).sourceInfo.id,
selectedTileColor: theme.popupMenuTheme.color,
onTap: () {
if (!playlistNotifier.isFetching() &&
if (!isFetchingActiveTrack &&
sourceInfo.id != (activeTrack as SourcedTrack).sourceInfo.id) {
activeTrackNotifier.swapSibling(sourceInfo);
Navigator.of(context).pop();

View File

@ -7,6 +7,7 @@ import 'package:spotube/components/playbutton_card.dart';
import 'package:spotube/extensions/image.dart';
import 'package:spotube/models/connect/connect.dart';
import 'package:spotube/pages/playlist/playlist.dart';
import 'package:spotube/provider/audio_player/querying_track_info.dart';
import 'package:spotube/provider/connect/connect.dart';
import 'package:spotube/provider/history/history.dart';
import 'package:spotube/provider/audio_player/audio_player.dart';
@ -24,6 +25,7 @@ class PlaylistCard extends HookConsumerWidget {
Widget build(BuildContext context, ref) {
final playlistQueue = ref.watch(audioPlayerProvider);
final playlistNotifier = ref.watch(audioPlayerProvider.notifier);
final isFetchingActiveTrack = ref.watch(queryingTrackInfoProvider);
final historyNotifier = ref.read(playbackHistoryProvider.notifier);
final playing =
@ -65,8 +67,7 @@ class PlaylistCard extends HookConsumerWidget {
placeholder: ImagePlaceholder.collection,
),
isPlaying: isPlaylistPlaying,
isLoading: (isPlaylistPlaying && playlistNotifier.isFetching()) ||
updating.value,
isLoading: (isPlaylistPlaying && isFetchingActiveTrack) || updating.value,
isOwner: playlist.owner?.id == me.asData?.value.id &&
me.asData?.value.id != null,
onTap: () {

View File

@ -299,11 +299,6 @@ class AudioPlayerNotifier extends Notifier<AudioPlayerState> {
await audioPlayer.moveTrack(oldIndex, newIndex);
}
bool isFetching() {
if (state.activeTrack == null) return false;
return ref.read(sourcedTrackProvider(state.activeTrack!)).isLoading;
}
Future<void> stop() async {
await audioPlayer.stop();
ref.read(discordProvider.notifier).clear();

View File

@ -0,0 +1,12 @@
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:spotube/provider/audio_player/audio_player.dart';
import 'package:spotube/provider/server/sourced_track.dart';
final queryingTrackInfoProvider = Provider<bool>((ref) {
final activeTrack =
ref.watch(audioPlayerProvider.select((s) => s.activeTrack));
if (activeTrack == null) return false;
return ref.read(sourcedTrackProvider(activeTrack)).isLoading;
});