diff --git a/.github/workflows/melos-ci.yml b/.github/workflows/melos-ci.yml index 9b5ed36..dab1703 100644 --- a/.github/workflows/melos-ci.yml +++ b/.github/workflows/melos-ci.yml @@ -11,4 +11,5 @@ jobs: secrets: inherit permissions: write-all with: - subfolder: '.' # add optional subfolder to run workflow in \ No newline at end of file + subfolder: '.' # add optional subfolder to run workflow in + flutter_version: 3.19.6 diff --git a/CHANGELOG.md b/CHANGELOG.md index b138f09..c808eeb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,14 @@ +## 2.0.0 + +- Add a serviceBuilder to the userstory configuration +- Add a translationsBuilder to the userstory configuration +- Change onPressUserProfile callback to use a ChatUserModel instead of a String +- Add a enableGroupChatCreation boolean to the userstory configuration to enable or disable group chat creation +- Change the ChatTranslations constructor to require all translations or use the ChatTranslations.empty constructor if you don't want to specify all translations +- Remove the Divider between the users on the new chat screen +- Add option to set a custom padding around the list of chats +- Fix nullpointer when firstWhere returns null because there is only 1 person in a groupchat + ## 1.4.3 - Added default styling. diff --git a/packages/flutter_chat/lib/src/flutter_chat_navigator_userstory.dart b/packages/flutter_chat/lib/src/flutter_chat_navigator_userstory.dart index 0ea5323..d65ed3f 100644 --- a/packages/flutter_chat/lib/src/flutter_chat_navigator_userstory.dart +++ b/packages/flutter_chat/lib/src/flutter_chat_navigator_userstory.dart @@ -4,7 +4,6 @@ import 'package:flutter/material.dart'; import 'package:flutter_chat/flutter_chat.dart'; -import 'package:uuid/uuid.dart'; /// Navigates to the chat user story screen. /// @@ -96,9 +95,9 @@ Widget _chatDetailScreenRoute( service: configuration.chatService, chatId: chatId, textfieldBottomPadding: configuration.textfieldBottomPadding ?? 0, - onPressUserProfile: (userId) async { + onPressUserProfile: (user) async { if (configuration.onPressUserProfile != null) { - return configuration.onPressUserProfile?.call(); + return configuration.onPressUserProfile?.call(context, user); } return Navigator.of(context).push( MaterialPageRoute( @@ -106,7 +105,7 @@ Widget _chatDetailScreenRoute( configuration, context, chatId, - userId, + user.id, ), ), ); @@ -172,7 +171,7 @@ Widget _chatProfileScreenRoute( userId: userId, onTapUser: (user) async { if (configuration.onPressUserProfile != null) { - return configuration.onPressUserProfile!.call(); + return configuration.onPressUserProfile!.call(context, user); } return Navigator.of(context).push( @@ -200,6 +199,7 @@ Widget _newChatScreenRoute( options: configuration.chatOptionsBuilder(context), translations: configuration.translations, service: configuration.chatService, + showGroupChatButton: configuration.enableGroupChatCreation, onPressCreateGroupChat: () async { configuration.onPressCreateGroupChat?.call(); if (context.mounted) { diff --git a/packages/flutter_chat/lib/src/flutter_chat_userstory.dart b/packages/flutter_chat/lib/src/flutter_chat_userstory.dart index 2e00c9d..9a1c267 100644 --- a/packages/flutter_chat/lib/src/flutter_chat_userstory.dart +++ b/packages/flutter_chat/lib/src/flutter_chat_userstory.dart @@ -14,9 +14,11 @@ List getChatStoryRoutes( GoRoute( path: ChatUserStoryRoutes.chatScreen, pageBuilder: (context, state) { + var service = configuration.chatServiceBuilder?.call(context) ?? + configuration.chatService; var chatScreen = ChatScreen( unreadMessageTextStyle: configuration.unreadMessageTextStyle, - service: configuration.chatService, + service: service, options: configuration.chatOptionsBuilder(context), onNoChats: () async => context.push(ChatUserStoryRoutes.newChatScreen), @@ -34,7 +36,8 @@ List getChatStoryRoutes( configuration.onDeleteChat?.call(context, chat) ?? configuration.chatService.chatOverviewService.deleteChat(chat), deleteChatDialog: configuration.deleteChatDialog, - translations: configuration.translations, + translations: configuration.translationsBuilder?.call(context) ?? + configuration.translations, ); return buildScreenWithoutTransition( context: context, @@ -53,6 +56,8 @@ List getChatStoryRoutes( path: ChatUserStoryRoutes.chatDetailScreen, pageBuilder: (context, state) { var chatId = state.pathParameters['id']; + var service = configuration.chatServiceBuilder?.call(context) ?? + configuration.chatService; var chatDetailScreen = ChatDetailScreen( chatTitleBuilder: configuration.chatTitleBuilder, usernameBuilder: configuration.usernameBuilder, @@ -60,16 +65,17 @@ List getChatStoryRoutes( iconDisabledColor: configuration.iconDisabledColor, pageSize: configuration.messagePageSize, options: configuration.chatOptionsBuilder(context), - translations: configuration.translations, - service: configuration.chatService, + translations: configuration.translationsBuilder?.call(context) ?? + configuration.translations, + service: service, chatId: chatId!, textfieldBottomPadding: configuration.textfieldBottomPadding ?? 0, - onPressUserProfile: (userId) async { + onPressUserProfile: (user) async { if (configuration.onPressUserProfile != null) { - return configuration.onPressUserProfile?.call(); + return configuration.onPressUserProfile?.call(context, user); } return context.push( - ChatUserStoryRoutes.chatProfileScreenPath(chatId, userId), + ChatUserStoryRoutes.chatProfileScreenPath(chatId, user.id), ); }, onMessageSubmit: (message) async { @@ -120,10 +126,14 @@ List getChatStoryRoutes( GoRoute( path: ChatUserStoryRoutes.newChatScreen, pageBuilder: (context, state) { + var service = configuration.chatServiceBuilder?.call(context) ?? + configuration.chatService; var newChatScreen = NewChatScreen( options: configuration.chatOptionsBuilder(context), - translations: configuration.translations, - service: configuration.chatService, + translations: configuration.translationsBuilder?.call(context) ?? + configuration.translations, + service: service, + showGroupChatButton: configuration.enableGroupChatCreation, onPressCreateChat: (user) async { configuration.onPressCreateChat?.call(user); if (configuration.onPressCreateChat != null) return; @@ -163,10 +173,13 @@ List getChatStoryRoutes( GoRoute( path: ChatUserStoryRoutes.newGroupChatScreen, pageBuilder: (context, state) { + var service = configuration.chatServiceBuilder?.call(context) ?? + configuration.chatService; var newGroupChatScreen = NewGroupChatScreen( options: configuration.chatOptionsBuilder(context), - translations: configuration.translations, - service: configuration.chatService, + translations: configuration.translationsBuilder?.call(context) ?? + configuration.translations, + service: service, onPressGroupChatOverview: (users) async => context.push( ChatUserStoryRoutes.newGroupChatOverviewScreen, extra: users, @@ -188,11 +201,14 @@ List getChatStoryRoutes( GoRoute( path: ChatUserStoryRoutes.newGroupChatOverviewScreen, pageBuilder: (context, state) { + var service = configuration.chatServiceBuilder?.call(context) ?? + configuration.chatService; var users = state.extra! as List; var newGroupChatOverviewScreen = NewGroupChatOverviewScreen( options: configuration.chatOptionsBuilder(context), - translations: configuration.translations, - service: configuration.chatService, + translations: configuration.translationsBuilder?.call(context) ?? + configuration.translations, + service: service, users: users, onPressCompleteGroupChatCreation: (users, groupChatName) async { configuration.onPressCompleteGroupChatCreation @@ -232,18 +248,21 @@ List getChatStoryRoutes( var chatId = state.pathParameters['id']; var userId = state.pathParameters['userId']; var id = userId == 'null' ? null : userId; + var service = configuration.chatServiceBuilder?.call(context) ?? + configuration.chatService; var profileScreen = ChatProfileScreen( - translations: configuration.translations, - chatService: configuration.chatService, + translations: configuration.translationsBuilder?.call(context) ?? + configuration.translations, + chatService: service, chatId: chatId!, userId: id, onTapUser: (user) async { if (configuration.onPressUserProfile != null) { - return configuration.onPressUserProfile!.call(); + return configuration.onPressUserProfile!.call(context, user); } return context.push( - ChatUserStoryRoutes.chatProfileScreenPath(chatId, user), + ChatUserStoryRoutes.chatProfileScreenPath(chatId, user.id), ); }, ); diff --git a/packages/flutter_chat/lib/src/models/chat_configuration.dart b/packages/flutter_chat/lib/src/models/chat_configuration.dart index cd47146..9e670d9 100644 --- a/packages/flutter_chat/lib/src/models/chat_configuration.dart +++ b/packages/flutter_chat/lib/src/models/chat_configuration.dart @@ -14,6 +14,7 @@ class ChatUserStoryConfiguration { const ChatUserStoryConfiguration({ required this.chatService, required this.chatOptionsBuilder, + this.chatServiceBuilder, this.onPressStartChat, this.onPressChat, this.onDeleteChat, @@ -27,7 +28,9 @@ class ChatUserStoryConfiguration { this.deleteChatDialog, this.disableDismissForPermanentChats = false, this.routeToNewChatIfEmpty = true, - this.translations = const ChatTranslations(), + this.enableGroupChatCreation = true, + this.translations = const ChatTranslations.empty(), + this.translationsBuilder, this.chatPageBuilder, this.onPressChatTitle, this.afterMessageSent, @@ -44,6 +47,9 @@ class ChatUserStoryConfiguration { /// The service responsible for handling chat-related functionalities. final ChatService chatService; + /// A method to get the chat service only when needed and with a context. + final ChatService Function(BuildContext context)? chatServiceBuilder; + /// Callback function triggered when a chat is pressed. final Function(BuildContext, ChatModel)? onPressChat; @@ -53,6 +59,9 @@ class ChatUserStoryConfiguration { /// Translations for internationalization/localization support. final ChatTranslations translations; + /// Translations builder because context might be needed for translations. + final ChatTranslations Function(BuildContext context)? translationsBuilder; + /// Determines whether dismissing is disabled for permanent chats. final bool disableDismissForPermanentChats; @@ -74,7 +83,10 @@ class ChatUserStoryConfiguration { /// Builder for chat options based on context. final Function(List, String)? onPressCompleteGroupChatCreation; + final Function()? onPressCreateGroupChat; + + /// Builder for the chat options which can be used to style the UI of the chat final ChatOptions Function(BuildContext context) chatOptionsBuilder; /// If true, the user will be routed to the new chat screen if there are @@ -84,6 +96,10 @@ class ChatUserStoryConfiguration { /// The size of each page of messages. final int messagePageSize; + /// Whether to enable group chat creation for the user. If false, + /// the button will be hidden + final bool enableGroupChatCreation; + /// Dialog for confirming chat deletion. final Future Function(BuildContext, ChatModel)? deleteChatDialog; @@ -100,11 +116,18 @@ class ChatUserStoryConfiguration { final Function()? onPressStartChat; /// Callback function triggered when user profile is pressed. - final Function()? onPressUserProfile; + final Function(BuildContext context, ChatUserModel user)? onPressUserProfile; + final double? textfieldBottomPadding; + final Color? iconDisabledColor; + + /// The text style used for the unread message counter. final TextStyle? unreadMessageTextStyle; + final Widget? Function(BuildContext context)? loadingWidgetBuilder; + final Widget Function(String userFullName)? usernameBuilder; + final Widget Function(String chatTitle)? chatTitleBuilder; } diff --git a/packages/flutter_chat/pubspec.yaml b/packages/flutter_chat/pubspec.yaml index 748478e..778afe6 100644 --- a/packages/flutter_chat/pubspec.yaml +++ b/packages/flutter_chat/pubspec.yaml @@ -4,7 +4,7 @@ name: flutter_chat description: A new Flutter package project. -version: 1.4.3 +version: 2.0.0 publish_to: none @@ -20,17 +20,17 @@ dependencies: git: url: https://github.com/Iconica-Development/flutter_chat path: packages/flutter_chat_view - ref: 1.4.3 + ref: 2.0.0 flutter_chat_interface: git: url: https://github.com/Iconica-Development/flutter_chat path: packages/flutter_chat_interface - ref: 1.4.3 + ref: 2.0.0 flutter_chat_local: git: url: https://github.com/Iconica-Development/flutter_chat path: packages/flutter_chat_local - ref: 1.4.3 + ref: 2.0.0 uuid: ^4.3.3 dev_dependencies: 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 a00fdeb..92da038 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 @@ -91,11 +91,15 @@ class FirebaseChatOverviewService implements ChatOverviewService { var chat = element.doc.data(); if (chat == null) return; - var otherUser = await _userService.getUser( - chat.users.firstWhere( - (element) => element != currentUser?.id, - ), - ); + var otherUser = chat.users.any( + (element) => element != currentUser?.id, + ) + ? await _userService.getUser( + chat.users.firstWhere( + (element) => element != currentUser?.id, + ), + ) + : null; var unread = await _addUnreadChatSubscription(chat.id!, currentUser!.id!); @@ -144,10 +148,10 @@ class FirebaseChatOverviewService implements ChatOverviewService { imageUrl: chat.imageUrl ?? '', unreadMessages: unread, users: users, - lastMessage: chat.lastMessage != null + lastMessage: chat.lastMessage != null && otherUser != null ? chat.lastMessage!.imageUrl == null ? ChatTextMessageModel( - sender: otherUser!, + sender: otherUser, text: chat.lastMessage!.text!, timestamp: DateTime.fromMillisecondsSinceEpoch( chat.lastMessage!.timestamp @@ -155,7 +159,7 @@ class FirebaseChatOverviewService implements ChatOverviewService { ), ) : ChatImageMessageModel( - sender: otherUser!, + sender: otherUser, imageUrl: chat.lastMessage!.imageUrl!, timestamp: DateTime.fromMillisecondsSinceEpoch( chat.lastMessage!.timestamp diff --git a/packages/flutter_chat_firebase/pubspec.yaml b/packages/flutter_chat_firebase/pubspec.yaml index 67c9eb5..d4ebeab 100644 --- a/packages/flutter_chat_firebase/pubspec.yaml +++ b/packages/flutter_chat_firebase/pubspec.yaml @@ -4,7 +4,7 @@ name: flutter_chat_firebase description: A new Flutter package project. -version: 1.4.3 +version: 2.0.0 publish_to: none environment: @@ -23,7 +23,7 @@ dependencies: git: url: https://github.com/Iconica-Development/flutter_chat path: packages/flutter_chat_interface - ref: 1.4.3 + ref: 2.0.0 dev_dependencies: flutter_iconica_analysis: diff --git a/packages/flutter_chat_interface/pubspec.yaml b/packages/flutter_chat_interface/pubspec.yaml index dfd6b0c..40d2480 100644 --- a/packages/flutter_chat_interface/pubspec.yaml +++ b/packages/flutter_chat_interface/pubspec.yaml @@ -4,7 +4,7 @@ name: flutter_chat_interface description: A new Flutter package project. -version: 1.4.3 +version: 2.0.0 publish_to: none environment: diff --git a/packages/flutter_chat_local/pubspec.yaml b/packages/flutter_chat_local/pubspec.yaml index 221a65b..c37efa4 100644 --- a/packages/flutter_chat_local/pubspec.yaml +++ b/packages/flutter_chat_local/pubspec.yaml @@ -1,8 +1,7 @@ name: flutter_chat_local description: "A new Flutter package project." -version: 1.4.3 +version: 2.0.0 publish_to: none -homepage: environment: sdk: ">=3.2.5 <4.0.0" @@ -15,7 +14,7 @@ dependencies: git: url: https://github.com/Iconica-Development/flutter_chat path: packages/flutter_chat_interface - ref: 1.4.3 + ref: 2.0.0 dev_dependencies: flutter_test: diff --git a/packages/flutter_chat_view/lib/src/components/chat_detail_row.dart b/packages/flutter_chat_view/lib/src/components/chat_detail_row.dart index 75b9838..107a855 100644 --- a/packages/flutter_chat_view/lib/src/components/chat_detail_row.dart +++ b/packages/flutter_chat_view/lib/src/components/chat_detail_row.dart @@ -31,7 +31,7 @@ class ChatDetailRow extends StatefulWidget { /// The previous chat message model. final ChatMessageModel? previousMessage; - final Function(String? userId) onPressUserProfile; + final Function(ChatUserModel user) onPressUserProfile; final Widget Function(String userFullName)? usernameBuilder; /// Flag indicating whether to show the time. @@ -65,7 +65,7 @@ class _ChatDetailRowState extends State { if (isNewDate || isSameSender) ...[ GestureDetector( onTap: () => widget.onPressUserProfile( - widget.message.sender.id, + widget.message.sender, ), child: Padding( padding: const EdgeInsets.only(left: 10.0), diff --git a/packages/flutter_chat_view/lib/src/config/chat_options.dart b/packages/flutter_chat_view/lib/src/config/chat_options.dart index 54fb1fb..7b49173 100644 --- a/packages/flutter_chat_view/lib/src/config/chat_options.dart +++ b/packages/flutter_chat_view/lib/src/config/chat_options.dart @@ -19,6 +19,7 @@ class ChatOptions { this.groupAvatarBuilder = _createGroupAvatar, this.noChatsPlaceholderBuilder = _createNoChatsPlaceholder, this.noUsersPlaceholderBuilder = _createNoUsersPlaceholder, + this.paddingAroundChatList, }); /// Builder function for the new chat button. @@ -47,6 +48,9 @@ class ChatOptions { /// Builder function for the placeholder shown when no users are available. final NoUsersPlaceholderBuilder noUsersPlaceholderBuilder; + + /// The padding around the chat list. + final EdgeInsets? paddingAroundChatList; } Widget _createNewChatButton( diff --git a/packages/flutter_chat_view/lib/src/config/chat_translations.dart b/packages/flutter_chat_view/lib/src/config/chat_translations.dart index 1156be1..77ba758 100644 --- a/packages/flutter_chat_view/lib/src/config/chat_translations.dart +++ b/packages/flutter_chat_view/lib/src/config/chat_translations.dart @@ -2,12 +2,48 @@ // // SPDX-License-Identifier: BSD-3-Clause +/// Class that holds all the translations for the chat component view and +/// the corresponding userstory class ChatTranslations { + /// ChatTranslations constructor where everything is required use this + /// if you want to be sure to have all translations specified + /// If you just want the default values use the empty constructor + /// and optionally override the values with the copyWith method const ChatTranslations({ + required this.chatsTitle, + required this.chatsUnread, + required this.newChatButton, + required this.newGroupChatButton, + required this.newChatTitle, + required this.deleteChatButton, + required this.image, + required this.searchPlaceholder, + required this.startTyping, + required this.cancelImagePickerBtn, + required this.messagePlaceholder, + required this.writeMessageToStartChat, + required this.writeFirstMessageInGroupChat, + required this.imageUploading, + required this.deleteChatModalTitle, + required this.deleteChatModalDescription, + required this.deleteChatModalCancel, + required this.deleteChatModalConfirm, + required this.noUsersFound, + required this.noChatsFound, + required this.chatCantBeDeleted, + required this.chatProfileUsers, + required this.imagePickerTitle, + required this.uploadFile, + required this.takePicture, + required this.anonymousUser, + }); + + /// Default translations for the chat component view + const ChatTranslations.empty({ this.chatsTitle = 'Chats', this.chatsUnread = 'unread', this.newChatButton = 'Start a chat', - this.newGroupChatButton = 'Start group chat', + this.newGroupChatButton = 'Create a group chat', this.newChatTitle = 'Start a chat', this.image = 'Image', this.searchPlaceholder = 'Search...', @@ -62,4 +98,67 @@ class ChatTranslations { /// Shown when the user has no name final String anonymousUser; + + // copyWith method to override the default values + ChatTranslations copyWith({ + String? chatsTitle, + String? chatsUnread, + String? newChatButton, + String? newGroupChatButton, + String? newChatTitle, + String? deleteChatButton, + String? image, + String? searchPlaceholder, + String? startTyping, + String? cancelImagePickerBtn, + String? messagePlaceholder, + String? writeMessageToStartChat, + String? writeFirstMessageInGroupChat, + String? imageUploading, + String? deleteChatModalTitle, + String? deleteChatModalDescription, + String? deleteChatModalCancel, + String? deleteChatModalConfirm, + String? noUsersFound, + String? noChatsFound, + String? chatCantBeDeleted, + String? chatProfileUsers, + String? imagePickerTitle, + String? uploadFile, + String? takePicture, + String? anonymousUser, + }) => + ChatTranslations( + chatsTitle: chatsTitle ?? this.chatsTitle, + chatsUnread: chatsUnread ?? this.chatsUnread, + newChatButton: newChatButton ?? this.newChatButton, + newGroupChatButton: newGroupChatButton ?? this.newGroupChatButton, + newChatTitle: newChatTitle ?? this.newChatTitle, + deleteChatButton: deleteChatButton ?? this.deleteChatButton, + image: image ?? this.image, + searchPlaceholder: searchPlaceholder ?? this.searchPlaceholder, + startTyping: startTyping ?? this.startTyping, + cancelImagePickerBtn: cancelImagePickerBtn ?? this.cancelImagePickerBtn, + messagePlaceholder: messagePlaceholder ?? this.messagePlaceholder, + writeMessageToStartChat: + writeMessageToStartChat ?? this.writeMessageToStartChat, + writeFirstMessageInGroupChat: + writeFirstMessageInGroupChat ?? this.writeFirstMessageInGroupChat, + imageUploading: imageUploading ?? this.imageUploading, + deleteChatModalTitle: deleteChatModalTitle ?? this.deleteChatModalTitle, + deleteChatModalDescription: + deleteChatModalDescription ?? this.deleteChatModalDescription, + deleteChatModalCancel: + deleteChatModalCancel ?? this.deleteChatModalCancel, + deleteChatModalConfirm: + deleteChatModalConfirm ?? this.deleteChatModalConfirm, + noUsersFound: noUsersFound ?? this.noUsersFound, + noChatsFound: noChatsFound ?? this.noChatsFound, + chatCantBeDeleted: chatCantBeDeleted ?? this.chatCantBeDeleted, + chatProfileUsers: chatProfileUsers ?? this.chatProfileUsers, + imagePickerTitle: imagePickerTitle ?? this.imagePickerTitle, + uploadFile: uploadFile ?? this.uploadFile, + takePicture: takePicture ?? this.takePicture, + anonymousUser: anonymousUser ?? this.anonymousUser, + ); } diff --git a/packages/flutter_chat_view/lib/src/screens/chat_detail_screen.dart b/packages/flutter_chat_view/lib/src/screens/chat_detail_screen.dart index 234325c..3fc852d 100644 --- a/packages/flutter_chat_view/lib/src/screens/chat_detail_screen.dart +++ b/packages/flutter_chat_view/lib/src/screens/chat_detail_screen.dart @@ -26,7 +26,7 @@ class ChatDetailScreen extends StatefulWidget { this.chatTitleBuilder, this.usernameBuilder, this.loadingWidgetBuilder, - this.translations = const ChatTranslations(), + this.translations = const ChatTranslations.empty(), this.iconColor, this.iconDisabledColor, this.showTime = false, @@ -53,7 +53,7 @@ class ChatDetailScreen extends StatefulWidget { final int pageSize; final double textfieldBottomPadding; final Color? iconDisabledColor; - final Function(String? userId) onPressUserProfile; + final Function(ChatUserModel user) onPressUserProfile; // ignore: avoid_positional_boolean_parameters final Widget? Function(BuildContext context)? loadingWidgetBuilder; final Widget Function(String userFullName)? usernameBuilder; diff --git a/packages/flutter_chat_view/lib/src/screens/chat_profile_screen.dart b/packages/flutter_chat_view/lib/src/screens/chat_profile_screen.dart index 5e92b55..a6bfa9a 100644 --- a/packages/flutter_chat_view/lib/src/screens/chat_profile_screen.dart +++ b/packages/flutter_chat_view/lib/src/screens/chat_profile_screen.dart @@ -26,7 +26,7 @@ class ChatProfileScreen extends StatefulWidget { final String? userId; /// Callback function for tapping on a user. - final Function(String userId) onTapUser; + final Function(ChatUserModel user) onTapUser; @override State createState() => _ProfileScreenState(); @@ -124,7 +124,7 @@ class _ProfileScreenState extends State { return Padding( padding: const EdgeInsets.symmetric(vertical: 4.0), child: GestureDetector( - onTap: () => widget.onTapUser.call(e.id!), + onTap: () => widget.onTapUser.call(e), child: Column( mainAxisAlignment: MainAxisAlignment.start, mainAxisSize: MainAxisSize.min, diff --git a/packages/flutter_chat_view/lib/src/screens/chat_screen.dart b/packages/flutter_chat_view/lib/src/screens/chat_screen.dart index 9e56321..1260af5 100644 --- a/packages/flutter_chat_view/lib/src/screens/chat_screen.dart +++ b/packages/flutter_chat_view/lib/src/screens/chat_screen.dart @@ -20,7 +20,7 @@ class ChatScreen extends StatefulWidget { this.unreadMessageTextStyle, this.onNoChats, this.deleteChatDialog, - this.translations = const ChatTranslations(), + this.translations = const ChatTranslations.empty(), this.disableDismissForPermanentChats = false, super.key, }); @@ -119,7 +119,8 @@ class _ChatScreenState extends State { child: ListView( controller: controller, physics: const AlwaysScrollableScrollPhysics(), - padding: const EdgeInsets.fromLTRB(28, 16, 28, 0), + padding: widget.options.paddingAroundChatList ?? + const EdgeInsets.fromLTRB(28, 16, 28, 0), children: [ StreamBuilder>( stream: widget.service.chatOverviewService.getChatsStream(), @@ -384,7 +385,6 @@ class ChatListItem extends StatelessWidget { ), ), ), - const Divider(), ], ); } diff --git a/packages/flutter_chat_view/lib/src/screens/new_chat_screen.dart b/packages/flutter_chat_view/lib/src/screens/new_chat_screen.dart index 50f2e71..8d5be29 100644 --- a/packages/flutter_chat_view/lib/src/screens/new_chat_screen.dart +++ b/packages/flutter_chat_view/lib/src/screens/new_chat_screen.dart @@ -11,7 +11,8 @@ class NewChatScreen extends StatefulWidget { required this.onPressCreateChat, required this.service, required this.onPressCreateGroupChat, - this.translations = const ChatTranslations(), + this.showGroupChatButton = true, + this.translations = const ChatTranslations.empty(), super.key, }); @@ -23,8 +24,13 @@ class NewChatScreen extends StatefulWidget { /// Callback function for creating a new chat with a user. final Function(ChatUserModel) onPressCreateChat; + + /// Callback function for creating a new group chat. final Function() onPressCreateGroupChat; + /// Option to enable the group chat creation button. + final bool showGroupChatButton; + /// Translations for the chat. final ChatTranslations translations; @@ -52,48 +58,50 @@ class _NewChatScreenState extends State { ), body: Column( children: [ - GestureDetector( - onTap: () async { - await widget.onPressCreateGroupChat(); - }, - child: Container( - color: Colors.grey[900], - child: SizedBox( - height: 60.0, - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Row( - mainAxisAlignment: MainAxisAlignment.start, - children: [ - Padding( - padding: const EdgeInsets.only( - left: 16.0, - ), - child: IconButton( - icon: const Icon( - Icons.group, - color: Colors.white, + if (widget.showGroupChatButton) ...[ + GestureDetector( + onTap: () async { + await widget.onPressCreateGroupChat(); + }, + child: Container( + color: Colors.grey[900], + child: SizedBox( + height: 60.0, + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.start, + children: [ + Padding( + padding: const EdgeInsets.only( + left: 16.0, + ), + child: IconButton( + icon: const Icon( + Icons.group, + color: Colors.white, + ), + onPressed: () { + // Handle group chat creation + }, ), - onPressed: () { - // Handle group chat creation - }, ), - ), - const Text( - 'Create group chat', - style: TextStyle( - color: Colors.white, - fontSize: 16.0, + Text( + widget.translations.newGroupChatButton, + style: const TextStyle( + color: Colors.white, + fontSize: 16.0, + ), ), - ), - ], - ), - ], + ], + ), + ], + ), ), ), ), - ), + ], Expanded( child: FutureBuilder>( // ignore: discarded_futures @@ -213,12 +221,8 @@ class _NewChatScreenState extends State { return widget.options.noChatsPlaceholderBuilder(widget.translations); } - return ListView.separated( + return ListView.builder( itemCount: filteredUsers.length, - separatorBuilder: (context, index) => const Padding( - padding: EdgeInsets.symmetric(horizontal: 28.0), - child: Divider(), - ), itemBuilder: (context, index) { var user = filteredUsers[index]; return GestureDetector( diff --git a/packages/flutter_chat_view/lib/src/screens/new_group_chat_overview_screen.dart b/packages/flutter_chat_view/lib/src/screens/new_group_chat_overview_screen.dart index 64bf286..22ff727 100644 --- a/packages/flutter_chat_view/lib/src/screens/new_group_chat_overview_screen.dart +++ b/packages/flutter_chat_view/lib/src/screens/new_group_chat_overview_screen.dart @@ -11,7 +11,7 @@ class NewGroupChatOverviewScreen extends StatefulWidget { required this.onPressCompleteGroupChatCreation, required this.service, required this.users, - this.translations = const ChatTranslations(), + this.translations = const ChatTranslations.empty(), super.key, }); 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 a7e6c07..d527e22 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 @@ -8,7 +8,7 @@ class NewGroupChatScreen extends StatefulWidget { required this.options, required this.onPressGroupChatOverview, required this.service, - this.translations = const ChatTranslations(), + this.translations = const ChatTranslations.empty(), super.key, }); diff --git a/packages/flutter_chat_view/pubspec.yaml b/packages/flutter_chat_view/pubspec.yaml index 9791dae..06de508 100644 --- a/packages/flutter_chat_view/pubspec.yaml +++ b/packages/flutter_chat_view/pubspec.yaml @@ -4,7 +4,7 @@ name: flutter_chat_view description: A standard flutter package. -version: 1.4.3 +version: 2.0.0 publish_to: none @@ -20,7 +20,7 @@ dependencies: git: url: https://github.com/Iconica-Development/flutter_chat path: packages/flutter_chat_interface - ref: 1.4.3 + ref: 2.0.0 cached_network_image: ^3.2.2 flutter_image_picker: git: