chore: Calc blurhash in other thread

This commit is contained in:
Krille 2024-03-21 10:19:14 +01:00
parent a518f8a019
commit 989c6146ce
No known key found for this signature in database
GPG key ID: E067ECD60F1A0652
2 changed files with 54 additions and 11 deletions

View file

@ -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<BlurHash> {
Uint8List? _data;
Future<Uint8List> 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<Uint8List> 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<Uint8List?> _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<Uint8List>(
future: getBlurhashData(),
return FutureBuilder<Uint8List?>(
future: _computeBlurhashData(),
builder: (context, snapshot) {
final data = snapshot.data;
if (data == null) {
@ -55,3 +67,27 @@ class _BlurHashState extends State<BlurHash> {
);
}
}
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<String, dynamic> json) => BlurhashData(
hsh: json['hsh'],
w: json['w'],
h: json['h'],
);
Map<String, dynamic> toJson() => {
'hsh': hsh,
'w': w,
'h': h,
};
}

View file

@ -130,8 +130,13 @@ class _MxcImageState extends State<MxcImage> {
}
}
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<MxcImage> {
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<MxcImage> {
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;