From 7f23979e039f7ff7dfdd7a4c4c72ff2d277b903a Mon Sep 17 00:00:00 2001 From: edde746 <86283021+edde746@users.noreply.github.com> Date: Wed, 3 Dec 2025 19:39:26 +0100 Subject: [PATCH] fix: limit mem cache resolution --- lib/screens/discover_screen.dart | 20 ++++++++++++++++++++ lib/services/video_filter_manager.dart | 2 -- lib/widgets/media_card.dart | 16 ++++++++++++++-- lib/widgets/playlist_item_card.dart | 3 +++ 4 files changed, 37 insertions(+), 4 deletions(-) diff --git a/lib/screens/discover_screen.dart b/lib/screens/discover_screen.dart index 2be52fd5..c46ba347 100644 --- a/lib/screens/discover_screen.dart +++ b/lib/screens/discover_screen.dart @@ -1032,6 +1032,19 @@ class _DiscoverScreenState extends State heroItem.art ?? heroItem.grandparentArt, ), fit: BoxFit.cover, + memCacheWidth: + (MediaQuery.of(context).size.width * + MediaQuery.of(context).devicePixelRatio) + .clamp(900, 2400) + .round(), + memCacheHeight: + (MediaQuery.of(context).size.height * + MediaQuery.of( + context, + ).devicePixelRatio * + 0.7) + .clamp(600, 1600) + .round(), placeholder: (context, url) => Container( color: Theme.of( context, @@ -1099,6 +1112,13 @@ class _DiscoverScreenState extends State ), filterQuality: FilterQuality.medium, fit: BoxFit.contain, + memCacheWidth: + (400 * + MediaQuery.of( + context, + ).devicePixelRatio) + .clamp(200, 800) + .round(), alignment: isLargeScreen ? Alignment.bottomLeft : Alignment.bottomCenter, diff --git a/lib/services/video_filter_manager.dart b/lib/services/video_filter_manager.dart index bdb3a869..d47fae78 100644 --- a/lib/services/video_filter_manager.dart +++ b/lib/services/video_filter_manager.dart @@ -27,7 +27,6 @@ class VideoFilterManager { /// Current player viewport size Size? _playerSize; - /// Debounced video filter update with leading edge execution late final Debounce _debouncedUpdateVideoFilter; @@ -87,7 +86,6 @@ class VideoFilterManager { } } - /// Update the video scaling and positioning based on current display mode void updateVideoFilter() async { try { diff --git a/lib/widgets/media_card.dart b/lib/widgets/media_card.dart index e624bd25..35fd17c5 100644 --- a/lib/widgets/media_card.dart +++ b/lib/widgets/media_card.dart @@ -978,15 +978,27 @@ Widget _buildPosterImage(BuildContext context, dynamic item) { } if (posterUrl != null) { - return Builder( - builder: (context) { + return LayoutBuilder( + builder: (context, constraints) { final client = _getClientForItem(context, item); + final devicePixelRatio = MediaQuery.of(context).devicePixelRatio; + // Fall back to a reasonable size if constraints are unbounded. + final targetWidth = + (constraints.maxWidth.isFinite ? constraints.maxWidth : 160) * + devicePixelRatio; + final targetHeight = + (constraints.maxHeight.isFinite ? constraints.maxHeight : 240) * + devicePixelRatio; return CachedNetworkImage( imageUrl: client.getThumbnailUrl(posterUrl!), fit: BoxFit.cover, width: double.infinity, height: double.infinity, + // Decode close to the rendered size to keep memory in check when + // many posters load at once. + memCacheWidth: targetWidth.clamp(120, 800).round(), + memCacheHeight: targetHeight.clamp(180, 1200).round(), filterQuality: FilterQuality.medium, fadeInDuration: const Duration(milliseconds: 300), placeholder: (context, url) => const SkeletonLoader(), diff --git a/lib/widgets/playlist_item_card.dart b/lib/widgets/playlist_item_card.dart index eedf512c..0d4698fb 100644 --- a/lib/widgets/playlist_item_card.dart +++ b/lib/widgets/playlist_item_card.dart @@ -168,6 +168,7 @@ class _PlaylistItemCardState extends State return Builder( builder: (context) { final client = _getClientForItem(context); + final devicePixelRatio = MediaQuery.of(context).devicePixelRatio; return ClipRRect( borderRadius: BorderRadius.circular(6), @@ -175,6 +176,8 @@ class _PlaylistItemCardState extends State imageUrl: client.getThumbnailUrl(posterUrl), width: 60, height: 90, + memCacheWidth: (60 * devicePixelRatio).round(), + memCacheHeight: (90 * devicePixelRatio).round(), fit: BoxFit.cover, placeholder: (context, url) => _buildPlaceholder(), errorWidget: (context, url, error) => _buildPlaceholder(),