diff --git a/package/expo-package/yarn.lock b/package/expo-package/yarn.lock index aeb2acdeea..1f25f07e3f 100644 --- a/package/expo-package/yarn.lock +++ b/package/expo-package/yarn.lock @@ -4733,10 +4733,10 @@ stream-buffers@2.2.x, stream-buffers@~2.2.0: resolved "https://registry.yarnpkg.com/stream-buffers/-/stream-buffers-2.2.0.tgz#91d5f5130d1cef96dcfa7f726945188741d09ee4" integrity sha512-uyQK/mx5QjHun80FLJTfaWE7JtwfRMKBLkMne6udYOmvH0CawotVa7TfgYHzAnpphn4+TweIx1QKMnRIbipmUg== -stream-chat-react-native-core@6.7.1: - version "6.7.1" - resolved "https://registry.yarnpkg.com/stream-chat-react-native-core/-/stream-chat-react-native-core-6.7.1.tgz#37cdfbc5c7f8a5bac5634b954da4bbdcd2fb95f2" - integrity sha512-4ePEMt1W+iw3zUulSDRFO9Nt4HPa8kW6wJ3Qv+ZN+y886rvcUuTuH18MFrdrJtHYb+UxCU+X3oz++3qzq7Jzxw== +stream-chat-react-native-core@6.7.2: + version "6.7.2" + resolved "https://registry.yarnpkg.com/stream-chat-react-native-core/-/stream-chat-react-native-core-6.7.2.tgz#955e048b80c55175db084ccbb8519f52ef4bb00c" + integrity sha512-WJFOCfQ7Xpn8Lr4AE6hUh4Qhrn1eGzsoAcKmL8eSoB/etxdNllOyZ3zrwvZgyy+KIEg9bcX4y+3OWtdKW6qfsA== dependencies: "@gorhom/bottom-sheet" "^5.1.1" dayjs "1.10.5" diff --git a/package/native-package/yarn.lock b/package/native-package/yarn.lock index 317331eb77..e586735c0f 100644 --- a/package/native-package/yarn.lock +++ b/package/native-package/yarn.lock @@ -3409,10 +3409,10 @@ statuses@~1.5.0: resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c" integrity sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA== -stream-chat-react-native-core@6.7.1: - version "6.7.1" - resolved "https://registry.yarnpkg.com/stream-chat-react-native-core/-/stream-chat-react-native-core-6.7.1.tgz#37cdfbc5c7f8a5bac5634b954da4bbdcd2fb95f2" - integrity sha512-4ePEMt1W+iw3zUulSDRFO9Nt4HPa8kW6wJ3Qv+ZN+y886rvcUuTuH18MFrdrJtHYb+UxCU+X3oz++3qzq7Jzxw== +stream-chat-react-native-core@6.7.2: + version "6.7.2" + resolved "https://registry.yarnpkg.com/stream-chat-react-native-core/-/stream-chat-react-native-core-6.7.2.tgz#955e048b80c55175db084ccbb8519f52ef4bb00c" + integrity sha512-WJFOCfQ7Xpn8Lr4AE6hUh4Qhrn1eGzsoAcKmL8eSoB/etxdNllOyZ3zrwvZgyy+KIEg9bcX4y+3OWtdKW6qfsA== dependencies: "@gorhom/bottom-sheet" "^5.1.1" dayjs "1.10.5" diff --git a/package/src/components/Channel/Channel.tsx b/package/src/components/Channel/Channel.tsx index ae5ca45407..f9ad338742 100644 --- a/package/src/components/Channel/Channel.tsx +++ b/package/src/components/Channel/Channel.tsx @@ -741,14 +741,33 @@ const ChannelWithContext = < channel, }); - /** - * Since we copy the current channel state all together, we need to find the greatest time among the below two and apply it as the throttling time for copying the channel state. - * This is done until we remove the newMessageStateUpdateThrottleInterval prop. - */ - const copyChannelStateThrottlingTime = - newMessageStateUpdateThrottleInterval > stateUpdateThrottleInterval - ? newMessageStateUpdateThrottleInterval - : stateUpdateThrottleInterval; + const setReadThrottled = useMemo( + () => + throttle( + () => { + if (channel) { + setRead(channel); + } + }, + stateUpdateThrottleInterval, + throttleOptions, + ), + [channel, stateUpdateThrottleInterval, setRead], + ); + + const copyMessagesStateFromChannelThrottled = useMemo( + () => + throttle( + () => { + if (channel) { + copyMessagesStateFromChannel(channel); + } + }, + newMessageStateUpdateThrottleInterval, + throttleOptions, + ), + [channel, newMessageStateUpdateThrottleInterval, copyMessagesStateFromChannel], + ); const copyChannelState = useMemo( () => @@ -759,10 +778,10 @@ const ChannelWithContext = < copyMessagesStateFromChannel(channel); } }, - copyChannelStateThrottlingTime, + stateUpdateThrottleInterval, throttleOptions, ), - [channel, copyChannelStateThrottlingTime, copyMessagesStateFromChannel, copyStateFromChannel], + [stateUpdateThrottleInterval, channel, copyStateFromChannel, copyMessagesStateFromChannel], ); const handleEvent: EventHandler = (event) => { @@ -819,6 +838,16 @@ const ChannelWithContext = < // only update channel state if the events are not the previously subscribed useEffect's subscription events if (channel && channel.initialized) { + if (event.type === 'message.new') { + copyMessagesStateFromChannelThrottled(); + return; + } + + if (event.type === 'message.read' || event.type === 'notification.mark_read') { + setReadThrottled(); + return; + } + copyChannelState(); } } @@ -829,7 +858,7 @@ const ChannelWithContext = < const initChannel = async () => { setLastRead(new Date()); const unreadCount = channel.countUnread(); - if (!channel || !shouldSyncChannel || channel.offlineMode) { + if (!channel || !shouldSyncChannel) { return; } let errored = false; @@ -900,20 +929,6 @@ const ChannelWithContext = < return unsubscribe; }, [channel?.cid, client]); - /** - * Subscription to the Notification mark_read event. - */ - useEffect(() => { - const handleEvent: EventHandler = (event) => { - if (channel.cid === event.cid) { - setRead(channel); - } - }; - - const { unsubscribe } = client.on('notification.mark_read', handleEvent); - return unsubscribe; - }, [channel, client, setRead]); - const threadPropsExists = !!threadProps; useEffect(() => { diff --git a/package/src/components/Channel/__tests__/Channel.test.js b/package/src/components/Channel/__tests__/Channel.test.js index 755f3a28f4..7f263ed528 100644 --- a/package/src/components/Channel/__tests__/Channel.test.js +++ b/package/src/components/Channel/__tests__/Channel.test.js @@ -356,7 +356,7 @@ describe('Channel initial load useEffect', () => { cleanup(); }); - it('should not call channel.watch if channel is not initialized', async () => { + it('should still call channel.watch if we are online and DB channels are loaded', async () => { const messages = Array.from({ length: 10 }, (_, i) => generateMessage({ id: i })); const mockedChannel = generateChannelResponse({ messages, @@ -366,13 +366,18 @@ describe('Channel initial load useEffect', () => { const channel = chatClient.channel('messaging', mockedChannel.id); await channel.watch(); channel.offlineMode = true; - channel.state = channelInitialState; + channel.state = { + ...channelInitialState, + messagePagination: { + hasPrev: true, + }, + }; const watchSpy = jest.fn(); channel.watch = watchSpy; renderComponent({ channel }); - await waitFor(() => expect(watchSpy).not.toHaveBeenCalled()); + await waitFor(() => expect(watchSpy).toHaveBeenCalledTimes(1)); }); it("should call channel.watch if channel is initialized and it's not in offline mode", async () => {