add read indicators

This commit is contained in:
Salvatore Giordano
2020-06-10 15:21:04 +02:00
parent cf29e62873
commit 7006aace12
3 changed files with 82 additions and 24 deletions
+12 -1
View File
@@ -425,6 +425,16 @@ class _MessageListViewState extends State<MessageListView> {
final isNextUser = final isNextUser =
index - 1 >= 0 && message.user.id == messages[index - 1]?.user?.id; index - 1 >= 0 && message.user.id == messages[index - 1]?.user?.id;
final readList = StreamChannel.of(context)
.channel
.state
.read
.where((read) =>
read.lastRead.isAfter(message.createdAt) &&
(index == 0 ||
read.lastRead.isBefore(messages[index - 1].createdAt)))
.toList();
return MessageWidget( return MessageWidget(
message: message, message: message,
reverse: isMyMessage, reverse: isMyMessage,
@@ -439,7 +449,7 @@ class _MessageListViewState extends State<MessageListView> {
(index == 0 || message.status != MessageSendingStatus.SENT) (index == 0 || message.status != MessageSendingStatus.SENT)
? DisplayWidget.show ? DisplayWidget.show
: DisplayWidget.hide, : DisplayWidget.hide,
showTimestamp: !isNextUser, showTimestamp: !isNextUser || readList.isNotEmpty,
showEditMessage: isMyMessage, showEditMessage: isMyMessage,
showDeleteMessage: isMyMessage, showDeleteMessage: isMyMessage,
borderSide: isMyMessage ? BorderSide.none : null, borderSide: isMyMessage ? BorderSide.none : null,
@@ -455,6 +465,7 @@ class _MessageListViewState extends State<MessageListView> {
messageTheme: isMyMessage messageTheme: isMyMessage
? StreamChatTheme.of(context).ownMessageTheme ? StreamChatTheme.of(context).ownMessageTheme
: StreamChatTheme.of(context).otherMessageTheme, : StreamChatTheme.of(context).otherMessageTheme,
readList: readList,
); );
} }
+69 -22
View File
@@ -97,6 +97,8 @@ class MessageWidget extends StatefulWidget {
/// The function called when tapping on UserAvatar /// The function called when tapping on UserAvatar
final void Function(User) onUserAvatarTap; final void Function(User) onUserAvatarTap;
final List<Read> readList;
/// If true show the users username next to the timestamp of the message /// If true show the users username next to the timestamp of the message
final bool showUsername; final bool showUsername;
final bool showTimestamp; final bool showTimestamp;
@@ -130,6 +132,7 @@ class MessageWidget extends StatefulWidget {
this.editMessageInputBuilder, this.editMessageInputBuilder,
this.textBuilder, this.textBuilder,
Map<String, AttachmentBuilder> customAttachmentBuilders, Map<String, AttachmentBuilder> customAttachmentBuilders,
this.readList,
this.padding, this.padding,
this.textPadding = const EdgeInsets.all(8.0), this.textPadding = const EdgeInsets.all(8.0),
this.attachmentPadding = EdgeInsets.zero, this.attachmentPadding = EdgeInsets.zero,
@@ -298,8 +301,9 @@ class _MessageWidgetState extends State<MessageWidget> {
), ),
if ((widget.message.createdAt != null && if ((widget.message.createdAt != null &&
widget.showTimestamp) || widget.showTimestamp) ||
widget.showUsername) widget.showUsername ||
_buildUsernameAndTimestamp(leftPadding), widget.readList?.isNotEmpty == true)
_buildBottomRow(leftPadding),
], ],
), ),
), ),
@@ -360,36 +364,79 @@ class _MessageWidgetState extends State<MessageWidget> {
); );
} }
Padding _buildUsernameAndTimestamp(double leftPadding) { Padding _buildBottomRow(double leftPadding) {
return Padding( return Padding(
padding: EdgeInsets.only( padding: EdgeInsets.only(
left: leftPadding, left: leftPadding,
top: 2, top: 2,
), ),
child: Transform( child: Row(
alignment: Alignment.center, mainAxisAlignment: MainAxisAlignment.start,
transform: Matrix4.rotationY(widget.reverse ? pi : 0), mainAxisSize: MainAxisSize.min,
child: RichText( children: <Widget>[
text: TextSpan( Transform(
style: widget.messageTheme.createdAt, alignment: Alignment.center,
children: <TextSpan>[ transform: Matrix4.rotationY(widget.reverse ? pi : 0),
if (widget.showUsername) child: RichText(
TextSpan( text: TextSpan(
text: widget.message.user.name, style: widget.messageTheme.createdAt,
style: TextStyle(fontWeight: FontWeight.bold), children: <TextSpan>[
), if (widget.showUsername)
if (widget.message.createdAt != null && widget.showTimestamp) TextSpan(
TextSpan( text: widget.message.user.name,
text: Jiffy(widget.message.createdAt.toLocal()) style: TextStyle(fontWeight: FontWeight.bold),
.format(' HH:mm'), ),
), if (widget.message.createdAt != null && widget.showTimestamp)
], TextSpan(
text: Jiffy(widget.message.createdAt.toLocal())
.format(' HH:mm'),
),
],
),
),
), ),
), if (widget.readList?.isNotEmpty == true)
SizedBox.fromSize(
size: Size(widget.readList.length * 20.0, 17),
child: Transform(
alignment: Alignment.center,
transform: Matrix4.rotationY(widget.reverse ? pi : 0),
child: Padding(
padding: const EdgeInsets.only(left: 4.0),
child: _buildReadIndicator(),
),
),
),
],
), ),
); );
} }
Widget _buildReadIndicator() {
var padding = 0.0;
return Stack(
children: widget.readList.map((e) {
padding += 10.0;
return Positioned(
left: padding - 10,
bottom: 0,
top: 0,
child: Material(
color: Colors.white,
shape: CircleBorder(),
child: Padding(
padding: const EdgeInsets.all(1.0),
child: UserAvatar(
user: e.user,
constraints: BoxConstraints.loose(Size.fromRadius(16)),
),
),
),
);
}).toList(),
);
}
Widget _buildReactionIndicator(BuildContext context) { Widget _buildReactionIndicator(BuildContext context) {
return AnimatedSwitcher( return AnimatedSwitcher(
key: _reactionPickerKey, key: _reactionPickerKey,
+1 -1
View File
@@ -21,7 +21,7 @@ dependencies:
file_picker: ^1.9.0+1 file_picker: ^1.9.0+1
image_picker: ^0.6.7 image_picker: ^0.6.7
flutter_keyboard_visibility: ^3.0.0 flutter_keyboard_visibility: ^3.0.0
stream_chat: ^0.2.0-alpha+19 stream_chat: ^0.2.0-alpha+20
mime: ^0.9.6+3 mime: ^0.9.6+3
visibility_detector: ^0.1.5 visibility_detector: ^0.1.5
http_parser: ^3.1.4 http_parser: ^3.1.4