Skip to content

Commit 3df3b4b

Browse files
Adjust existing conditions
1 parent 3801375 commit 3df3b4b

File tree

2 files changed

+86
-31
lines changed

2 files changed

+86
-31
lines changed

src/components/ChannelList/hooks/useChannelListShape.ts

Lines changed: 47 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import { Channel, Event, ExtendableGenerics } from 'stream-chat';
55
import uniqBy from 'lodash.uniqby';
66

77
import {
8+
extractSortValue,
89
findLastPinnedChannelIndex,
910
isChannelArchived,
1011
isChannelPinned,
@@ -56,7 +57,7 @@ type HandleNotificationAddedToChannelParameters<
5657

5758
type HandleMemberUpdatedParameters<SCG extends ExtendableGenerics> = BaseParameters<SCG> & {
5859
lockChannelOrder: boolean;
59-
} & Required<Pick<ChannelListProps<SCG>, 'sort'>>;
60+
} & Required<Pick<ChannelListProps<SCG>, 'sort' | 'filters'>>;
6061

6162
type HandleChannelDeletedParameters<SCG extends ExtendableGenerics> = BaseParameters<SCG> &
6263
RepeatedParameters<SCG>;
@@ -124,9 +125,9 @@ export const useChannelListShapeDefaults = <SCG extends ExtendableGenerics>() =>
124125
const considerPinnedChannels = shouldConsiderPinnedChannels(sort);
125126

126127
if (
127-
// target channel is archived
128-
(isTargetChannelArchived && considerArchivedChannels) ||
129-
// target channel is pinned
128+
// target channel is archived, filter is defined and is set to false
129+
(isTargetChannelArchived && considerArchivedChannels && !filters.archived) ||
130+
// target channel is pinned, sort is defined
130131
(isTargetChannelPinned && considerPinnedChannels) ||
131132
// list order is locked
132133
lockChannelOrder ||
@@ -182,7 +183,7 @@ export const useChannelListShapeDefaults = <SCG extends ExtendableGenerics>() =>
182183
});
183184

184185
const considerArchivedChannels = shouldConsiderArchivedChannels(filters);
185-
if (isChannelArchived(channel) && considerArchivedChannels) {
186+
if (isChannelArchived(channel) && considerArchivedChannels && !filters.archived) {
186187
return;
187188
}
188189

@@ -208,26 +209,38 @@ export const useChannelListShapeDefaults = <SCG extends ExtendableGenerics>() =>
208209
customHandler,
209210
event,
210211
setChannels,
212+
sort,
211213
}: HandleNotificationAddedToChannelParameters<SCG>) => {
212214
if (typeof customHandler === 'function') {
213215
return customHandler(setChannels, event);
214216
}
215217

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'));
218+
if (!event.channel || !allowNewMessagesFromUnfilteredChannels) {
219+
return;
230220
}
221+
222+
const channel = await getChannel({
223+
client,
224+
id: event.channel.id,
225+
members: event.channel.members?.reduce<string[]>((newMembers, { user, user_id }) => {
226+
const userId = user_id || user?.id;
227+
228+
if (userId) newMembers.push(userId);
229+
230+
return newMembers;
231+
}, []),
232+
type: event.channel.type,
233+
});
234+
235+
// membership has been reset (target channel shouldn't be pinned nor archived)
236+
setChannels((channels) =>
237+
moveChannelUpwards({
238+
channels,
239+
channelToMove: channel,
240+
channelToMoveIndexWithinChannels: -1,
241+
sort,
242+
}),
243+
);
231244
},
232245
[client],
233246
);
@@ -248,7 +261,13 @@ export const useChannelListShapeDefaults = <SCG extends ExtendableGenerics>() =>
248261
);
249262

250263
const handleMemberUpdated = useCallback(
251-
({ event, lockChannelOrder, setChannels, sort }: HandleMemberUpdatedParameters<SCG>) => {
264+
({
265+
event,
266+
filters,
267+
lockChannelOrder,
268+
setChannels,
269+
sort,
270+
}: HandleMemberUpdatedParameters<SCG>) => {
252271
if (!event.member?.user || event.member.user.id !== client.userID || !event.channel_type) {
253272
return;
254273
}
@@ -258,9 +277,9 @@ export const useChannelListShapeDefaults = <SCG extends ExtendableGenerics>() =>
258277
const channelId = event.channel_id;
259278

260279
const considerPinnedChannels = shouldConsiderPinnedChannels(sort);
280+
const considerArchivedChannels = shouldConsiderArchivedChannels(filters);
261281

262-
// TODO: extract this and consider single property sort object too
263-
const pinnedAtSort = Array.isArray(sort) ? sort[0]?.pinned_at ?? null : null;
282+
const pinnedAtSort = extractSortValue({ atIndex: 0, sort, targetKey: 'pinned_at' });
264283

265284
setChannels((currentChannels) => {
266285
const targetChannel = client.channel(channelType, channelId);
@@ -278,7 +297,11 @@ export const useChannelListShapeDefaults = <SCG extends ExtendableGenerics>() =>
278297
}
279298

280299
// handle archiving (remove channel)
281-
if (typeof member.archived_at === 'string') {
300+
if (
301+
considerArchivedChannels &&
302+
((typeof member.archived_at === 'string' && !filters.archived) ||
303+
(!member.archived_at && filters.archived))
304+
) {
282305
return newChannels;
283306
}
284307

@@ -553,6 +576,7 @@ export const usePrepareShapeHandlers = <SCG extends ExtendableGenerics>({
553576
case 'member.updated':
554577
defaults.handleMemberUpdated({
555578
event,
579+
filters,
556580
lockChannelOrder,
557581
setChannels,
558582
sort,

src/components/ChannelList/utils.ts

Lines changed: 39 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import uniqBy from 'lodash.uniqby';
2-
import type { Channel, ChannelSort, ExtendableGenerics } from 'stream-chat';
2+
import type { Channel, ChannelSort, ChannelSortBase, ExtendableGenerics } from 'stream-chat';
33

44
import type { DefaultStreamChatGenerics } from '../../types/types';
55
import type { ChannelListProps } from './ChannelList';
@@ -118,20 +118,51 @@ export const moveChannelUpwards = <
118118
};
119119

120120
/**
121-
* Returns true only if `{ pinned_at: -1 }` or `{ pinned_at: 1 }` option is first within the `sort` array.
121+
* Returns `true` only if `{ pinned_at: -1 }` or `{ pinned_at: 1 }` option is first within the `sort` array or if `pinned_at` key of the `sort` object gets picked first when using `for...in`.
122122
*/
123123
export const shouldConsiderPinnedChannels = <SCG extends ExtendableGenerics>(
124124
sort: ChannelListProps<SCG>['sort'],
125125
) => {
126-
if (!sort) return false;
126+
const value = extractSortValue<SCG>({ atIndex: 0, sort, targetKey: 'pinned_at' });
127127

128-
if (!Array.isArray(sort)) return false;
128+
if (typeof value !== 'number') return false;
129129

130-
const [option] = sort;
130+
return Math.abs(value) === 1;
131+
};
131132

132-
if (!option?.pinned_at) return false;
133+
export const extractSortValue = <SCG extends ExtendableGenerics>({
134+
atIndex,
135+
sort,
136+
targetKey,
137+
}: {
138+
atIndex: number;
139+
targetKey: keyof ChannelSortBase<SCG>;
140+
sort?: ChannelListProps<SCG>['sort'];
141+
}) => {
142+
if (!sort) return null;
143+
let option: null | ChannelSort<SCG> = null;
144+
145+
if (Array.isArray(sort)) {
146+
option = sort[atIndex] ?? null;
147+
} else {
148+
let index = 0;
149+
for (const key in sort) {
150+
if (index !== atIndex) {
151+
index++;
152+
continue;
153+
}
154+
155+
if (key !== targetKey) {
156+
return null;
157+
}
158+
159+
option = sort;
160+
161+
break;
162+
}
163+
}
133164

134-
return Math.abs(option.pinned_at) === 1;
165+
return option?.[targetKey] ?? null;
135166
};
136167

137168
/**
@@ -142,7 +173,7 @@ export const shouldConsiderArchivedChannels = <SCG extends ExtendableGenerics>(
142173
) => {
143174
if (!filters) return false;
144175

145-
return !filters.archived;
176+
return typeof filters.archived === 'boolean';
146177
};
147178

148179
export const isChannelPinned = <SCG extends ExtendableGenerics>(channel: Channel<SCG>) => {

0 commit comments

Comments
 (0)