mirror of
https://github.com/KRTirtho/spotube.git
synced 2025-09-13 07:55:18 +00:00
fix: collection currently playing state persist on restart
This commit is contained in:
parent
9251121ba0
commit
1c89e3efb0
@ -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"),
|
||||
|
@ -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(
|
||||
|
@ -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;
|
||||
|
@ -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: () {
|
||||
|
@ -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,
|
||||
|
@ -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,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -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(
|
||||
|
Loading…
Reference in New Issue
Block a user