1- import { useEffect , useMemo , useState } from 'react' ;
1+ import { type SetStateAction , useEffect , useMemo , useState } from 'react' ;
22
33import throttle from 'lodash/throttle' ;
4- import type { Channel , ChannelState , Event , MessageResponse , StreamChat } from 'stream-chat' ;
4+ import type { Channel , Event , LocalMessage , MessageResponse , StreamChat } from 'stream-chat' ;
55
66import { useIsChannelMuted } from './useIsChannelMuted' ;
77
88import { useLatestMessagePreview } from './useLatestMessagePreview' ;
99
1010import { useChannelsContext } from '../../../contexts' ;
11+ import { useStableCallback } from '../../../hooks' ;
12+
13+ const setLastMessageThrottleTimeout = 500 ;
14+ const setLastMessageThrottleOptions = { leading : true , trailing : true } ;
15+
16+ const refreshUnreadCountThrottleTimeout = 400 ;
17+ const refreshUnreadCountThrottleOptions = setLastMessageThrottleOptions ;
18+
19+ type LastMessageType = LocalMessage | MessageResponse ;
1120
1221export const useChannelPreviewData = (
1322 channel : Channel ,
1423 client : StreamChat ,
1524 forceUpdateOverride ?: number ,
1625) => {
1726 const [ forceUpdate , setForceUpdate ] = useState ( 0 ) ;
18- const [ lastMessage , setLastMessage ] = useState <
19- ReturnType < ChannelState [ 'formatMessage' ] > | MessageResponse
20- > ( channel . state . messages [ channel . state . messages . length - 1 ] ) ;
27+ const [ lastMessage , setLastMessageInner ] = useState < LastMessageType > (
28+ ( ) => channel . state . messages [ channel . state . messages . length - 1 ] ,
29+ ) ;
30+ const throttledSetLastMessage = useMemo (
31+ ( ) =>
32+ throttle (
33+ ( newLastMessage : SetStateAction < LastMessageType > ) => setLastMessageInner ( newLastMessage ) ,
34+ setLastMessageThrottleTimeout ,
35+ setLastMessageThrottleOptions ,
36+ ) ,
37+ [ ] ,
38+ ) ;
39+ const setLastMessage = useStableCallback ( ( newLastMessage : SetStateAction < LastMessageType > ) =>
40+ throttledSetLastMessage ( newLastMessage ) ,
41+ ) ;
2142 const [ unread , setUnread ] = useState ( channel . countUnread ( ) ) ;
2243 const { muted } = useIsChannelMuted ( channel ) ;
2344 const { forceUpdate : contextForceUpdate } = useChannelsContext ( ) ;
@@ -26,29 +47,50 @@ export const useChannelPreviewData = (
2647 const channelLastMessage = channel . lastMessage ( ) ;
2748 const channelLastMessageString = `${ channelLastMessage ?. id } ${ channelLastMessage ?. updated_at } ` ;
2849
50+ const refreshUnreadCount = useMemo (
51+ ( ) =>
52+ throttle (
53+ ( ) => {
54+ if ( muted ) {
55+ setUnread ( 0 ) ;
56+ } else {
57+ setUnread ( channel . countUnread ( ) ) ;
58+ }
59+ } ,
60+ refreshUnreadCountThrottleTimeout ,
61+ refreshUnreadCountThrottleOptions ,
62+ ) ,
63+ [ channel , muted ] ,
64+ ) ;
65+
2966 useEffect ( ( ) => {
3067 const unsubscribe = channel . messageComposer . registerDraftEventSubscriptions ( ) ;
3168 return ( ) => unsubscribe ( ) ;
3269 } , [ channel . messageComposer ] ) ;
3370
3471 useEffect ( ( ) => {
3572 const { unsubscribe } = client . on ( 'notification.mark_read' , ( ) => {
36- setUnread ( channel . countUnread ( ) ) ;
73+ refreshUnreadCount ( ) ;
3774 } ) ;
3875 return unsubscribe ;
39- } , [ channel , client ] ) ;
76+ } , [ client , refreshUnreadCount ] ) ;
4077
4178 useEffect ( ( ) => {
42- if (
79+ setLastMessage ( ( prevLastMessage ) =>
4380 channelLastMessage &&
44- ( channelLastMessage . id !== lastMessage ?. id ||
45- channelLastMessage . updated_at !== lastMessage ?. updated_at )
46- ) {
47- setLastMessage ( channelLastMessage ) ;
48- }
49- const newUnreadCount = channel . countUnread ( ) ;
50- setUnread ( newUnreadCount ) ;
51- } , [ channel , channelLastMessage , channelLastMessageString , channelListForceUpdate , lastMessage ] ) ;
81+ ( channelLastMessage . id !== prevLastMessage ?. id ||
82+ channelLastMessage . updated_at !== prevLastMessage ?. updated_at )
83+ ? channelLastMessage
84+ : prevLastMessage ,
85+ ) ;
86+ refreshUnreadCount ( ) ;
87+ } , [
88+ channelLastMessage ,
89+ channelLastMessageString ,
90+ channelListForceUpdate ,
91+ setLastMessage ,
92+ refreshUnreadCount ,
93+ ] ) ;
5294
5395 /**
5496 * This effect listens for the `notification.mark_read` event and sets the unread count to 0
@@ -91,18 +133,6 @@ export const useChannelPreviewData = (
91133 return unsubscribe ;
92134 } , [ client , channel ] ) ;
93135
94- const refreshUnreadCount = useMemo (
95- ( ) =>
96- throttle ( ( ) => {
97- if ( muted ) {
98- setUnread ( 0 ) ;
99- } else {
100- setUnread ( channel . countUnread ( ) ) ;
101- }
102- } , 400 ) ,
103- [ channel , muted ] ,
104- ) ;
105-
106136 /**
107137 * This effect listens for the `message.new`, `message.updated`, `message.deleted`, `message.undeleted`, and `channel.truncated` events
108138 */
@@ -118,7 +148,7 @@ export const useChannelPreviewData = (
118148 const message = event . message ;
119149 if ( message && ( ! message . parent_id || message . show_in_channel ) ) {
120150 setLastMessage ( message ) ;
121- setUnread ( channel . countUnread ( ) ) ;
151+ refreshUnreadCount ( ) ;
122152 }
123153 } ;
124154
@@ -140,9 +170,13 @@ export const useChannelPreviewData = (
140170 ] ;
141171
142172 return ( ) => listeners . forEach ( ( l ) => l . unsubscribe ( ) ) ;
143- } , [ channel , refreshUnreadCount , forceUpdate , channelListForceUpdate ] ) ;
173+ } , [ channel , refreshUnreadCount , forceUpdate , channelListForceUpdate , setLastMessage ] ) ;
144174
145- const latestMessagePreview = useLatestMessagePreview ( channel , forceUpdate , lastMessage ) ;
175+ const latestMessagePreview = useLatestMessagePreview (
176+ channel ,
177+ forceUpdate ,
178+ lastMessage as LocalMessage ,
179+ ) ;
146180
147181 return { latestMessagePreview, muted, unread } ;
148182} ;
0 commit comments