From 70d2a81fee552a4ef0a499e1c6fab9bc808720c4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20Ku=C3=9Fowski?= Date: Wed, 24 Dec 2025 13:09:57 +0100 Subject: [PATCH] refactor: Remove native imaging and enable web worker --- .gitignore | 1 + lib/utils/client_manager.dart | 9 ++- lib/utils/custom_image_resizer.dart | 101 ---------------------------- scripts/prepare-web.sh | 9 +-- web/native_executor.dart | 3 + 5 files changed, 10 insertions(+), 113 deletions(-) delete mode 100644 lib/utils/custom_image_resizer.dart create mode 100644 web/native_executor.dart diff --git a/.gitignore b/.gitignore index 7ed5bfe78..ba0d23ffa 100644 --- a/.gitignore +++ b/.gitignore @@ -71,3 +71,4 @@ android/app/google-services.json web/pkg/package.json web/pkg/vodozemac_bindings_dart_bg.wasm web/pkg/vodozemac_bindings_dart.js +web/native_executor.js* diff --git a/lib/utils/client_manager.dart b/lib/utils/client_manager.dart index 64d5b23d3..c318ceb11 100644 --- a/lib/utils/client_manager.dart +++ b/lib/utils/client_manager.dart @@ -14,7 +14,6 @@ import 'package:universal_html/html.dart' as html; import 'package:fluffychat/config/setting_keys.dart'; import 'package:fluffychat/l10n/l10n.dart'; import 'package:fluffychat/utils/custom_http_client.dart'; -import 'package:fluffychat/utils/custom_image_resizer.dart'; import 'package:fluffychat/utils/init_with_restore.dart'; import 'package:fluffychat/utils/platform_infos.dart'; import 'matrix_sdk_extensions/flutter_matrix_dart_sdk_database/builder.dart'; @@ -95,7 +94,10 @@ abstract class ClientManager { } static NativeImplementations get nativeImplementations => kIsWeb - ? const NativeImplementationsDummy() + ? NativeImplementationsWebWorker( + Uri.parse('native_executor.js'), + timeout: const Duration(minutes: 1), + ) : NativeImplementationsIsolate( compute, vodozemacInit: () => vod.init(wasmPath: './assets/assets/vodozemac/'), @@ -127,9 +129,6 @@ abstract class ClientManager { AuthenticationTypes.sso, }, nativeImplementations: nativeImplementations, - customImageResizer: PlatformInfos.isMobile || kIsWeb - ? customImageResizer - : null, defaultNetworkRequestTimeout: const Duration(minutes: 30), enableDehydratedDevices: true, shareKeysWith: diff --git a/lib/utils/custom_image_resizer.dart b/lib/utils/custom_image_resizer.dart deleted file mode 100644 index b25ecbbff..000000000 --- a/lib/utils/custom_image_resizer.dart +++ /dev/null @@ -1,101 +0,0 @@ -import 'dart:ui'; - -import 'package:flutter/foundation.dart'; -import 'package:flutter/painting.dart'; - -import 'package:matrix/matrix.dart'; -import 'package:native_imaging/native_imaging.dart' as native; - -(int, int) _scaleToBox(int width, int height, {required int boxSize}) { - final fit = applyBoxFit( - BoxFit.scaleDown, - Size(width.toDouble(), height.toDouble()), - Size(boxSize.toDouble(), boxSize.toDouble()), - ).destination; - return (fit.width.round(), fit.height.round()); -} - -Future customImageResizer( - MatrixImageFileResizeArguments arguments, -) async { - await native.init(); - - var imageBytes = arguments.bytes; - String? blurhash; - - var originalWidth = 0; - var originalHeight = 0; - var width = 0; - var height = 0; - - try { - // for the other platforms - final dartCodec = await instantiateImageCodec(arguments.bytes); - final frameCount = dartCodec.frameCount; - final dartFrame = await dartCodec.getNextFrame(); - final rgbaData = await dartFrame.image.toByteData(); - if (rgbaData == null) { - return null; - } - final rgba = Uint8List.view( - rgbaData.buffer, - rgbaData.offsetInBytes, - rgbaData.lengthInBytes, - ); - - width = originalWidth = dartFrame.image.width; - height = originalHeight = dartFrame.image.height; - - var nativeImg = native.Image.fromRGBA(width, height, rgba); - - dartFrame.image.dispose(); - dartCodec.dispose(); - - if (arguments.calcBlurhash) { - // scale down image for blurhashing to speed it up - final (blurW, blurH) = _scaleToBox(width, height, boxSize: 100); - final blurhashImg = nativeImg.resample( - blurW, - blurH, - // nearest is unsupported... - native.Transform.bilinear, - ); - - blurhash = blurhashImg.toBlurhash(3, 3); - - blurhashImg.free(); - } - - if (frameCount > 1) { - // Don't scale down animated images, since those would lose frames. - nativeImg.free(); - } else { - final max = arguments.maxDimension; - if (width > max || height > max) { - (width, height) = _scaleToBox(width, height, boxSize: max); - - final scaledImg = nativeImg.resample( - width, - height, - native.Transform.lanczos, - ); - nativeImg.free(); - nativeImg = scaledImg; - } - - imageBytes = await nativeImg.toJpeg(75); - nativeImg.free(); - } - } catch (e, s) { - Logs().e("Could not generate preview", e, s); - } - - return MatrixImageFileResizedResponse( - bytes: imageBytes, - width: width, - height: height, - originalWidth: originalWidth, - originalHeight: originalHeight, - blurhash: blurhash, - ); -} diff --git a/scripts/prepare-web.sh b/scripts/prepare-web.sh index 6ffb59f6e..085274204 100755 --- a/scripts/prepare-web.sh +++ b/scripts/prepare-web.sh @@ -11,10 +11,5 @@ rm -f ./assets/vodozemac/vodozemac_bindings_dart* mv .vodozemac/dart/web/pkg/vodozemac_bindings_dart* ./assets/vodozemac/ rm -rf .vodozemac -# Add native imaging: -cd web/ -curl -L 'https://github.com/famedly/dart_native_imaging/releases/download/v0.2.1/native_imaging.zip' > native_imaging.zip # make sure to sync version with pubspec.yaml -unzip native_imaging.zip -mv js/* . -rmdir js -rm native_imaging.zip \ No newline at end of file +flutter pub get +dart compile js ./web/native_executor.dart -o ./web/native_executor.js -m \ No newline at end of file diff --git a/web/native_executor.dart b/web/native_executor.dart new file mode 100644 index 000000000..888af44a9 --- /dev/null +++ b/web/native_executor.dart @@ -0,0 +1,3 @@ +import 'package:matrix/matrix.dart'; + +void main() => startWebWorker();