@@ -417,6 +417,9 @@ class _StreamMessageListViewState extends State<StreamMessageListView> {
417
417
if (newStreamChannel != streamChannel) {
418
418
streamChannel = newStreamChannel;
419
419
420
+ debouncedMarkRead.cancel ();
421
+ debouncedMarkThreadRead.cancel ();
422
+
420
423
_messageNewListener? .cancel ();
421
424
_userReadListener? .cancel ();
422
425
@@ -467,8 +470,8 @@ class _StreamMessageListViewState extends State<StreamMessageListView> {
467
470
468
471
@override
469
472
void dispose () {
470
- debouncedMarkRead? .cancel ();
471
- debouncedMarkThreadRead? .cancel ();
473
+ debouncedMarkRead.cancel ();
474
+ debouncedMarkThreadRead.cancel ();
472
475
_messageNewListener? .cancel ();
473
476
_userReadListener? .cancel ();
474
477
_itemPositionListener.itemPositions
@@ -954,29 +957,23 @@ class _StreamMessageListViewState extends State<StreamMessageListView> {
954
957
}
955
958
}
956
959
957
- late final debouncedMarkRead = switch (streamChannel) {
958
- final streamChannel? => debounce (
959
- streamChannel.channel.markRead,
960
- const Duration (seconds: 1 ),
961
- ),
962
- _ => null ,
963
- };
960
+ late final debouncedMarkRead = debounce (
961
+ ([String ? id]) => streamChannel? .channel.markRead (messageId: id),
962
+ const Duration (seconds: 1 ),
963
+ );
964
964
965
- late final debouncedMarkThreadRead = switch (streamChannel) {
966
- final streamChannel? => debounce (
967
- streamChannel.channel.markThreadRead,
968
- const Duration (seconds: 1 ),
969
- ),
970
- _ => null ,
971
- };
965
+ late final debouncedMarkThreadRead = debounce (
966
+ (String parentId) => streamChannel? .channel.markThreadRead (parentId),
967
+ const Duration (seconds: 1 ),
968
+ );
972
969
973
970
Future <void > _markMessagesAsRead () async {
974
- // Mark regular messages as read.
975
- debouncedMarkRead? .call ();
976
-
977
- // Mark thread messages as read.
978
971
if (widget.parentMessage case final parent? ) {
979
- debouncedMarkThreadRead? .call ([parent.id]);
972
+ // If we are in a thread, mark the thread as read.
973
+ debouncedMarkThreadRead.call ([parent.id]);
974
+ } else {
975
+ // Otherwise, mark the channel as read.
976
+ debouncedMarkRead.call ();
980
977
}
981
978
}
982
979
@@ -1473,24 +1470,43 @@ class _StreamMessageListViewState extends State<StreamMessageListView> {
1473
1470
null => true , // Allows setting the initial value.
1474
1471
};
1475
1472
1476
- // If the channel is upToDate and the last fully visible message has
1477
- // been changed, we need to update the value and mark the messages as read.
1478
- if (_upToDate && lastFullyVisibleMessageChanged) {
1473
+ // If the last fully visible message has been changed, we need to update the
1474
+ // value and maybe mark messages as read if needed .
1475
+ if (lastFullyVisibleMessageChanged) {
1479
1476
_lastFullyVisibleMessage = newLastFullyVisibleMessage;
1480
1477
1481
- if (streamChannel? .channel case final channel? ) {
1482
- final hasUnread = (channel.state? .unreadCount ?? 0 ) > 0 ;
1483
- final allowMarkRead = channel.config? .readEvents == true ;
1484
- final canMarkReadAtBottom = widget.markReadWhenAtTheBottom;
1485
-
1486
- // Mark messages as read if it's allowed.
1487
- if (hasUnread && allowMarkRead && canMarkReadAtBottom) {
1488
- return _markMessagesAsRead ().ignore ();
1489
- }
1478
+ // Mark messages as read if needed.
1479
+ if (widget.markReadWhenAtTheBottom) {
1480
+ _maybeMarkMessagesAsRead ().ignore ();
1490
1481
}
1491
1482
}
1492
1483
}
1493
1484
1485
+ // Marks messages as read if the conditions are met.
1486
+ //
1487
+ // The conditions are:
1488
+ // 1. The channel is up to date or we are in a thread conversation.
1489
+ // 2. There are unread messages or we are in a thread conversation.
1490
+ //
1491
+ // If any of the conditions are not met, the function returns early.
1492
+ // Otherwise, it calls the _markMessagesAsRead function to mark the messages
1493
+ // as read.
1494
+ Future <void > _maybeMarkMessagesAsRead () async {
1495
+ final channel = streamChannel? .channel;
1496
+ if (channel == null ) return ;
1497
+
1498
+ final isInThread = widget.parentMessage != null ;
1499
+
1500
+ final isUpToDate = channel.state? .isUpToDate ?? false ;
1501
+ if (! isInThread && ! isUpToDate) return ;
1502
+
1503
+ final hasUnread = (channel.state? .unreadCount ?? 0 ) > 0 ;
1504
+ if (! isInThread && ! hasUnread) return ;
1505
+
1506
+ // Mark messages as read if it's allowed.
1507
+ return _markMessagesAsRead ();
1508
+ }
1509
+
1494
1510
void _getOnThreadTap () {
1495
1511
if (widget.onThreadTap != null ) {
1496
1512
_onThreadTap = (Message message) {
0 commit comments