Skip to content

Commit 61c0400

Browse files
authored
feat: time and status grouping same minute fix #764 (#792)
* Add messageGroupingMode * Add TimeAndStatusPosition.none
1 parent a85115e commit 61c0400

File tree

9 files changed

+35
-5
lines changed

9 files changed

+35
-5
lines changed

packages/flutter_chat_core/lib/src/utils/typedefs.dart

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,13 @@ typedef UserID = String;
1616
enum MessageStatus { delivered, error, seen, sending, sent }
1717

1818
/// Defines the position of the timestamp and status indicator relative to the message content.
19-
enum TimeAndStatusPosition { start, end, inline }
19+
enum TimeAndStatusPosition { start, end, inline, none }
2020

2121
/// Signature for a callback function that resolves a [User] object from a [UserID].
2222
typedef ResolveUserCallback = Future<User?> Function(UserID id);
2323

24+
enum MessagesGroupingMode { timeDifference, sameMinute }
25+
2426
/// Signature for a function that builds a single chat list item widget.
2527
/// Used by [ChatAnimatedList] and [ChatAnimatedListReversed].
2628
typedef ChatItem =
@@ -29,6 +31,7 @@ typedef ChatItem =
2931
Message message,
3032
int index,
3133
Animation<double> animation, {
34+
MessagesGroupingMode? messagesGroupingMode,
3235
int? messageGroupingTimeoutInSeconds,
3336
bool? isRemoved,
3437
});

packages/flutter_chat_ui/lib/src/chat.dart

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,7 @@ class _ChatState extends State<Chat> with WidgetsBindingObserver {
176176
Message message,
177177
int index,
178178
Animation<double> animation, {
179+
MessagesGroupingMode? messagesGroupingMode,
179180
int? messageGroupingTimeoutInSeconds,
180181
bool? isRemoved,
181182
}) {
@@ -184,6 +185,7 @@ class _ChatState extends State<Chat> with WidgetsBindingObserver {
184185
message: message,
185186
index: index,
186187
animation: animation,
188+
messagesGroupingMode: messagesGroupingMode,
187189
messageGroupingTimeoutInSeconds: messageGroupingTimeoutInSeconds,
188190
isRemoved: isRemoved,
189191
);

packages/flutter_chat_ui/lib/src/chat_animated_list/chat_animated_list.dart

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,9 @@ class ChatAnimatedList extends StatefulWidget {
103103
/// A value of 0.2 means pagination will trigger when scrolled to 20% from the top.
104104
final double? paginationThreshold;
105105

106+
/// The mode to use for grouping messages.
107+
final MessagesGroupingMode? messagesGroupingMode;
108+
106109
/// Timeout in seconds for grouping consecutive messages from the same author.
107110
final int? messageGroupingTimeoutInSeconds;
108111

@@ -154,6 +157,7 @@ class ChatAnimatedList extends StatefulWidget {
154157
// Modify this value at your own risk. If you increase it and experience
155158
// unstable pagination jumps, revert to a smaller value like 0.01.
156159
this.paginationThreshold = 0.01,
160+
this.messagesGroupingMode,
157161
this.messageGroupingTimeoutInSeconds,
158162
this.physics,
159163
});

packages/flutter_chat_ui/lib/src/chat_animated_list/chat_animated_list_reversed.dart

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,9 @@ class ChatAnimatedListReversed extends StatelessWidget {
6262
/// Defaults to 0.2. See note below.
6363
final double? paginationThreshold;
6464

65+
/// The mode to use for grouping messages.
66+
final MessagesGroupingMode? messagesGroupingMode;
67+
6568
/// Timeout in seconds for grouping consecutive messages from the same author.
6669
final int? messageGroupingTimeoutInSeconds;
6770

@@ -94,6 +97,7 @@ class ChatAnimatedListReversed extends StatelessWidget {
9497
// because new items are added at the bottom (index 0). The default of 0.2
9598
// triggers pagination when 20% from the visual top is reached.
9699
this.paginationThreshold = 0.2,
100+
this.messagesGroupingMode,
97101
this.messageGroupingTimeoutInSeconds,
98102
this.physics,
99103
});

packages/flutter_chat_ui/lib/src/chat_message/chat_message_internal.dart

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,11 @@ class ChatMessageInternal extends StatefulWidget {
2323
/// Animation provided by the parent [SliverAnimatedList].
2424
final Animation<double> animation;
2525

26+
/// The mode to use for grouping messages.
27+
final MessagesGroupingMode? messagesGroupingMode;
28+
2629
/// Timeout in seconds for grouping messages from the same author.
30+
/// when [messagesGroupingMode] is [MessagingGroupingMode.timeDifference].
2731
final int? messageGroupingTimeoutInSeconds;
2832

2933
/// Flag indicating if this item is being animated out (removed).
@@ -35,6 +39,7 @@ class ChatMessageInternal extends StatefulWidget {
3539
required this.message,
3640
required this.index,
3741
required this.animation,
42+
this.messagesGroupingMode = MessagesGroupingMode.timeDifference,
3843
this.messageGroupingTimeoutInSeconds,
3944
this.isRemoved,
4045
});
@@ -146,15 +151,19 @@ class _ChatMessageInternalState extends State<ChatMessageInternal> {
146151
final isGroupedWithNext =
147152
nextMessage != null &&
148153
nextMessage.authorId == currentMessage.authorId &&
149-
nextMessageDate.difference(currentMessageDate).inSeconds <
150-
timeoutInSeconds;
154+
(widget.messagesGroupingMode == MessagesGroupingMode.timeDifference
155+
? nextMessageDate.difference(currentMessageDate).inSeconds <
156+
timeoutInSeconds
157+
: nextMessageDate.minute == currentMessageDate.minute);
151158

152159
// Check if message is part of a group with previous message
153160
final isGroupedWithPrevious =
154161
previousMessage != null &&
155162
previousMessage.authorId == currentMessage.authorId &&
156-
currentMessageDate.difference(previousMessageDate).inSeconds <
157-
timeoutInSeconds;
163+
(widget.messagesGroupingMode == MessagesGroupingMode.timeDifference
164+
? currentMessageDate.difference(previousMessageDate).inSeconds <
165+
timeoutInSeconds
166+
: currentMessageDate.minute == previousMessageDate.minute);
158167

159168
// If not grouped with either message, return null
160169
if (!isGroupedWithNext && !isGroupedWithPrevious) {

packages/flutter_chat_ui/lib/src/simple_text_message.dart

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -218,6 +218,8 @@ class SimpleTextMessage extends StatelessWidget {
218218
),
219219
],
220220
);
221+
case TimeAndStatusPosition.none:
222+
return textContent;
221223
}
222224
}
223225

packages/flyer_chat_file_message/lib/src/flyer_chat_file_message.dart

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -225,6 +225,8 @@ class FlyerChatFileMessage extends StatelessWidget {
225225
),
226226
],
227227
);
228+
case TimeAndStatusPosition.none:
229+
return fileContent;
228230
}
229231
}
230232

packages/flyer_chat_text_message/lib/src/flyer_chat_text_message.dart

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -226,6 +226,8 @@ class FlyerChatTextMessage extends StatelessWidget {
226226
),
227227
],
228228
);
229+
case TimeAndStatusPosition.none:
230+
return textContent;
229231
}
230232
}
231233

packages/flyer_chat_text_stream_message/lib/src/flyer_chat_text_stream_message.dart

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -429,6 +429,8 @@ class _FlyerChatTextStreamMessageState extends State<FlyerChatTextStreamMessage>
429429
),
430430
],
431431
);
432+
case TimeAndStatusPosition.none:
433+
return textContent;
432434
}
433435
}
434436

0 commit comments

Comments
 (0)