11import { useEffect , useMemo , useRef , useState } from 'react' ;
22
3- import type { Channel , ChannelFilters , ChannelOptions , ChannelSort } from 'stream-chat' ;
3+ import {
4+ Channel ,
5+ ChannelFilters ,
6+ ChannelManager ,
7+ ChannelManagerState ,
8+ ChannelOptions ,
9+ ChannelSort ,
10+ } from 'stream-chat' ;
411
512import { useActiveChannelsRefContext } from '../../../contexts/activeChannelsRefContext/ActiveChannelsRefContext' ;
613import { useChatContext } from '../../../contexts/chatContext/ChatContext' ;
14+ import { useStateStore } from '../../../hooks' ;
715import { useIsMountedRef } from '../../../hooks/useIsMountedRef' ;
816
917import { getChannelsForFilterSort } from '../../../store/apis/getChannelsForFilterSort' ;
@@ -24,6 +32,7 @@ type Parameters<StreamChatGenerics extends DefaultStreamChatGenerics = DefaultSt
2432 options : ChannelOptions ;
2533 setForceUpdate : React . Dispatch < React . SetStateAction < number > > ;
2634 sort : ChannelSort < StreamChatGenerics > ;
35+ channelManager ?: ChannelManager < StreamChatGenerics > ;
2736 } ;
2837
2938const DEFAULT_OPTIONS = {
@@ -37,23 +46,32 @@ type QueryType = 'queryLocalDB' | 'reload' | 'refresh' | 'loadChannels';
3746
3847export type QueryChannels = ( queryType ?: QueryType , retryCount ?: number ) => Promise < void > ;
3948
49+ const selector = ( nextValue : ChannelManagerState ) =>
50+ ( {
51+ channels : nextValue . channels ,
52+ pagination : nextValue . pagination ,
53+ } as const ) ;
54+
4055export const usePaginatedChannels = <
4156 StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics ,
4257> ( {
58+ channelManager,
4359 enableOfflineSupport,
4460 filters = { } ,
4561 options = DEFAULT_OPTIONS ,
4662 setForceUpdate,
4763 sort = { } ,
4864} : Parameters < StreamChatGenerics > ) => {
49- const [ channels , setChannels ] = useState < Channel < StreamChatGenerics > [ ] | null > ( null ) ;
65+ // const [channels, setChannels] = useState<Channel<StreamChatGenerics>[] | null>(null);
5066 const [ error , setError ] = useState < Error | undefined > ( undefined ) ;
5167 const [ staticChannelsActive , setStaticChannelsActive ] = useState < boolean > ( false ) ;
5268 const [ activeQueryType , setActiveQueryType ] = useState < QueryType | null > ( 'queryLocalDB' ) ;
53- const [ hasNextPage , setHasNextPage ] = useState < boolean > ( false ) ;
69+ // const [hasNextPage, setHasNextPage] = useState<boolean>(false);
5470 const activeChannels = useActiveChannelsRefContext ( ) ;
5571 const isMountedRef = useIsMountedRef ( ) ;
5672 const { client } = useChatContext < StreamChatGenerics > ( ) ;
73+ const { channels, pagination } = useStateStore ( channelManager ?. state , selector ) ?? { } ;
74+ const hasNextPage = pagination ?. hasNext ;
5775
5876 const filtersRef = useRef < typeof filters | null > ( null ) ;
5977 const sortRef = useRef < typeof sort | null > ( null ) ;
@@ -95,8 +113,7 @@ export const usePaginatedChannels = <
95113
96114 const newOptions = {
97115 limit : options ?. limit ?? MAX_QUERY_CHANNELS_LIMIT ,
98- offset :
99- queryType === 'loadChannels' && ! staticChannelsActive && channels ? channels . length : 0 ,
116+ offset : 0 ,
100117 ...options ,
101118 } ;
102119
@@ -106,28 +123,32 @@ export const usePaginatedChannels = <
106123 * when they all (may) update the channel state at the same time (when connection state recovers)
107124 * TODO: if we move the channel state to a single context and share it between ChannelList, Channel and Thread we can remove this
108125 */
109- const channelQueryResponse = await client . queryChannels ( filters , sort , newOptions , {
110- skipInitialization : enableOfflineSupport ? undefined : activeChannels . current ,
111- } ) ;
126+ if ( queryType === 'loadChannels' ) {
127+ await channelManager ?. loadNext ( ) ;
128+ } else {
129+ await channelManager ?. queryChannels ( filters , sort , newOptions , {
130+ skipInitialization : enableOfflineSupport ? undefined : activeChannels . current ,
131+ } ) ;
132+ }
112133 if ( isQueryStale ( ) || ! isMountedRef . current ) {
113134 return ;
114135 }
115136
116- const newChannels =
117- queryType === 'loadChannels' && ! staticChannelsActive && channels
118- ? [ ...channels , ...channelQueryResponse ]
119- : channelQueryResponse . map ( ( c ) => {
120- const existingChannel = client . activeChannels [ c . cid ] ;
121- if ( existingChannel ) {
122- return existingChannel ;
123- }
124-
125- return c ;
126- } ) ;
127-
128- setChannels ( newChannels ) ;
137+ // const newChannels =
138+ // queryType === 'loadChannels' && !staticChannelsActive && channels
139+ // ? [...channels, ...channelQueryResponse]
140+ // : channelQueryResponse.map((c) => {
141+ // const existingChannel = client.activeChannels[c.cid];
142+ // if (existingChannel) {
143+ // return existingChannel;
144+ // }
145+ //
146+ // return c;
147+ // });
148+
149+ // setChannels(newChannels);
129150 setStaticChannelsActive ( false ) ;
130- setHasNextPage ( channelQueryResponse . length >= newOptions . limit ) ;
151+ // setHasNextPage(channelQueryResponse.length >= newOptions.limit);
131152 isQueryingRef . current = false ;
132153 } catch ( err : unknown ) {
133154 isQueryingRef . current = false ;
@@ -207,7 +228,7 @@ export const usePaginatedChannels = <
207228 skipInitialization : [ ] , // passing empty array will clear out the existing messages from channel state, this removes the possibility of duplicate messages
208229 } ) ;
209230
210- setChannels ( offlineChannels ) ;
231+ channelManager ?. setChannels ( offlineChannels ) ;
211232 setStaticChannelsActive ( true ) ;
212233 }
213234 } catch ( e ) {
@@ -257,26 +278,18 @@ export const usePaginatedChannels = <
257278
258279 return ( ) => listener ?. unsubscribe ?.( ) ;
259280 // eslint-disable-next-line react-hooks/exhaustive-deps
260- } , [ filterStr , sortStr ] ) ;
281+ } , [ filterStr , sortStr , channelManager ] ) ;
261282
262283 return {
263284 channels,
264285 error,
265286 hasNextPage,
266- loadingChannels :
267- activeQueryType === 'queryLocalDB'
268- ? true
269- : ( activeQueryType === 'reload' || activeQueryType === null ) && channels === null ,
287+ loadingChannels : activeQueryType === 'queryLocalDB' ? true : pagination . isLoading ,
270288 loadingNextPage : activeQueryType === 'loadChannels' ,
271- loadNextPage : queryChannels ,
289+ loadNextPage : channelManager ?. loadNext ,
272290 refreshing : activeQueryType === 'refresh' ,
273291 refreshList,
274292 reloadList,
275- // Although channels can be null, there is no practical case where channels will be null
276- // when setChannels is used. setChannels is only recommended to be used for overriding
277- // event handler. Thus instead of adding if check for channels === null, its better to
278- // simply reassign types here.
279- setChannels,
280293 staticChannelsActive,
281294 } ;
282295} ;
0 commit comments