From f4d723c0b15c9d067bb6da5ee914d24121bfd49d Mon Sep 17 00:00:00 2001 From: Sorunome Date: Tue, 30 Nov 2021 14:40:03 +0100 Subject: [PATCH] fix: Thumbnails in the image bubble not always showing a cached thumbnail When in the timeline an image bubble with animated=false was displayed and you tapped on an image, it would attempt to show the thumbnail with animated=true. This thumbnail, of course, was not cached, thus not showing the cached image, and actually downloading the thumbnail multiple times. This PR fixes that by first checking if the animated=false thumbnail is cached, and if so, display that while the final image is loading. --- lib/pages/chat/events/image_bubble.dart | 45 ++++++++++++++++++++----- 1 file changed, 36 insertions(+), 9 deletions(-) diff --git a/lib/pages/chat/events/image_bubble.dart b/lib/pages/chat/events/image_bubble.dart index 11cf7df6a..9b20e7225 100644 --- a/lib/pages/chat/events/image_bubble.dart +++ b/lib/pages/chat/events/image_bubble.dart @@ -4,6 +4,7 @@ import 'package:flutter/material.dart'; import 'package:cached_network_image/cached_network_image.dart'; import 'package:flutter_blurhash/flutter_blurhash.dart'; +import 'package:flutter_cache_manager/flutter_cache_manager.dart'; import 'package:flutter_gen/gen_l10n/l10n.dart'; import 'package:flutter_svg/flutter_svg.dart'; import 'package:lottie/lottie.dart'; @@ -48,6 +49,8 @@ class ImageBubble extends StatefulWidget { class _ImageBubbleState extends State { // for plaintext: holds the http URL for the thumbnail String thumbnailUrl; + // for plaintext. holds the http URL for the thumbnial, without the animated flag + String thumbnailUrlNoAnimated; // for plaintext: holds the http URL of the original String attachmentUrl; MatrixFile _file; @@ -166,6 +169,9 @@ class _ImageBubbleState extends State { thumbnailUrl = widget.event .getAttachmentUrl(getThumbnail: true, animated: widget.animated) ?.toString(); + thumbnailUrlNoAnimated = widget.event + .getAttachmentUrl(getThumbnail: true, animated: false) + ?.toString(); attachmentUrl = widget.event.getAttachmentUrl(animated: widget.animated)?.toString(); if (thumbnailUrl == null) { @@ -304,15 +310,30 @@ class _ImageBubbleState extends State { displayUrl != thumbnailUrl && displayUrl == attachmentUrl) { // we have to display the thumbnail while loading - return CachedNetworkImage( - key: ValueKey(thumbnailUrl), - imageUrl: thumbnailUrl, - placeholder: (c, u) => getPlaceholderWidget(), - imageBuilder: (context, imageProvider) => Image( - image: imageProvider, - frameBuilder: frameBuilder, - fit: widget.fit, - ), + return FutureBuilder( + future: (() async { + return await DefaultCacheManager() + .getFileFromCache(thumbnailUrl) != + null; + })(), + builder: (BuildContext context, AsyncSnapshot snapshot) { + if (!snapshot.hasData) { + return getPlaceholderWidget(); + } + final effectiveUrl = snapshot.data == true + ? thumbnailUrl + : thumbnailUrlNoAnimated; + return CachedNetworkImage( + key: ValueKey(effectiveUrl), + imageUrl: effectiveUrl, + placeholder: (c, u) => getPlaceholderWidget(), + imageBuilder: (context, imageProvider) => Image( + image: imageProvider, + frameBuilder: frameBuilder, + fit: widget.fit, + ), + ); + }, ); } return getPlaceholderWidget(); @@ -335,6 +356,12 @@ class _ImageBubbleState extends State { useThumbnailMxcUrl: true, animated: widget.animated) ?.toString(); + thumbnailUrlNoAnimated = widget.event + .getAttachmentUrl( + getThumbnail: true, + useThumbnailMxcUrl: true, + animated: false) + ?.toString(); attachmentUrl = widget.event .getAttachmentUrl( useThumbnailMxcUrl: true, animated: widget.animated)