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 =
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(
message: message,
reverse: isMyMessage,
@@ -439,7 +449,7 @@ class _MessageListViewState extends State<MessageListView> {
(index == 0 || message.status != MessageSendingStatus.SENT)
? DisplayWidget.show
: DisplayWidget.hide,
showTimestamp: !isNextUser,
showTimestamp: !isNextUser || readList.isNotEmpty,
showEditMessage: isMyMessage,
showDeleteMessage: isMyMessage,
borderSide: isMyMessage ? BorderSide.none : null,
@@ -455,6 +465,7 @@ class _MessageListViewState extends State<MessageListView> {
messageTheme: isMyMessage
? StreamChatTheme.of(context).ownMessageTheme
: 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
final void Function(User) onUserAvatarTap;
final List<Read> readList;
/// If true show the users username next to the timestamp of the message
final bool showUsername;
final bool showTimestamp;
@@ -130,6 +132,7 @@ class MessageWidget extends StatefulWidget {
this.editMessageInputBuilder,
this.textBuilder,
Map<String, AttachmentBuilder> customAttachmentBuilders,
this.readList,
this.padding,
this.textPadding = const EdgeInsets.all(8.0),
this.attachmentPadding = EdgeInsets.zero,
@@ -298,8 +301,9 @@ class _MessageWidgetState extends State<MessageWidget> {
),
if ((widget.message.createdAt != null &&
widget.showTimestamp) ||
widget.showUsername)
_buildUsernameAndTimestamp(leftPadding),
widget.showUsername ||
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(
padding: EdgeInsets.only(
left: leftPadding,
top: 2,
),
child: Transform(
alignment: Alignment.center,
transform: Matrix4.rotationY(widget.reverse ? pi : 0),
child: RichText(
text: TextSpan(
style: widget.messageTheme.createdAt,
children: <TextSpan>[
if (widget.showUsername)
TextSpan(
text: widget.message.user.name,
style: TextStyle(fontWeight: FontWeight.bold),
),
if (widget.message.createdAt != null && widget.showTimestamp)
TextSpan(
text: Jiffy(widget.message.createdAt.toLocal())
.format(' HH:mm'),
),
],
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Transform(
alignment: Alignment.center,
transform: Matrix4.rotationY(widget.reverse ? pi : 0),
child: RichText(
text: TextSpan(
style: widget.messageTheme.createdAt,
children: <TextSpan>[
if (widget.showUsername)
TextSpan(
text: widget.message.user.name,
style: TextStyle(fontWeight: FontWeight.bold),
),
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) {
return AnimatedSwitcher(
key: _reactionPickerKey,
+1 -1
View File
@@ -21,7 +21,7 @@ dependencies:
file_picker: ^1.9.0+1
image_picker: ^0.6.7
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
visibility_detector: ^0.1.5
http_parser: ^3.1.4