mirror of
https://github.com/austinried/subtracks.git
synced 2026-02-10 23:02:43 +01:00
artist list with images
This commit is contained in:
@@ -10,7 +10,7 @@ import '../state/database.dart';
|
||||
import '../state/settings.dart';
|
||||
import 'list_items.dart';
|
||||
|
||||
const kPageSize = 30;
|
||||
const kPageSize = 60;
|
||||
|
||||
class AlbumsGrid extends HookConsumerWidget {
|
||||
const AlbumsGrid({super.key});
|
||||
|
||||
81
lib/app/lists/artists_list.dart
Normal file
81
lib/app/lists/artists_list.dart
Normal file
@@ -0,0 +1,81 @@
|
||||
import 'package:drift/drift.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||
import 'package:infinite_scroll_pagination/infinite_scroll_pagination.dart';
|
||||
|
||||
import '../../sources/models.dart';
|
||||
import '../hooks/use_paging_controller.dart';
|
||||
import '../state/database.dart';
|
||||
import '../state/settings.dart';
|
||||
import 'list_items.dart';
|
||||
|
||||
const kPageSize = 30;
|
||||
|
||||
typedef _ArtistItem = ({Artist artist, int? albumCount});
|
||||
|
||||
class ArtistsList extends HookConsumerWidget {
|
||||
const ArtistsList({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
final db = ref.watch(databaseProvider);
|
||||
final sourceId = ref.watch(sourceIdProvider);
|
||||
|
||||
final controller = usePagingController<int, _ArtistItem>(
|
||||
getNextPageKey: (state) =>
|
||||
state.lastPageIsEmpty ? null : state.nextIntPageKey,
|
||||
fetchPage: (pageKey) async {
|
||||
final albumCount = db.albums.id.count();
|
||||
|
||||
final query =
|
||||
db.artists.select().join([
|
||||
leftOuterJoin(
|
||||
db.albums,
|
||||
db.albums.artistId.equalsExp(db.artists.id),
|
||||
),
|
||||
])
|
||||
..addColumns([albumCount])
|
||||
..where(
|
||||
db.artists.sourceId.equals(sourceId) &
|
||||
db.albums.sourceId.equals(sourceId),
|
||||
)
|
||||
..groupBy([db.artists.sourceId, db.artists.id])
|
||||
..orderBy([OrderingTerm.asc(db.artists.name)])
|
||||
..limit(kPageSize, offset: (pageKey - 1) * kPageSize);
|
||||
|
||||
return (await query.get())
|
||||
.map(
|
||||
(row) => (
|
||||
artist: row.readTable(db.artists),
|
||||
albumCount: row.read(albumCount),
|
||||
),
|
||||
)
|
||||
.toList();
|
||||
},
|
||||
);
|
||||
|
||||
return PagingListener(
|
||||
controller: controller,
|
||||
builder: (context, state, fetchNextPage) {
|
||||
return PagedSliverList(
|
||||
state: state,
|
||||
fetchNextPage: fetchNextPage,
|
||||
builderDelegate: PagedChildBuilderDelegate<_ArtistItem>(
|
||||
itemBuilder: (context, item, index) {
|
||||
final (:artist, :albumCount) = item;
|
||||
|
||||
return ArtistListTile(
|
||||
artist: artist,
|
||||
albumCount: albumCount,
|
||||
onTap: () async {
|
||||
context.push('/artist/${artist.id}');
|
||||
},
|
||||
);
|
||||
},
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,3 @@
|
||||
import 'package:cached_network_image/cached_network_image.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||
|
||||
@@ -33,19 +32,28 @@ class AlbumGridTile extends HookConsumerWidget {
|
||||
}
|
||||
|
||||
class ArtistListTile extends StatelessWidget {
|
||||
const ArtistListTile({super.key});
|
||||
const ArtistListTile({
|
||||
super.key,
|
||||
required this.artist,
|
||||
this.albumCount,
|
||||
this.onTap,
|
||||
});
|
||||
|
||||
final Artist artist;
|
||||
final int? albumCount;
|
||||
final void Function()? onTap;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return ListTile(
|
||||
leading: CircleClip(
|
||||
child: CachedNetworkImage(
|
||||
imageUrl: 'https://placehold.net/400x400.png',
|
||||
placeholder: (context, url) => CircularProgressIndicator(),
|
||||
errorWidget: (context, url, error) => Icon(Icons.error),
|
||||
),
|
||||
child: artist.coverArt != null
|
||||
? CoverArtImage(coverArt: artist.coverArt)
|
||||
: CachedImage(artist.smallImage),
|
||||
),
|
||||
title: Text('Some Artist'),
|
||||
title: Text(artist.name),
|
||||
subtitle: albumCount != null ? Text('$albumCount albums') : null,
|
||||
onTap: onTap,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@ import 'package:go_router/go_router.dart';
|
||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||
import 'package:material_symbols_icons/symbols.dart';
|
||||
|
||||
import '../lists/albums_grid.dart';
|
||||
import '../lists/artists_list.dart';
|
||||
import '../state/services.dart';
|
||||
import '../util/custom_scroll_fix.dart';
|
||||
|
||||
@@ -210,7 +210,7 @@ class _NewWidgetState extends State<NewWidget>
|
||||
),
|
||||
SliverPadding(
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
sliver: AlbumsGrid(),
|
||||
sliver: ArtistsList(),
|
||||
),
|
||||
],
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user