Skip to content

Commit 552e024

Browse files
committed
feat:✨Added a support for showing message time in message bubble. Removed enableSwipeToSeeTime(bool) & added showMessageTimeIn(Enum) from FeatureActiveConfig class.(#115)
1 parent 31eedc2 commit 552e024

15 files changed

+444
-228
lines changed

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
## [1.4.0] (UnReleased)
2+
3+
* **Feat**: [115](https://github.com/SimformSolutionsPvtLtd/flutter_chatview/issues/115) Added
4+
option for showing message sent/received time in message bubble. Removed 'enableSwipeToSeeTime'
5+
& added 'showMessageTimeIn' from FeatureActiveConfig class for the visibility of message time.
6+
17
## [1.3.1]
28

39
* **Feat**: [105](https://github.com/SimformSolutionsPvtLtd/flutter_chatview/pull/105) Allow user

example/lib/data.dart

Lines changed: 81 additions & 81 deletions
Original file line numberDiff line numberDiff line change
@@ -32,86 +32,86 @@ class Data {
3232
sendBy: '1',
3333
status: MessageStatus.read,
3434
),
35-
Message(
36-
id: '5',
37-
message: "That's fine",
38-
createdAt: DateTime.now(),
39-
sendBy: '2',
40-
reaction: Reaction(reactions: ['\u{2764}'], reactedUserIds: ['1']),
41-
status: MessageStatus.read,
42-
),
43-
Message(
44-
id: '6',
45-
message: "When to go ?",
46-
createdAt: DateTime.now(),
47-
sendBy: '3',
48-
status: MessageStatus.read,
49-
),
50-
Message(
51-
id: '7',
52-
message: "I guess Simform will reply",
53-
createdAt: DateTime.now(),
54-
sendBy: '4',
55-
status: MessageStatus.read,
56-
),
57-
Message(
58-
id: '8',
59-
message: "https://bit.ly/3JHS2Wl",
60-
createdAt: DateTime.now(),
61-
sendBy: '2',
62-
reaction: Reaction(
63-
reactions: ['\u{2764}', '\u{1F44D}', '\u{1F44D}'],
64-
reactedUserIds: ['2', '3', '4'],
65-
),
66-
status: MessageStatus.read,
67-
replyMessage: const ReplyMessage(
68-
message: "Can you write the time and place of the meeting?",
69-
replyTo: '1',
70-
replyBy: '2',
71-
messageId: '4',
72-
),
73-
),
74-
Message(
75-
id: '9',
76-
message: "Done",
77-
createdAt: DateTime.now(),
78-
sendBy: '1',
79-
status: MessageStatus.read,
80-
reaction: Reaction(
81-
reactions: [
82-
'\u{2764}',
83-
'\u{2764}',
84-
'\u{2764}',
85-
],
86-
reactedUserIds: ['2', '3', '4'],
87-
),
88-
),
89-
Message(
90-
id: '10',
91-
message: "Thank you!!",
92-
status: MessageStatus.read,
93-
createdAt: DateTime.now(),
94-
sendBy: '1',
95-
reaction: Reaction(
96-
reactions: ['\u{2764}', '\u{2764}', '\u{2764}', '\u{2764}'],
97-
reactedUserIds: ['2', '4', '3', '1'],
98-
),
99-
),
100-
Message(
101-
id: '11',
102-
message: "https://miro.medium.com/max/1000/0*s7of7kWnf9fDg4XM.jpeg",
103-
createdAt: DateTime.now(),
104-
messageType: MessageType.image,
105-
sendBy: '1',
106-
reaction: Reaction(reactions: ['\u{2764}'], reactedUserIds: ['2']),
107-
status: MessageStatus.read,
108-
),
109-
Message(
110-
id: '12',
111-
message: "🤩🤩",
112-
createdAt: DateTime.now(),
113-
sendBy: '2',
114-
status: MessageStatus.read,
115-
),
35+
// Message(
36+
// id: '5',
37+
// message: "That's fine",
38+
// createdAt: DateTime.now(),
39+
// sendBy: '2',
40+
// reaction: Reaction(reactions: ['\u{2764}'], reactedUserIds: ['1']),
41+
// status: MessageStatus.read,
42+
// ),
43+
// Message(
44+
// id: '6',
45+
// message: "When to go ?",
46+
// createdAt: DateTime.now(),
47+
// sendBy: '3',
48+
// status: MessageStatus.read,
49+
// ),
50+
// Message(
51+
// id: '7',
52+
// message: "I guess Simform will reply",
53+
// createdAt: DateTime.now(),
54+
// sendBy: '4',
55+
// status: MessageStatus.read,
56+
// ),
57+
// Message(
58+
// id: '8',
59+
// message: "https://bit.ly/3JHS2Wl",
60+
// createdAt: DateTime.now(),
61+
// sendBy: '2',
62+
// reaction: Reaction(
63+
// reactions: ['\u{2764}', '\u{1F44D}', '\u{1F44D}'],
64+
// reactedUserIds: ['2', '3', '4'],
65+
// ),
66+
// status: MessageStatus.read,
67+
// replyMessage: const ReplyMessage(
68+
// message: "Can you write the time and place of the meeting?",
69+
// replyTo: '1',
70+
// replyBy: '2',
71+
// messageId: '4',
72+
// ),
73+
// ),
74+
// Message(
75+
// id: '9',
76+
// message: "Done",
77+
// createdAt: DateTime.now(),
78+
// sendBy: '1',
79+
// status: MessageStatus.read,
80+
// reaction: Reaction(
81+
// reactions: [
82+
// '\u{2764}',
83+
// '\u{2764}',
84+
// '\u{2764}',
85+
// ],
86+
// reactedUserIds: ['2', '3', '4'],
87+
// ),
88+
// ),
89+
// Message(
90+
// id: '10',
91+
// message: "Thank you!!",
92+
// status: MessageStatus.read,
93+
// createdAt: DateTime.now(),
94+
// sendBy: '1',
95+
// reaction: Reaction(
96+
// reactions: ['\u{2764}', '\u{2764}', '\u{2764}', '\u{2764}'],
97+
// reactedUserIds: ['2', '4', '3', '1'],
98+
// ),
99+
// ),
100+
// Message(
101+
// id: '11',
102+
// message: "https://miro.medium.com/max/1000/0*s7of7kWnf9fDg4XM.jpeg",
103+
// createdAt: DateTime.now(),
104+
// messageType: MessageType.image,
105+
// sendBy: '1',
106+
// reaction: Reaction(reactions: ['\u{2764}'], reactedUserIds: ['2']),
107+
// status: MessageStatus.read,
108+
// ),
109+
// Message(
110+
// id: '12',
111+
// message: "🤩🤩",
112+
// createdAt: DateTime.now(),
113+
// sendBy: '2',
114+
// status: MessageStatus.read,
115+
// ),
116116
];
117117
}

example/lib/main.dart

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@ class _ChatScreenState extends State<ChatScreen> {
8181
featureActiveConfig: const FeatureActiveConfig(
8282
lastSeenAgoBuilderVisibility: true,
8383
receiptsBuilderVisibility: true,
84+
messageTimePositionType: MessageTimePositionType.insideChatBubble,
8485
),
8586
chatViewState: ChatViewState.hasMessages,
8687
chatViewStateConfig: ChatViewStateConfiguration(

lib/src/models/feature_active_config.dart

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
1+
import 'package:chatview/chatview.dart';
2+
13
class FeatureActiveConfig {
24
const FeatureActiveConfig({
35
this.enableSwipeToReply = true,
46
this.enableReactionPopup = true,
57
this.enableTextField = true,
6-
this.enableSwipeToSeeTime = true,
78
this.enableCurrentUserProfileAvatar = false,
89
this.enableOtherUserProfileAvatar = true,
910
this.enableReplySnackBar = true,
@@ -12,8 +13,8 @@ class FeatureActiveConfig {
1213
this.enableDoubleTapToLike = true,
1314
this.lastSeenAgoBuilderVisibility = true,
1415
this.receiptsBuilderVisibility = true,
15-
});
16-
16+
this.messageTimePositionType = MessageTimePositionType.onRightSwipe,
17+
}) ;
1718
/// Used for enable/disable swipe to reply.
1819
final bool enableSwipeToReply;
1920

@@ -23,9 +24,6 @@ class FeatureActiveConfig {
2324
/// Used for enable/disable text field.
2425
final bool enableTextField;
2526

26-
/// Used for enable/disable swipe whole chat to see message created time.
27-
final bool enableSwipeToSeeTime;
28-
2927
/// Used for enable/disable current user profile circle.
3028
final bool enableCurrentUserProfileAvatar;
3129

@@ -49,4 +47,8 @@ class FeatureActiveConfig {
4947

5048
/// Controls the visibility of the message [receiptsBuilder]
5149
final bool receiptsBuilderVisibility;
50+
51+
/// Controls the Position of message created time.
52+
/// default value: onRightSwipe
53+
final MessageTimePositionType messageTimePositionType;
5254
}

lib/src/models/message_configuration.dart

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,11 @@
1919
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
2020
* SOFTWARE.
2121
*/
22-
import 'package:chatview/src/models/models.dart';
22+
import 'package:chatview/chatview.dart';
2323
import 'package:chatview/src/models/voice_message_configuration.dart';
2424
import 'package:flutter/material.dart';
2525

26+
2627
class MessageConfiguration {
2728
/// Provides configuration of image message appearance.
2829
final ImageMessageConfiguration? imageMessageConfig;
@@ -39,11 +40,15 @@ class MessageConfiguration {
3940
/// Configurations for voice message bubble
4041
final VoiceMessageConfiguration? voiceMessageConfig;
4142

43+
/// Allow user to set custom formatting of message time.
44+
final MessageDateTimeBuilder? messageDateTimeBuilder;
45+
4246
const MessageConfiguration({
4347
this.imageMessageConfig,
4448
this.messageReactionConfig,
4549
this.emojiMessageConfig,
4650
this.customMessageBuilder,
4751
this.voiceMessageConfig,
52+
this.messageDateTimeBuilder,
4853
});
4954
}

lib/src/values/enumaration.dart

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ enum MessageType {
3030
custom
3131
}
3232

33-
/// Events, Wheter the user is still typing a message or has
33+
/// Events, Whether the user is still typing a message or has
3434
/// typed the message
3535
enum TypeWriterStatus { typing, typed }
3636

@@ -52,3 +52,22 @@ extension ChatViewStateExtension on ChatViewState {
5252

5353
bool get noMessages => this == ChatViewState.noData;
5454
}
55+
56+
enum MessageTimePositionType {
57+
/// Used for viewing the message created time inside the chatBubble.
58+
insideChatBubble,
59+
/// Used for viewing the message created time outside the chatBubble.
60+
outsideChatBubble,
61+
/// Used for enable/disable swipe whole chat to see message created time.
62+
onRightSwipe,
63+
/// Used for disabling the viewing of the message created time.
64+
disable;
65+
66+
bool get isInsideChatBubble => this == insideChatBubble;
67+
68+
bool get isOutSideChatBubble => this == outsideChatBubble;
69+
70+
bool get isOnRightSwipe => this == onRightSwipe;
71+
72+
bool get isDisable => this == disable;
73+
}

lib/src/values/typedefs.dart

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,3 +35,4 @@ typedef VoidCallBackWithFuture = Future<void> Function();
3535
typedef StringsCallBack = void Function(String emoji, String messageId);
3636
typedef StringWithReturnWidget = Widget Function(String separator);
3737
typedef DragUpdateDetailsCallback = void Function(DragUpdateDetails);
38+
typedef MessageDateTimeBuilder = Widget Function(DateTime date);

lib/src/widgets/chat_bubble_widget.dart

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -127,13 +127,15 @@ class _ChatBubbleWidgetState extends State<ChatBubbleWidget> {
127127
final messagedUser = chatController?.getUserFromId(widget.message.sendBy);
128128
return Stack(
129129
children: [
130-
if (featureActiveConfig?.enableSwipeToSeeTime ?? true) ...[
130+
if (featureActiveConfig?.messageTimePositionType.isOnRightSwipe ?? true) ...[
131131
Visibility(
132132
visible: widget.slideAnimation?.value.dx == 0.0 ? false : true,
133133
child: Positioned.fill(
134134
child: Align(
135135
alignment: Alignment.centerRight,
136136
child: MessageTimeWidget(
137+
messageDateTimeBuilder:
138+
widget.messageConfig?.messageDateTimeBuilder,
137139
messageTime: widget.message.createdAt,
138140
isCurrentUser: isMessageBySender,
139141
messageTimeIconColor: widget.messageTimeIconColor,

lib/src/widgets/chat_list_widget.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -192,7 +192,7 @@ class _ChatListWidgetState extends State<ChatListWidget>
192192
showTypingIndicator: showTypingIndicator,
193193
scrollController: scrollController,
194194
isEnableSwipeToSeeTime:
195-
featureActiveConfig?.enableSwipeToSeeTime ?? true,
195+
featureActiveConfig?.messageTimePositionType.isOnRightSwipe ?? true,
196196
chatBackgroundConfig: widget.chatBackgroundConfig,
197197
assignReplyMessage: widget.assignReplyMessage,
198198
replyMessage: widget.replyMessage,

lib/src/widgets/image_message_view.dart

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,12 @@
2222
import 'dart:convert';
2323
import 'dart:io';
2424

25+
import 'package:chatview/chatview.dart';
2526
import 'package:chatview/src/extensions/extensions.dart';
26-
import 'package:chatview/src/models/models.dart';
27+
import 'package:chatview/src/widgets/message_time_widget.dart';
2728
import 'package:flutter/material.dart';
2829

30+
import 'chat_view_inherited_widget.dart';
2931
import 'reaction_widget.dart';
3032
import 'share_icon.dart';
3133

@@ -38,6 +40,7 @@ class ImageMessageView extends StatelessWidget {
3840
this.messageReactionConfig,
3941
this.highlightImage = false,
4042
this.highlightScale = 1.2,
43+
this.messageDateTimeBuilder,
4144
}) : super(key: key);
4245

4346
/// Provides message instance of chat.
@@ -58,6 +61,9 @@ class ImageMessageView extends StatelessWidget {
5861
/// Provides scale of highlighted image when user taps on replied image.
5962
final double highlightScale;
6063

64+
/// Allow user to set custom formatting of message time.
65+
final MessageDateTimeBuilder? messageDateTimeBuilder;
66+
6167
String get imageUrl => message.message;
6268

6369
Widget get iconButton => ShareIcon(
@@ -67,6 +73,10 @@ class ImageMessageView extends StatelessWidget {
6773

6874
@override
6975
Widget build(BuildContext context) {
76+
final messageTimePositionType = ChatViewInheritedWidget.of(context)
77+
?.featureActiveConfig
78+
.messageTimePositionType ??
79+
MessageTimePositionType.onRightSwipe;
7080
return Row(
7181
mainAxisSize: MainAxisSize.min,
7282
mainAxisAlignment:
@@ -139,6 +149,17 @@ class ImageMessageView extends StatelessWidget {
139149
reaction: message.reaction,
140150
messageReactionConfig: messageReactionConfig,
141151
),
152+
if (!messageTimePositionType.isOnRightSwipe &&
153+
!messageTimePositionType.isDisable)
154+
Positioned(
155+
right: message.reaction.reactions.isNotEmpty ? 16 : 18,
156+
bottom: 20,
157+
child: messageDateTimeBuilder?.call(message.createdAt) ??
158+
MessageTimeWidget(
159+
isCurrentUser: isMessageBySender,
160+
messageTime: message.createdAt,
161+
),
162+
),
142163
],
143164
),
144165
if (!isMessageBySender) iconButton,

0 commit comments

Comments
 (0)