disable thumbhash for local assets

better update condition

load from provider first

show thumbhash for merged assets when scrubbing

fix disposal
This commit is contained in:
mertalev 2025-07-26 16:35:18 -04:00
parent 97a6c6d7a0
commit b81081e777
No known key found for this signature in database
GPG Key ID: DF6ABC77AAD98C95
2 changed files with 49 additions and 19 deletions

View File

@ -88,7 +88,6 @@ class Thumbnail extends StatefulWidget {
} }
class _ThumbnailState extends State<Thumbnail> { class _ThumbnailState extends State<Thumbnail> {
ui.Image? _thumbhashImage;
ui.Image? _providerImage; ui.Image? _providerImage;
ImageStream? _imageStream; ImageStream? _imageStream;
ImageStreamListener? _imageStreamListener; ImageStreamListener? _imageStreamListener;
@ -104,9 +103,17 @@ class _ThumbnailState extends State<Thumbnail> {
@override @override
void didUpdateWidget(Thumbnail oldWidget) { void didUpdateWidget(Thumbnail oldWidget) {
super.didUpdateWidget(oldWidget); super.didUpdateWidget(oldWidget);
if (oldWidget.imageProvider != widget.imageProvider || if (widget.imageProvider != oldWidget.imageProvider) {
oldWidget.blurhash != widget.blurhash || return _loadImage();
(oldWidget.thumbhashMode == ThumbhashMode.disabled && oldWidget.thumbhashMode != ThumbhashMode.disabled)) { }
if (_providerImage != null) {
return;
}
if ((oldWidget.thumbhashMode == ThumbhashMode.disabled && widget.thumbhashMode != ThumbhashMode.disabled) ||
(oldWidget.thumbhashMode == ThumbhashMode.only && widget.thumbhashMode != ThumbhashMode.only) ||
(widget.thumbhashMode != ThumbhashMode.disabled && oldWidget.blurhash != widget.blurhash)) {
_loadImage(); _loadImage();
} }
} }
@ -119,13 +126,13 @@ class _ThumbnailState extends State<Thumbnail> {
void _loadImage() { void _loadImage() {
_stopListeningToStream(); _stopListeningToStream();
if (widget.thumbhashMode != ThumbhashMode.disabled && widget.blurhash != null) {
_decodeThumbhash();
}
if (widget.thumbhashMode != ThumbhashMode.only && widget.imageProvider != null) { if (widget.thumbhashMode != ThumbhashMode.only && widget.imageProvider != null) {
_loadFromProvider(); _loadFromProvider();
} }
if (widget.thumbhashMode != ThumbhashMode.disabled && widget.blurhash != null) {
_decodeThumbhash();
}
} }
void _loadFromProvider() { void _loadFromProvider() {
@ -137,7 +144,6 @@ class _ThumbnailState extends State<Thumbnail> {
(ImageInfo imageInfo, bool synchronousCall) { (ImageInfo imageInfo, bool synchronousCall) {
if (!mounted) return; if (!mounted) return;
_thumbhashImage?.dispose();
if (_providerImage != imageInfo.image) { if (_providerImage != imageInfo.image) {
setState(() { setState(() {
_providerImage = imageInfo.image; _providerImage = imageInfo.image;
@ -220,7 +226,7 @@ class _ThumbnailState extends State<Thumbnail> {
); );
return _ThumbnailLeaf( return _ThumbnailLeaf(
image: _providerImage ?? _thumbhashImage, image: _providerImage,
fit: widget.fit, fit: widget.fit,
placeholderGradient: gradient, placeholderGradient: gradient,
); );
@ -229,7 +235,7 @@ class _ThumbnailState extends State<Thumbnail> {
@override @override
void dispose() { void dispose() {
_stopListeningToStream(); _stopListeningToStream();
_thumbhashImage?.dispose(); _providerImage?.dispose();
super.dispose(); super.dispose();
} }
} }
@ -302,7 +308,7 @@ class _ThumbnailRenderBox extends RenderBox {
markNeedsPaint(); markNeedsPaint();
}); });
} else { } else {
// _previousImage?.dispose(); _previousImage?.dispose();
_previousImage = null; _previousImage = null;
_fadeStartTime = null; _fadeStartTime = null;
} }
@ -347,7 +353,7 @@ class _ThumbnailRenderBox extends RenderBox {
final time = DateTime.now(); final time = DateTime.now();
if (time.difference(_lastImageRequest).inMilliseconds >= 16) { if (time.difference(_lastImageRequest).inMilliseconds >= 16) {
_fadeStartTime = DateTime.now(); _fadeStartTime = time;
_previousImage = _image; _previousImage = _image;
} }
_image = value; _image = value;
@ -376,4 +382,10 @@ class _ThumbnailRenderBox extends RenderBox {
markNeedsPaint(); markNeedsPaint();
} }
} }
@override
dispose() {
_previousImage?.dispose();
super.dispose();
}
} }

View File

@ -78,16 +78,34 @@ class ThumbnailTile extends ConsumerWidget {
tag: '${asset?.heroTag ?? ''}_$heroIndex', tag: '${asset?.heroTag ?? ''}_$heroIndex',
child: Thumbnail.fromBaseAsset( child: Thumbnail.fromBaseAsset(
asset: asset, asset: asset,
thumbhashMode: isScrubbing ? ThumbhashMode.only : ThumbhashMode.enabled, thumbhashMode: isScrubbing
? ThumbhashMode.only
: asset != null && asset.hasLocal
? ThumbhashMode.disabled
: ThumbhashMode.enabled,
), ),
), ),
), ),
if (hasStack) if (hasStack)
Align( asset.isVideo
alignment: Alignment.topRight, ? const Align(
child: Padding( alignment: Alignment.topRight,
padding: EdgeInsets.only(right: 10.0, top: asset.isVideo ? 24.0 : 6.0), child: Padding(
child: const _TileOverlayIcon(Icons.burst_mode_rounded), padding: EdgeInsets.only(
right: 10.0,
top: 24.0,
),
child: _TileOverlayIcon(Icons.burst_mode_rounded),
),
)
: const Align(
alignment: Alignment.topRight,
child: Padding(
padding: EdgeInsets.only(
right: 10.0,
top: 6.0,
),
child: _TileOverlayIcon(Icons.burst_mode_rounded),
), ),
), ),
if (asset != null && asset.isVideo) if (asset != null && asset.isVideo)