diff --git a/packages/chat_repository_interface/lib/src/interfaces/chat_repostory_interface.dart b/packages/chat_repository_interface/lib/src/interfaces/chat_repostory_interface.dart index 2ee9ad1..becd6cb 100644 --- a/packages/chat_repository_interface/lib/src/interfaces/chat_repostory_interface.dart +++ b/packages/chat_repository_interface/lib/src/interfaces/chat_repostory_interface.dart @@ -73,6 +73,12 @@ abstract class ChatRepositoryInterface { required MessageModel firstMessage, }); + /// Function that provides the next message id + Future getNextMessageId({ + required String userId, + required String chatId, + }); + /// Send a message with the given parameters. /// [chatId] is the chat id. /// [senderId] is the sender id. diff --git a/packages/chat_repository_interface/lib/src/local/local_chat_repository.dart b/packages/chat_repository_interface/lib/src/local/local_chat_repository.dart index a0f45e7..1691f21 100644 --- a/packages/chat_repository_interface/lib/src/local/local_chat_repository.dart +++ b/packages/chat_repository_interface/lib/src/local/local_chat_repository.dart @@ -208,6 +208,13 @@ class LocalChatRepository implements ChatRepositoryInterface { return Stream.value(message); } + @override + Future getNextMessageId({ + required String userId, + required String chatId, + }) async => + "$chatId-$userId-${DateTime.now()}"; + @override Future sendMessage({ required String chatId, diff --git a/packages/chat_repository_interface/lib/src/services/chat_service.dart b/packages/chat_repository_interface/lib/src/services/chat_service.dart index 6d5d8ea..1e9dc18 100644 --- a/packages/chat_repository_interface/lib/src/services/chat_service.dart +++ b/packages/chat_repository_interface/lib/src/services/chat_service.dart @@ -25,9 +25,9 @@ class ChatService { PendingMessageRepositoryInterface? pendingMessageRepository, UserRepositoryInterface? userRepository, }) : chatRepository = chatRepository ?? LocalChatRepository(), + userRepository = userRepository ?? LocalUserRepository(), pendingMessageRepository = - pendingMessageRepository ?? LocalPendingMessageRepository(), - userRepository = userRepository ?? LocalUserRepository(); + pendingMessageRepository ?? LocalPendingMessageRepository(); /// The user ID of the person currently looking at the chat final String userId; @@ -200,12 +200,15 @@ class ChatService { Future sendMessage({ required String chatId, required String senderId, - required String messageId, + String? presetMessageId, String? text, String? messageType, String? imageUrl, Uint8List? imageData, }) async { + var messageId = presetMessageId ?? + await chatRepository.getNextMessageId(userId: userId, chatId: chatId); + await pendingMessageRepository.createMessage( chatId: chatId, senderId: senderId, @@ -239,6 +242,32 @@ class ChatService { ); } + /// Method for sending an image and a message at the same time. + Future sendImageMessage({ + required String chatId, + required String userId, + required Uint8List data, + }) async { + var messageId = await chatRepository.getNextMessageId( + userId: userId, + chatId: chatId, + ); + + var path = await uploadImage( + path: "chats/$messageId", + image: data, + chatId: chatId, + ); + + await sendMessage( + presetMessageId: messageId, + chatId: chatId, + senderId: userId, + imageUrl: path, + imageData: data, + ); + } + /// Delete the chat with the given parameters. /// [chatId] is the chat id. Future deleteChat({ diff --git a/packages/firebase_chat_repository/lib/src/firebase_chat_repository.dart b/packages/firebase_chat_repository/lib/src/firebase_chat_repository.dart index 0f639ac..6f50663 100644 --- a/packages/firebase_chat_repository/lib/src/firebase_chat_repository.dart +++ b/packages/firebase_chat_repository/lib/src/firebase_chat_repository.dart @@ -140,6 +140,13 @@ class FirebaseChatRepository implements ChatRepositoryInterface { } } + @override + Future getNextMessageId({ + required String userId, + required String chatId, + }) async => + "$chatId-$userId-${DateTime.now()}"; + @override Future sendMessage({ required String chatId, diff --git a/packages/flutter_chat/lib/src/config/chat_options.dart b/packages/flutter_chat/lib/src/config/chat_options.dart index 16c4f26..ae9c336 100644 --- a/packages/flutter_chat/lib/src/config/chat_options.dart +++ b/packages/flutter_chat/lib/src/config/chat_options.dart @@ -29,12 +29,19 @@ class ChatOptions { this.timeIndicatorOptions = const ChatTimeIndicatorOptions(), ChatRepositoryInterface? chatRepository, UserRepositoryInterface? userRepository, + PendingMessageRepositoryInterface? pendingMessagesRepository, }) : chatRepository = chatRepository ?? LocalChatRepository(), - userRepository = userRepository ?? LocalUserRepository(); + userRepository = userRepository ?? LocalUserRepository(), + pendingMessagesRepository = + pendingMessagesRepository ?? LocalPendingMessageRepository(); /// The implementation for communication with persistance layer for chats final ChatRepositoryInterface chatRepository; + /// The implementation for communication with persistance layer + /// for pending messages + final PendingMessageRepositoryInterface pendingMessagesRepository; + /// The implementation for communication with persistance layer for users final UserRepositoryInterface userRepository; diff --git a/packages/flutter_chat/lib/src/flutter_chat_entry_widget.dart b/packages/flutter_chat/lib/src/flutter_chat_entry_widget.dart index bcbd329..ac6eadd 100644 --- a/packages/flutter_chat/lib/src/flutter_chat_entry_widget.dart +++ b/packages/flutter_chat/lib/src/flutter_chat_entry_widget.dart @@ -83,6 +83,7 @@ class _FlutterChatEntryWidgetState extends State { userId: widget.userId, chatRepository: widget.options?.chatRepository, userRepository: widget.options?.userRepository, + pendingMessageRepository: widget.options?.pendingMessagesRepository, ); } diff --git a/packages/flutter_chat/lib/src/flutter_chat_navigator_userstories.dart b/packages/flutter_chat/lib/src/flutter_chat_navigator_userstories.dart index 18afb12..f5661f0 100644 --- a/packages/flutter_chat/lib/src/flutter_chat_navigator_userstories.dart +++ b/packages/flutter_chat/lib/src/flutter_chat_navigator_userstories.dart @@ -94,6 +94,7 @@ abstract class _BaseChatNavigatorUserstory extends HookWidget { userId: userId, chatRepository: options.chatRepository, userRepository: options.userRepository, + pendingMessageRepository: options.pendingMessagesRepository, ), [userId, options], ); diff --git a/packages/flutter_chat/lib/src/routes.dart b/packages/flutter_chat/lib/src/routes.dart index 8682754..b7591dd 100644 --- a/packages/flutter_chat/lib/src/routes.dart +++ b/packages/flutter_chat/lib/src/routes.dart @@ -50,28 +50,16 @@ MaterialPageRoute chatDetailRoute({ chatId: chatId, onExit: onExit, onReadChat: (chat) async => chatService.markAsRead(chatId: chat.id), - onUploadImage: (data) async { - var path = await chatService.uploadImage( - path: "chats/$chatId-$userId-${DateTime.now()}", - image: data, - chatId: chatId, - ); - await chatService.sendMessage( - messageId: "$chatId-$userId-${DateTime.now()}", - chatId: chatId, - senderId: userId, - imageUrl: path, - imageData: data, - ); - }, - onMessageSubmit: (text) async { - await chatService.sendMessage( - messageId: "$chatId-$userId-${DateTime.now()}", - chatId: chatId, - senderId: userId, - text: text, - ); - }, + onUploadImage: (data) async => chatService.sendImageMessage( + chatId: chatId, + userId: userId, + data: data, + ), + onMessageSubmit: (text) async => chatService.sendMessage( + chatId: chatId, + senderId: userId, + text: text, + ), onPressChatTitle: (chat) async { if (chat.isGroupChat) { await _routeToScreen(