updates and bug fixes

This commit is contained in:
Forrest 2026-07-30 11:39:33 -04:00
parent 8aacce5aa8
commit 351d47b3ff
9 changed files with 419 additions and 64 deletions

View file

@ -315,6 +315,7 @@ class _TracksPanelState extends ConsumerState<_TracksPanel> {
Widget build(BuildContext context) {
final index = ref.watch(libraryIndexProvider);
final playback = ref.read(playbackProvider.notifier);
final client = ref.watch(subsonicClientProvider);
final Widget body;
if (index.building) {
@ -345,9 +346,13 @@ class _TracksPanelState extends ConsumerState<_TracksPanel> {
itemCount: index.songs.length,
itemBuilder: (context, i) {
final song = index.songs[i];
final artUri = (client != null && song.coverArt != null)
? client.coverArtUri(song.coverArt!, size: 128).toString()
: null;
return BrowseRow(
title: song.title ?? 'Untitled',
trailing: song.artist,
subtitle: song.artist,
artUri: artUri,
downloadStatus: downloads.byId[song.id]?.status,
onTap: () => playback.playSongs(index.songs, startIndex: i),
onPlayNext: () => playback.playNext(song),
@ -527,6 +532,8 @@ class BrowseRow extends StatelessWidget {
required this.title,
this.leading,
this.trailing,
this.subtitle,
this.artUri,
this.onTap,
this.onPlayNext,
this.onAddToQueue,
@ -540,6 +547,14 @@ class BrowseRow extends StatelessWidget {
final String title;
final String? leading;
final String? trailing;
/// Secondary line rendered below [title] in a smaller, dimmed font (e.g. the
/// artist name on track rows).
final String? subtitle;
/// When set, a small square album-cover thumbnail is shown at the start of
/// the row.
final String? artUri;
final VoidCallback? onTap;
/// When set, renders inline "play next" / "add to queue" icons (song rows).
@ -578,6 +593,23 @@ class BrowseRow extends StatelessWidget {
padding: const EdgeInsets.only(left: TimbreSpacing.lg),
child: Row(
children: [
if (artUri != null) ...[
SizedBox(
width: 40,
height: 40,
child: ColoredBox(
color: TimbreColors.surface,
child: Image.network(
artUri!,
key: ValueKey(artUri),
fit: BoxFit.cover,
gaplessPlayback: true,
errorBuilder: (_, _, _) => const _AlbumArtFallback(),
),
),
),
const SizedBox(width: TimbreSpacing.md),
],
if (leading != null)
SizedBox(
width: 28,
@ -585,11 +617,25 @@ class BrowseRow extends StatelessWidget {
style: const TextStyle(color: TimbreColors.dimmed)),
),
Expanded(
child: Text(
title,
maxLines: 1,
overflow: TextOverflow.ellipsis,
style: const TextStyle(color: TimbreColors.foreground),
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
title,
maxLines: 1,
overflow: TextOverflow.ellipsis,
style: const TextStyle(color: TimbreColors.foreground),
),
if (subtitle != null)
Text(
subtitle!,
maxLines: 1,
overflow: TextOverflow.ellipsis,
style: const TextStyle(
color: TimbreColors.dimmed, fontSize: 12),
),
],
),
),
if (isDone)