mirror of
https://github.com/KRTirtho/spotube.git
synced 2025-09-12 23:45:18 +00:00
refactor: use provider based is track loading implementation
This commit is contained in:
parent
a83dd64476
commit
75173e5096
@ -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,
|
||||
|
@ -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 {
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
);
|
||||
});
|
||||
|
@ -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() ?? ""}",
|
||||
|
@ -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);
|
||||
|
@ -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,
|
||||
),
|
||||
|
@ -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();
|
||||
|
@ -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: () {
|
||||
|
@ -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();
|
||||
|
12
lib/provider/audio_player/querying_track_info.dart
Normal file
12
lib/provider/audio_player/querying_track_info.dart
Normal 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;
|
||||
});
|
Loading…
Reference in New Issue
Block a user