From 4dd0b333fa7014ef3e6d054e361cc70e813e2ebc Mon Sep 17 00:00:00 2001 From: Apurva-Simform <122270609+apurva010@users.noreply.github.com> Date: Wed, 22 May 2024 16:08:32 +0530 Subject: [PATCH] =?UTF-8?q?feat:=E2=9C=A8added=20field=20to=20provide=20pa?= =?UTF-8?q?ttern=20to=20separate=20chat=20#93.=20(#171)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CHANGELOG.md | 2 ++ README.md | 16 +++++++++++++ lib/src/extensions/extensions.dart | 9 ++++---- .../models/message_list_configuration.dart | 7 ++++++ lib/src/utils/constants/constants.dart | 2 +- lib/src/widgets/chat_group_header.dart | 7 +++++- lib/src/widgets/chat_groupedlist_widget.dart | 23 +++++++++++++++---- 7 files changed, 54 insertions(+), 12 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a8308144..a602986d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,7 @@ ## [1.3.2] (Unreleased) +* **Feat**: [93](https://github.com/SimformSolutionsPvtLtd/flutter_chatview/issues/93) Added support + that provide date pattern to change chat separation. * **Fix**: [142](https://github.com/SimformSolutionsPvtLtd/flutter_chatview/issues/142) Added field to provide base64 string data for profile picture. * **Fix**: [165](https://github.com/SimformSolutionsPvtLtd/flutter_chatview/issues/165) Fix issue diff --git a/README.md b/README.md index a6ea91b4..7fb06f99 100644 --- a/README.md +++ b/README.md @@ -601,6 +601,22 @@ ChatView( ``` +25. Added `chatSeparatorDatePattern` in `DefaultGroupSeparatorConfiguration` to separate chats with provided pattern. + +```dart +ChatView( + ... + chatBackgroundConfig: ChatBackgroundConfiguration( + ... + defaultGroupSeparatorConfig: DefaultGroupSeparatorConfiguration( + chatSeparatorDatePattern: 'MMM dd, yyyy' + ), + ... + ), + ... +) +``` + ## How to use diff --git a/lib/src/extensions/extensions.dart b/lib/src/extensions/extensions.dart index 666d4021..6067ee88 100644 --- a/lib/src/extensions/extensions.dart +++ b/lib/src/extensions/extensions.dart @@ -29,16 +29,15 @@ import '../utils/package_strings.dart'; /// Extension for DateTime to get specific formats of dates and time. extension TimeDifference on DateTime { - String get getDay { - final DateTime formattedDate = DateFormat(dateFormat).parse(toString()); - final DateFormat formatter = DateFormat.yMMMMd(enUS); - final differenceInDays = formattedDate.difference(DateTime.now()).inDays; + String getDay(String chatSeparatorDatePattern) { + final differenceInDays = difference(DateTime.now()).inDays; if (differenceInDays == 0) { return PackageStrings.today; } else if (differenceInDays <= 1 && differenceInDays >= -1) { return PackageStrings.yesterday; } else { - return formatter.format(formattedDate); + final DateFormat formatter = DateFormat(chatSeparatorDatePattern); + return formatter.format(this); } } diff --git a/lib/src/models/message_list_configuration.dart b/lib/src/models/message_list_configuration.dart index a1fcfc10..512b923e 100644 --- a/lib/src/models/message_list_configuration.dart +++ b/lib/src/models/message_list_configuration.dart @@ -22,6 +22,7 @@ import 'package:flutter/material.dart'; import 'package:grouped_list/grouped_list.dart'; +import '../utils/constants/constants.dart'; import '../values/typedefs.dart'; class ChatBackgroundConfiguration { @@ -95,8 +96,14 @@ class DefaultGroupSeparatorConfiguration { /// Used for giving text style of chat separator widget. final TextStyle? textStyle; + /// Provides pattern to separate chat + /// Defaults to ['MMM dd, yyyy'] + /// e.g. May 21, 2024 + final String chatSeparatorDatePattern; + const DefaultGroupSeparatorConfiguration({ this.padding, this.textStyle, + this.chatSeparatorDatePattern = defaultChatSeparatorDatePattern, }); } diff --git a/lib/src/utils/constants/constants.dart b/lib/src/utils/constants/constants.dart index ae8e6188..620239a5 100644 --- a/lib/src/utils/constants/constants.dart +++ b/lib/src/utils/constants/constants.dart @@ -26,7 +26,6 @@ import 'package:timeago/timeago.dart' as timeago; import '../../../chatview.dart'; import '../../widgets/chat_message_sending_to_sent_animation.dart'; -const String enUS = "en_US"; const String emojiRegExpression = r'(\u00a9|\u00ae|[\u2000-\u3300]|\ud83c[\ud000-\udfff]|\ud83d[\ud000-\udfff]|\ud83e[\ud000-\udfff])'; const String imageUrlRegExpression = @@ -58,6 +57,7 @@ const double replyBorderRadius1 = 30; const double replyBorderRadius2 = 18; const double leftPadding3 = 12; const double textFieldBorderRadius = 27; +const String defaultChatSeparatorDatePattern = 'MMM dd, yyyy'; applicationDateFormatter(DateTime inputTime) { if (DateTime.now().difference(inputTime).inDays <= 3) { diff --git a/lib/src/widgets/chat_group_header.dart b/lib/src/widgets/chat_group_header.dart index 825b29af..4ed42e0d 100644 --- a/lib/src/widgets/chat_group_header.dart +++ b/lib/src/widgets/chat_group_header.dart @@ -23,6 +23,8 @@ import 'package:flutter/material.dart'; import 'package:chatview/src/models/models.dart'; import 'package:chatview/src/extensions/extensions.dart'; +import '../utils/constants/constants.dart'; + class ChatGroupHeader extends StatelessWidget { const ChatGroupHeader({ Key? key, @@ -42,7 +44,10 @@ class ChatGroupHeader extends StatelessWidget { padding: groupSeparatorConfig?.padding ?? const EdgeInsets.symmetric(vertical: 12), child: Text( - day.getDay, + day.getDay( + groupSeparatorConfig?.chatSeparatorDatePattern ?? + defaultChatSeparatorDatePattern, + ), textAlign: TextAlign.center, style: groupSeparatorConfig?.textStyle ?? const TextStyle(fontSize: 17), ), diff --git a/lib/src/widgets/chat_groupedlist_widget.dart b/lib/src/widgets/chat_groupedlist_widget.dart index 32eb607c..0c511831 100644 --- a/lib/src/widgets/chat_groupedlist_widget.dart +++ b/lib/src/widgets/chat_groupedlist_widget.dart @@ -283,14 +283,27 @@ class _ChatGroupedListWidgetState extends State } Widget get _chatStreamBuilder { + DateTime lastMatchedDate = DateTime.now(); return StreamBuilder>( stream: chatController?.messageStreamController.stream, builder: (context, snapshot) { return snapshot.connectionState.isActive - ? GroupedListView( + ? GroupedListView( shrinkWrap: true, elements: snapshot.data!, - groupBy: (element) => element.createdAt.getDateFromDateTime, + groupBy: (message) { + /// If the conversation is ongoing on the same date, + /// return the same date [lastMatchedDate]. + + /// When the conversation starts on a new date, + /// we assign the new date [message.createdAt] + /// to [lastMatchedDate]. + return lastMatchedDate = + lastMatchedDate.getDateFromDateTime == + message.createdAt.getDateFromDateTime + ? lastMatchedDate + : message.createdAt; + }, itemComparator: (message1, message2) => message1.message.compareTo(message2.message), physics: const NeverScrollableScrollPhysics(), @@ -359,16 +372,16 @@ class _GroupSeparatorBuilder extends StatelessWidget { this.groupSeparatorBuilder, this.defaultGroupSeparatorConfig, }) : super(key: key); - final String separator; + final DateTime separator; final StringWithReturnWidget? groupSeparatorBuilder; final DefaultGroupSeparatorConfiguration? defaultGroupSeparatorConfig; @override Widget build(BuildContext context) { return groupSeparatorBuilder != null - ? groupSeparatorBuilder!(separator) + ? groupSeparatorBuilder!(separator.toString()) : ChatGroupHeader( - day: DateTime.parse(separator), + day: separator, groupSeparatorConfig: defaultGroupSeparatorConfig, ); }