Skip to content

Commit

Permalink
TW-688 Web avoid frezze when uploading file
Browse files Browse the repository at this point in the history
  • Loading branch information
drminh2807 committed Sep 27, 2023
1 parent 58a0938 commit 7465cfa
Show file tree
Hide file tree
Showing 6 changed files with 81 additions and 14 deletions.
49 changes: 36 additions & 13 deletions lib/presentation/extensions/send_file_web_extension.dart
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
import 'dart:typed_data';
import 'package:blurhash_dart/blurhash_dart.dart';
import 'package:fluffychat/config/app_config.dart';
import 'package:fluffychat/utils/extension/web_url_creation_extension.dart';
import 'package:fluffychat/utils/js_window/non_js_window.dart'
if (dart.library.js) 'package:fluffychat/utils/js_window/js_window.dart';
import 'package:fluffychat/utils/js_window/universal_image_bitmap.dart';
import 'package:flutter_image_compress/flutter_image_compress.dart';
import 'package:matrix/matrix.dart';
import 'package:image/image.dart';
Expand All @@ -19,20 +23,22 @@ extension SendFileWebExtension on Room {
Map<String, dynamic>? extraContent,
}) async {
txid ??= client.generateUniqueTransactionId();
Image? img;
UniversalImageBitmap? imageBitmap;
if (file.bytes != null && file is MatrixImageFile) {
img = decodeImage(file.bytes!);
final stopwatch = Stopwatch()..start();
imageBitmap = await convertUint8ListToBitmap(file.bytes!);
Logs().v('ImageBitmap creation took ${stopwatch.elapsed}');
file = MatrixImageFile(
name: file.name,
width: img?.width,
height: img?.height,
width: imageBitmap?.width,
height: imageBitmap?.height,
bytes: file.bytes,
);
}
sendingFilePlaceholders[txid] = MatrixImageFile(
name: file.name,
width: img?.width,
height: img?.height,
width: imageBitmap?.width,
height: imageBitmap?.height,
bytes: file.bytes,
);
fakeImageEvent ??= await sendFakeImageEvent(
Expand Down Expand Up @@ -262,19 +268,18 @@ extension SendFileWebExtension on Room {
try {
final result = await FlutterImageCompress.compressWithList(
originalFile.bytes!,
quality: 70,
quality: AppConfig.thumbnailQuality,
);

final image = decodeImage(result);
final blurHash = image != null ? BlurHash.encode(image) : null;
final blurHash = await _generateBlurHash(result);

return MatrixImageFile(
bytes: result,
name: originalFile.name,
mimeType: originalFile.mimeType,
width: originalFile.width,
height: originalFile.height,
blurhash: blurHash?.hash,
blurhash: blurHash,
);
} catch (e) {
Logs().e('Error while generating thumbnail', e);
Expand All @@ -296,16 +301,15 @@ extension SendFileWebExtension on Room {
imageFormat: ImageFormat.JPEG,
quality: AppConfig.thumbnailQuality,
);
final image = decodeImage(result);
final blurHash = image != null ? BlurHash.encode(image) : null;
final blurHash = await _generateBlurHash(result);

return MatrixImageFile(
bytes: result,
name: originalFile.name,
mimeType: originalFile.mimeType,
width: originalFile.width,
height: originalFile.height,
blurhash: blurHash?.hash,
blurhash: blurHash,
);
} catch (e) {
Logs().e('Error while generating thumbnail', e);
Expand Down Expand Up @@ -334,3 +338,22 @@ extension SendFileWebExtension on Room {
}
}
}

Future<String?> _generateBlurHash(Uint8List data) async {
try {
final stopwatch = Stopwatch()..start();
final result = await FlutterImageCompress.compressWithList(
data,
minHeight: AppConfig.blurHashSize,
minWidth: AppConfig.blurHashSize,
);
Logs().v('_generateBlurHash::compress ${stopwatch.elapsed}');
final image = decodeJpg(result);
final blurHash = image != null ? BlurHash.encode(image) : null;
Logs().v('_generateBlurHash::encode ${stopwatch.elapsed}');
return blurHash?.hash;
} catch (e) {
Logs().e('_generateBlurHash::error', e);
return null;
}
}
28 changes: 28 additions & 0 deletions lib/utils/js_window/js_window.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
@JS()
library window;

import 'package:fluffychat/utils/js_window/universal_image_bitmap.dart';
import 'package:universal_html/html.dart';
import 'dart:typed_data';

import 'package:js/js.dart';
import 'package:js/js_util.dart';

@JS()
@staticInterop
class JSWindow {}

extension JSWindowExtension on JSWindow {
external Function get createImageBitmap;
}

JSWindow get jsWindow => window as JSWindow;

Future<UniversalImageBitmap?> convertUint8ListToBitmap(Uint8List buffer) async {
final blob = Blob([buffer]);

final result = await jsWindow.createImageBitmap(blob);
final ImageBitmap bitmap = await promiseToFuture(result);

return UniversalImageBitmap(width: bitmap.width, height: bitmap.height);
}
7 changes: 7 additions & 0 deletions lib/utils/js_window/non_js_window.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import 'dart:typed_data';

import 'package:fluffychat/utils/js_window/universal_image_bitmap.dart';

Future<UniversalImageBitmap?> convertUint8ListToBitmap(Uint8List buffer) async {
return null;
}
8 changes: 8 additions & 0 deletions lib/utils/js_window/universal_image_bitmap.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
class UniversalImageBitmap {
int? height;
int? width;
UniversalImageBitmap({
this.height,
this.width,
});
}
2 changes: 1 addition & 1 deletion pubspec.lock
Original file line number Diff line number Diff line change
Expand Up @@ -1376,7 +1376,7 @@ packages:
source: hosted
version: "2.1.1"
js:
dependency: transitive
dependency: "direct main"
description:
name: js
sha256: f2c445dce49627136094980615a031419f7f3eb393237e4ecd97ac15dea343f3
Expand Down
1 change: 1 addition & 0 deletions pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,7 @@ dependencies:
media_kit_video: ^1.1.8
media_kit_libs_video: ^1.0.1
video_player: ^2.7.2
js: ^0.6.7
dev_dependencies:
build_runner: ^2.3.3
dart_code_metrics: ^5.7.3
Expand Down

0 comments on commit 7465cfa

Please sign in to comment.