fix: playbutton card play state not changing

refactor(player_controls): move stop playback button to queue sheet
This commit is contained in:
Kingkor Roy Tirtho 2023-02-05 20:47:42 +06:00
parent b8f3493138
commit ee46d0970b
6 changed files with 125 additions and 74 deletions

View File

@ -24,7 +24,8 @@ class AlbumCard extends HookConsumerWidget {
@override
Widget build(BuildContext context, ref) {
final playlist = ref.watch(PlaylistQueueNotifier.provider);
final playing = useStream(PlaylistQueueNotifier.playing).data ?? false;
final playing = useStream(PlaylistQueueNotifier.playing).data ??
PlaylistQueueNotifier.isPlaying;
final playlistNotifier = ref.watch(PlaylistQueueNotifier.notifier);
final queryBowl = QueryBowl.of(context);
final query = queryBowl.getQuery<List<TrackSimple>, SpotifyApi>(
@ -33,6 +34,9 @@ class AlbumCard extends HookConsumerWidget {
bool isPlaylistPlaying = playlistNotifier.isPlayingPlaylist(tracks.value);
final int marginH =
useBreakpointValue(sm: 10, md: 15, lg: 20, xl: 20, xxl: 20);
final updating = useState(false);
return PlaybuttonCard(
imageUrl: TypeConversionUtils.image_X_UrlString(
album.images,
@ -49,43 +53,53 @@ class AlbumCard extends HookConsumerWidget {
ServiceUtils.navigate(context, "/album/${album.id}", extra: album);
},
onPlaybuttonPressed: () async {
if (isPlaylistPlaying && playing) {
return playlistNotifier.pause();
} else if (isPlaylistPlaying && !playing) {
return playlistNotifier.resume();
}
updating.value = true;
try {
if (isPlaylistPlaying && playing) {
return playlistNotifier.pause();
} else if (isPlaylistPlaying && !playing) {
return playlistNotifier.resume();
}
await playlistNotifier.loadAndPlay(album.tracks
?.map(
(e) => TypeConversionUtils.simpleTrack_X_Track(e, album))
.toList() ??
[]);
await playlistNotifier.loadAndPlay(album.tracks
?.map((e) =>
TypeConversionUtils.simpleTrack_X_Track(e, album))
.toList() ??
[]);
} finally {
updating.value = false;
}
},
onAddToQueuePressed: () async {
if (isPlaylistPlaying) {
return;
}
final fetchedTracks =
await queryBowl.fetchQuery<List<TrackSimple>, SpotifyApi>(
Queries.album.tracksOf(album.id!),
externalData: ref.read(spotifyProvider),
key: ValueKey(const Uuid().v4()),
);
updating.value = true;
try {
final fetchedTracks =
await queryBowl.fetchQuery<List<TrackSimple>, SpotifyApi>(
Queries.album.tracksOf(album.id!),
externalData: ref.read(spotifyProvider),
key: ValueKey(const Uuid().v4()),
);
if (fetchedTracks == null || fetchedTracks.isEmpty) return;
if (fetchedTracks == null || fetchedTracks.isEmpty) return;
playlistNotifier.add(
fetchedTracks
.map((e) => TypeConversionUtils.simpleTrack_X_Track(e, album))
.toList(),
);
tracks.value = fetchedTracks;
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text("Added ${album.tracks?.length} tracks to queue"),
),
);
playlistNotifier.add(
fetchedTracks
.map((e) => TypeConversionUtils.simpleTrack_X_Track(e, album))
.toList(),
);
tracks.value = fetchedTracks;
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text("Added ${album.tracks?.length} tracks to queue"),
),
);
} finally {
updating.value = false;
}
});
}
}

View File

@ -38,7 +38,8 @@ class PlayerControls extends HookConsumerWidget {
[]);
final playlist = ref.watch(PlaylistQueueNotifier.provider);
final playlistNotifier = ref.watch(PlaylistQueueNotifier.notifier);
final playing = useStream(PlaylistQueueNotifier.playing).data ?? false;
final playing = useStream(PlaylistQueueNotifier.playing).data ??
PlaylistQueueNotifier.isPlaying;
return GestureDetector(
behavior: HitTestBehavior.translucent,
@ -89,6 +90,7 @@ class PlayerControls extends HookConsumerWidget {
return null;
}, [progressStatic]);
// this is a hack to fix duration not being updated
useEffect(() {
WidgetsBinding.instance.addPostFrameCallback((_) async {
if (positionSnapshot.hasData &&
@ -200,14 +202,6 @@ class PlayerControls extends HookConsumerWidget {
),
onPressed: playlistNotifier.next,
),
PlatformIconButton(
tooltip: "Stop playback",
icon: Icon(
SpotubeIcons.stop,
color: iconColor,
),
onPressed: playlist != null ? playlistNotifier.stop : null,
),
PlatformIconButton(
tooltip: playlist?.isLooping != true
? "Loop Track"

View File

@ -27,7 +27,8 @@ class PlayerOverlay extends HookConsumerWidget {
PlaylistQueueNotifier.provider.select((s) => s != null),
);
final playlistNotifier = ref.watch(PlaylistQueueNotifier.notifier);
final playing = useStream(PlaylistQueueNotifier.playing).data ?? false;
final playing = useStream(PlaylistQueueNotifier.playing).data ??
PlaylistQueueNotifier.isPlaying;
return GestureDetector(
onVerticalDragEnd: (details) {

View File

@ -5,6 +5,7 @@ import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:platform_ui/platform_ui.dart';
import 'package:scroll_to_index/scroll_to_index.dart';
import 'package:spotube/collections/spotube_icons.dart';
import 'package:spotube/components/shared/fallbacks/not_found.dart';
import 'package:spotube/components/shared/track_table/track_tile.dart';
import 'package:spotube/hooks/use_auto_scroll_controller.dart';
@ -76,7 +77,33 @@ class PlayerQueue extends HookConsumerWidget {
borderRadius: BorderRadius.circular(20),
),
),
PlatformText.subheading("Queue"),
PlatformAppBar(
title:
PlatformText.subheading("${tracks.length} tracks in Queue"),
backgroundColor: Colors.transparent,
automaticallyImplyLeading: false,
actions: [
PlatformFilledButton(
style: ButtonStyle(
backgroundColor: MaterialStatePropertyAll(
PlatformTheme.of(context)
.scaffoldBackgroundColor
?.withOpacity(0.5)),
),
child: Row(
children: const [
Icon(SpotubeIcons.playlistRemove),
SizedBox(width: 5),
PlatformText("Clear All"),
],
),
onPressed: () {
playlistNotifier.stop();
Navigator.of(context).pop();
},
),
],
),
const SizedBox(height: 10),
Flexible(
child: ListView.builder(

View File

@ -24,7 +24,8 @@ class PlaylistCard extends HookConsumerWidget {
Widget build(BuildContext context, ref) {
final playlistQueue = ref.watch(PlaylistQueueNotifier.provider);
final playlistNotifier = ref.watch(PlaylistQueueNotifier.notifier);
final playing = useStream(PlaylistQueueNotifier.playing).data ?? false;
final playing = useStream(PlaylistQueueNotifier.playing).data ??
PlaylistQueueNotifier.isPlaying;
final queryBowl = QueryBowl.of(context);
final query = queryBowl.getQuery<List<Track>, SpotifyApi>(
Queries.playlist.tracksOf(playlist.id!).queryKey,
@ -34,6 +35,9 @@ class PlaylistCard extends HookConsumerWidget {
final int marginH =
useBreakpointValue(sm: 10, md: 15, lg: 20, xl: 20, xxl: 20);
final updating = useState(false);
return PlaybuttonCard(
viewType: viewType,
margin: EdgeInsets.symmetric(horizontal: marginH.toDouble()),
@ -43,7 +47,8 @@ class PlaylistCard extends HookConsumerWidget {
placeholder: ImagePlaceholder.collection,
),
isPlaying: isPlaylistPlaying && playing,
isLoading: isPlaylistPlaying && playlistQueue?.isLoading == true,
isLoading: (isPlaylistPlaying && playlistQueue?.isLoading == true) ||
updating.value,
onTap: () {
ServiceUtils.navigate(
context,
@ -52,42 +57,52 @@ class PlaylistCard extends HookConsumerWidget {
);
},
onPlaybuttonPressed: () async {
if (isPlaylistPlaying && playing) {
return playlistNotifier.pause();
} else if (isPlaylistPlaying && !playing) {
return playlistNotifier.resume();
try {
updating.value = true;
if (isPlaylistPlaying && playing) {
return playlistNotifier.pause();
} else if (isPlaylistPlaying && !playing) {
return playlistNotifier.resume();
}
List<Track> fetchedTracks = await queryBowl.fetchQuery(
key: ValueKey(const Uuid().v4()),
Queries.playlist.tracksOf(playlist.id!),
externalData: ref.read(spotifyProvider),
) ??
[];
if (fetchedTracks.isEmpty) return;
await playlistNotifier.loadAndPlay(fetchedTracks);
tracks.value = fetchedTracks;
} finally {
updating.value = false;
}
List<Track> fetchedTracks = await queryBowl.fetchQuery(
key: ValueKey(const Uuid().v4()),
Queries.playlist.tracksOf(playlist.id!),
externalData: ref.read(spotifyProvider),
) ??
[];
if (fetchedTracks.isEmpty) return;
await playlistNotifier.loadAndPlay(fetchedTracks);
tracks.value = fetchedTracks;
},
onAddToQueuePressed: () async {
if (isPlaylistPlaying) return;
List<Track> fetchedTracks = await queryBowl.fetchQuery(
key: ValueKey(const Uuid().v4()),
Queries.playlist.tracksOf(playlist.id!),
externalData: ref.read(spotifyProvider),
) ??
[];
updating.value = true;
try {
if (isPlaylistPlaying) return;
List<Track> fetchedTracks = await queryBowl.fetchQuery(
key: ValueKey(const Uuid().v4()),
Queries.playlist.tracksOf(playlist.id!),
externalData: ref.read(spotifyProvider),
) ??
[];
if (fetchedTracks.isEmpty) return;
if (fetchedTracks.isEmpty) return;
playlistNotifier.add(fetchedTracks);
tracks.value = fetchedTracks;
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text("Added ${fetchedTracks.length} tracks to queue"),
),
);
playlistNotifier.add(fetchedTracks);
tracks.value = fetchedTracks;
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text("Added ${fetchedTracks.length} tracks to queue"),
),
);
} finally {
updating.value = false;
}
},
);
}

View File

@ -104,7 +104,7 @@ class PlaybuttonCard extends HookWidget {
),
);
final addToQueueButton = PlatformIconButton(
onPressed: onAddToQueuePressed,
onPressed: isLoading ? null : onAddToQueuePressed,
backgroundColor:
PlatformTheme.of(context).secondaryBackgroundColor,
hoverColor: PlatformTheme.of(context)