playlists list

This commit is contained in:
austinried
2025-12-06 10:22:14 +09:00
parent a4e4c6fa57
commit f3969dc6af
13 changed files with 1040 additions and 32 deletions

View File

@@ -27,10 +27,7 @@ class AlbumsGrid extends HookConsumerWidget {
AlbumsQuery(
sourceId: ref.read(sourceIdProvider),
sort: IList([
AlbumsSortingTerm(
dir: SortDirection.desc,
by: AlbumsColumn.created,
),
SortingTerm.albumsDesc(AlbumsColumn.created),
]),
limit: kPageSize,
offset: (pageKey - 1) * kPageSize,

View File

@@ -27,10 +27,7 @@ class ArtistsList extends HookConsumerWidget {
ArtistsQuery(
sourceId: ref.read(sourceIdProvider),
sort: IList([
ArtistsSortingTerm(
dir: SortDirection.asc,
by: ArtistsColumn.name,
),
SortingTerm.artistsAsc(ArtistsColumn.name),
]),
limit: kPageSize,
offset: (pageKey - 1) * kPageSize,

View File

@@ -38,12 +38,12 @@ class ArtistListTile extends StatelessWidget {
const ArtistListTile({
super.key,
required this.artist,
this.albumCount,
required this.albumCount,
this.onTap,
});
final Artist artist;
final int? albumCount;
final int albumCount;
final void Function()? onTap;
@override
@@ -56,7 +56,33 @@ class ArtistListTile extends StatelessWidget {
),
),
title: Text(artist.name),
subtitle: albumCount != null ? Text('$albumCount albums') : null,
subtitle: Text('$albumCount albums'),
onTap: onTap,
);
}
}
class PlaylistListTile extends StatelessWidget {
const PlaylistListTile({
super.key,
required this.playlist,
this.albumCount,
this.onTap,
});
final Playlist playlist;
final int? albumCount;
final void Function()? onTap;
@override
Widget build(BuildContext context) {
return ListTile(
leading: CoverArtImage(
coverArt: playlist.coverArt,
thumbnail: true,
),
title: Text(playlist.name),
subtitle: Text(playlist.comment ?? ''),
onTap: onTap,
);
}

View File

@@ -0,0 +1,58 @@
import 'package:fast_immutable_collections/fast_immutable_collections.dart';
import 'package:flutter/material.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:infinite_scroll_pagination/infinite_scroll_pagination.dart';
import '../../../database/query.dart';
import '../../../sources/models.dart';
import '../../hooks/use_on_source.dart';
import '../../hooks/use_paging_controller.dart';
import '../../state/database.dart';
import '../../state/source.dart';
import 'items.dart';
const kPageSize = 30;
class PlaylistsList extends HookConsumerWidget {
const PlaylistsList({super.key});
@override
Widget build(BuildContext context, WidgetRef ref) {
final db = ref.watch(databaseProvider);
final controller = usePagingController<int, Playlist>(
getNextPageKey: (state) =>
state.lastPageIsEmpty ? null : state.nextIntPageKey,
fetchPage: (pageKey) => db.libraryDao.listPlaylists(
PlaylistsQuery(
sourceId: ref.read(sourceIdProvider),
sort: IList([
SortingTerm.playlistsDesc(PlaylistsColumn.created),
]),
limit: kPageSize,
offset: (pageKey - 1) * kPageSize,
),
),
);
useOnSourceChange(ref, (_) => controller.refresh());
useOnSourceSync(ref, controller.refresh);
return PagingListener(
controller: controller,
builder: (context, state, fetchNextPage) {
return PagedSliverList(
state: state,
fetchNextPage: fetchNextPage,
builderDelegate: PagedChildBuilderDelegate<Playlist>(
itemBuilder: (context, item, index) {
return PlaylistListTile(
playlist: item,
onTap: () {},
);
},
),
);
},
);
}
}