@@ -1641,6 +1641,14 @@ class Channel {
16411641 /// read from a particular message onwards.
16421642 Future <EmptyResponse > markRead ({String ? messageId}) async {
16431643 _checkInitialized ();
1644+
1645+ if (! canReceiveReadEvents) {
1646+ throw const StreamChatError (
1647+ 'Cannot mark as read: Channel does not support read events. '
1648+ 'Enable read_events in your channel type configuration.' ,
1649+ );
1650+ }
1651+
16441652 return _client.markChannelRead (id! , type, messageId: messageId);
16451653 }
16461654
@@ -1650,19 +1658,43 @@ class Channel {
16501658 /// to be marked as unread.
16511659 Future <EmptyResponse > markUnread (String messageId) async {
16521660 _checkInitialized ();
1661+
1662+ if (! canReceiveReadEvents) {
1663+ throw const StreamChatError (
1664+ 'Cannot mark as unread: Channel does not support read events. '
1665+ 'Enable read_events in your channel type configuration.' ,
1666+ );
1667+ }
1668+
16531669 return _client.markChannelUnread (id! , type, messageId);
16541670 }
16551671
16561672 /// Mark the thread with [threadId] in the channel as read.
1657- Future <EmptyResponse > markThreadRead (String threadId) {
1673+ Future <EmptyResponse > markThreadRead (String threadId) async {
16581674 _checkInitialized ();
1659- return client.markThreadRead (id! , type, threadId);
1675+
1676+ if (! canReceiveReadEvents) {
1677+ throw const StreamChatError (
1678+ 'Cannot mark thread as read: Channel does not support read events. '
1679+ 'Enable read_events in your channel type configuration.' ,
1680+ );
1681+ }
1682+
1683+ return _client.markThreadRead (id! , type, threadId);
16601684 }
16611685
16621686 /// Mark the thread with [threadId] in the channel as unread.
1663- Future <EmptyResponse > markThreadUnread (String threadId) {
1687+ Future <EmptyResponse > markThreadUnread (String threadId) async {
16641688 _checkInitialized ();
1665- return client.markThreadUnread (id! , type, threadId);
1689+
1690+ if (! canReceiveReadEvents) {
1691+ throw const StreamChatError (
1692+ 'Cannot mark thread as unread: Channel does not support read events. '
1693+ 'Enable read_events in your channel type configuration.' ,
1694+ );
1695+ }
1696+
1697+ return _client.markThreadUnread (id! , type, threadId);
16661698 }
16671699
16681700 void _initState (ChannelState channelState) {
@@ -2066,20 +2098,29 @@ class Channel {
20662098 onStopTyping: stopTyping,
20672099 );
20682100
2101+ // Whether sending typing events is allowed in the channel and by the user
2102+ // privacy settings.
2103+ bool get _canSendTypingEvents {
2104+ final currentUser = client.state.currentUser;
2105+ final typingIndicatorsEnabled = currentUser? .isTypingIndicatorsEnabled;
2106+
2107+ return canUseTypingEvents && (typingIndicatorsEnabled ?? true );
2108+ }
2109+
20692110 /// Sends the [Event.typingStart] event and schedules a timer to invoke the
20702111 /// [Event.typingStop] event.
20712112 ///
20722113 /// This is meant to be called every time the user presses a key.
20732114 Future <void > keyStroke ([String ? parentId]) async {
2074- if (config ? .typingEvents == false ) return ;
2115+ if (! _canSendTypingEvents ) return ;
20752116
20762117 client.logger.info ('KeyStroke received' );
20772118 return _keyStrokeHandler (parentId);
20782119 }
20792120
20802121 /// Sends the [EventType.typingStart] event.
20812122 Future <void > startTyping ([String ? parentId]) async {
2082- if (config ? .typingEvents == false ) return ;
2123+ if (! _canSendTypingEvents ) return ;
20832124
20842125 client.logger.info ('start typing' );
20852126 await sendEvent (Event (
@@ -2090,7 +2131,7 @@ class Channel {
20902131
20912132 /// Sends the [EventType.typingStop] event.
20922133 Future <void > stopTyping ([String ? parentId]) async {
2093- if (config ? .typingEvents == false ) return ;
2134+ if (! _canSendTypingEvents ) return ;
20942135
20952136 client.logger.info ('stop typing' );
20962137 await sendEvent (Event (
@@ -3091,8 +3132,6 @@ class ChannelClientState {
30913132 }
30923133
30933134 void _listenReadEvents () {
3094- if (_channelState.channel? .config.readEvents == false ) return ;
3095-
30963135 _subscriptions
30973136 ..add (
30983137 _channel
@@ -3489,17 +3528,17 @@ class ChannelClientState {
34893528 final _typingEventsController = BehaviorSubject .seeded (< User , Event > {});
34903529
34913530 void _listenTypingEvents () {
3492- if (_channelState.channel? .config.typingEvents == false ) return ;
3493-
3494- final currentUser = _channel.client.state.currentUser;
3495- if (currentUser == null ) return ;
3496-
34973531 _subscriptions
34983532 ..add (
34993533 _channel.on (EventType .typingStart).listen (
35003534 (event) {
35013535 final user = event.user;
3502- if (user != null && user.id != currentUser.id) {
3536+ if (user == null ) return ;
3537+
3538+ final currentUser = _channel.client.state.currentUser;
3539+ if (currentUser == null ) return ;
3540+
3541+ if (user.id != currentUser.id) {
35033542 final events = {...typingEvents};
35043543 events[user] = event;
35053544 _typingEventsController.safeAdd (events);
@@ -3511,7 +3550,12 @@ class ChannelClientState {
35113550 _channel.on (EventType .typingStop).listen (
35123551 (event) {
35133552 final user = event.user;
3514- if (user != null && user.id != currentUser.id) {
3553+ if (user == null ) return ;
3554+
3555+ final currentUser = _channel.client.state.currentUser;
3556+ if (currentUser == null ) return ;
3557+
3558+ if (user.id != currentUser.id) {
35153559 final events = {...typingEvents}..remove (user);
35163560 _typingEventsController.safeAdd (events);
35173561 }
@@ -3526,8 +3570,6 @@ class ChannelClientState {
35263570 // the sender due to technical difficulties. e.g. process death, loss of
35273571 // Internet connection or custom implementation.
35283572 void _startCleaningStaleTypingEvents () {
3529- if (_channelState.channel? .config.typingEvents == false ) return ;
3530-
35313573 _staleTypingEventsCleanerTimer = Timer .periodic (
35323574 const Duration (seconds: 1 ),
35333575 (_) {
@@ -3703,7 +3745,9 @@ extension ChannelCapabilityCheck on Channel {
37033745 }
37043746
37053747 /// True, if the current user can send typing events.
3748+ @Deprecated ('Use canUseTypingEvents instead' )
37063749 bool get canSendTypingEvents {
3750+ if (canUseTypingEvents) return true ;
37073751 return ownCapabilities.contains (ChannelCapability .sendTypingEvents);
37083752 }
37093753
0 commit comments