From cb423c582ce19e8a06b55af94abbda95f9ec265c Mon Sep 17 00:00:00 2001 From: mike doornenbal Date: Fri, 29 Dec 2023 12:02:54 +0100 Subject: [PATCH] feat: updated readme, ui colors and null values --- README.md | 102 ++++++++++++++---- .../lib/service/firebase_chat_service.dart | 15 +-- .../lib/src/components/chat_detail_row.dart | 15 ++- .../lib/src/components/chat_image.dart | 10 +- .../lib/src/config/chat_options.dart | 2 +- .../lib/src/screens/chat_screen.dart | 85 ++++++++------- 6 files changed, 154 insertions(+), 75 deletions(-) diff --git a/README.md b/README.md index 244791e..ac12805 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,5 @@ # Flutter Community Chat + Flutter Community Chat is a package which gives the possibility to add a (personal or group) chat to your Flutter-application. Default this package adds support for a Firebase back-end. You can add your custom back-end (like a Websocket-API) by extending the `CommunityChatInterface` interface from the `flutter_community_chat_interface` package. ![Flutter Community Chat GIF](example.gif) @@ -7,11 +8,12 @@ Figma Design that defines this component (only accessible for Iconica developers Figma clickable prototype that demonstrates this component (only accessible for Iconica developers): https://www.figma.com/proto/PRJoVXQ5aOjAICfkQdAq2A/Iconica-User-Stories?page-id=1%3A2&type=design&node-id=56-6837&viewport=279%2C2452%2C0.2&t=E7Al3Xng2WXnbCEQ-1&scaling=scale-down&starting-point-node-id=56%3A6837&mode=design ## Setup + To use this package, add flutter_community_chat as a dependency in your pubspec.yaml file: ``` flutter_community_chat: - git: + git: url: https://github.com/Iconica-Development/flutter_community_chat.git path: packages/flutter_community_chat ``` @@ -20,43 +22,102 @@ If you are going to use Firebase as the back-end of the Community Chat, you shou ``` flutter_community_chat_firebase: - git: + git: url: https://github.com/Iconica-Development/flutter_community_chat.git path: packages/flutter_community_chat_firebase ``` +Create a Firebase project for your application and add firebase firestore and storage. + ## How to use -To use the module within your Flutter-application you should add the following code to the build-method of a chosen widget. + +To use the module within your Flutter-application with predefined `Go_router` routes you should add the following: + +Add go_router as dependency to your project. +Add the following configuration to your flutter_application: ``` -CommunityChat( - dataProvider: FirebaseCommunityChatDataProvider(), -) +List getCommunityChatRoutes() => getCommunityChatStoryRoutes( + CommunityChatUserStoryConfiguration( + service: FirebaseChatService(userService: FirebaseUserService()), + userService: FirebaseUserService(), + messageService: + FirebaseMessageService(userService: FirebaseUserService()), + chatOptionsBuilder: (ctx) => const ChatOptions(), + ), + ); ``` -In this example we provide a `FirebaseCommunityChatDataProvider` as a data provider. You can also specify your own implementation here of the `CommunityChatInterface` interface. - -You can also include your custom configuration for both the Community Chat itself as the Image Picker which is included in this package. You can specify those configurations as a parameter: +Add the `getCommunityChatRoutes()` to your go_router routes like so: ``` -CommunityChat( - dataProvider: FirebaseCommunityChatDataProvider(), - imagePickerTheme: ImagePickerTheme(), - chatOptions: ChatOptions(), -) +final GoRouter _router = GoRouter( + routes: [ + GoRoute( + path: '/', + builder: (BuildContext context, GoRouterState state) { + return const MyHomePage( + title: "home", + ); + }, + ), + ...getCommunityChatRoutes() + ], +); +``` + +To use the module within your Flutter-application without predefined `Go_router` routes add the following code to the build-method of a chosen widget: + +To add the `ChatScreen` add the following code: + +```` +ChatScreen( + options: options, + onPressStartChat: onPressStartChat, + onPressChat: onPressChat, + onDeleteChat: onDeleteChat, + service: service, + pageSize: pageSize, + ); +``` + +To add the `ChatDetailScreen` add the following code: + +``` +ChatDetailScreen( + options: options, + onMessageSubmit: onMessageSubmit, + onUploadImage: onUploadImage, + onReadChat: onReadChat, + service: service, + chatUserService: chatUserService, + messageService: messageService, + pageSize: pageSize, + ); +``` + +To add the `NewChatScreen` add the following code: + +``` +NewChatScreen( + options: options, + onPressCreateChat: onPressCreateChat, + service: service, + userService: userService, + ); ``` The `ChatOptions` has its own parameters, as specified below: | Parameter | Explanation | |-----------|-------------| -| newChatButtonBuilder | Builds the 'New Chat' button, to initiate a new chat session. This button is displayed on the chat overview. | -| messageInputBuilder | Builds the text input which is displayed within the chat view, responsible for sending text messages. | -| chatRowContainerBuilder | Builds a chat row. A row with the users' avatar, name and eventually the last massage sended in the chat. This builder is used both in the *chat overview screen* as in the *new chat screen*. | -| imagePickerContainerBuilder | Builds the container around the ImagePicker. | +| newChatButtonBuilder | Builds the 'New Chat' button, to initiate a new chat session. This button is displayed on the chat overview. | +| messageInputBuilder | Builds the text input which is displayed within the chat view, responsible for sending text messages. | +| chatRowContainerBuilder | Builds a chat row. A row with the users' avatar, name and eventually the last massage sended in the chat. This builder is used both in the _chat overview screen_ as in the _new chat screen_. | +| imagePickerContainerBuilder | Builds the container around the ImagePicker. | | closeImagePickerButtonBuilder | Builds the close button for the Image Picker pop-up window. | -| scaffoldBuilder | Builds the default Scaffold-widget around the Community Chat. The chat title is displayed within the Scaffolds' title for example. | +| scaffoldBuilder | Builds the default Scaffold-widget around the Community Chat. The chat title is displayed within the Scaffolds' title for example. | -The `ImagePickerTheme` also has its own parameters, how to use these parameters can be found in [the documentation of the flutter_image_picker package](https://github.com/Iconica-Development/flutter_image_picker). +The `ImagePickerTheme` also has its own parameters, how to use these parameters can be found in [the documentation of the flutter_image_picker package](https://github.com/Iconica-Development/flutter_image_picker). ## Issues @@ -69,3 +130,4 @@ If you would like to contribute to the plugin (e.g. by improving the documentati ## Author This `flutter_community_chat` for Flutter is developed by [Iconica](https://iconica.nl). You can contact us at +```` diff --git a/packages/flutter_community_chat_firebase/lib/service/firebase_chat_service.dart b/packages/flutter_community_chat_firebase/lib/service/firebase_chat_service.dart index 954e1e6..cd6178e 100644 --- a/packages/flutter_community_chat_firebase/lib/service/firebase_chat_service.dart +++ b/packages/flutter_community_chat_firebase/lib/service/firebase_chat_service.dart @@ -267,13 +267,16 @@ class FirebaseChatService implements ChatService { var startIndex = (pageNumber - 1) * pageSize; var endIndex = startIndex + pageSize; - if (startIndex >= groupChatIds.length) { - return []; + if (groupChatIds != null) { + if (startIndex >= groupChatIds.length) { + return []; + } + var groupIds = groupChatIds.sublist( + startIndex, endIndex.clamp(0, groupChatIds.length)); + lastGroupId = groupIds.last; + return groupIds; } - var groupIds = groupChatIds.sublist( - startIndex, endIndex.clamp(0, groupChatIds.length)); - lastGroupId = groupIds.last; - return groupIds; + return []; }); if (userSnapshot.docs.isNotEmpty) { diff --git a/packages/flutter_community_chat_view/lib/src/components/chat_detail_row.dart b/packages/flutter_community_chat_view/lib/src/components/chat_detail_row.dart index eacf2ee..217b037 100644 --- a/packages/flutter_community_chat_view/lib/src/components/chat_detail_row.dart +++ b/packages/flutter_community_chat_view/lib/src/components/chat_detail_row.dart @@ -37,7 +37,6 @@ class _ChatDetailRowState extends State { widget.message.timestamp.day != widget.previousMessage?.timestamp.day; var isSameSender = widget.previousMessage == null || widget.previousMessage?.sender.id != widget.message.sender.id; - print(isNewDate); return Padding( padding: EdgeInsets.only( @@ -79,9 +78,13 @@ class _ChatDetailRowState extends State { Text( widget.message.sender.fullName?.toUpperCase() ?? widget.translations.anonymousUser, - style: const TextStyle( + style: TextStyle( fontSize: 14, fontWeight: FontWeight.w500, + color: Theme.of(context) + .textTheme + .labelMedium + ?.color, ), ), Padding( @@ -106,7 +109,13 @@ class _ChatDetailRowState extends State { text: TextSpan( text: (widget.message as ChatTextMessageModel) .text, - style: const TextStyle(fontSize: 16), + style: TextStyle( + fontSize: 16, + color: Theme.of(context) + .textTheme + .labelMedium + ?.color, + ), children: [ if (widget.showTime) TextSpan( diff --git a/packages/flutter_community_chat_view/lib/src/components/chat_image.dart b/packages/flutter_community_chat_view/lib/src/components/chat_image.dart index 83e3bb0..f10fe08 100644 --- a/packages/flutter_community_chat_view/lib/src/components/chat_image.dart +++ b/packages/flutter_community_chat_view/lib/src/components/chat_image.dart @@ -24,9 +24,11 @@ class ChatImage extends StatelessWidget { ), width: size, height: size, - child: CachedNetworkImage( - imageUrl: image, - fit: BoxFit.cover, - ), + child: image != '' + ? CachedNetworkImage( + imageUrl: image, + fit: BoxFit.cover, + ) + : null, ); } diff --git a/packages/flutter_community_chat_view/lib/src/config/chat_options.dart b/packages/flutter_community_chat_view/lib/src/config/chat_options.dart index a71155b..ad72a7d 100644 --- a/packages/flutter_community_chat_view/lib/src/config/chat_options.dart +++ b/packages/flutter_community_chat_view/lib/src/config/chat_options.dart @@ -75,7 +75,7 @@ Widget _createImagePickerContainer( ) => Container( padding: const EdgeInsets.all(8.0), - color: Colors.black, + color: Colors.white, child: ImagePicker( customButton: ElevatedButton( onPressed: onClose, diff --git a/packages/flutter_community_chat_view/lib/src/screens/chat_screen.dart b/packages/flutter_community_chat_view/lib/src/screens/chat_screen.dart index 2eb1e87..524c1b2 100644 --- a/packages/flutter_community_chat_view/lib/src/screens/chat_screen.dart +++ b/packages/flutter_community_chat_view/lib/src/screens/chat_screen.dart @@ -316,48 +316,51 @@ class ChatListItem extends StatelessWidget { Widget build(BuildContext context) { return GestureDetector( onTap: () => widget.onPressChat(chat), - child: widget.options.chatRowContainerBuilder( - (chat is PersonalChatModel) - ? ChatRow( - unreadMessages: chat.unreadMessages ?? 0, - avatar: widget.options.userAvatarBuilder( - (chat as PersonalChatModel).user, - 40.0, + child: Container( + color: Colors.transparent, + child: widget.options.chatRowContainerBuilder( + (chat is PersonalChatModel) + ? ChatRow( + unreadMessages: chat.unreadMessages ?? 0, + avatar: widget.options.userAvatarBuilder( + (chat as PersonalChatModel).user, + 40.0, + ), + title: (chat as PersonalChatModel).user.fullName ?? + translations.anonymousUser, + subTitle: chat.lastMessage != null + ? chat.lastMessage is ChatTextMessageModel + ? (chat.lastMessage! as ChatTextMessageModel).text + : '📷 ' + '${translations.image}' + : '', + lastUsed: chat.lastUsed != null + ? _dateFormatter.format( + date: chat.lastUsed!, + ) + : null, + ) + : ChatRow( + title: (chat as GroupChatModel).title, + unreadMessages: chat.unreadMessages ?? 0, + subTitle: chat.lastMessage != null + ? chat.lastMessage is ChatTextMessageModel + ? (chat.lastMessage! as ChatTextMessageModel).text + : '📷 ' + '${translations.image}' + : '', + avatar: widget.options.groupAvatarBuilder( + (chat as GroupChatModel).title, + (chat as GroupChatModel).imageUrl, + 40.0, + ), + lastUsed: chat.lastUsed != null + ? _dateFormatter.format( + date: chat.lastUsed!, + ) + : null, ), - title: (chat as PersonalChatModel).user.fullName ?? - translations.anonymousUser, - subTitle: chat.lastMessage != null - ? chat.lastMessage is ChatTextMessageModel - ? (chat.lastMessage! as ChatTextMessageModel).text - : '📷 ' - '${translations.image}' - : '', - lastUsed: chat.lastUsed != null - ? _dateFormatter.format( - date: chat.lastUsed!, - ) - : null, - ) - : ChatRow( - title: (chat as GroupChatModel).title, - unreadMessages: chat.unreadMessages ?? 0, - subTitle: chat.lastMessage != null - ? chat.lastMessage is ChatTextMessageModel - ? (chat.lastMessage! as ChatTextMessageModel).text - : '📷 ' - '${translations.image}' - : '', - avatar: widget.options.groupAvatarBuilder( - (chat as GroupChatModel).title, - (chat as GroupChatModel).imageUrl, - 40.0, - ), - lastUsed: chat.lastUsed != null - ? _dateFormatter.format( - date: chat.lastUsed!, - ) - : null, - ), + ), ), ); }