diff --git a/lib/pages/add_story/add_story.dart b/lib/pages/add_story/add_story.dart index 037175af..90e3e588 100644 --- a/lib/pages/add_story/add_story.dart +++ b/lib/pages/add_story/add_story.dart @@ -13,7 +13,6 @@ import 'package:fluffychat/pages/add_story/add_story_view.dart'; import 'package:fluffychat/pages/add_story/invite_story_page.dart'; import 'package:fluffychat/utils/matrix_sdk_extensions.dart/matrix_file_extension.dart'; import 'package:fluffychat/utils/resize_image.dart'; -import 'package:fluffychat/utils/room_send_file_extension.dart'; import 'package:fluffychat/utils/string_color.dart'; import 'package:fluffychat/widgets/matrix.dart'; import '../../utils/matrix_sdk_extensions.dart/client_stories_extension.dart'; @@ -29,8 +28,8 @@ class AddStoryController extends State { final TextEditingController controller = TextEditingController(); late Color backgroundColor; late Color backgroundColorDark; - MatrixFile? image; - MatrixFile? video; + MatrixImageFile? image; + MatrixVideoFile? video; VideoPlayerController? videoPlayerController; @@ -49,8 +48,13 @@ class AddStoryController extends State { ); final fileName = picked.fileName; if (fileName == null) return; + final shrinked = await MatrixImageFile.shrink( + bytes: picked.toUint8List(), + name: fileName, + compute: Matrix.of(context).client.runInBackground, + ); setState(() { - image = MatrixFile(bytes: picked.toUint8List(), name: fileName); + image = shrinked; }); } @@ -60,8 +64,13 @@ class AddStoryController extends State { ); if (picked == null) return; final bytes = await picked.readAsBytes(); + final shrinked = await MatrixImageFile.shrink( + bytes: bytes, + name: picked.name, + compute: Matrix.of(context).client.runInBackground, + ); setState(() { - image = MatrixFile(bytes: bytes, name: picked.name); + image = shrinked; }); } @@ -73,7 +82,7 @@ class AddStoryController extends State { final bytes = await picked.readAsBytes(); setState(() { - video = MatrixFile(bytes: bytes, name: picked.name); + video = MatrixVideoFile(bytes: bytes, name: picked.name); videoPlayerController = VideoPlayerController.file(File(picked.path)) ..setLooping(true); }); @@ -109,16 +118,17 @@ class AddStoryController extends State { var video = this.video?.detectFileType; if (video != null) { video = await video.resizeVideo(); - await storiesRoom.sendFileEventWithThumbnail( + final thumbnail = await video.getVideoThumbnail(); + await storiesRoom.sendFileEvent( video, extraContent: {'body': controller.text}, + thumbnail: thumbnail, ); return; } - var image = this.image?.detectFileType; + final image = this.image; if (image != null) { - image = await image.resizeImage(); - await storiesRoom.sendFileEventWithThumbnail( + await storiesRoom.sendFileEvent( image, extraContent: {'body': controller.text}, ); @@ -142,9 +152,10 @@ class AddStoryController extends State { final shareContent = Matrix.of(context).shareContent; // ignore: unnecessary_null_comparison if (shareContent != null) { - image = shareContent.tryGet('file'); + final shareFile = shareContent.tryGet('file')?.detectFileType; + controller.text = shareContent.tryGet('body') ?? ''; - if (shareContent.tryGet('msgtype') == MessageTypes.Image) { + if (shareFile is MatrixImageFile) { Event( content: shareContent, type: EventTypes.Message, @@ -154,10 +165,10 @@ class AddStoryController extends State { originServerTs: DateTime.now(), ).downloadAndDecryptAttachment().then((file) { setState(() { - image = file; + image = shareFile; }); }); - } else if (shareContent.tryGet('msgtype') == MessageTypes.Video) { + } else if (shareFile is MatrixVideoFile) { Event( content: shareContent, type: EventTypes.Message, @@ -167,7 +178,7 @@ class AddStoryController extends State { originServerTs: DateTime.now(), ).downloadAndDecryptAttachment().then((file) { setState(() { - video = file; + video = shareFile; }); }); } diff --git a/lib/pages/chat/send_file_dialog.dart b/lib/pages/chat/send_file_dialog.dart index ae7e403f..aadcb117 100644 --- a/lib/pages/chat/send_file_dialog.dart +++ b/lib/pages/chat/send_file_dialog.dart @@ -6,7 +6,6 @@ import 'package:matrix/matrix.dart'; import '../../utils/matrix_sdk_extensions.dart/matrix_file_extension.dart'; import '../../utils/resize_image.dart'; -import '../../utils/room_send_file_extension.dart'; class SendFileDialog extends StatefulWidget { final Room room; @@ -31,15 +30,21 @@ class _SendFileDialogState extends State { Future _send() async { var file = widget.file; + MatrixImageFile? thumbnail; if (file is MatrixImageFile && !origImage && file.bytes.length > minSizeToCompress) { - file = await file.resizeImage(); + file = await MatrixImageFile.shrink( + bytes: file.bytes, + name: file.name, + compute: widget.room.client.runInBackground, + ); } if (file is MatrixVideoFile && file.bytes.length > minSizeToCompress) { file = await file.resizeVideo(); + thumbnail = await file.getVideoThumbnail(); } - await widget.room.sendFileEventWithThumbnail(file); + await widget.room.sendFileEvent(file, thumbnail: thumbnail); } @override diff --git a/lib/pages/settings_emotes/settings_emotes.dart b/lib/pages/settings_emotes/settings_emotes.dart index c96df15a..276cb054 100644 --- a/lib/pages/settings_emotes/settings_emotes.dart +++ b/lib/pages/settings_emotes/settings_emotes.dart @@ -7,7 +7,6 @@ import 'package:future_loading_dialog/future_loading_dialog.dart'; import 'package:matrix/matrix.dart'; import 'package:vrouter/vrouter.dart'; -import '../../utils/resize_image.dart'; import '../../widgets/matrix.dart'; import 'settings_emotes_view.dart'; @@ -206,14 +205,19 @@ class EmotesSettingsController extends State { name: result.fileName!, ); try { - file = await file.resizeImage(calcBlurhash: false); + file = (await file.generateThumbnail( + compute: Matrix.of(context).client.runInBackground, + ))!; } catch (_) { // do nothing } final uploadResp = await showFutureLoadingDialog( context: context, - future: () => Matrix.of(context).client.uploadContent(file.bytes, - filename: file.name, contentType: file.mimeType), + future: () => Matrix.of(context).client.uploadContent( + file.bytes, + filename: file.name, + contentType: file.mimeType, + ), ); if (uploadResp.error == null) { setState(() { diff --git a/lib/utils/resize_image.dart b/lib/utils/resize_image.dart index 99dca101..e8e9de58 100644 --- a/lib/utils/resize_image.dart +++ b/lib/utils/resize_image.dart @@ -1,9 +1,6 @@ import 'dart:io'; -import 'dart:math' as math; import 'dart:typed_data'; -import 'package:flutter/foundation.dart'; - import 'package:blurhash_dart/blurhash_dart.dart'; import 'package:image/image.dart'; import 'package:matrix/matrix.dart'; @@ -50,74 +47,15 @@ extension ResizeImage on MatrixFile { return MatrixImageFile( bytes: bytes, name: name, - ).resizeImage(); + ); } catch (e, s) { SentryController.captureException(e, s); } return null; } - - Future resizeImage({ - bool calcBlurhash = true, - int max = ResizeImage.max, - int quality = ResizeImage.quality, - }) async { - final bytes = mimeType == 'image/gif' - ? this.bytes - : await compute<_ResizeBytesConfig, Uint8List>( - resizeBytes, - _ResizeBytesConfig( - bytes: this.bytes, - mimeType: mimeType, - max: max, - quality: quality, - )); - final blurhash = calcBlurhash - ? await compute(createBlurHash, bytes) - : null; - return MatrixImageFile( - bytes: bytes, - name: '${name.split('.').first}_thumbnail_$max.jpg', - blurhash: blurhash?.hash, - ); - } } Future createBlurHash(Uint8List file) async { final image = decodeImage(file)!; return BlurHash.encode(image, numCompX: 4, numCompY: 3); } - -Future resizeBytes(_ResizeBytesConfig config) async { - var image = decodeImage(config.bytes)!; - - // Is file already smaller than max? Then just return. - if (math.max(image.width, image.height) > config.max) { - // Use the larger side to resize. - final useWidth = image.width >= image.height; - image = useWidth - ? copyResize(image, width: config.max) - : copyResize(image, height: config.max); - } - - const pngMimeType = 'image/png'; - final encoded = config.mimeType.toLowerCase() == pngMimeType - ? encodePng(image) - : encodeJpg(image, quality: config.quality); - - return Uint8List.fromList(encoded); -} - -class _ResizeBytesConfig { - final Uint8List bytes; - final int max; - final int quality; - final String mimeType; - - const _ResizeBytesConfig({ - required this.bytes, - this.max = ResizeImage.max, - this.quality = ResizeImage.quality, - required this.mimeType, - }); -} diff --git a/lib/utils/room_send_file_extension.dart b/lib/utils/room_send_file_extension.dart deleted file mode 100644 index 1ae7e917..00000000 --- a/lib/utils/room_send_file_extension.dart +++ /dev/null @@ -1,35 +0,0 @@ -import 'package:matrix/matrix.dart'; - -import 'resize_image.dart'; - -extension RoomSendFileExtension on Room { - Future sendFileEventWithThumbnail( - MatrixFile file, { - String? txid, - Event? inReplyTo, - String? editEventId, - bool? waitUntilSent, - Map? extraContent, - }) async { - MatrixImageFile? thumbnail; - if (file is MatrixImageFile) { - thumbnail = await file.resizeImage(); - - if (thumbnail.size > file.size ~/ 2) { - thumbnail = null; - } - } else if (file is MatrixVideoFile) { - thumbnail = await file.getVideoThumbnail(); - } - - return sendFileEvent( - file, - txid: txid, - inReplyTo: inReplyTo, - editEventId: editEventId, - waitUntilSent: waitUntilSent ?? false, - thumbnail: thumbnail, - extraContent: extraContent, - ); - } -} diff --git a/pubspec.lock b/pubspec.lock index 1463c5af..60da74a4 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -486,7 +486,7 @@ packages: name: flutter_native_splash url: "https://pub.dartlang.org" source: hosted - version: "1.3.3" + version: "2.0.1+1" flutter_olm: dependency: "direct main" description: @@ -818,7 +818,7 @@ packages: name: matrix url: "https://pub.dartlang.org" source: hosted - version: "0.7.3" + version: "0.8.0" matrix_api_lite: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index f8fc568d..b2d5fb69 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -50,7 +50,7 @@ dependencies: intl: any localstorage: ^4.0.0+1 lottie: ^1.2.1 - matrix: ^0.7.3 + matrix: ^0.8.0 matrix_link_text: ^1.0.2 open_noti_settings: ^0.4.0 package_info_plus: ^1.2.1 @@ -82,7 +82,7 @@ dependencies: dev_dependencies: dart_code_metrics: ^4.2.0-dev.3 flutter_lints: ^1.0.4 - flutter_native_splash: ^1.2.4 + flutter_native_splash: ^2.0.1+1 flutter_test: sdk: flutter import_sorter: ^4.6.0