@@ -5,6 +5,7 @@ import { Channel, Event, ExtendableGenerics } from 'stream-chat';
55import uniqBy from 'lodash.uniqby' ;
66
77import {
8+ extractSortValue ,
89 findLastPinnedChannelIndex ,
910 isChannelArchived ,
1011 isChannelPinned ,
@@ -56,7 +57,7 @@ type HandleNotificationAddedToChannelParameters<
5657
5758type HandleMemberUpdatedParameters < SCG extends ExtendableGenerics > = BaseParameters < SCG > & {
5859 lockChannelOrder : boolean ;
59- } & Required < Pick < ChannelListProps < SCG > , 'sort' > > ;
60+ } & Required < Pick < ChannelListProps < SCG > , 'sort' | 'filters' > > ;
6061
6162type HandleChannelDeletedParameters < SCG extends ExtendableGenerics > = BaseParameters < SCG > &
6263 RepeatedParameters < SCG > ;
@@ -112,10 +113,15 @@ export const useChannelListShapeDefaults = <SCG extends ExtendableGenerics>() =>
112113 return customHandler ( setChannels , event ) ;
113114 }
114115
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 ) ;
117124 const targetChannelExistsWithinList = targetChannelIndex >= 0 ;
118- const targetChannel = channels [ targetChannelIndex ] ;
119125
120126 const isTargetChannelPinned = isChannelPinned ( targetChannel ) ;
121127 const isTargetChannelArchived = isChannelArchived ( targetChannel ) ;
@@ -124,35 +130,26 @@ export const useChannelListShapeDefaults = <SCG extends ExtendableGenerics>() =>
124130 const considerPinnedChannels = shouldConsiderPinnedChannels ( sort ) ;
125131
126132 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 ) ||
131139 // list order is locked
132140 lockChannelOrder ||
133141 // target channel is not within the loaded list and loading from cache is disallowed
134142 ( ! targetChannelExistsWithinList && ! allowNewMessagesFromUnfilteredChannels )
135143 ) {
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 ;
153145 }
154146
155- return channels ;
147+ return moveChannelUpwards ( {
148+ channels : currentChannels ,
149+ channelToMove : targetChannel ,
150+ channelToMoveIndexWithinChannels : targetChannelIndex ,
151+ sort,
152+ } ) ;
156153 } ) ;
157154 } ,
158155 [ client ] ,
@@ -182,7 +179,7 @@ export const useChannelListShapeDefaults = <SCG extends ExtendableGenerics>() =>
182179 } ) ;
183180
184181 const considerArchivedChannels = shouldConsiderArchivedChannels ( filters ) ;
185- if ( isChannelArchived ( channel ) && considerArchivedChannels ) {
182+ if ( isChannelArchived ( channel ) && considerArchivedChannels && ! filters . archived ) {
186183 return ;
187184 }
188185
@@ -208,26 +205,38 @@ export const useChannelListShapeDefaults = <SCG extends ExtendableGenerics>() =>
208205 customHandler,
209206 event,
210207 setChannels,
208+ sort,
211209 } : HandleNotificationAddedToChannelParameters < SCG > ) => {
212210 if ( typeof customHandler === 'function' ) {
213211 return customHandler ( setChannels , event ) ;
214212 }
215213
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 ;
230216 }
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+ ) ;
231240 } ,
232241 [ client ] ,
233242 ) ;
@@ -248,26 +257,34 @@ export const useChannelListShapeDefaults = <SCG extends ExtendableGenerics>() =>
248257 ) ;
249258
250259 const handleMemberUpdated = useCallback (
251- ( { event, lockChannelOrder, setChannels, sort } : HandleMemberUpdatedParameters < SCG > ) => {
260+ ( {
261+ event,
262+ filters,
263+ lockChannelOrder,
264+ setChannels,
265+ sort,
266+ } : HandleMemberUpdatedParameters < SCG > ) => {
252267 if ( ! event . member ?. user || event . member . user . id !== client . userID || ! event . channel_type ) {
253268 return ;
254269 }
255270
256- const member = event . member ;
257271 const channelType = event . channel_type ;
258272 const channelId = event . channel_id ;
259273
260274 const considerPinnedChannels = shouldConsiderPinnedChannels ( sort ) ;
275+ const considerArchivedChannels = shouldConsiderArchivedChannels ( filters ) ;
261276
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' } ) ;
264278
265279 setChannels ( ( currentChannels ) => {
266280 const targetChannel = client . channel ( channelType , channelId ) ;
267281 // assumes that channel instances are not changing
268282 const targetChannelIndex = currentChannels . indexOf ( targetChannel ) ;
269283 const targetChannelExistsWithinList = targetChannelIndex >= 0 ;
270284
285+ const isTargetChannelArchived = isChannelArchived ( targetChannel ) ;
286+ const isTargetChannelPinned = isChannelPinned ( targetChannel ) ;
287+
271288 // handle pinning
272289 if ( ! considerPinnedChannels || lockChannelOrder ) return currentChannels ;
273290
@@ -278,7 +295,10 @@ export const useChannelListShapeDefaults = <SCG extends ExtendableGenerics>() =>
278295 }
279296
280297 // handle archiving (remove channel)
281- if ( typeof member . archived_at === 'string' ) {
298+ if (
299+ ( considerArchivedChannels && isTargetChannelArchived && ! filters . archived ) ||
300+ ( considerArchivedChannels && ! isTargetChannelArchived && filters . archived )
301+ ) {
282302 return newChannels ;
283303 }
284304
@@ -287,7 +307,7 @@ export const useChannelListShapeDefaults = <SCG extends ExtendableGenerics>() =>
287307 // calculate last pinned channel index only if `pinned_at` sort is set to
288308 // ascending order or if it's in descending order while the pin is being removed, otherwise
289309 // we move to the top (index 0)
290- if ( pinnedAtSort === 1 || ( pinnedAtSort === - 1 && ! member . pinned_at ) ) {
310+ if ( pinnedAtSort === 1 || ( pinnedAtSort === - 1 && ! isTargetChannelPinned ) ) {
291311 lastPinnedChannelIndex = findLastPinnedChannelIndex ( { channels : newChannels } ) ;
292312 }
293313
@@ -553,6 +573,7 @@ export const usePrepareShapeHandlers = <SCG extends ExtendableGenerics>({
553573 case 'member.updated' :
554574 defaults . handleMemberUpdated ( {
555575 event,
576+ filters,
556577 lockChannelOrder,
557578 setChannels,
558579 sort,
0 commit comments