fix(ui): listen for read events in the message widget
This commit is contained in:
@@ -1,3 +1,4 @@
|
|||||||
|
import 'package:equatable/equatable.dart';
|
||||||
import 'package:json_annotation/json_annotation.dart';
|
import 'package:json_annotation/json_annotation.dart';
|
||||||
import 'package:stream_chat/src/core/models/user.dart';
|
import 'package:stream_chat/src/core/models/user.dart';
|
||||||
|
|
||||||
@@ -5,7 +6,7 @@ part 'read.g.dart';
|
|||||||
|
|
||||||
/// The class that defines a read event
|
/// The class that defines a read event
|
||||||
@JsonSerializable()
|
@JsonSerializable()
|
||||||
class Read {
|
class Read extends Equatable {
|
||||||
/// Constructor used for json serialization
|
/// Constructor used for json serialization
|
||||||
Read({
|
Read({
|
||||||
required this.lastRead,
|
required this.lastRead,
|
||||||
@@ -39,4 +40,11 @@ class Read {
|
|||||||
user: user ?? this.user,
|
user: user ?? this.user,
|
||||||
unreadMessages: unreadMessages ?? this.unreadMessages,
|
unreadMessages: unreadMessages ?? this.unreadMessages,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@override
|
||||||
|
List<Object?> get props => [
|
||||||
|
lastRead,
|
||||||
|
user,
|
||||||
|
unreadMessages,
|
||||||
|
];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -126,16 +126,26 @@ class ChannelPreview extends StatelessWidget {
|
|||||||
streamChatState.currentUser?.id) {
|
streamChatState.currentUser?.id) {
|
||||||
return Padding(
|
return Padding(
|
||||||
padding: const EdgeInsets.only(right: 4),
|
padding: const EdgeInsets.only(right: 4),
|
||||||
child: SendingIndicator(
|
child: BetterStreamBuilder<List<Read>>(
|
||||||
message: lastMessage!,
|
stream: channel.state?.readStream,
|
||||||
size: channelPreviewTheme.indicatorIconSize,
|
initialData: channel.state?.read,
|
||||||
isMessageRead: channel.state!.read
|
builder: (context, data) {
|
||||||
.where((element) =>
|
final readList = data.where((it) =>
|
||||||
element.user.id !=
|
it.user.id !=
|
||||||
channel.client.state.currentUser!.id)
|
channel.client.state.currentUser?.id &&
|
||||||
.where((element) => element.lastRead
|
(it.lastRead
|
||||||
.isAfter(lastMessage.createdAt))
|
.isAfter(lastMessage!.createdAt) ||
|
||||||
.isNotEmpty,
|
it.lastRead.isAtSameMomentAs(
|
||||||
|
lastMessage.createdAt,
|
||||||
|
)));
|
||||||
|
final isMessageRead = readList.length >=
|
||||||
|
(channel.memberCount ?? 0) - 1;
|
||||||
|
return SendingIndicator(
|
||||||
|
message: lastMessage!,
|
||||||
|
size: channelPreviewTheme.indicatorIconSize,
|
||||||
|
isMessageRead: isMessageRead,
|
||||||
|
);
|
||||||
|
},
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -97,14 +97,20 @@ class MessageWidget extends StatefulWidget {
|
|||||||
this.deletedBottomRowBuilder,
|
this.deletedBottomRowBuilder,
|
||||||
this.onReturnAction,
|
this.onReturnAction,
|
||||||
this.customAttachmentBuilders,
|
this.customAttachmentBuilders,
|
||||||
this.readList,
|
|
||||||
this.padding,
|
this.padding,
|
||||||
this.textPadding = const EdgeInsets.symmetric(
|
this.textPadding = const EdgeInsets.symmetric(
|
||||||
horizontal: 16,
|
horizontal: 16,
|
||||||
vertical: 8,
|
vertical: 8,
|
||||||
),
|
),
|
||||||
this.attachmentPadding = EdgeInsets.zero,
|
this.attachmentPadding = EdgeInsets.zero,
|
||||||
this.allRead = false,
|
@Deprecated('''
|
||||||
|
allRead is now deprecated and it will be removed in future releases.
|
||||||
|
The MessageWidget now listens for read events on its own.
|
||||||
|
''') this.allRead = false,
|
||||||
|
@Deprecated('''
|
||||||
|
readList is now deprecated and it will be removed in future releases.
|
||||||
|
The MessageWidget now listens for read events on its own.
|
||||||
|
''') this.readList,
|
||||||
this.onQuotedMessageTap,
|
this.onQuotedMessageTap,
|
||||||
this.customActions = const [],
|
this.customActions = const [],
|
||||||
this.onAttachmentTap,
|
this.onAttachmentTap,
|
||||||
@@ -558,8 +564,6 @@ class _MessageWidgetState extends State<MessageWidget>
|
|||||||
|
|
||||||
bool get showTimeStamp => widget.showTimestamp;
|
bool get showTimeStamp => widget.showTimestamp;
|
||||||
|
|
||||||
bool get isMessageRead => widget.readList?.isNotEmpty == true;
|
|
||||||
|
|
||||||
bool get showInChannel => widget.showInChannelIndicator;
|
bool get showInChannel => widget.showInChannelIndicator;
|
||||||
|
|
||||||
bool get hasQuotedMessage => widget.message.quotedMessage != null;
|
bool get hasQuotedMessage => widget.message.quotedMessage != null;
|
||||||
@@ -1253,27 +1257,40 @@ class _MessageWidgetState extends State<MessageWidget>
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget child = SendingIndicator(
|
final channel = StreamChannel.of(context).channel;
|
||||||
message: message,
|
|
||||||
isMessageRead: isMessageRead,
|
return BetterStreamBuilder<List<Read>>(
|
||||||
size: style!.fontSize,
|
stream: channel.state?.readStream,
|
||||||
|
initialData: channel.state?.read,
|
||||||
|
builder: (context, data) {
|
||||||
|
final readList = data.where((it) =>
|
||||||
|
it.user.id != _streamChat.currentUser?.id &&
|
||||||
|
(it.lastRead.isAfter(message.createdAt) ||
|
||||||
|
it.lastRead.isAtSameMomentAs(message.createdAt)));
|
||||||
|
final isMessageRead = readList.length >= (channel.memberCount ?? 0) - 1;
|
||||||
|
Widget child = SendingIndicator(
|
||||||
|
message: message,
|
||||||
|
isMessageRead: isMessageRead,
|
||||||
|
size: style!.fontSize,
|
||||||
|
);
|
||||||
|
if (isMessageRead) {
|
||||||
|
child = Row(
|
||||||
|
children: [
|
||||||
|
if (memberCount > 2)
|
||||||
|
Text(
|
||||||
|
readList.length.toString(),
|
||||||
|
style: style.copyWith(
|
||||||
|
color: _streamChatTheme.colorTheme.accentPrimary,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(width: 2),
|
||||||
|
child,
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return child;
|
||||||
|
},
|
||||||
);
|
);
|
||||||
if (isMessageRead) {
|
|
||||||
child = Row(
|
|
||||||
children: [
|
|
||||||
if (memberCount > 2)
|
|
||||||
Text(
|
|
||||||
widget.readList!.length.toString(),
|
|
||||||
style: style.copyWith(
|
|
||||||
color: _streamChatTheme.colorTheme.accentPrimary,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
const SizedBox(width: 2),
|
|
||||||
child,
|
|
||||||
],
|
|
||||||
);
|
|
||||||
}
|
|
||||||
return child;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget _buildUserAvatar() => Transform.translate(
|
Widget _buildUserAvatar() => Transform.translate(
|
||||||
|
|||||||
Reference in New Issue
Block a user