diff --git a/lib/components/library/user_albums.dart b/lib/components/library/user_albums.dart index f731d55c..d4bd6fde 100644 --- a/lib/components/library/user_albums.dart +++ b/lib/components/library/user_albums.dart @@ -4,7 +4,6 @@ import 'package:collection/collection.dart'; import 'package:fuzzywuzzy/fuzzywuzzy.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:skeletonizer/skeletonizer.dart'; -import 'package:spotify/spotify.dart'; import 'package:spotube/collections/fake.dart'; import 'package:spotube/collections/spotube_icons.dart'; @@ -15,7 +14,7 @@ import 'package:spotube/components/shared/fallbacks/anonymous_fallback.dart'; import 'package:spotube/components/shared/waypoint.dart'; import 'package:spotube/extensions/context.dart'; import 'package:spotube/provider/authentication_provider.dart'; -import 'package:spotube/services/queries/queries.dart'; +import 'package:spotube/provider/spotify/spotify.dart'; import 'package:spotube/utils/type_conversion_utils.dart'; @@ -25,32 +24,28 @@ class UserAlbums extends HookConsumerWidget { @override Widget build(BuildContext context, ref) { final auth = ref.watch(AuthenticationNotifier.provider); - final albumsQuery = useQueries.album.ofMine(ref); + final albumsQuery = ref.watch(favoriteAlbumsProvider); + final albumsQueryNotifier = ref.watch(favoriteAlbumsProvider.notifier); final controller = useScrollController(); final searchText = useState(''); - final allAlbums = useMemoized( - () => albumsQuery.pages - .expand((element) => element.items ?? []), - [albumsQuery.pages], - ); - final albums = useMemoized(() { if (searchText.value.isEmpty) { - return allAlbums; + return albumsQuery.value?.items ?? []; } - return allAlbums - .map((e) => ( - weightedRatio(e.name!, searchText.value), - e, - )) - .sorted((a, b) => b.$1.compareTo(a.$1)) - .where((e) => e.$1 > 50) - .map((e) => e.$2) - .toList(); - }, [allAlbums, searchText.value]); + return albumsQuery.value?.items + .map((e) => ( + weightedRatio(e.name!, searchText.value), + e, + )) + .sorted((a, b) => b.$1.compareTo(a.$1)) + .where((e) => e.$1 > 50) + .map((e) => e.$2) + .toList() ?? + []; + }, [albumsQuery.value, searchText.value]); if (auth == null) { return const AnonymousFallback(); @@ -60,7 +55,7 @@ class UserAlbums extends HookConsumerWidget { return RefreshIndicator( onRefresh: () async { - await albumsQuery.refresh(); + ref.invalidate(favoriteAlbumsProvider); }, child: SafeArea( child: Scaffold( @@ -85,7 +80,7 @@ class UserAlbums extends HookConsumerWidget { padding: const EdgeInsets.all(8.0), controller: controller, child: Skeletonizer( - enabled: albumsQuery.pages.isEmpty, + enabled: albumsQuery.isLoadingAndEmpty, child: Center( child: Wrap( runSpacing: 20, @@ -93,7 +88,8 @@ class UserAlbums extends HookConsumerWidget { runAlignment: WrapAlignment.center, crossAxisAlignment: WrapCrossAlignment.center, children: [ - if (albumsQuery.pages.isEmpty) + if (albumsQuery.value == null || + albumsQuery.value!.items.isEmpty) ...List.generate( 10, (index) => AlbumCard(FakeData.album), @@ -107,11 +103,12 @@ class UserAlbums extends HookConsumerWidget { AlbumCard( TypeConversionUtils.simpleAlbum_X_Album(album), ), - if (albums.isNotEmpty && albumsQuery.hasNextPage) + if (albums.isNotEmpty && + albumsQuery.value?.hasMore == true) Waypoint( controller: controller, isGrid: true, - onTouchEdge: albumsQuery.fetchNext, + onTouchEdge: albumsQueryNotifier.fetchMore, child: AlbumCard(FakeData.album), ) ], diff --git a/lib/components/library/user_artists.dart b/lib/components/library/user_artists.dart index 3b55e5d0..605fb52e 100644 --- a/lib/components/library/user_artists.dart +++ b/lib/components/library/user_artists.dart @@ -13,7 +13,7 @@ import 'package:spotube/components/shared/fallbacks/not_found.dart'; import 'package:spotube/components/shared/inter_scrollbar/inter_scrollbar.dart'; import 'package:spotube/extensions/context.dart'; import 'package:spotube/provider/authentication_provider.dart'; -import 'package:spotube/services/queries/queries.dart'; +import 'package:spotube/provider/spotify/spotify.dart'; class UserArtists extends HookConsumerWidget { const UserArtists({super.key}); @@ -23,12 +23,12 @@ class UserArtists extends HookConsumerWidget { final theme = Theme.of(context); final auth = ref.watch(AuthenticationNotifier.provider); - final artistQuery = useQueries.artist.followedByMeAll(ref); + final artistQuery = ref.watch(followedArtistsProvider); final searchText = useState(''); final filteredArtists = useMemoized(() { - final artists = artistQuery.data ?? []; + final artists = artistQuery.value?.items ?? []; if (searchText.value.isEmpty) { return artists.toList(); @@ -42,7 +42,7 @@ class UserArtists extends HookConsumerWidget { .where((e) => e.$1 > 50) .map((e) => e.$2) .toList(); - }, [artistQuery.data, searchText.value]); + }, [artistQuery.value?.items, searchText.value]); final controller = useScrollController(); @@ -66,7 +66,7 @@ class UserArtists extends HookConsumerWidget { ), ), backgroundColor: theme.scaffoldBackgroundColor, - body: artistQuery.data?.isEmpty == true + body: artistQuery.value?.items.isEmpty == true ? Padding( padding: const EdgeInsets.all(20), child: Row( @@ -80,7 +80,7 @@ class UserArtists extends HookConsumerWidget { ) : RefreshIndicator( onRefresh: () async { - await artistQuery.refresh(); + ref.invalidate(followedArtistsProvider); }, child: InterScrollbar( controller: controller, @@ -109,8 +109,9 @@ class UserArtists extends HookConsumerWidget { ) ] : filteredArtists - .mapIndexed((index, artist) => - ArtistCard(artist)) + .mapIndexed( + (index, artist) => ArtistCard(artist), + ) .toList(), ), ), diff --git a/lib/components/library/user_local_tracks.dart b/lib/components/library/user_local_tracks.dart index 0868f32b..8208b9e6 100644 --- a/lib/components/library/user_local_tracks.dart +++ b/lib/components/library/user_local_tracks.dart @@ -217,7 +217,7 @@ class UserLocalTracks extends HookConsumerWidget { FilledButton( child: const Icon(SpotubeIcons.refresh), onPressed: () { - ref.refresh(localTracksProvider); + ref.invalidate(localTracksProvider); }, ) ], @@ -269,7 +269,7 @@ class UserLocalTracks extends HookConsumerWidget { return Expanded( child: RefreshIndicator( onRefresh: () async { - ref.refresh(localTracksProvider); + ref.invalidate(localTracksProvider); }, child: InterScrollbar( controller: controller, diff --git a/lib/components/library/user_playlists.dart b/lib/components/library/user_playlists.dart index 2956e3b4..d0ebeb81 100644 --- a/lib/components/library/user_playlists.dart +++ b/lib/components/library/user_playlists.dart @@ -17,7 +17,7 @@ import 'package:spotube/components/shared/waypoint.dart'; import 'package:spotube/extensions/constrains.dart'; import 'package:spotube/extensions/context.dart'; import 'package:spotube/provider/authentication_provider.dart'; -import 'package:spotube/services/queries/queries.dart'; +import 'package:spotube/provider/spotify/spotify.dart'; class UserPlaylists extends HookConsumerWidget { const UserPlaylists({super.key}); @@ -28,13 +28,9 @@ class UserPlaylists extends HookConsumerWidget { final auth = ref.watch(AuthenticationNotifier.provider); - final playlistsQuery = useQueries.playlist.ofMine(ref); - - final pagePlaylists = useMemoized( - () => playlistsQuery.pages - .expand((page) => page.items?.toList() ?? []), - [playlistsQuery.pages], - ); + final playlistsQuery = ref.watch(favoritePlaylistsProvider); + final playlistsQueryNotifier = + ref.watch(favoritePlaylistsProvider.notifier); final likedTracksPlaylist = useMemoized( () => PlaylistSimple() @@ -58,12 +54,12 @@ class UserPlaylists extends HookConsumerWidget { if (searchText.value.isEmpty) { return [ likedTracksPlaylist, - ...pagePlaylists, + ...?playlistsQuery.value?.items, ]; } return [ likedTracksPlaylist, - ...pagePlaylists, + ...?playlistsQuery.value?.items, ] .map((e) => (weightedRatio(e.name!, searchText.value), e)) .sorted((a, b) => b.$1.compareTo(a.$1)) @@ -71,7 +67,7 @@ class UserPlaylists extends HookConsumerWidget { .map((e) => e.$2) .toList(); }, - [pagePlaylists, searchText.value], + [playlistsQuery, searchText.value], ); final controller = useScrollController(); @@ -81,7 +77,9 @@ class UserPlaylists extends HookConsumerWidget { } return RefreshIndicator( - onRefresh: playlistsQuery.refresh, + onRefresh: () async { + ref.invalidate(favoritePlaylistsProvider); + }, child: SafeArea( child: InterScrollbar( controller: controller, @@ -132,14 +130,14 @@ class UserPlaylists extends HookConsumerWidget { ), itemBuilder: (context, index) { if (playlists.isNotEmpty && index == playlists.length) { - if (!playlistsQuery.hasNextPage) { + if (playlistsQuery.value?.hasMore != true) { return const SizedBox.shrink(); } return Waypoint( controller: controller, isGrid: true, - onTouchEdge: playlistsQuery.fetchNext, + onTouchEdge: playlistsQueryNotifier.fetchMore, child: Skeletonizer( enabled: true, child: PlaylistCard(FakeData.playlistSimple), diff --git a/lib/provider/custom_spotify_endpoint_provider.dart b/lib/provider/custom_spotify_endpoint_provider.dart index 4857a358..7a4c5533 100644 --- a/lib/provider/custom_spotify_endpoint_provider.dart +++ b/lib/provider/custom_spotify_endpoint_provider.dart @@ -1,8 +1,10 @@ import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:spotube/provider/authentication_provider.dart'; +import 'package:spotube/provider/spotify_provider.dart'; import 'package:spotube/services/custom_spotify_endpoints/spotify_endpoints.dart'; final customSpotifyEndpointProvider = Provider((ref) { + ref.watch(spotifyProvider); final auth = ref.watch(AuthenticationNotifier.provider); return CustomSpotifyEndpoints(auth?.accessToken ?? ""); }); diff --git a/lib/provider/spotify/artist/following.dart b/lib/provider/spotify/artist/following.dart index c75a3c47..4e6bcfe8 100644 --- a/lib/provider/spotify/artist/following.dart +++ b/lib/provider/spotify/artist/following.dart @@ -1,6 +1,6 @@ part of '../spotify.dart'; -class FollowedArtistsState extends CursorPaginatedState { +class FollowedArtistsState extends CursorPaginatedState { FollowedArtistsState({ required super.items, required super.offset, @@ -10,7 +10,7 @@ class FollowedArtistsState extends CursorPaginatedState { @override FollowedArtistsState copyWith({ - List? items, + List? items, String? offset, int? limit, bool? hasMore, @@ -25,7 +25,7 @@ class FollowedArtistsState extends CursorPaginatedState { } class FollowedArtistsNotifier - extends CursorPaginatedAsyncNotifier { + extends CursorPaginatedAsyncNotifier { FollowedArtistsNotifier() : super(); @override @@ -95,7 +95,7 @@ final followedArtistsProvider = () => FollowedArtistsNotifier(), ); -final allFollowedArtistsProvider = FutureProvider>( +final allFollowedArtistsProvider = FutureProvider>( (ref) async { final spotify = ref.watch(spotifyProvider); final artists = await spotify.me.following(FollowingType.artist).all();