@@ -5,6 +5,7 @@ import { Channel, Event, ExtendableGenerics } from 'stream-chat';
5
5
import uniqBy from 'lodash.uniqby' ;
6
6
7
7
import {
8
+ extractSortValue ,
8
9
findLastPinnedChannelIndex ,
9
10
isChannelArchived ,
10
11
isChannelPinned ,
@@ -56,7 +57,7 @@ type HandleNotificationAddedToChannelParameters<
56
57
57
58
type HandleMemberUpdatedParameters < SCG extends ExtendableGenerics > = BaseParameters < SCG > & {
58
59
lockChannelOrder : boolean ;
59
- } & Required < Pick < ChannelListProps < SCG > , 'sort' > > ;
60
+ } & Required < Pick < ChannelListProps < SCG > , 'sort' | 'filters' > > ;
60
61
61
62
type HandleChannelDeletedParameters < SCG extends ExtendableGenerics > = BaseParameters < SCG > &
62
63
RepeatedParameters < SCG > ;
@@ -112,10 +113,15 @@ export const useChannelListShapeDefaults = <SCG extends ExtendableGenerics>() =>
112
113
return customHandler ( setChannels , event ) ;
113
114
}
114
115
115
- setChannels ( ( channels ) => {
116
- const targetChannelIndex = channels . findIndex ( ( channel ) => channel . cid === event . cid ) ;
116
+ const channelType = event . channel_type ;
117
+ const channelId = event . channel_id ;
118
+
119
+ if ( ! channelType || ! channelId ) return ;
120
+
121
+ setChannels ( ( currentChannels ) => {
122
+ const targetChannel = client . channel ( channelType , channelId ) ;
123
+ const targetChannelIndex = currentChannels . indexOf ( targetChannel ) ;
117
124
const targetChannelExistsWithinList = targetChannelIndex >= 0 ;
118
- const targetChannel = channels [ targetChannelIndex ] ;
119
125
120
126
const isTargetChannelPinned = isChannelPinned ( targetChannel ) ;
121
127
const isTargetChannelArchived = isChannelArchived ( targetChannel ) ;
@@ -124,35 +130,26 @@ export const useChannelListShapeDefaults = <SCG extends ExtendableGenerics>() =>
124
130
const considerPinnedChannels = shouldConsiderPinnedChannels ( sort ) ;
125
131
126
132
if (
127
- // target channel is archived
128
- ( isTargetChannelArchived && considerArchivedChannels ) ||
129
- // target channel is pinned
130
- ( isTargetChannelPinned && considerPinnedChannels ) ||
133
+ // filter is defined, target channel is archived and filter option is set to false
134
+ ( considerArchivedChannels && isTargetChannelArchived && ! filters . archived ) ||
135
+ // filter is defined, target channel isn't archived and filter option is set to true
136
+ ( considerArchivedChannels && ! isTargetChannelArchived && filters . archived ) ||
137
+ // sort option is defined, target channel is pinned
138
+ ( considerPinnedChannels && isTargetChannelPinned ) ||
131
139
// list order is locked
132
140
lockChannelOrder ||
133
141
// target channel is not within the loaded list and loading from cache is disallowed
134
142
( ! targetChannelExistsWithinList && ! allowNewMessagesFromUnfilteredChannels )
135
143
) {
136
- return channels ;
137
- }
138
-
139
- // we either have the channel to move or we pull it from the cache (or instantiate) if it's allowed
140
- const channelToMove : Channel < SCG > | null =
141
- channels [ targetChannelIndex ] ??
142
- ( allowNewMessagesFromUnfilteredChannels && event . channel_type
143
- ? client . channel ( event . channel_type , event . channel_id )
144
- : null ) ;
145
-
146
- if ( channelToMove ) {
147
- return moveChannelUpwards ( {
148
- channels,
149
- channelToMove,
150
- channelToMoveIndexWithinChannels : targetChannelIndex ,
151
- sort,
152
- } ) ;
144
+ return currentChannels ;
153
145
}
154
146
155
- return channels ;
147
+ return moveChannelUpwards ( {
148
+ channels : currentChannels ,
149
+ channelToMove : targetChannel ,
150
+ channelToMoveIndexWithinChannels : targetChannelIndex ,
151
+ sort,
152
+ } ) ;
156
153
} ) ;
157
154
} ,
158
155
[ client ] ,
@@ -182,7 +179,7 @@ export const useChannelListShapeDefaults = <SCG extends ExtendableGenerics>() =>
182
179
} ) ;
183
180
184
181
const considerArchivedChannels = shouldConsiderArchivedChannels ( filters ) ;
185
- if ( isChannelArchived ( channel ) && considerArchivedChannels ) {
182
+ if ( isChannelArchived ( channel ) && considerArchivedChannels && ! filters . archived ) {
186
183
return ;
187
184
}
188
185
@@ -208,26 +205,38 @@ export const useChannelListShapeDefaults = <SCG extends ExtendableGenerics>() =>
208
205
customHandler,
209
206
event,
210
207
setChannels,
208
+ sort,
211
209
} : HandleNotificationAddedToChannelParameters < SCG > ) => {
212
210
if ( typeof customHandler === 'function' ) {
213
211
return customHandler ( setChannels , event ) ;
214
212
}
215
213
216
- if ( allowNewMessagesFromUnfilteredChannels && event . channel ?. type ) {
217
- const channel = await getChannel ( {
218
- client,
219
- id : event . channel . id ,
220
- members : event . channel . members ?. reduce < string [ ] > ( ( acc , { user, user_id } ) => {
221
- const userId = user_id || user ?. id ;
222
- if ( userId ) {
223
- acc . push ( userId ) ;
224
- }
225
- return acc ;
226
- } , [ ] ) ,
227
- type : event . channel . type ,
228
- } ) ;
229
- setChannels ( ( channels ) => uniqBy ( [ channel , ...channels ] , 'cid' ) ) ;
214
+ if ( ! event . channel || ! allowNewMessagesFromUnfilteredChannels ) {
215
+ return ;
230
216
}
217
+
218
+ const channel = await getChannel ( {
219
+ client,
220
+ id : event . channel . id ,
221
+ members : event . channel . members ?. reduce < string [ ] > ( ( newMembers , { user, user_id } ) => {
222
+ const userId = user_id || user ?. id ;
223
+
224
+ if ( userId ) newMembers . push ( userId ) ;
225
+
226
+ return newMembers ;
227
+ } , [ ] ) ,
228
+ type : event . channel . type ,
229
+ } ) ;
230
+
231
+ // membership has been reset (target channel shouldn't be pinned nor archived)
232
+ setChannels ( ( channels ) =>
233
+ moveChannelUpwards ( {
234
+ channels,
235
+ channelToMove : channel ,
236
+ channelToMoveIndexWithinChannels : - 1 ,
237
+ sort,
238
+ } ) ,
239
+ ) ;
231
240
} ,
232
241
[ client ] ,
233
242
) ;
@@ -248,26 +257,34 @@ export const useChannelListShapeDefaults = <SCG extends ExtendableGenerics>() =>
248
257
) ;
249
258
250
259
const handleMemberUpdated = useCallback (
251
- ( { event, lockChannelOrder, setChannels, sort } : HandleMemberUpdatedParameters < SCG > ) => {
260
+ ( {
261
+ event,
262
+ filters,
263
+ lockChannelOrder,
264
+ setChannels,
265
+ sort,
266
+ } : HandleMemberUpdatedParameters < SCG > ) => {
252
267
if ( ! event . member ?. user || event . member . user . id !== client . userID || ! event . channel_type ) {
253
268
return ;
254
269
}
255
270
256
- const member = event . member ;
257
271
const channelType = event . channel_type ;
258
272
const channelId = event . channel_id ;
259
273
260
274
const considerPinnedChannels = shouldConsiderPinnedChannels ( sort ) ;
275
+ const considerArchivedChannels = shouldConsiderArchivedChannels ( filters ) ;
261
276
262
- // TODO: extract this and consider single property sort object too
263
- const pinnedAtSort = Array . isArray ( sort ) ? sort [ 0 ] ?. pinned_at ?? null : null ;
277
+ const pinnedAtSort = extractSortValue ( { atIndex : 0 , sort, targetKey : 'pinned_at' } ) ;
264
278
265
279
setChannels ( ( currentChannels ) => {
266
280
const targetChannel = client . channel ( channelType , channelId ) ;
267
281
// assumes that channel instances are not changing
268
282
const targetChannelIndex = currentChannels . indexOf ( targetChannel ) ;
269
283
const targetChannelExistsWithinList = targetChannelIndex >= 0 ;
270
284
285
+ const isTargetChannelArchived = isChannelArchived ( targetChannel ) ;
286
+ const isTargetChannelPinned = isChannelPinned ( targetChannel ) ;
287
+
271
288
// handle pinning
272
289
if ( ! considerPinnedChannels || lockChannelOrder ) return currentChannels ;
273
290
@@ -278,7 +295,10 @@ export const useChannelListShapeDefaults = <SCG extends ExtendableGenerics>() =>
278
295
}
279
296
280
297
// handle archiving (remove channel)
281
- if ( typeof member . archived_at === 'string' ) {
298
+ if (
299
+ ( considerArchivedChannels && isTargetChannelArchived && ! filters . archived ) ||
300
+ ( considerArchivedChannels && ! isTargetChannelArchived && filters . archived )
301
+ ) {
282
302
return newChannels ;
283
303
}
284
304
@@ -287,7 +307,7 @@ export const useChannelListShapeDefaults = <SCG extends ExtendableGenerics>() =>
287
307
// calculate last pinned channel index only if `pinned_at` sort is set to
288
308
// ascending order or if it's in descending order while the pin is being removed, otherwise
289
309
// we move to the top (index 0)
290
- if ( pinnedAtSort === 1 || ( pinnedAtSort === - 1 && ! member . pinned_at ) ) {
310
+ if ( pinnedAtSort === 1 || ( pinnedAtSort === - 1 && ! isTargetChannelPinned ) ) {
291
311
lastPinnedChannelIndex = findLastPinnedChannelIndex ( { channels : newChannels } ) ;
292
312
}
293
313
@@ -553,6 +573,7 @@ export const usePrepareShapeHandlers = <SCG extends ExtendableGenerics>({
553
573
case 'member.updated' :
554
574
defaults . handleMemberUpdated ( {
555
575
event,
576
+ filters,
556
577
lockChannelOrder,
557
578
setChannels,
558
579
sort,
0 commit comments