diff --git a/lib/di/global/get_it_initializer.dart b/lib/di/global/get_it_initializer.dart index cf9023606d..472573b620 100644 --- a/lib/di/global/get_it_initializer.dart +++ b/lib/di/global/get_it_initializer.dart @@ -63,7 +63,7 @@ class GetItInitializer { } void bindingQueue() { - getIt.registerSingleton(Queue()); + getIt.registerFactory(() => Queue()); } void bindingAPI() { diff --git a/lib/domain/usecase/send_file_on_web_interactor.dart b/lib/domain/usecase/send_file_on_web_interactor.dart index c03580bbf2..64cef09351 100644 --- a/lib/domain/usecase/send_file_on_web_interactor.dart +++ b/lib/domain/usecase/send_file_on_web_interactor.dart @@ -13,25 +13,21 @@ class SendFileOnWebInteractor { Map? extraContent, }) async { try { - final fileInfos = filePickerResult.files + final matrixFiles = filePickerResult.files .map( (xFile) => MatrixFile( bytes: xFile.bytes, name: xFile.name, + filePath: '', ), ) .toList(); - final txIdMapToImageInfo = - await room.sendPlaceholdersWebForImages(entities: fileInfos); - - for (final txId in txIdMapToImageInfo.value1.keys) { + for (final matrixFile in matrixFiles) { await room.sendFileOnWebEvent( - txIdMapToImageInfo.value1[txId]!, - fakeImageEvent: txIdMapToImageInfo.value2[txId], + matrixFile, txid: txId, ); - room.clearOlderImagesCacheInRoom(txId: txId); } } catch (error) { Logs().d("SendFileInteractor: execute(): $error"); diff --git a/lib/pages/chat/chat.dart b/lib/pages/chat/chat.dart index 5123f7892c..a5a84d638b 100644 --- a/lib/pages/chat/chat.dart +++ b/lib/pages/chat/chat.dart @@ -397,7 +397,7 @@ class ChatController extends State with ImagePickerMixin, SendFilesMixin { prefs.remove('draft_$roomId'); var parseCommands = true; - final commandMatch = RegExp(r'^\/(\w+)').firstMatch(sendController.text); + final commandMatch = RegExp(r'^/(\w+)').firstMatch(sendController.text); if (commandMatch != null && !room!.client.commands.keys.contains(commandMatch[1]!.toLowerCase())) { final l10n = L10n.of(context)!; @@ -1249,6 +1249,23 @@ class ChatController extends State with ImagePickerMixin, SendFilesMixin { editEvent = null; }); + void onSendFileClick() async { + if (PlatformInfos.isMobile) { + showImagesPickerBottomSheetAction( + room: room, + context: context, + onItemAction: (action) => onClickItemAction( + action: action, + room: room, + context: context, + ), + onSendTap: () => sendImages(room: room), + ); + } else { + sendFileOnWebAction(context, room: room); + } + } + @override Widget build(BuildContext context) { return ChatView(this, key: widget.key); diff --git a/lib/pages/chat/chat_input_row.dart b/lib/pages/chat/chat_input_row.dart index 128a9b4767..11e015edc2 100644 --- a/lib/pages/chat/chat_input_row.dart +++ b/lib/pages/chat/chat_input_row.dart @@ -84,19 +84,7 @@ class ChatInputRow extends StatelessWidget { tooltip: L10n.of(context)!.more, margin: const EdgeInsets.only(right: 4.0), icon: Icons.add_circle_outline, - onPressed: () async { - controller.showImagesPickerBottomSheetAction( - room: controller.room, - context: context, - onItemAction: (action) => controller.onClickItemAction( - action: action, - room: controller.room, - context: context, - ), - onSendTap: () => - controller.sendImages(room: controller.room), - ); - }, + onPressed: controller.onSendFileClick, ), if (controller.matrix!.isMultiAccount && controller.matrix!.hasComplexBundles && diff --git a/lib/pages/chat/events/message_content.dart b/lib/pages/chat/events/message_content.dart index a46025049d..3f4f219c3e 100644 --- a/lib/pages/chat/events/message_content.dart +++ b/lib/pages/chat/events/message_content.dart @@ -2,7 +2,7 @@ import 'package:fluffychat/pages/chat/chat.dart'; import 'package:fluffychat/config/app_config.dart'; import 'package:fluffychat/pages/bootstrap/bootstrap_dialog.dart'; import 'package:fluffychat/pages/chat/events/message_content_style.dart'; -import 'package:fluffychat/pages/chat/events/sending_image_widget.dart'; +import 'package:fluffychat/pages/chat/events/send_image_info_widget.dart'; import 'package:fluffychat/pages/chat/events/sending_video_widget.dart'; import 'package:fluffychat/utils/platform_infos.dart'; import 'package:fluffychat/utils/string_extension.dart'; @@ -131,16 +131,17 @@ class MessageContent extends StatelessWidget { child: Icon(Icons.error, color: Colors.red), ), ); - } - final matrixFile = event.getMatrixFile(); - if (matrixFile != null && - matrixFile.filePath != null && - matrixFile is MatrixImageFile) { - return SendingImageWidget( - matrixFile: matrixFile, - event: event, - onTapPreview: onTapPreview, - ); + } else if (event.status == EventStatus.sending) { + final matrixFile = event.getMatrixFile(); + if (matrixFile != null && + matrixFile.filePath != null && + matrixFile is MatrixImageFile) { + return SendImageInfoWidget( + matrixFile: matrixFile, + event: event, + onTapPreview: onTapPreview, + ); + } } return ImageBubble( event, diff --git a/lib/pages/chat/events/sending_image_widget.dart b/lib/pages/chat/events/send_image_info_widget.dart similarity index 96% rename from lib/pages/chat/events/sending_image_widget.dart rename to lib/pages/chat/events/send_image_info_widget.dart index bb305566f1..cd0f12aa26 100644 --- a/lib/pages/chat/events/sending_image_widget.dart +++ b/lib/pages/chat/events/send_image_info_widget.dart @@ -1,13 +1,12 @@ import 'dart:io'; - import 'package:fluffychat/pages/chat/events/message_content_style.dart'; import 'package:fluffychat/pages/image_viewer/image_viewer.dart'; import 'package:flutter/material.dart'; import 'package:linagora_design_flutter/colors/linagora_ref_colors.dart'; import 'package:matrix/matrix.dart' hide Visibility; -class SendingImageWidget extends StatelessWidget { - SendingImageWidget({ +class SendImageInfoWidget extends StatelessWidget { + SendImageInfoWidget({ super.key, required this.matrixFile, required this.event, diff --git a/lib/presentation/extensions/send_file_web_extension.dart b/lib/presentation/extensions/send_file_web_extension.dart index a9270a323e..642d0f3a4b 100644 --- a/lib/presentation/extensions/send_file_web_extension.dart +++ b/lib/presentation/extensions/send_file_web_extension.dart @@ -1,8 +1,3 @@ -import 'dart:collection'; - -import 'package:dartz/dartz.dart' hide id; -import 'package:fluffychat/di/global/get_it_initializer.dart'; -import 'package:fluffychat/presentation/extensions/send_file_extension.dart'; import 'package:matrix/matrix.dart'; extension SendFileWebExtension on Room { @@ -46,22 +41,26 @@ extension SendFileWebExtension on Room { } EncryptedFile? encryptedFile; + MatrixFile? uploadFile; if (encrypted && client.fileEncryptionEnabled) { fakeImageEvent.rooms!.join!.values.first.timeline!.events!.first .unsigned![fileSendingStatusKey] = FileSendingStatus.encrypting.name; await handleImageFakeSync(fakeImageEvent); encryptedFile = await file.encrypt(); + uploadFile = + MatrixFile.fromMimeType(bytes: encryptedFile!.data, name: 'crypt'); } Uri? uploadResp; fakeImageEvent.rooms!.join!.values.first.timeline!.events!.first .unsigned![fileSendingStatusKey] = FileSendingStatus.uploading.name; - while (uploadResp == null && file.bytes != null) { + while ( + uploadResp == null && uploadFile != null && uploadFile.bytes != null) { try { uploadResp = await client.uploadContent( - file.bytes!, - filename: file.name, - contentType: file.mimeType, + uploadFile.bytes!, + filename: uploadFile.name, + contentType: uploadFile.mimeType, ); } on MatrixException catch (e) { fakeImageEvent.rooms!.join!.values.first.timeline!.events!.first @@ -176,34 +175,4 @@ extension SendFileWebExtension on Room { await client.handleSync(fakeImageEvent, direction: direction); } } - - void clearOlderImagesCacheInRoom({String? txId}) { - final imageCacheQueue = getIt.get(); - // clear older image cache - while (imageCacheQueue.length >= maxImagesCacheInRoom) { - if (sendingFilePlaceholders.containsKey(txId)) { - sendingFilePlaceholders.remove(txId); - } - if (sendingFileThumbnails.containsKey(txId)) { - sendingFileThumbnails.remove(txId); - } - } - } - - Future< - Tuple2, - Map>> sendPlaceholdersWebForImages({ - required List entities, - }) async { - // ignore: prefer_const_constructors - final txIdMapToImageFile = Tuple2, - Map>({}, {}); - for (final entity in entities) { - final txid = client.generateUniqueTransactionId(); - final fakeImageEvent = await sendFakeImageEvent(entity, txid: txid); - txIdMapToImageFile.value1[txid] = entity; - txIdMapToImageFile.value2[txid] = fakeImageEvent; - } - return txIdMapToImageFile; - } } diff --git a/lib/presentation/mixins/send_files_mixin.dart b/lib/presentation/mixins/send_files_mixin.dart index 2ddc433e69..a83463292c 100644 --- a/lib/presentation/mixins/send_files_mixin.dart +++ b/lib/presentation/mixins/send_files_mixin.dart @@ -1,6 +1,7 @@ import 'package:file_picker/file_picker.dart'; import 'package:fluffychat/di/global/get_it_initializer.dart'; import 'package:fluffychat/domain/usecase/send_file_interactor.dart'; +import 'package:fluffychat/domain/usecase/send_file_on_web_interactor.dart'; import 'package:fluffychat/domain/usecase/send_image_interactor.dart'; import 'package:fluffychat/domain/usecase/send_images_interactor.dart'; import 'package:fluffychat/pages/chat/chat_actions.dart'; @@ -57,6 +58,20 @@ mixin SendFilesMixin on ImagePickerMixin { sendFileInteractor.execute(room: room!, filePickerResult: result!); } + void sendFileOnWebAction( + BuildContext context, { + Room? room, + }) async { + if (room == null) {} + final sendFileOnWebInteractor = getIt.get(); + final result = await FilePicker.platform.pickFiles( + withData: true, + ); + if (result == null && result?.files.isEmpty == true) return; + + sendFileOnWebInteractor.execute(room: room!, filePickerResult: result!); + } + void onClickItemAction({ required BuildContext context, Room? room,