From 989c6146ce12c471a6edc500e13d4daaa569bb1e Mon Sep 17 00:00:00 2001 From: Krille Date: Thu, 21 Mar 2024 10:19:14 +0100 Subject: [PATCH] chore: Calc blurhash in other thread --- lib/widgets/blur_hash.dart | 52 ++++++++++++++++++++++++++++++++------ lib/widgets/mxc_image.dart | 13 +++++++--- 2 files changed, 54 insertions(+), 11 deletions(-) diff --git a/lib/widgets/blur_hash.dart b/lib/widgets/blur_hash.dart index d0298a4e1..24ae45278 100644 --- a/lib/widgets/blur_hash.dart +++ b/lib/widgets/blur_hash.dart @@ -1,5 +1,4 @@ -import 'dart:typed_data'; - +import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:blurhash_dart/blurhash_dart.dart' as b; @@ -26,16 +25,29 @@ class BlurHash extends StatefulWidget { class _BlurHashState extends State { Uint8List? _data; - Future getBlurhashData() async { - final blurhash = b.BlurHash.decode(widget.blurhash); - final img = blurhash.toImage(widget.width.round(), widget.height.round()); - return _data ??= Uint8List.fromList(image.encodePng(img)); + static Future getBlurhashData( + BlurhashData blurhashData, + ) async { + final blurhash = b.BlurHash.decode(blurhashData.hsh); + final img = blurhash.toImage(blurhashData.w, blurhashData.h); + return Uint8List.fromList(image.encodePng(img)); + } + + Future _computeBlurhashData() async { + return _data ??= await compute( + getBlurhashData, + BlurhashData( + hsh: widget.blurhash, + w: widget.width.round(), + h: widget.height.round(), + ), + ); } @override Widget build(BuildContext context) { - return FutureBuilder( - future: getBlurhashData(), + return FutureBuilder( + future: _computeBlurhashData(), builder: (context, snapshot) { final data = snapshot.data; if (data == null) { @@ -55,3 +67,27 @@ class _BlurHashState extends State { ); } } + +class BlurhashData { + final String hsh; + final int w; + final int h; + + const BlurhashData({ + required this.hsh, + required this.w, + required this.h, + }); + + factory BlurhashData.fromJson(Map json) => BlurhashData( + hsh: json['hsh'], + w: json['w'], + h: json['h'], + ); + + Map toJson() => { + 'hsh': hsh, + 'w': w, + 'h': h, + }; +} diff --git a/lib/widgets/mxc_image.dart b/lib/widgets/mxc_image.dart index 1021328d1..55eb3e6ad 100644 --- a/lib/widgets/mxc_image.dart +++ b/lib/widgets/mxc_image.dart @@ -130,8 +130,13 @@ class _MxcImageState extends State { } } + bool _hasDataFromBeginning = false; + void _tryLoad(_) async { - if (_imageData != null) return; + if (_imageData != null) { + _hasDataFromBeginning = true; + return; + } try { await _load(); } catch (_) { @@ -160,7 +165,7 @@ class _MxcImageState extends State { return Stack( children: [ - if (!hasData) placeholder(context), + if (!_hasDataFromBeginning) placeholder(context), AnimatedOpacity( opacity: hasData ? 1 : 0, duration: FluffyThemes.animationDuration, @@ -171,7 +176,9 @@ class _MxcImageState extends State { width: widget.width, height: widget.height, fit: widget.fit, - filterQuality: FilterQuality.medium, + filterQuality: widget.isThumbnail + ? FilterQuality.low + : FilterQuality.medium, errorBuilder: (context, __, ___) { _isCached = false; _imageData = null;