fix(images): decode cast cards at the square grid-cell budget
close #1591
This commit is contained in:
@@ -19,8 +19,8 @@ enum ImageType {
|
||||
thumb, // 16:9 episode thumbnails
|
||||
logo, // Variable ratio clear logos
|
||||
heroLogo, // Large hero clear logos
|
||||
avatar, // Square-ish user avatars
|
||||
square, // 1:1 music artwork (albums, artists, tracks)
|
||||
avatar, // Small square-ish avatars (user profiles, inline person headers)
|
||||
square, // 1:1 grid-cell artwork (albums, artists, tracks, cast cards)
|
||||
}
|
||||
|
||||
/// Backend-neutral image URL helper.
|
||||
|
||||
@@ -214,7 +214,7 @@ class CastMemberStripState extends State<CastMemberStrip> {
|
||||
width: imageSize,
|
||||
height: imageSize,
|
||||
fit: BoxFit.cover,
|
||||
imageType: ImageType.avatar,
|
||||
imageType: ImageType.square,
|
||||
fallbackIcon: Symbols.person_rounded,
|
||||
),
|
||||
),
|
||||
|
||||
@@ -1564,7 +1564,7 @@ class TvBrowseRailState extends State<TvBrowseRail> {
|
||||
width: cardWidth,
|
||||
height: imageSize,
|
||||
fit: BoxFit.cover,
|
||||
imageType: ImageType.avatar,
|
||||
imageType: ImageType.square,
|
||||
fallbackIcon: Symbols.person_rounded,
|
||||
),
|
||||
RasterizedGradient(
|
||||
@@ -1631,7 +1631,7 @@ class TvBrowseRailState extends State<TvBrowseRail> {
|
||||
width: imageSize,
|
||||
height: imageSize,
|
||||
fit: BoxFit.cover,
|
||||
imageType: ImageType.avatar,
|
||||
imageType: ImageType.square,
|
||||
fallbackIcon: Symbols.person_rounded,
|
||||
),
|
||||
),
|
||||
|
||||
@@ -158,6 +158,21 @@ void main() {
|
||||
);
|
||||
});
|
||||
|
||||
test('square keeps a grid-cell decode budget while avatar stays small', () {
|
||||
DevicePerformance.debugReset(autoReduced: false, override: VisualEffectsSetting.auto);
|
||||
|
||||
// Cast cards fill poster-width grid cells (issue #1591): a retina cell
|
||||
// needs well over the avatar cap, so they use the square budget.
|
||||
expect(
|
||||
MediaImageHelper.getMemCacheDimensions(displayWidth: 4000, displayHeight: 4000, imageType: ImageType.square),
|
||||
(720, 720),
|
||||
);
|
||||
expect(
|
||||
MediaImageHelper.getMemCacheDimensions(displayWidth: 4000, displayHeight: 4000, imageType: ImageType.avatar),
|
||||
(300, 300),
|
||||
);
|
||||
});
|
||||
|
||||
test('card artwork follows square, wide, and poster media shapes', () {
|
||||
for (final kind in [MediaKind.artist, MediaKind.album, MediaKind.track]) {
|
||||
expect(
|
||||
|
||||
@@ -3,8 +3,10 @@ import 'package:flutter/services.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:plezy/services/settings_service.dart';
|
||||
import 'package:plezy/theme/mono_theme.dart';
|
||||
import 'package:plezy/utils/media_image_helper.dart';
|
||||
import 'package:plezy/utils/platform_detector.dart';
|
||||
import 'package:plezy/widgets/cast_member_strip.dart';
|
||||
import 'package:plezy/widgets/optimized_media_image.dart';
|
||||
|
||||
import '../test_helpers/prefs.dart';
|
||||
|
||||
@@ -68,6 +70,23 @@ void main() {
|
||||
expect(navigatedDown, 1);
|
||||
});
|
||||
|
||||
testWidgets('renders member images with the square grid-cell decode budget', (tester) async {
|
||||
// Cast cards are poster-cell sized; the small avatar budget decodes them
|
||||
// below retina resolution and blurs them (issue #1591).
|
||||
await tester.pumpWidget(
|
||||
MaterialApp(
|
||||
theme: monoTheme(dark: true),
|
||||
home: Scaffold(body: CastMemberStrip(members: _members)),
|
||||
),
|
||||
);
|
||||
|
||||
final images = tester.widgetList<OptimizedMediaImage>(find.byType(OptimizedMediaImage));
|
||||
expect(images, hasLength(_members.length));
|
||||
for (final image in images) {
|
||||
expect(image.imageType, ImageType.square);
|
||||
}
|
||||
});
|
||||
|
||||
testWidgets('clamps its focus index when the member list changes', (tester) async {
|
||||
final key = GlobalKey<CastMemberStripState>();
|
||||
var members = _members;
|
||||
|
||||
Reference in New Issue
Block a user