chore: Calc blurhash in other thread

pull/953/head
Krille 2 years ago
parent a518f8a019
commit 989c6146ce
No known key found for this signature in database
GPG Key ID: E067ECD60F1A0652

@ -1,5 +1,4 @@
import 'dart:typed_data'; import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:blurhash_dart/blurhash_dart.dart' as b; import 'package:blurhash_dart/blurhash_dart.dart' as b;
@ -26,16 +25,29 @@ class BlurHash extends StatefulWidget {
class _BlurHashState extends State<BlurHash> { class _BlurHashState extends State<BlurHash> {
Uint8List? _data; Uint8List? _data;
Future<Uint8List> getBlurhashData() async { static Future<Uint8List> getBlurhashData(
final blurhash = b.BlurHash.decode(widget.blurhash); BlurhashData blurhashData,
final img = blurhash.toImage(widget.width.round(), widget.height.round()); ) async {
return _data ??= Uint8List.fromList(image.encodePng(img)); 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 @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return FutureBuilder<Uint8List>( return FutureBuilder<Uint8List?>(
future: getBlurhashData(), future: _computeBlurhashData(),
builder: (context, snapshot) { builder: (context, snapshot) {
final data = snapshot.data; final data = snapshot.data;
if (data == null) { 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,
};
}

@ -130,8 +130,13 @@ class _MxcImageState extends State<MxcImage> {
} }
} }
bool _hasDataFromBeginning = false;
void _tryLoad(_) async { void _tryLoad(_) async {
if (_imageData != null) return; if (_imageData != null) {
_hasDataFromBeginning = true;
return;
}
try { try {
await _load(); await _load();
} catch (_) { } catch (_) {
@ -160,7 +165,7 @@ class _MxcImageState extends State<MxcImage> {
return Stack( return Stack(
children: [ children: [
if (!hasData) placeholder(context), if (!_hasDataFromBeginning) placeholder(context),
AnimatedOpacity( AnimatedOpacity(
opacity: hasData ? 1 : 0, opacity: hasData ? 1 : 0,
duration: FluffyThemes.animationDuration, duration: FluffyThemes.animationDuration,
@ -171,7 +176,9 @@ class _MxcImageState extends State<MxcImage> {
width: widget.width, width: widget.width,
height: widget.height, height: widget.height,
fit: widget.fit, fit: widget.fit,
filterQuality: FilterQuality.medium, filterQuality: widget.isThumbnail
? FilterQuality.low
: FilterQuality.medium,
errorBuilder: (context, __, ___) { errorBuilder: (context, __, ___) {
_isCached = false; _isCached = false;
_imageData = null; _imageData = null;

Loading…
Cancel
Save