@@ -2,20 +2,11 @@ import React, { useCallback, useEffect, useRef, useState } from 'react';
2
2
import clsx from 'clsx' ;
3
3
4
4
import { ChannelListMessenger , ChannelListMessengerProps } from './ChannelListMessenger' ;
5
- import { useChannelDeletedListener } from './hooks/useChannelDeletedListener' ;
6
- import { useChannelHiddenListener } from './hooks/useChannelHiddenListener' ;
7
- import { useChannelTruncatedListener } from './hooks/useChannelTruncatedListener' ;
8
- import { useChannelUpdatedListener } from './hooks/useChannelUpdatedListener' ;
9
- import { useChannelVisibleListener } from './hooks/useChannelVisibleListener' ;
10
5
import { useConnectionRecoveredListener } from './hooks/useConnectionRecoveredListener' ;
11
- import { useMessageNewListener } from './hooks/useMessageNewListener' ;
12
6
import { useMobileNavigation } from './hooks/useMobileNavigation' ;
13
- import { useNotificationAddedToChannelListener } from './hooks/useNotificationAddedToChannelListener' ;
14
- import { useNotificationMessageNewListener } from './hooks/useNotificationMessageNewListener' ;
15
- import { useNotificationRemovedFromChannelListener } from './hooks/useNotificationRemovedFromChannelListener' ;
16
7
import { CustomQueryChannelsFn , usePaginatedChannels } from './hooks/usePaginatedChannels' ;
17
- import { useUserPresenceChangedListener } from './hooks/useUserPresenceChangedListener ' ;
18
- import { MAX_QUERY_CHANNELS_LIMIT , moveChannelUp } from './utils' ;
8
+ import { MAX_QUERY_CHANNELS_LIMIT , moveChannelUpwards } from './utils ' ;
9
+
19
10
import { Avatar as DefaultAvatar } from '../Avatar' ;
20
11
import { ChannelPreview , ChannelPreviewUIComponentProps } from '../ChannelPreview/ChannelPreview' ;
21
12
import {
@@ -37,6 +28,7 @@ import type { Channel, ChannelFilters, ChannelOptions, ChannelSort, Event } from
37
28
import type { ChannelAvatarProps } from '../Avatar' ;
38
29
import type { TranslationContextValue } from '../../context/TranslationContext' ;
39
30
import type { DefaultStreamChatGenerics , PaginatorProps } from '../../types/types' ;
31
+ import { useChannelListShape , usePrepareShapeHandlers } from './hooks/useChannelListShape' ;
40
32
41
33
const DEFAULT_FILTERS = { } ;
42
34
const DEFAULT_OPTIONS = { } ;
@@ -62,6 +54,7 @@ export type ChannelListProps<
62
54
) => Array < Channel < StreamChatGenerics > > ;
63
55
/** Custom UI component to display search results, defaults to and accepts same props as: [ChannelSearch](https://github.com/GetStream/stream-chat-react/blob/master/src/components/ChannelSearch/ChannelSearch.tsx) */
64
56
ChannelSearch ?: React . ComponentType < ChannelSearchProps < StreamChatGenerics > > ;
57
+ // FIXME: how is this even legal (WHY IS IT STRING?!)
65
58
/** Set a channel (with this ID) to active and manually move it to the top of the list */
66
59
customActiveChannel ?: string ;
67
60
/** Custom function that handles the channel pagination. Has to build query filters, sort and options and query and append channels to the current channels state and update the hasNext pagination flag after each query. */
@@ -160,26 +153,24 @@ export type ChannelListProps<
160
153
watchers ?: { limit ?: number ; offset ?: number } ;
161
154
} ;
162
155
163
- const UnMemoizedChannelList = <
164
- StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics
165
- > (
166
- props : ChannelListProps < StreamChatGenerics > ,
156
+ const UnMemoizedChannelList = < SCG extends DefaultStreamChatGenerics = DefaultStreamChatGenerics > (
157
+ props : ChannelListProps < SCG > ,
167
158
) => {
168
159
const {
169
160
additionalChannelSearchProps,
170
161
Avatar = DefaultAvatar ,
171
- allowNewMessagesFromUnfilteredChannels,
162
+ allowNewMessagesFromUnfilteredChannels = true ,
172
163
channelRenderFilterFn,
173
164
ChannelSearch = DefaultChannelSearch ,
174
165
customActiveChannel,
175
166
customQueryChannels,
176
167
EmptyStateIndicator = DefaultEmptyStateIndicator ,
177
- filters,
168
+ filters = { } ,
178
169
getLatestMessagePreview,
179
170
LoadingErrorIndicator = NullComponent ,
180
171
LoadingIndicator = LoadingChannels ,
181
172
List = ChannelListMessenger ,
182
- lockChannelOrder,
173
+ lockChannelOrder = false ,
183
174
onAddedToChannel,
184
175
onChannelDeleted,
185
176
onChannelHidden,
@@ -211,7 +202,7 @@ const UnMemoizedChannelList = <
211
202
setActiveChannel,
212
203
theme,
213
204
useImageFlagEmojisOnWindows,
214
- } = useChatContext < StreamChatGenerics > ( 'ChannelList' ) ;
205
+ } = useChatContext < SCG > ( 'ChannelList' ) ;
215
206
216
207
const channelListRef = useRef < HTMLDivElement > ( null ) ;
217
208
const [ channelUpdateCount , setChannelUpdateCount ] = useState ( 0 ) ;
@@ -221,14 +212,15 @@ const UnMemoizedChannelList = <
221
212
* If customActiveChannel prop is absent, then set the first channel in list as active channel.
222
213
*/
223
214
const activeChannelHandler = async (
224
- channels : Array < Channel < StreamChatGenerics > > ,
225
- setChannels : React . Dispatch < React . SetStateAction < Array < Channel < StreamChatGenerics > > > > ,
215
+ channels : Array < Channel < SCG > > ,
216
+ setChannels : React . Dispatch < React . SetStateAction < Array < Channel < SCG > > > > ,
226
217
) => {
227
218
if ( ! channels . length || channels . length > ( options ?. limit || MAX_QUERY_CHANNELS_LIMIT ) ) {
228
219
return ;
229
220
}
230
221
231
222
if ( customActiveChannel ) {
223
+ // FIXME: this is wrong...
232
224
let customActiveChannelObject = channels . find ( ( chan ) => chan . id === customActiveChannel ) ;
233
225
234
226
if ( ! customActiveChannelObject ) {
@@ -239,10 +231,10 @@ const UnMemoizedChannelList = <
239
231
if ( customActiveChannelObject ) {
240
232
setActiveChannel ( customActiveChannelObject , watchers ) ;
241
233
242
- const newChannels = moveChannelUp ( {
243
- activeChannel : customActiveChannelObject ,
234
+ const newChannels = moveChannelUpwards ( {
244
235
channels,
245
- cid : customActiveChannelObject . cid ,
236
+ channelToMove : customActiveChannelObject ,
237
+ sort,
246
238
} ) ;
247
239
248
240
setChannels ( newChannels ) ;
@@ -260,16 +252,11 @@ const UnMemoizedChannelList = <
260
252
* For some events, inner properties on the channel will update but the shallow comparison will not
261
253
* force a re-render. Incrementing this dummy variable ensures the channel previews update.
262
254
*/
263
- const forceUpdate = useCallback ( ( ) => setChannelUpdateCount ( ( count ) => count + 1 ) , [
264
- setChannelUpdateCount ,
265
- ] ) ;
255
+ const forceUpdate = useCallback ( ( ) => setChannelUpdateCount ( ( count ) => count + 1 ) , [ ] ) ;
266
256
267
257
const onSearch = useCallback ( ( event : React . ChangeEvent < HTMLInputElement > ) => {
268
- if ( ! event . target . value ) {
269
- setSearchActive ( false ) ;
270
- } else {
271
- setSearchActive ( true ) ;
272
- }
258
+ setSearchActive ( ! ! event . target . value ) ;
259
+
273
260
additionalChannelSearchProps ?. onSearch ?.( event ) ;
274
261
// eslint-disable-next-line react-hooks/exhaustive-deps
275
262
} , [ ] ) ;
@@ -294,33 +281,32 @@ const UnMemoizedChannelList = <
294
281
295
282
useMobileNavigation ( channelListRef , navOpen , closeMobileNav ) ;
296
283
297
- useMessageNewListener (
298
- setChannels ,
299
- onMessageNewHandler ,
300
- lockChannelOrder ,
284
+ const { customHandler, defaultHandler } = usePrepareShapeHandlers < SCG > ( {
301
285
allowNewMessagesFromUnfilteredChannels,
302
- ) ;
303
- useNotificationMessageNewListener (
304
- setChannels ,
286
+ filters,
287
+ lockChannelOrder,
288
+ onAddedToChannel,
289
+ onChannelDeleted,
290
+ onChannelHidden,
291
+ onChannelTruncated,
292
+ onChannelUpdated,
293
+ onChannelVisible,
305
294
onMessageNew,
306
- allowNewMessagesFromUnfilteredChannels ,
307
- ) ;
308
- useNotificationAddedToChannelListener (
295
+ onMessageNewHandler,
296
+ onRemovedFromChannel,
309
297
setChannels,
310
- onAddedToChannel ,
311
- allowNewMessagesFromUnfilteredChannels ,
312
- ) ;
313
- useNotificationRemovedFromChannelListener ( setChannels , onRemovedFromChannel ) ;
314
- useChannelDeletedListener ( setChannels , onChannelDeleted ) ;
315
- useChannelHiddenListener ( setChannels , onChannelHidden ) ;
316
- useChannelVisibleListener ( setChannels , onChannelVisible ) ;
317
- useChannelTruncatedListener ( setChannels , onChannelTruncated , forceUpdate ) ;
318
- useChannelUpdatedListener ( setChannels , onChannelUpdated , forceUpdate ) ;
298
+ sort,
299
+ // TODO: implement
300
+ // customHandleChannelListShape
301
+ } ) ;
302
+
303
+ useChannelListShape < SCG > ( customHandler ?? defaultHandler ) ;
304
+
305
+ // TODO: maybe move this too
319
306
useConnectionRecoveredListener ( forceUpdate ) ;
320
- useUserPresenceChangedListener ( setChannels ) ;
321
307
322
308
useEffect ( ( ) => {
323
- const handleEvent = ( event : Event < StreamChatGenerics > ) => {
309
+ const handleEvent = ( event : Event < SCG > ) => {
324
310
if ( event . cid === channel ?. cid ) {
325
311
setActiveChannel ( ) ;
326
312
}
@@ -336,7 +322,7 @@ const UnMemoizedChannelList = <
336
322
// eslint-disable-next-line react-hooks/exhaustive-deps
337
323
} , [ channel ?. cid ] ) ;
338
324
339
- const renderChannel = ( item : Channel < StreamChatGenerics > ) => {
325
+ const renderChannel = ( item : Channel < SCG > ) => {
340
326
const previewProps = {
341
327
activeChannel : channel ,
342
328
Avatar,
0 commit comments