Skip to content

Channel markReadOnMount does not work if the channel was not initialized before #3067

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
danmana opened this issue Apr 28, 2025 · 1 comment

Comments

@danmana
Copy link

danmana commented Apr 28, 2025

When opening a <Channel> directly, with an uninitialized channel the auto markRead functionality does not work.
Note that we are not coming from the ChannelList, but from one of our components directly opening a <Channel>.

Something like this

const channel  = client.channel('messaging', channelId);

  return (
    <Channel channel={channel}>
      <MessageList />
      <MessageInput />
    </Channel>
  );
  1. In the initChannel useEffect, the unreadCount is not correct when read at the top, because the channel was not yet watched/initialized (which happens a few lines below)

const initChannel = async () => {
setLastRead(new Date());
const unreadCount = channel.countUnread();
if (!channel || !shouldSyncChannel || channel.offlineMode) {
return;
}
let errored = false;
if (!channel.initialized || !channel.state.isUpToDate) {
try {
await channel?.watch();
} catch (err) {
console.warn('Channel watch request failed with error:', err);
setError(true);
errored = true;
}
}

Moving the const unreadCount = channel.countUnread(); after the .watch() solves this.

  1. In initChannel when markRead is called (for a freshly initialized channel), the clientChannelConfig closure is still undefined, and markRead will do nothing.

clientChannelConfig will become defined only on the next render, but getChannelConfigSafely() is defined because we just called .watch()

if (unreadCount > 0 && markReadOnMount) {
await markRead({ updateChannelUnreadState: false });
}

const markRead: ChannelContextValue<StreamChatGenerics>['markRead'] = throttle(
async (options?: MarkReadFunctionOptions) => {
const { updateChannelUnreadState = true } = options ?? {};
if (!channel || channel?.disconnected || !clientChannelConfig?.read_events) {
return;
}

Changing clientChannelConfig to getChannelConfigSafely() fixes the issue


Here is a patch I generated for stream-chat-react-native-core@6.7.1 using patch-package, which fixes the markRead issues on an un-initialized channel

diff --git a/node_modules/stream-chat-react-native-core/src/components/Channel/Channel.tsx b/node_modules/stream-chat-react-native-core/src/components/Channel/Channel.tsx
index 1bc8ad5..fe31bd0 100644
--- a/node_modules/stream-chat-react-native-core/src/components/Channel/Channel.tsx
+++ b/node_modules/stream-chat-react-native-core/src/components/Channel/Channel.tsx
@@ -826,7 +826,6 @@ const ChannelWithContext = <
     let listener: ReturnType<typeof channel.on>;
     const initChannel = async () => {
       setLastRead(new Date());
-      const unreadCount = channel.countUnread();
       if (!channel || !shouldSyncChannel || channel.offlineMode) {
         return;
       }
@@ -842,6 +841,9 @@ const ChannelWithContext = <
         }
       }
 
+      // Fix: count unread messages after channel is initialized/watched
+      const unreadCount = channel.countUnread();
+
       if (!errored) {
         initStateFromChannel(channel);
         loadInitialMessagesStateFromChannel(channel, channel.state.messagePagination.hasPrev);
@@ -947,7 +949,8 @@ const ChannelWithContext = <
   const markRead: ChannelContextValue<StreamChatGenerics>['markRead'] = throttle(
     async (options?: MarkReadFunctionOptions) => {
       const { updateChannelUnreadState = true } = options ?? {};
-      if (!channel || channel?.disconnected || !clientChannelConfig?.read_events) {
+      // Fix: use getChannelConfigSafely() instead of clientChannelConfig because of closure issue when the channel is initialized in initChannel
+      if (!channel || channel?.disconnected || !getChannelConfigSafely()?.read_events) {
         return;
       }
 

This issue body was partially generated by patch-package.

@danmana
Copy link
Author

danmana commented Apr 28, 2025

May be related to #3058

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant