chore: fix pagination for liked tracks and saved albums not working

This commit is contained in:
Kingkor Roy Tirtho 2025-09-05 10:50:14 +06:00
parent 005355e267
commit 345c6ac714
4 changed files with 29 additions and 32 deletions

View File

@ -99,7 +99,7 @@ class UserAlbumsPage extends HookConsumerWidget {
features: const [ features: const [
InputFeature.leading(Icon(SpotubeIcons.filter)) InputFeature.leading(Icon(SpotubeIcons.filter))
], ],
placeholder: Text(context.l10n.filter_artist), placeholder: Text(context.l10n.filter_albums),
), ),
), ),
), ),
@ -121,7 +121,7 @@ class UserAlbumsPage extends HookConsumerWidget {
color: Theme.of(context).colorScheme.primary, color: Theme.of(context).colorScheme.primary,
), ),
Text( Text(
context.l10n.not_following_artists, context.l10n.no_favorite_albums_yet,
textAlign: TextAlign.center, textAlign: TextAlign.center,
).muted().small() ).muted().small()
], ],

View File

@ -8,6 +8,7 @@ import 'package:spotube/models/metadata/metadata.dart';
import 'package:spotube/pages/playlist/playlist.dart'; import 'package:spotube/pages/playlist/playlist.dart';
import 'package:spotube/provider/metadata_plugin/library/tracks.dart'; import 'package:spotube/provider/metadata_plugin/library/tracks.dart';
import 'package:auto_route/auto_route.dart'; import 'package:auto_route/auto_route.dart';
import 'package:spotube/provider/metadata_plugin/utils/common.dart';
@RoutePage() @RoutePage()
class LikedPlaylistPage extends HookConsumerWidget { class LikedPlaylistPage extends HookConsumerWidget {
@ -22,6 +23,8 @@ class LikedPlaylistPage extends HookConsumerWidget {
@override @override
Widget build(BuildContext context, ref) { Widget build(BuildContext context, ref) {
final likedTracks = ref.watch(metadataPluginSavedTracksProvider); final likedTracks = ref.watch(metadataPluginSavedTracksProvider);
final likedTracksNotifier =
ref.watch(metadataPluginSavedTracksProvider.notifier);
final tracks = likedTracks.asData?.value.items ?? []; final tracks = likedTracks.asData?.value.items ?? [];
return material.RefreshIndicator.adaptive( return material.RefreshIndicator.adaptive(
@ -33,11 +36,13 @@ class LikedPlaylistPage extends HookConsumerWidget {
collection: playlist, collection: playlist,
image: Assets.images.likedTracks.path, image: Assets.images.likedTracks.path,
pagination: PaginationProps( pagination: PaginationProps(
hasNextPage: false, hasNextPage: likedTracks.asData?.value.hasMore ?? false,
isLoading: likedTracks.isLoading, isLoading: likedTracks.isLoadingNextPage && !likedTracks.isLoading,
onFetchMore: () {}, onFetchMore: () async {
await likedTracksNotifier.fetchMore();
},
onFetchAll: () async { onFetchAll: () async {
return tracks.toList(); return await likedTracksNotifier.fetchAll();
}, },
onRefresh: () async { onRefresh: () async {
ref.invalidate(metadataPluginSavedTracksProvider); ref.invalidate(metadataPluginSavedTracksProvider);

View File

@ -14,20 +14,16 @@ abstract class FamilyPaginatedAsyncNotifier<K, A>
state = AsyncLoadingNext(state.asData!.value); state = AsyncLoadingNext(state.asData!.value);
state = await AsyncValue.guard( final newState = await fetch(
() async { state.value!.nextOffset!,
final newState = await fetch( state.value!.limit,
state.value!.nextOffset!,
state.value!.limit,
);
final oldItems =
state.value!.items.isEmpty ? <K>[] : state.value!.items.cast<K>();
final items = newState.items.isEmpty ? <K>[] : newState.items.cast<K>();
return newState.copyWith(items: <K>[...oldItems, ...items]);
},
); );
final oldItems =
state.value!.items.isEmpty ? <K>[] : state.value!.items.cast<K>();
final items = newState.items.isEmpty ? <K>[] : newState.items.cast<K>();
state = AsyncData(newState.copyWith(items: <K>[...oldItems, ...items]));
} }
Future<List<K>> fetchAll() async { Future<List<K>> fetchAll() async {

View File

@ -16,20 +16,16 @@ mixin PaginatedAsyncNotifierMixin<K>
state = AsyncLoadingNext(state.asData!.value); state = AsyncLoadingNext(state.asData!.value);
state = await AsyncValue.guard( final newState = await fetch(
() async { state.value!.nextOffset!,
final newState = await fetch( state.value!.limit,
state.value!.nextOffset!,
state.value!.limit,
);
final oldItems =
state.value!.items.isEmpty ? <K>[] : state.value!.items.cast<K>();
final items = newState.items.isEmpty ? <K>[] : newState.items.cast<K>();
return newState.copyWith(items: <K>[...oldItems, ...items]);
},
); );
final oldItems =
state.value!.items.isEmpty ? <K>[] : state.value!.items.cast<K>();
final items = newState.items.isEmpty ? <K>[] : newState.items.cast<K>();
state = AsyncData(newState.copyWith(items: <K>[...oldItems, ...items]));
} }
Future<List<K>> fetchAll() async { Future<List<K>> fetchAll() async {