diff --git a/packages/flutter_chat/lib/src/flutter_chat_userstory.dart b/packages/flutter_chat/lib/src/flutter_chat_userstory.dart index e5de04d..2e00c9d 100644 --- a/packages/flutter_chat/lib/src/flutter_chat_userstory.dart +++ b/packages/flutter_chat/lib/src/flutter_chat_userstory.dart @@ -163,12 +163,13 @@ List getChatStoryRoutes( GoRoute( path: ChatUserStoryRoutes.newGroupChatScreen, pageBuilder: (context, state) { - var newChatScreen = NewGroupChatScreen( + var newGroupChatScreen = NewGroupChatScreen( options: configuration.chatOptionsBuilder(context), translations: configuration.translations, service: configuration.chatService, - onPressGroupChatOverview: (user) async => context.push( + onPressGroupChatOverview: (users) async => context.push( ChatUserStoryRoutes.newGroupChatOverviewScreen, + extra: users, ), ); return buildScreenWithoutTransition( @@ -176,10 +177,51 @@ List getChatStoryRoutes( state: state, child: configuration.chatPageBuilder?.call( context, - newChatScreen, + newGroupChatScreen, ) ?? Scaffold( - body: newChatScreen, + body: newGroupChatScreen, + ), + ); + }, + ), + GoRoute( + path: ChatUserStoryRoutes.newGroupChatOverviewScreen, + pageBuilder: (context, state) { + var users = state.extra! as List; + var newGroupChatOverviewScreen = NewGroupChatOverviewScreen( + options: configuration.chatOptionsBuilder(context), + translations: configuration.translations, + service: configuration.chatService, + users: users, + onPressCompleteGroupChatCreation: (users, groupChatName) async { + configuration.onPressCompleteGroupChatCreation + ?.call(users, groupChatName); + var chat = await configuration.chatService.chatOverviewService + .storeChatIfNot( + GroupChatModel( + canBeDeleted: true, + title: groupChatName, + imageUrl: 'https://picsum.photos/200/300', + users: users, + ), + ); + if (context.mounted) { + await context.push( + ChatUserStoryRoutes.chatDetailViewPath(chat.id ?? ''), + ); + } + }, + ); + return buildScreenWithoutTransition( + context: context, + state: state, + child: configuration.chatPageBuilder?.call( + context, + newGroupChatOverviewScreen, + ) ?? + Scaffold( + body: newGroupChatOverviewScreen, ), ); }, diff --git a/packages/flutter_chat_firebase/lib/service/firebase_chat_overview_service.dart b/packages/flutter_chat_firebase/lib/service/firebase_chat_overview_service.dart index 5f0abca..a00fdeb 100644 --- a/packages/flutter_chat_firebase/lib/service/firebase_chat_overview_service.dart +++ b/packages/flutter_chat_firebase/lib/service/firebase_chat_overview_service.dart @@ -144,22 +144,25 @@ class FirebaseChatOverviewService implements ChatOverviewService { imageUrl: chat.imageUrl ?? '', unreadMessages: unread, users: users, - lastMessage: chat.lastMessage != null && - chat.lastMessage!.imageUrl == null - ? ChatTextMessageModel( - sender: otherUser!, - text: chat.lastMessage!.text!, - timestamp: DateTime.fromMillisecondsSinceEpoch( - chat.lastMessage!.timestamp.millisecondsSinceEpoch, - ), - ) - : ChatImageMessageModel( - sender: otherUser!, - imageUrl: chat.lastMessage!.imageUrl!, - timestamp: DateTime.fromMillisecondsSinceEpoch( - chat.lastMessage!.timestamp.millisecondsSinceEpoch, - ), - ), + lastMessage: chat.lastMessage != null + ? chat.lastMessage!.imageUrl == null + ? ChatTextMessageModel( + sender: otherUser!, + text: chat.lastMessage!.text!, + timestamp: DateTime.fromMillisecondsSinceEpoch( + chat.lastMessage!.timestamp + .millisecondsSinceEpoch, + ), + ) + : ChatImageMessageModel( + sender: otherUser!, + imageUrl: chat.lastMessage!.imageUrl!, + timestamp: DateTime.fromMillisecondsSinceEpoch( + chat.lastMessage!.timestamp + .millisecondsSinceEpoch, + ), + ) + : null, canBeDeleted: chat.canBeDeleted, lastUsed: chat.lastUsed == null ? null @@ -381,7 +384,7 @@ class FirebaseChatOverviewService implements ChatOverviewService { ]; var reference = await _db - .collection(_options.chatsCollectionName) + .collection(_options.chatsMetaDataCollectionName) .withConverter( fromFirestore: (snapshot, _) => FirebaseChatDocument.fromJson(snapshot.data()!, snapshot.id), @@ -390,6 +393,8 @@ class FirebaseChatOverviewService implements ChatOverviewService { .add( FirebaseChatDocument( personal: false, + title: chat.title, + imageUrl: chat.imageUrl, canBeDeleted: chat.canBeDeleted, users: userIds, lastUsed: Timestamp.now(), @@ -404,7 +409,6 @@ class FirebaseChatOverviewService implements ChatOverviewService { .doc(reference.id) .set({'users': userIds}, SetOptions(merge: true)); } - chat.id = reference.id; } else { throw Exception('Chat type not supported for firebase'); diff --git a/packages/flutter_chat_interface/lib/src/model/chat_user.dart b/packages/flutter_chat_interface/lib/src/model/chat_user.dart index e97226a..814c930 100644 --- a/packages/flutter_chat_interface/lib/src/model/chat_user.dart +++ b/packages/flutter_chat_interface/lib/src/model/chat_user.dart @@ -3,6 +3,8 @@ // // SPDX-License-Identifier: BSD-3-Clause +import 'package:flutter/material.dart'; + abstract class ChatUserModelInterface { String? get id; String? get firstName; @@ -14,6 +16,7 @@ abstract class ChatUserModelInterface { /// A concrete implementation of [ChatUserModelInterface] /// representing a chat user. +@immutable class ChatUserModel implements ChatUserModelInterface { /// Constructs a [ChatUserModel] instance. /// @@ -24,7 +27,8 @@ class ChatUserModel implements ChatUserModelInterface { /// [lastName]: The last name of the user. /// /// [imageUrl]: The URL of the user's image. - ChatUserModel({ + /// + const ChatUserModel({ this.id, this.firstName, this.lastName, @@ -57,4 +61,12 @@ class ChatUserModel implements ChatUserModelInterface { return fullName == '' ? null : fullName; } + + @override + bool operator ==(Object other) => + identical(this, other) || other is ChatUserModel && id == other.id; + + @override + int get hashCode => + id.hashCode ^ firstName.hashCode ^ lastName.hashCode ^ imageUrl.hashCode; } diff --git a/packages/flutter_chat_local/lib/service/local_chat_detail_service.dart b/packages/flutter_chat_local/lib/service/local_chat_detail_service.dart index edf2006..7341235 100644 --- a/packages/flutter_chat_local/lib/service/local_chat_detail_service.dart +++ b/packages/flutter_chat_local/lib/service/local_chat_detail_service.dart @@ -29,13 +29,13 @@ class LocalChatDetailService with ChangeNotifier implements ChatDetailService { int pageSize, String chatId, ) async { - await chatOverviewService.getChatById(chatId).then((value) { - _cumulativeMessages.clear(); + var value = await chatOverviewService.getChatById(chatId); + _cumulativeMessages.clear(); + if (value.messages != null) { _cumulativeMessages.addAll(value.messages!); - _controller.add(_cumulativeMessages); - }); + } + _controller.add(_cumulativeMessages); notifyListeners(); - return Future.value(); } @override @@ -48,9 +48,11 @@ class LocalChatDetailService with ChangeNotifier implements ChatDetailService { _controller.onListen = () async { _subscription = chatOverviewService.getChatById(chatId).asStream().listen((event) { - _cumulativeMessages.clear(); - _cumulativeMessages.addAll(event.messages!); - _controller.add(_cumulativeMessages); + if (event.messages != null) { + _cumulativeMessages.clear(); + _cumulativeMessages.addAll(event.messages!); + _controller.add(_cumulativeMessages); + } }); }; diff --git a/packages/flutter_chat_view/lib/src/screens/new_group_chat_screen.dart b/packages/flutter_chat_view/lib/src/screens/new_group_chat_screen.dart index a4a5251..42f609c 100644 --- a/packages/flutter_chat_view/lib/src/screens/new_group_chat_screen.dart +++ b/packages/flutter_chat_view/lib/src/screens/new_group_chat_screen.dart @@ -150,12 +150,13 @@ class _NewGroupChatScreenState extends State { itemCount: filteredUsers.length, itemBuilder: (context, index) { var user = filteredUsers[index]; - var isSelected = selectedUserList.contains(user); + var isSelected = + selectedUserList.any((selectedUser) => selectedUser == user); return InkWell( onTap: () { setState(() { - if (isSelected) { + if (selectedUserList.contains(user)) { selectedUserList.remove(user); } else { selectedUserList.add(user);