fix(flutter): keep artist avatars round in the Library grid
ArtistCard hardcoded its avatar at Container(width: 124, height: 124) inside a ClipOval. In the Library Artists 3-column grid the cell is narrower than the card's nominal 140dp width — on a typical phone the cell is ~109dp, the padded inner content area ~93dp. The parent constrained the Container's width to ~93dp but the explicit height stayed 124dp, so ClipOval clipped a 93×124 rectangle and the avatar rendered as a vertical ellipse. Fix mirrors AlbumCard's pattern: ArtistCard takes an optional `width` parameter (default 140 for horizontal carousels) and derives coverSize = width - 16, so the Container is always square. ArtistsTab now uses LayoutBuilder to compute cell width and passes it through, same as AlbumsTab. Avatar stays a true circle at any cell width. mainAxisExtent on the grid replaces the previous fixed childAspectRatio so cell height tracks cellW + name line, with slack matching AlbumsTab's overflow guard.
This commit is contained in:
@@ -12,15 +12,27 @@ import '../library_providers.dart';
|
||||
import 'play_circle_button.dart';
|
||||
|
||||
class ArtistCard extends ConsumerWidget {
|
||||
const ArtistCard({required this.artist, required this.onTap, super.key});
|
||||
const ArtistCard({
|
||||
required this.artist,
|
||||
required this.onTap,
|
||||
this.width = 140,
|
||||
super.key,
|
||||
});
|
||||
final ArtistRef artist;
|
||||
final VoidCallback onTap;
|
||||
|
||||
/// Outer width of the card. Avatar is a circle of width-16 (8dp
|
||||
/// horizontal padding either side). Default suits horizontal lists;
|
||||
/// grids should pass the cell width so the avatar shrinks
|
||||
/// proportionally and stays a true circle.
|
||||
final double width;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
final fs = Theme.of(context).extension<FabledSwordTheme>()!;
|
||||
final coverSize = width - 16;
|
||||
return SizedBox(
|
||||
width: 140,
|
||||
width: width,
|
||||
child: Material(
|
||||
color: Colors.transparent,
|
||||
child: InkWell(
|
||||
@@ -29,15 +41,20 @@ class ArtistCard extends ConsumerWidget {
|
||||
padding: const EdgeInsets.symmetric(horizontal: 8),
|
||||
child: Column(crossAxisAlignment: CrossAxisAlignment.start, children: [
|
||||
// Stack: circular avatar + overlaid play button at bottom-right.
|
||||
// The avatar is a circle (ClipOval) — bottom-right of its
|
||||
// bounding box still places the button inside the visible area
|
||||
// because the button is small relative to the radius.
|
||||
// Avatar size derives from the [width] parameter so the
|
||||
// Library Artists 3-column grid can pass its cell width
|
||||
// (~109dp on typical phones) and the avatar stays a
|
||||
// perfect circle. Previous hardcoded 124×124 got squeezed
|
||||
// horizontally in the grid (cell narrower than 124+16
|
||||
// padding) but kept its 124dp height — ClipOval produced
|
||||
// a visible vertical ellipse. Mirrors AlbumCard's width-
|
||||
// parameter convention.
|
||||
Stack(
|
||||
children: [
|
||||
ClipOval(
|
||||
child: Container(
|
||||
width: 124,
|
||||
height: 124,
|
||||
width: coverSize,
|
||||
height: coverSize,
|
||||
color: fs.slate,
|
||||
child: artist.coverUrl.isEmpty
|
||||
? SvgPicture.asset('assets/svg/album-fallback.svg',
|
||||
|
||||
Reference in New Issue
Block a user