fix: collection currently playing state persist on restart

This commit is contained in:
Kingkor Roy Tirtho 2023-06-20 11:55:23 +06:00
parent 9251121ba0
commit 1c89e3efb0
7 changed files with 46 additions and 11 deletions

View File

@ -46,11 +46,9 @@ class AlbumCard extends HookConsumerWidget {
useStream(audioPlayer.playingStream).data ?? audioPlayer.isPlaying;
final playlistNotifier = ref.watch(ProxyPlaylistNotifier.notifier);
final queryClient = useQueryClient();
final query = queryClient
.getQuery<List<TrackSimple>, dynamic>("album-tracks/${album.id}");
bool isPlaylistPlaying = useMemoized(
() => playlist.containsTracks(query?.data ?? album.tracks ?? []),
[playlistNotifier, query?.data, album.tracks],
() => playlist.containsCollection(album.id!),
[playlist, album.id],
);
final int marginH =
useBreakpointValue(xs: 10, sm: 10, md: 15, lg: 20, xl: 20, xxl: 20);
@ -89,6 +87,7 @@ class AlbumCard extends HookConsumerWidget {
[],
autoPlay: true,
);
playlistNotifier.addCollection(album.id!);
} finally {
updating.value = false;
}
@ -118,6 +117,7 @@ class AlbumCard extends HookConsumerWidget {
if (fetchedTracks == null || fetchedTracks.isEmpty) return;
playlistNotifier.addTracks(fetchedTracks);
playlistNotifier.addCollection(album.id!);
if (context.mounted) {
final snackbar = SnackBar(
content: Text("Added ${album.tracks?.length} tracks to queue"),

View File

@ -24,13 +24,10 @@ class PlaylistCard extends HookConsumerWidget {
final playing =
useStream(audioPlayer.playingStream).data ?? audioPlayer.isPlaying;
final queryBowl = QueryClient.of(context);
final query = queryBowl.getQuery<List<Track>, dynamic>(
"playlist-tracks/${playlist.id}",
);
final tracks = useState<List<TrackSimple>?>(null);
bool isPlaylistPlaying = useMemoized(
() => playlistQueue.containsTracks(tracks.value ?? query?.data ?? []),
[playlistNotifier, tracks.value, query?.data],
() => playlistQueue.containsCollection(playlist.id!),
[playlistQueue, playlist.id],
);
final updating = useState(false);
@ -72,6 +69,7 @@ class PlaylistCard extends HookConsumerWidget {
if (fetchedTracks.isEmpty) return;
await playlistNotifier.load(fetchedTracks, autoPlay: true);
playlistNotifier.addCollection(playlist.id!);
tracks.value = fetchedTracks;
} finally {
updating.value = false;
@ -90,6 +88,7 @@ class PlaylistCard extends HookConsumerWidget {
if (fetchedTracks.isEmpty) return;
playlistNotifier.addTracks(fetchedTracks);
playlistNotifier.addCollection(playlist.id!);
tracks.value = fetchedTracks;
if (context.mounted) {
final snackbar = SnackBar(

View File

@ -1,6 +1,5 @@
import 'package:collection/collection.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:fuzzywuzzy/fuzzywuzzy.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
@ -219,6 +218,9 @@ class TracksTableView extends HookConsumerWidget {
case "play-next":
{
playback.addTracksAtFirst(selectedTracks);
if (playlistId != null) {
playback.addCollection(playlistId!);
}
selected.value = [];
showCheck.value = false;
break;
@ -226,6 +228,9 @@ class TracksTableView extends HookConsumerWidget {
case "add-to-queue":
{
playback.addTracks(selectedTracks);
if (playlistId != null) {
playback.addCollection(playlistId!);
}
selected.value = [];
showCheck.value = false;
break;

View File

@ -32,6 +32,7 @@ class AlbumPage extends HookConsumerWidget {
sortedTracks,
initialIndex: sortedTracks.indexWhere((s) => s.id == currentTrack?.id),
);
playback.addCollection(album.id!);
} else if (isPlaylistPlaying &&
currentTrack.id != null &&
currentTrack.id != playlist.activeTrack?.id) {
@ -101,6 +102,7 @@ class AlbumPage extends HookConsumerWidget {
TypeConversionUtils.simpleTrack_X_Track(track, album))
.toList(),
);
playback.addCollection(album.id!);
}
},
onShare: () {

View File

@ -36,6 +36,7 @@ class PlaylistView extends HookConsumerWidget {
initialIndex: sortedTracks.indexWhere((s) => s.id == currentTrack?.id),
autoPlay: true,
);
playback.addCollection(playlist.id!);
} else if (isPlaylistPlaying &&
currentTrack.id != null &&
currentTrack.id != proxyPlaylist.activeTrack?.id) {
@ -97,6 +98,7 @@ class PlaylistView extends HookConsumerWidget {
onAddToQueue: () {
if (tracksSnapshot.hasData && !isPlaylistPlaying) {
playlistNotifier.addTracks(tracksSnapshot.data!);
playlistNotifier.addCollection(playlist.id!);
}
},
bottomSpace: mediaQuery.mdAndDown,

View File

@ -6,15 +6,20 @@ import 'package:spotube/models/spotube_track.dart';
class ProxyPlaylist {
final Set<Track> tracks;
final Set<String> collections;
final int? active;
ProxyPlaylist(this.tracks, [this.active]);
ProxyPlaylist(this.tracks, [this.active, this.collections = const {}]);
factory ProxyPlaylist.fromJson(Map<String, dynamic> json) {
return ProxyPlaylist(
List.castFrom<dynamic, Map<String, dynamic>>(
json['tracks'] ?? <Map<String, dynamic>>[],
).map(_makeAppropriateTrack).toSet(),
json['active'] as int?,
json['collections'] == null
? {}
: (json['collections'] as List).toSet().cast<String>(),
);
}
@ -26,6 +31,10 @@ class ProxyPlaylist {
activeTrack is! SpotubeTrack &&
activeTrack is! LocalTrack;
bool containsCollection(String collection) {
return collections.contains(collection);
}
bool containsTrack(TrackSimple track) {
return tracks.firstWhereOrNull((element) => element.id == track.id) != null;
}
@ -57,16 +66,19 @@ class ProxyPlaylist {
return {
'tracks': tracks.map(_makeAppropriateTrackJson).toList(),
'active': active,
'collections': collections.toList(),
};
}
ProxyPlaylist copyWith({
Set<Track>? tracks,
int? active,
Set<String>? collections,
}) {
return ProxyPlaylist(
tracks ?? this.tracks,
active ?? this.active,
collections ?? this.collections,
);
}
}

View File

@ -185,6 +185,19 @@ class ProxyPlaylistNotifier extends PersistedStateNotifier<ProxyPlaylist>
}
}
void addCollection(String collectionId) {
state = state.copyWith(collections: {
...state.collections,
collectionId,
});
}
void removeCollection(String collectionId) {
state = state.copyWith(collections: {
...state.collections..remove(collectionId),
});
}
// TODO: Safely Remove playing tracks
Future<void> removeTrack(String trackId) async {
@ -224,6 +237,7 @@ class ProxyPlaylistNotifier extends PersistedStateNotifier<ProxyPlaylist>
state = state.copyWith(
tracks: tracks.toSet(),
active: initialIndex,
collections: {},
);
await notificationService.addTrack(indexTrack);
} else {
@ -236,6 +250,7 @@ class ProxyPlaylistNotifier extends PersistedStateNotifier<ProxyPlaylist>
state = state.copyWith(
tracks: mergeTracks([addableTrack], tracks),
active: initialIndex,
collections: {},
);
await notificationService.addTrack(addableTrack);
await storeTrack(