stream-chat-react-native-core 6.3.1 → 6.4.0-beta.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/commonjs/components/Attachment/AudioAttachment.js +255 -216
- package/lib/commonjs/components/Attachment/AudioAttachment.js.map +1 -1
- package/lib/commonjs/components/Attachment/FileAttachmentGroup.js +11 -11
- package/lib/commonjs/components/Attachment/FileAttachmentGroup.js.map +1 -1
- package/lib/commonjs/components/Attachment/Gallery.js +9 -0
- package/lib/commonjs/components/Attachment/Gallery.js.map +1 -1
- package/lib/commonjs/components/ChannelList/ChannelList.js +23 -0
- package/lib/commonjs/components/ChannelList/ChannelList.js.map +1 -1
- package/lib/commonjs/components/ChannelList/hooks/listeners/useAddedToChannelNotification.js +31 -8
- package/lib/commonjs/components/ChannelList/hooks/listeners/useAddedToChannelNotification.js.map +1 -1
- package/lib/commonjs/components/ChannelList/hooks/listeners/useChannelMemberUpdated.js +75 -0
- package/lib/commonjs/components/ChannelList/hooks/listeners/useChannelMemberUpdated.js.map +1 -0
- package/lib/commonjs/components/ChannelList/hooks/listeners/useNewMessage.js +21 -10
- package/lib/commonjs/components/ChannelList/hooks/listeners/useNewMessage.js.map +1 -1
- package/lib/commonjs/components/ChannelList/hooks/listeners/useNewMessageNotification.js +23 -7
- package/lib/commonjs/components/ChannelList/hooks/listeners/useNewMessageNotification.js.map +1 -1
- package/lib/commonjs/components/ChannelList/hooks/useChannelMembershipState.js +17 -0
- package/lib/commonjs/components/ChannelList/hooks/useChannelMembershipState.js.map +1 -0
- package/lib/commonjs/components/ChannelList/hooks/useSelectedChannelState.js +32 -0
- package/lib/commonjs/components/ChannelList/hooks/useSelectedChannelState.js.map +1 -0
- package/lib/commonjs/components/ChannelList/hooks/utils/index.js +102 -0
- package/lib/commonjs/components/ChannelList/hooks/utils/index.js.map +1 -0
- package/lib/commonjs/components/ChannelList/utils.js +23 -11
- package/lib/commonjs/components/ChannelList/utils.js.map +1 -1
- package/lib/commonjs/components/ChannelPreview/ChannelPreviewMessenger.js +1 -2
- package/lib/commonjs/components/ChannelPreview/ChannelPreviewMessenger.js.map +1 -1
- package/lib/commonjs/components/ImageGallery/components/ImageGalleryVideoControl.js +24 -13
- package/lib/commonjs/components/ImageGallery/components/ImageGalleryVideoControl.js.map +1 -1
- package/lib/commonjs/components/Message/Message.js.map +1 -1
- package/lib/commonjs/components/MessageInput/FileUploadPreview.js +35 -23
- package/lib/commonjs/components/MessageInput/FileUploadPreview.js.map +1 -1
- package/lib/commonjs/components/ProgressControl/ProgressControl.js +57 -54
- package/lib/commonjs/components/ProgressControl/ProgressControl.js.map +1 -1
- package/lib/commonjs/components/ProgressControl/WaveProgressBar.js +52 -52
- package/lib/commonjs/components/ProgressControl/WaveProgressBar.js.map +1 -1
- package/lib/commonjs/components/index.js +22 -0
- package/lib/commonjs/components/index.js.map +1 -1
- package/lib/commonjs/contexts/themeContext/utils/theme.js +1 -0
- package/lib/commonjs/contexts/themeContext/utils/theme.js.map +1 -1
- package/lib/commonjs/hooks/useAudioPlayer.js +158 -0
- package/lib/commonjs/hooks/useAudioPlayer.js.map +1 -0
- package/lib/commonjs/icons/Archieve.js +33 -0
- package/lib/commonjs/icons/Archieve.js.map +1 -0
- package/lib/commonjs/icons/Pause.js +2 -2
- package/lib/commonjs/icons/Pause.js.map +1 -1
- package/lib/commonjs/icons/Play.js +2 -2
- package/lib/commonjs/icons/Play.js.map +1 -1
- package/lib/commonjs/icons/index.js +11 -0
- package/lib/commonjs/icons/index.js.map +1 -1
- package/lib/commonjs/native.js.map +1 -1
- package/lib/commonjs/types/types.js.map +1 -1
- package/lib/commonjs/version.json +1 -1
- package/lib/module/components/Attachment/AudioAttachment.js +255 -216
- package/lib/module/components/Attachment/AudioAttachment.js.map +1 -1
- package/lib/module/components/Attachment/FileAttachmentGroup.js +11 -11
- package/lib/module/components/Attachment/FileAttachmentGroup.js.map +1 -1
- package/lib/module/components/Attachment/Gallery.js +9 -0
- package/lib/module/components/Attachment/Gallery.js.map +1 -1
- package/lib/module/components/ChannelList/ChannelList.js +23 -0
- package/lib/module/components/ChannelList/ChannelList.js.map +1 -1
- package/lib/module/components/ChannelList/hooks/listeners/useAddedToChannelNotification.js +31 -8
- package/lib/module/components/ChannelList/hooks/listeners/useAddedToChannelNotification.js.map +1 -1
- package/lib/module/components/ChannelList/hooks/listeners/useChannelMemberUpdated.js +75 -0
- package/lib/module/components/ChannelList/hooks/listeners/useChannelMemberUpdated.js.map +1 -0
- package/lib/module/components/ChannelList/hooks/listeners/useNewMessage.js +21 -10
- package/lib/module/components/ChannelList/hooks/listeners/useNewMessage.js.map +1 -1
- package/lib/module/components/ChannelList/hooks/listeners/useNewMessageNotification.js +23 -7
- package/lib/module/components/ChannelList/hooks/listeners/useNewMessageNotification.js.map +1 -1
- package/lib/module/components/ChannelList/hooks/useChannelMembershipState.js +17 -0
- package/lib/module/components/ChannelList/hooks/useChannelMembershipState.js.map +1 -0
- package/lib/module/components/ChannelList/hooks/useSelectedChannelState.js +32 -0
- package/lib/module/components/ChannelList/hooks/useSelectedChannelState.js.map +1 -0
- package/lib/module/components/ChannelList/hooks/utils/index.js +102 -0
- package/lib/module/components/ChannelList/hooks/utils/index.js.map +1 -0
- package/lib/module/components/ChannelList/utils.js +23 -11
- package/lib/module/components/ChannelList/utils.js.map +1 -1
- package/lib/module/components/ChannelPreview/ChannelPreviewMessenger.js +1 -2
- package/lib/module/components/ChannelPreview/ChannelPreviewMessenger.js.map +1 -1
- package/lib/module/components/ImageGallery/components/ImageGalleryVideoControl.js +24 -13
- package/lib/module/components/ImageGallery/components/ImageGalleryVideoControl.js.map +1 -1
- package/lib/module/components/Message/Message.js.map +1 -1
- package/lib/module/components/MessageInput/FileUploadPreview.js +35 -23
- package/lib/module/components/MessageInput/FileUploadPreview.js.map +1 -1
- package/lib/module/components/ProgressControl/ProgressControl.js +57 -54
- package/lib/module/components/ProgressControl/ProgressControl.js.map +1 -1
- package/lib/module/components/ProgressControl/WaveProgressBar.js +52 -52
- package/lib/module/components/ProgressControl/WaveProgressBar.js.map +1 -1
- package/lib/module/components/index.js +22 -0
- package/lib/module/components/index.js.map +1 -1
- package/lib/module/contexts/themeContext/utils/theme.js +1 -0
- package/lib/module/contexts/themeContext/utils/theme.js.map +1 -1
- package/lib/module/hooks/useAudioPlayer.js +158 -0
- package/lib/module/hooks/useAudioPlayer.js.map +1 -0
- package/lib/module/icons/Archieve.js +33 -0
- package/lib/module/icons/Archieve.js.map +1 -0
- package/lib/module/icons/Pause.js +2 -2
- package/lib/module/icons/Pause.js.map +1 -1
- package/lib/module/icons/Play.js +2 -2
- package/lib/module/icons/Play.js.map +1 -1
- package/lib/module/icons/index.js +11 -0
- package/lib/module/icons/index.js.map +1 -1
- package/lib/module/native.js.map +1 -1
- package/lib/module/types/types.js.map +1 -1
- package/lib/module/version.json +1 -1
- package/lib/typescript/components/Attachment/AudioAttachment.d.ts +2 -2
- package/lib/typescript/components/Attachment/AudioAttachment.d.ts.map +1 -1
- package/lib/typescript/components/Attachment/FileAttachmentGroup.d.ts.map +1 -1
- package/lib/typescript/components/Attachment/Gallery.d.ts.map +1 -1
- package/lib/typescript/components/ChannelList/ChannelList.d.ts +20 -6
- package/lib/typescript/components/ChannelList/ChannelList.d.ts.map +1 -1
- package/lib/typescript/components/ChannelList/hooks/listeners/useAddedToChannelNotification.d.ts +4 -3
- package/lib/typescript/components/ChannelList/hooks/listeners/useAddedToChannelNotification.d.ts.map +1 -1
- package/lib/typescript/components/ChannelList/hooks/listeners/useChannelMemberUpdated.d.ts +12 -0
- package/lib/typescript/components/ChannelList/hooks/listeners/useChannelMemberUpdated.d.ts.map +1 -0
- package/lib/typescript/components/ChannelList/hooks/listeners/useNewMessage.d.ts +4 -3
- package/lib/typescript/components/ChannelList/hooks/listeners/useNewMessage.d.ts.map +1 -1
- package/lib/typescript/components/ChannelList/hooks/listeners/useNewMessageNotification.d.ts +4 -3
- package/lib/typescript/components/ChannelList/hooks/listeners/useNewMessageNotification.d.ts.map +1 -1
- package/lib/typescript/components/ChannelList/hooks/useChannelMembershipState.d.ts +5 -0
- package/lib/typescript/components/ChannelList/hooks/useChannelMembershipState.d.ts.map +1 -0
- package/lib/typescript/components/ChannelList/hooks/useSelectedChannelState.d.ts +13 -0
- package/lib/typescript/components/ChannelList/hooks/useSelectedChannelState.d.ts.map +1 -0
- package/lib/typescript/components/ChannelList/hooks/utils/index.d.ts +22 -0
- package/lib/typescript/components/ChannelList/hooks/utils/index.d.ts.map +1 -0
- package/lib/typescript/components/ChannelList/utils.d.ts +10 -4
- package/lib/typescript/components/ChannelList/utils.d.ts.map +1 -1
- package/lib/typescript/components/ChannelPreview/ChannelPreviewMessenger.d.ts.map +1 -1
- package/lib/typescript/components/ImageGallery/components/ImageGalleryVideoControl.d.ts.map +1 -1
- package/lib/typescript/components/Message/Message.d.ts +22 -11
- package/lib/typescript/components/Message/Message.d.ts.map +1 -1
- package/lib/typescript/components/MessageInput/FileUploadPreview.d.ts.map +1 -1
- package/lib/typescript/components/ProgressControl/ProgressControl.d.ts +35 -2
- package/lib/typescript/components/ProgressControl/ProgressControl.d.ts.map +1 -1
- package/lib/typescript/components/ProgressControl/WaveProgressBar.d.ts +27 -0
- package/lib/typescript/components/ProgressControl/WaveProgressBar.d.ts.map +1 -1
- package/lib/typescript/components/index.d.ts +2 -0
- package/lib/typescript/components/index.d.ts.map +1 -1
- package/lib/typescript/contexts/themeContext/utils/theme.d.ts +1 -0
- package/lib/typescript/contexts/themeContext/utils/theme.d.ts.map +1 -1
- package/lib/typescript/hooks/useAudioPlayer.d.ts +16 -0
- package/lib/typescript/hooks/useAudioPlayer.d.ts.map +1 -0
- package/lib/typescript/icons/Archieve.d.ts +4 -0
- package/lib/typescript/icons/Archieve.d.ts.map +1 -0
- package/lib/typescript/icons/Pause.d.ts.map +1 -1
- package/lib/typescript/icons/index.d.ts +1 -0
- package/lib/typescript/icons/index.d.ts.map +1 -1
- package/lib/typescript/native.d.ts +10 -3
- package/lib/typescript/native.d.ts.map +1 -1
- package/lib/typescript/types/types.d.ts +5 -1
- package/lib/typescript/types/types.d.ts.map +1 -1
- package/package.json +4 -2
- package/src/components/Attachment/AudioAttachment.tsx +173 -137
- package/src/components/Attachment/FileAttachmentGroup.tsx +9 -16
- package/src/components/Attachment/Gallery.tsx +3 -0
- package/src/components/ChannelList/ChannelList.tsx +38 -3
- package/src/components/ChannelList/hooks/listeners/useAddedToChannelNotification.ts +32 -3
- package/src/components/ChannelList/hooks/listeners/useChannelMemberUpdated.ts +116 -0
- package/src/components/ChannelList/hooks/listeners/useNewMessage.ts +46 -17
- package/src/components/ChannelList/hooks/listeners/useNewMessageNotification.ts +18 -3
- package/src/components/ChannelList/hooks/useChannelMembershipState.ts +22 -0
- package/src/components/ChannelList/hooks/useSelectedChannelState.ts +57 -0
- package/src/components/ChannelList/hooks/utils/index.ts +130 -0
- package/src/components/ChannelList/utils.ts +50 -14
- package/src/components/ChannelPreview/ChannelPreviewMessenger.tsx +1 -2
- package/src/components/ImageGallery/components/ImageGalleryVideoControl.tsx +23 -13
- package/src/components/Message/Message.tsx +26 -4
- package/src/components/MessageInput/FileUploadPreview.tsx +29 -28
- package/src/components/ProgressControl/ProgressControl.tsx +115 -92
- package/src/components/ProgressControl/WaveProgressBar.tsx +96 -59
- package/src/components/index.ts +2 -0
- package/src/contexts/themeContext/utils/theme.ts +2 -0
- package/src/hooks/useAudioPlayer.ts +59 -0
- package/src/icons/Archieve.tsx +10 -0
- package/src/icons/Pause.tsx +2 -5
- package/src/icons/Play.tsx +2 -2
- package/src/icons/index.ts +1 -0
- package/src/native.ts +11 -3
- package/src/types/types.ts +14 -1
- package/src/version.json +1 -1
|
@@ -12,6 +12,7 @@ import { ChannelListMessenger, ChannelListMessengerProps } from './ChannelListMe
|
|
|
12
12
|
import { useAddedToChannelNotification } from './hooks/listeners/useAddedToChannelNotification';
|
|
13
13
|
import { useChannelDeleted } from './hooks/listeners/useChannelDeleted';
|
|
14
14
|
import { useChannelHidden } from './hooks/listeners/useChannelHidden';
|
|
15
|
+
import { useChannelMemberUpdated } from './hooks/listeners/useChannelMemberUpdated';
|
|
15
16
|
import { useChannelTruncated } from './hooks/listeners/useChannelTruncated';
|
|
16
17
|
import { useChannelUpdated } from './hooks/listeners/useChannelUpdated';
|
|
17
18
|
import { useChannelVisible } from './hooks/listeners/useChannelVisible';
|
|
@@ -29,7 +30,7 @@ import {
|
|
|
29
30
|
} from '../../contexts/channelsContext/ChannelsContext';
|
|
30
31
|
import { useChatContext } from '../../contexts/chatContext/ChatContext';
|
|
31
32
|
import { upsertCidsForQuery } from '../../store/apis/upsertCidsForQuery';
|
|
32
|
-
import type { DefaultStreamChatGenerics } from '../../types/types';
|
|
33
|
+
import type { ChannelListEventListenerOptions, DefaultStreamChatGenerics } from '../../types/types';
|
|
33
34
|
import { ChannelPreviewMessenger } from '../ChannelPreview/ChannelPreviewMessenger';
|
|
34
35
|
import { EmptyStateIndicator as EmptyStateIndicatorDefault } from '../Indicators/EmptyStateIndicator';
|
|
35
36
|
import { LoadingErrorIndicator as LoadingErrorIndicatorDefault } from '../Indicators/LoadingErrorIndicator';
|
|
@@ -89,12 +90,15 @@ export type ChannelListProps<
|
|
|
89
90
|
*
|
|
90
91
|
* @param setChannels Setter for internal state property - `channels`. It's created from useState() hook.
|
|
91
92
|
* @param event An [Event Object](https://getstream.io/chat/docs/event_object) corresponding to `notification.added_to_channel` event
|
|
93
|
+
* @param filters Channel filters
|
|
94
|
+
* @param sort Channel sort options
|
|
92
95
|
*
|
|
93
96
|
* @overrideType Function
|
|
94
97
|
* */
|
|
95
98
|
onAddedToChannel?: (
|
|
96
99
|
setChannels: React.Dispatch<React.SetStateAction<Channel<StreamChatGenerics>[] | null>>,
|
|
97
100
|
event: Event<StreamChatGenerics>,
|
|
101
|
+
options?: ChannelListEventListenerOptions<StreamChatGenerics>,
|
|
98
102
|
) => void;
|
|
99
103
|
/**
|
|
100
104
|
* Function that overrides default behavior when a channel gets deleted. In absence of this prop, the channel will be removed from the list.
|
|
@@ -120,6 +124,21 @@ export type ChannelListProps<
|
|
|
120
124
|
setChannels: React.Dispatch<React.SetStateAction<Channel<StreamChatGenerics>[] | null>>,
|
|
121
125
|
event: Event<StreamChatGenerics>,
|
|
122
126
|
) => void;
|
|
127
|
+
/**
|
|
128
|
+
* Function that overrides default behavior when a channel member.updated event is triggered
|
|
129
|
+
* @param lockChannelOrder If set to true, channels won't dynamically sort by most recent message, defaults to false
|
|
130
|
+
* @param setChannels Setter for internal state property - `channels`. It's created from useState() hook.
|
|
131
|
+
* @param event An [Event object](https://getstream.io/chat/docs/event_object) corresponding to `member.updated` event
|
|
132
|
+
* @param filters Channel filters
|
|
133
|
+
* @param sort Channel sort options
|
|
134
|
+
* @overrideType Function
|
|
135
|
+
*/
|
|
136
|
+
onChannelMemberUpdated?: (
|
|
137
|
+
lockChannelOrder: boolean,
|
|
138
|
+
setChannels: React.Dispatch<React.SetStateAction<Channel<StreamChatGenerics>[] | null>>,
|
|
139
|
+
event: Event<StreamChatGenerics>,
|
|
140
|
+
options?: ChannelListEventListenerOptions<StreamChatGenerics>,
|
|
141
|
+
) => void;
|
|
123
142
|
/**
|
|
124
143
|
* Function to customize behavior when a channel gets truncated
|
|
125
144
|
*
|
|
@@ -163,13 +182,16 @@ export type ChannelListProps<
|
|
|
163
182
|
* @param lockChannelOrder If set to true, channels won't dynamically sort by most recent message, defaults to false
|
|
164
183
|
* @param setChannels Setter for internal state property - `channels`. It's created from useState() hook.
|
|
165
184
|
* @param event An [Event object](https://getstream.io/chat/docs/event_object) corresponding to `message.new` event
|
|
166
|
-
*
|
|
185
|
+
* @param considerArchivedChannels If set to true, archived channels will be considered while updating the list of channels
|
|
186
|
+
* @param filters Channel filters
|
|
187
|
+
* @param sort Channel sort options
|
|
167
188
|
* @overrideType Function
|
|
168
189
|
* */
|
|
169
190
|
onNewMessage?: (
|
|
170
191
|
lockChannelOrder: boolean,
|
|
171
192
|
setChannels: React.Dispatch<React.SetStateAction<Channel<StreamChatGenerics>[] | null>>,
|
|
172
193
|
event: Event<StreamChatGenerics>,
|
|
194
|
+
options?: ChannelListEventListenerOptions<StreamChatGenerics>,
|
|
173
195
|
) => void;
|
|
174
196
|
/**
|
|
175
197
|
* Override the default listener/handler for event `notification.message_new`
|
|
@@ -177,13 +199,15 @@ export type ChannelListProps<
|
|
|
177
199
|
*
|
|
178
200
|
* @param setChannels Setter for internal state property - `channels`. It's created from useState() hook.
|
|
179
201
|
* @param event An [Event object](https://getstream.io/chat/docs/event_object) corresponding to `notification.message_new` event
|
|
180
|
-
*
|
|
202
|
+
* @param filters Channel filters
|
|
181
203
|
* @overrideType Function
|
|
182
204
|
* */
|
|
183
205
|
onNewMessageNotification?: (
|
|
184
206
|
setChannels: React.Dispatch<React.SetStateAction<Channel<StreamChatGenerics>[] | null>>,
|
|
185
207
|
event: Event<StreamChatGenerics>,
|
|
208
|
+
options?: ChannelListEventListenerOptions<StreamChatGenerics>,
|
|
186
209
|
) => void;
|
|
210
|
+
|
|
187
211
|
/**
|
|
188
212
|
* Function that overrides default behavior when a user gets removed from a channel
|
|
189
213
|
*
|
|
@@ -244,6 +268,7 @@ export const ChannelList = <
|
|
|
244
268
|
onAddedToChannel,
|
|
245
269
|
onChannelDeleted,
|
|
246
270
|
onChannelHidden,
|
|
271
|
+
onChannelMemberUpdated,
|
|
247
272
|
onChannelTruncated,
|
|
248
273
|
onChannelUpdated,
|
|
249
274
|
onChannelVisible,
|
|
@@ -289,6 +314,7 @@ export const ChannelList = <
|
|
|
289
314
|
// Setup event listeners
|
|
290
315
|
useAddedToChannelNotification({
|
|
291
316
|
onAddedToChannel,
|
|
317
|
+
options: { filters, sort },
|
|
292
318
|
setChannels,
|
|
293
319
|
});
|
|
294
320
|
|
|
@@ -302,6 +328,13 @@ export const ChannelList = <
|
|
|
302
328
|
setChannels,
|
|
303
329
|
});
|
|
304
330
|
|
|
331
|
+
useChannelMemberUpdated({
|
|
332
|
+
lockChannelOrder,
|
|
333
|
+
onChannelMemberUpdated,
|
|
334
|
+
options: { filters, sort },
|
|
335
|
+
setChannels,
|
|
336
|
+
});
|
|
337
|
+
|
|
305
338
|
useChannelTruncated({
|
|
306
339
|
onChannelTruncated,
|
|
307
340
|
refreshList,
|
|
@@ -322,11 +355,13 @@ export const ChannelList = <
|
|
|
322
355
|
useNewMessage({
|
|
323
356
|
lockChannelOrder,
|
|
324
357
|
onNewMessage,
|
|
358
|
+
options: { filters, sort },
|
|
325
359
|
setChannels,
|
|
326
360
|
});
|
|
327
361
|
|
|
328
362
|
useNewMessageNotification({
|
|
329
363
|
onNewMessageNotification,
|
|
364
|
+
options: { filters, sort },
|
|
330
365
|
setChannels,
|
|
331
366
|
});
|
|
332
367
|
|
|
@@ -6,8 +6,12 @@ import type { Channel, Event } from 'stream-chat';
|
|
|
6
6
|
|
|
7
7
|
import { useChatContext } from '../../../../contexts/chatContext/ChatContext';
|
|
8
8
|
|
|
9
|
-
import type {
|
|
9
|
+
import type {
|
|
10
|
+
ChannelListEventListenerOptions,
|
|
11
|
+
DefaultStreamChatGenerics,
|
|
12
|
+
} from '../../../../types/types';
|
|
10
13
|
import { getChannel } from '../../utils';
|
|
14
|
+
import { findLastPinnedChannelIndex, findPinnedAtSortOrder } from '../utils';
|
|
11
15
|
|
|
12
16
|
type Parameters<StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics> =
|
|
13
17
|
{
|
|
@@ -15,13 +19,16 @@ type Parameters<StreamChatGenerics extends DefaultStreamChatGenerics = DefaultSt
|
|
|
15
19
|
onAddedToChannel?: (
|
|
16
20
|
setChannels: React.Dispatch<React.SetStateAction<Channel<StreamChatGenerics>[] | null>>,
|
|
17
21
|
event: Event<StreamChatGenerics>,
|
|
22
|
+
options?: ChannelListEventListenerOptions<StreamChatGenerics>,
|
|
18
23
|
) => void;
|
|
24
|
+
options?: ChannelListEventListenerOptions<StreamChatGenerics>;
|
|
19
25
|
};
|
|
20
26
|
|
|
21
27
|
export const useAddedToChannelNotification = <
|
|
22
28
|
StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics,
|
|
23
29
|
>({
|
|
24
30
|
onAddedToChannel,
|
|
31
|
+
options,
|
|
25
32
|
setChannels,
|
|
26
33
|
}: Parameters<StreamChatGenerics>) => {
|
|
27
34
|
const { client } = useChatContext<StreamChatGenerics>();
|
|
@@ -29,15 +36,37 @@ export const useAddedToChannelNotification = <
|
|
|
29
36
|
useEffect(() => {
|
|
30
37
|
const handleEvent = async (event: Event<StreamChatGenerics>) => {
|
|
31
38
|
if (typeof onAddedToChannel === 'function') {
|
|
32
|
-
onAddedToChannel(setChannels, event);
|
|
39
|
+
onAddedToChannel(setChannels, event, options);
|
|
33
40
|
} else {
|
|
41
|
+
if (!options) return;
|
|
42
|
+
const { sort } = options;
|
|
34
43
|
if (event.channel?.id && event.channel?.type) {
|
|
35
44
|
const channel = await getChannel<StreamChatGenerics>({
|
|
36
45
|
client,
|
|
37
46
|
id: event.channel.id,
|
|
38
47
|
type: event.channel.type,
|
|
39
48
|
});
|
|
40
|
-
|
|
49
|
+
|
|
50
|
+
const pinnedAtSort = findPinnedAtSortOrder({ sort });
|
|
51
|
+
|
|
52
|
+
setChannels((channels) => {
|
|
53
|
+
if (!channels) return channels;
|
|
54
|
+
|
|
55
|
+
// handle pinning
|
|
56
|
+
let lastPinnedChannelIndex: number | null = null;
|
|
57
|
+
|
|
58
|
+
const newChannels = [...channels];
|
|
59
|
+
if (pinnedAtSort === 1 || pinnedAtSort === -1) {
|
|
60
|
+
lastPinnedChannelIndex = findLastPinnedChannelIndex({ channels: newChannels });
|
|
61
|
+
const newTargetChannelIndex =
|
|
62
|
+
typeof lastPinnedChannelIndex === 'number' ? lastPinnedChannelIndex + 1 : 0;
|
|
63
|
+
|
|
64
|
+
newChannels.splice(newTargetChannelIndex, 0, channel);
|
|
65
|
+
return newChannels;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
return uniqBy([channel, ...channels], 'cid');
|
|
69
|
+
});
|
|
41
70
|
}
|
|
42
71
|
}
|
|
43
72
|
};
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
import { useEffect } from 'react';
|
|
2
|
+
|
|
3
|
+
import type { Channel, Event } from 'stream-chat';
|
|
4
|
+
|
|
5
|
+
import { useChatContext } from '../../../../contexts/chatContext/ChatContext';
|
|
6
|
+
|
|
7
|
+
import type {
|
|
8
|
+
ChannelListEventListenerOptions,
|
|
9
|
+
DefaultStreamChatGenerics,
|
|
10
|
+
} from '../../../../types/types';
|
|
11
|
+
import {
|
|
12
|
+
findLastPinnedChannelIndex,
|
|
13
|
+
findPinnedAtSortOrder,
|
|
14
|
+
isChannelArchived,
|
|
15
|
+
isChannelPinned,
|
|
16
|
+
shouldConsiderArchivedChannels,
|
|
17
|
+
shouldConsiderPinnedChannels,
|
|
18
|
+
} from '../utils';
|
|
19
|
+
|
|
20
|
+
type Parameters<StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics> =
|
|
21
|
+
{
|
|
22
|
+
lockChannelOrder: boolean;
|
|
23
|
+
setChannels: React.Dispatch<React.SetStateAction<Channel<StreamChatGenerics>[] | null>>;
|
|
24
|
+
onChannelMemberUpdated?: (
|
|
25
|
+
lockChannelOrder: boolean,
|
|
26
|
+
setChannels: React.Dispatch<React.SetStateAction<Channel<StreamChatGenerics>[] | null>>,
|
|
27
|
+
event: Event<StreamChatGenerics>,
|
|
28
|
+
options?: ChannelListEventListenerOptions<StreamChatGenerics>,
|
|
29
|
+
) => void;
|
|
30
|
+
options?: ChannelListEventListenerOptions<StreamChatGenerics>;
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
export const useChannelMemberUpdated = <
|
|
34
|
+
StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics,
|
|
35
|
+
>({
|
|
36
|
+
lockChannelOrder,
|
|
37
|
+
onChannelMemberUpdated,
|
|
38
|
+
options,
|
|
39
|
+
setChannels,
|
|
40
|
+
}: Parameters<StreamChatGenerics>) => {
|
|
41
|
+
const { client } = useChatContext<StreamChatGenerics>();
|
|
42
|
+
|
|
43
|
+
useEffect(() => {
|
|
44
|
+
const handleEvent = (event: Event<StreamChatGenerics>) => {
|
|
45
|
+
if (typeof onChannelMemberUpdated === 'function') {
|
|
46
|
+
onChannelMemberUpdated(lockChannelOrder, setChannels, event, options);
|
|
47
|
+
} else {
|
|
48
|
+
if (!options) return;
|
|
49
|
+
const { filters, sort } = options;
|
|
50
|
+
if (!event.member?.user || event.member.user.id !== client.userID || !event.channel_type) {
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
const channelType = event.channel_type;
|
|
54
|
+
const channelId = event.channel_id;
|
|
55
|
+
|
|
56
|
+
const considerPinnedChannels = shouldConsiderPinnedChannels(sort);
|
|
57
|
+
const considerArchivedChannels = shouldConsiderArchivedChannels(filters);
|
|
58
|
+
const pinnedAtSort = findPinnedAtSortOrder({ sort });
|
|
59
|
+
|
|
60
|
+
setChannels((currentChannels) => {
|
|
61
|
+
if (!currentChannels) return currentChannels;
|
|
62
|
+
|
|
63
|
+
const targetChannel = client.channel(channelType, channelId);
|
|
64
|
+
// assumes that channel instances are not changing
|
|
65
|
+
const targetChannelIndex = currentChannels.indexOf(targetChannel);
|
|
66
|
+
const targetChannelExistsWithinList = targetChannelIndex >= 0;
|
|
67
|
+
|
|
68
|
+
const isTargetChannelPinned = isChannelPinned(targetChannel);
|
|
69
|
+
const isTargetChannelArchived = isChannelArchived(targetChannel);
|
|
70
|
+
|
|
71
|
+
if (!considerPinnedChannels || lockChannelOrder) {
|
|
72
|
+
return currentChannels;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
const newChannels = [...currentChannels];
|
|
76
|
+
|
|
77
|
+
if (targetChannelExistsWithinList) {
|
|
78
|
+
newChannels.splice(targetChannelIndex, 1);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
// handle archiving (remove channel)
|
|
82
|
+
if (
|
|
83
|
+
// When archived filter true, and channel is unarchived
|
|
84
|
+
(considerArchivedChannels && !isTargetChannelArchived && filters?.archived) ||
|
|
85
|
+
// When archived filter false, and channel is archived
|
|
86
|
+
(considerArchivedChannels && isTargetChannelArchived && !filters?.archived)
|
|
87
|
+
) {
|
|
88
|
+
return newChannels;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
// handle pinning
|
|
92
|
+
let lastPinnedChannelIndex: number | null = null;
|
|
93
|
+
|
|
94
|
+
if (pinnedAtSort === 1 || (pinnedAtSort === -1 && !isTargetChannelPinned)) {
|
|
95
|
+
lastPinnedChannelIndex = findLastPinnedChannelIndex({ channels: newChannels });
|
|
96
|
+
}
|
|
97
|
+
const newTargetChannelIndex =
|
|
98
|
+
typeof lastPinnedChannelIndex === 'number' ? lastPinnedChannelIndex + 1 : 0;
|
|
99
|
+
|
|
100
|
+
// skip re-render if the position of the channel does not change
|
|
101
|
+
if (currentChannels[newTargetChannelIndex] === targetChannel) {
|
|
102
|
+
return currentChannels;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
newChannels.splice(newTargetChannelIndex, 0, targetChannel);
|
|
106
|
+
|
|
107
|
+
return newChannels;
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
};
|
|
111
|
+
|
|
112
|
+
const listener = client?.on('member.updated', handleEvent);
|
|
113
|
+
return () => listener?.unsubscribe();
|
|
114
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
115
|
+
}, []);
|
|
116
|
+
};
|
|
@@ -4,8 +4,17 @@ import type { Channel, Event } from 'stream-chat';
|
|
|
4
4
|
|
|
5
5
|
import { useChatContext } from '../../../../contexts/chatContext/ChatContext';
|
|
6
6
|
|
|
7
|
-
import type {
|
|
7
|
+
import type {
|
|
8
|
+
ChannelListEventListenerOptions,
|
|
9
|
+
DefaultStreamChatGenerics,
|
|
10
|
+
} from '../../../../types/types';
|
|
8
11
|
import { moveChannelUp } from '../../utils';
|
|
12
|
+
import {
|
|
13
|
+
isChannelArchived,
|
|
14
|
+
isChannelPinned,
|
|
15
|
+
shouldConsiderArchivedChannels,
|
|
16
|
+
shouldConsiderPinnedChannels,
|
|
17
|
+
} from '../utils';
|
|
9
18
|
|
|
10
19
|
type Parameters<StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics> =
|
|
11
20
|
{
|
|
@@ -15,7 +24,9 @@ type Parameters<StreamChatGenerics extends DefaultStreamChatGenerics = DefaultSt
|
|
|
15
24
|
lockChannelOrder: boolean,
|
|
16
25
|
setChannels: React.Dispatch<React.SetStateAction<Channel<StreamChatGenerics>[] | null>>,
|
|
17
26
|
event: Event<StreamChatGenerics>,
|
|
27
|
+
options?: ChannelListEventListenerOptions<StreamChatGenerics>,
|
|
18
28
|
) => void;
|
|
29
|
+
options?: ChannelListEventListenerOptions<StreamChatGenerics>;
|
|
19
30
|
};
|
|
20
31
|
|
|
21
32
|
export const useNewMessage = <
|
|
@@ -23,6 +34,7 @@ export const useNewMessage = <
|
|
|
23
34
|
>({
|
|
24
35
|
lockChannelOrder,
|
|
25
36
|
onNewMessage,
|
|
37
|
+
options,
|
|
26
38
|
setChannels,
|
|
27
39
|
}: Parameters<StreamChatGenerics>) => {
|
|
28
40
|
const { client } = useChatContext<StreamChatGenerics>();
|
|
@@ -30,27 +42,44 @@ export const useNewMessage = <
|
|
|
30
42
|
useEffect(() => {
|
|
31
43
|
const handleEvent = (event: Event<StreamChatGenerics>) => {
|
|
32
44
|
if (typeof onNewMessage === 'function') {
|
|
33
|
-
onNewMessage(lockChannelOrder, setChannels, event);
|
|
45
|
+
onNewMessage(lockChannelOrder, setChannels, event, options);
|
|
34
46
|
} else {
|
|
47
|
+
if (!options) return;
|
|
48
|
+
const { filters, sort } = options;
|
|
49
|
+
const considerPinnedChannels = shouldConsiderPinnedChannels(sort);
|
|
50
|
+
const considerArchivedChannels = shouldConsiderArchivedChannels(filters);
|
|
51
|
+
|
|
52
|
+
const channelType = event.channel_type;
|
|
53
|
+
const channelId = event.channel_id;
|
|
54
|
+
|
|
55
|
+
if (!channelType || !channelId) return;
|
|
56
|
+
|
|
35
57
|
setChannels((channels) => {
|
|
36
58
|
if (!channels) return channels;
|
|
37
|
-
const
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
// We remove it from `channels` state, but its still being watched and exists in client.activeChannels.
|
|
43
|
-
const channel = client.channel(event.channel_type, event.channel_id);
|
|
44
|
-
return [channel, ...channels];
|
|
45
|
-
}
|
|
59
|
+
const targetChannel = client.channel(channelType, channelId);
|
|
60
|
+
const targetChannelIndex = channels.indexOf(targetChannel);
|
|
61
|
+
|
|
62
|
+
const isTargetChannelArchived = isChannelArchived(targetChannel);
|
|
63
|
+
const isTargetChannelPinned = isChannelPinned(targetChannel);
|
|
46
64
|
|
|
47
|
-
if (
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
65
|
+
if (
|
|
66
|
+
// When archived filter false, and channel is archived
|
|
67
|
+
(considerArchivedChannels && isTargetChannelArchived && !filters?.archived) ||
|
|
68
|
+
// When archived filter true, and channel is unarchived
|
|
69
|
+
(considerArchivedChannels && !isTargetChannelArchived && filters?.archived) ||
|
|
70
|
+
// If the channel is pinned and we are not considering pinned channels
|
|
71
|
+
(isTargetChannelPinned && considerPinnedChannels) ||
|
|
72
|
+
lockChannelOrder
|
|
73
|
+
) {
|
|
74
|
+
return [...channels];
|
|
75
|
+
}
|
|
52
76
|
|
|
53
|
-
return
|
|
77
|
+
return moveChannelUp<StreamChatGenerics>({
|
|
78
|
+
channels,
|
|
79
|
+
channelToMove: targetChannel,
|
|
80
|
+
channelToMoveIndexWithinChannels: targetChannelIndex,
|
|
81
|
+
sort,
|
|
82
|
+
});
|
|
54
83
|
});
|
|
55
84
|
}
|
|
56
85
|
};
|
|
@@ -6,23 +6,29 @@ import type { Channel, Event } from 'stream-chat';
|
|
|
6
6
|
|
|
7
7
|
import { useChatContext } from '../../../../contexts/chatContext/ChatContext';
|
|
8
8
|
|
|
9
|
-
import type {
|
|
9
|
+
import type {
|
|
10
|
+
ChannelListEventListenerOptions,
|
|
11
|
+
DefaultStreamChatGenerics,
|
|
12
|
+
} from '../../../../types/types';
|
|
10
13
|
import { getChannel } from '../../utils';
|
|
14
|
+
import { isChannelArchived } from '../utils';
|
|
11
15
|
|
|
12
16
|
type Parameters<StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics> =
|
|
13
17
|
{
|
|
14
18
|
setChannels: React.Dispatch<React.SetStateAction<Channel<StreamChatGenerics>[] | null>>;
|
|
15
|
-
|
|
16
19
|
onNewMessageNotification?: (
|
|
17
20
|
setChannels: React.Dispatch<React.SetStateAction<Channel<StreamChatGenerics>[] | null>>,
|
|
18
21
|
event: Event<StreamChatGenerics>,
|
|
22
|
+
options?: ChannelListEventListenerOptions<StreamChatGenerics>,
|
|
19
23
|
) => void;
|
|
24
|
+
options?: ChannelListEventListenerOptions<StreamChatGenerics>;
|
|
20
25
|
};
|
|
21
26
|
|
|
22
27
|
export const useNewMessageNotification = <
|
|
23
28
|
StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics,
|
|
24
29
|
>({
|
|
25
30
|
onNewMessageNotification,
|
|
31
|
+
options,
|
|
26
32
|
setChannels,
|
|
27
33
|
}: Parameters<StreamChatGenerics>) => {
|
|
28
34
|
const { client } = useChatContext<StreamChatGenerics>();
|
|
@@ -30,14 +36,23 @@ export const useNewMessageNotification = <
|
|
|
30
36
|
useEffect(() => {
|
|
31
37
|
const handleEvent = async (event: Event<StreamChatGenerics>) => {
|
|
32
38
|
if (typeof onNewMessageNotification === 'function') {
|
|
33
|
-
onNewMessageNotification(setChannels, event);
|
|
39
|
+
onNewMessageNotification(setChannels, event, options);
|
|
34
40
|
} else {
|
|
41
|
+
if (!options) return;
|
|
42
|
+
const { filters } = options;
|
|
35
43
|
if (event.channel?.id && event.channel?.type) {
|
|
36
44
|
const channel = await getChannel({
|
|
37
45
|
client,
|
|
38
46
|
id: event.channel.id,
|
|
39
47
|
type: event.channel.type,
|
|
40
48
|
});
|
|
49
|
+
|
|
50
|
+
// Handle archived channels
|
|
51
|
+
const considerArchivedChannels = filters && filters.archived === false;
|
|
52
|
+
if (isChannelArchived(channel) && considerArchivedChannels) {
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
|
|
41
56
|
setChannels((channels) => (channels ? uniqBy([channel, ...channels], 'cid') : channels));
|
|
42
57
|
}
|
|
43
58
|
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { Channel, ChannelMemberResponse, EventTypes } from 'stream-chat';
|
|
2
|
+
|
|
3
|
+
import { useSelectedChannelState } from './useSelectedChannelState';
|
|
4
|
+
|
|
5
|
+
import { DefaultStreamChatGenerics } from '../../../types/types';
|
|
6
|
+
|
|
7
|
+
const selector = <StreamChatGenerics extends DefaultStreamChatGenerics>(
|
|
8
|
+
channel: Channel<StreamChatGenerics>,
|
|
9
|
+
) => channel.state.membership;
|
|
10
|
+
const keys: EventTypes[] = ['member.updated'];
|
|
11
|
+
|
|
12
|
+
export function useChannelMembershipState<StreamChatGenerics extends DefaultStreamChatGenerics>(
|
|
13
|
+
channel: Channel<StreamChatGenerics>,
|
|
14
|
+
): ChannelMemberResponse<StreamChatGenerics>;
|
|
15
|
+
export function useChannelMembershipState<StreamChatGenerics extends DefaultStreamChatGenerics>(
|
|
16
|
+
channel?: Channel<StreamChatGenerics>,
|
|
17
|
+
): ChannelMemberResponse<StreamChatGenerics> | undefined;
|
|
18
|
+
export function useChannelMembershipState<StreamChatGenerics extends DefaultStreamChatGenerics>(
|
|
19
|
+
channel?: Channel<StreamChatGenerics>,
|
|
20
|
+
) {
|
|
21
|
+
return useSelectedChannelState({ channel, selector, stateChangeEventKeys: keys });
|
|
22
|
+
}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { useCallback } from 'react';
|
|
2
|
+
|
|
3
|
+
import type { Channel, EventTypes } from 'stream-chat';
|
|
4
|
+
import { useSyncExternalStore } from 'use-sync-external-store/shim';
|
|
5
|
+
|
|
6
|
+
import { DefaultStreamChatGenerics } from '../../../types/types';
|
|
7
|
+
|
|
8
|
+
const noop = () => {};
|
|
9
|
+
|
|
10
|
+
export function useSelectedChannelState<
|
|
11
|
+
StreamChatGenerics extends DefaultStreamChatGenerics,
|
|
12
|
+
O,
|
|
13
|
+
>(_: {
|
|
14
|
+
channel: Channel<StreamChatGenerics>;
|
|
15
|
+
selector: (channel: Channel<StreamChatGenerics>) => O;
|
|
16
|
+
stateChangeEventKeys?: EventTypes[];
|
|
17
|
+
}): O;
|
|
18
|
+
export function useSelectedChannelState<
|
|
19
|
+
StreamChatGenerics extends DefaultStreamChatGenerics,
|
|
20
|
+
O,
|
|
21
|
+
>(_: {
|
|
22
|
+
selector: (channel: Channel<StreamChatGenerics>) => O;
|
|
23
|
+
channel?: Channel<StreamChatGenerics> | undefined;
|
|
24
|
+
stateChangeEventKeys?: EventTypes[];
|
|
25
|
+
}): O | undefined;
|
|
26
|
+
export function useSelectedChannelState<StreamChatGenerics extends DefaultStreamChatGenerics, O>({
|
|
27
|
+
channel,
|
|
28
|
+
selector,
|
|
29
|
+
stateChangeEventKeys = ['all'],
|
|
30
|
+
}: {
|
|
31
|
+
selector: (channel: Channel<StreamChatGenerics>) => O;
|
|
32
|
+
channel?: Channel<StreamChatGenerics>;
|
|
33
|
+
stateChangeEventKeys?: EventTypes[];
|
|
34
|
+
}): O | undefined {
|
|
35
|
+
const subscribe = useCallback(
|
|
36
|
+
(onStoreChange: (value: O) => void) => {
|
|
37
|
+
if (!channel) return noop;
|
|
38
|
+
|
|
39
|
+
const subscriptions = stateChangeEventKeys.map((et) =>
|
|
40
|
+
channel.on(et, () => {
|
|
41
|
+
onStoreChange(selector(channel));
|
|
42
|
+
}),
|
|
43
|
+
);
|
|
44
|
+
|
|
45
|
+
return () => subscriptions.forEach((subscription) => subscription.unsubscribe());
|
|
46
|
+
},
|
|
47
|
+
[channel, selector, stateChangeEventKeys],
|
|
48
|
+
);
|
|
49
|
+
|
|
50
|
+
const getSnapshot = useCallback(() => {
|
|
51
|
+
if (!channel) return undefined;
|
|
52
|
+
|
|
53
|
+
return selector(channel);
|
|
54
|
+
}, [channel, selector]);
|
|
55
|
+
|
|
56
|
+
return useSyncExternalStore(subscribe, getSnapshot);
|
|
57
|
+
}
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
import { Channel, ChannelSortBase } from 'stream-chat';
|
|
2
|
+
|
|
3
|
+
import { DefaultStreamChatGenerics } from '../../../../types/types';
|
|
4
|
+
import { ChannelListProps } from '../../ChannelList';
|
|
5
|
+
|
|
6
|
+
export const isChannelPinned = <
|
|
7
|
+
StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics,
|
|
8
|
+
>(
|
|
9
|
+
channel: Channel<StreamChatGenerics>,
|
|
10
|
+
) => {
|
|
11
|
+
if (!channel) return false;
|
|
12
|
+
|
|
13
|
+
const member = channel.state.membership;
|
|
14
|
+
|
|
15
|
+
return !!member?.pinned_at;
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
export const isChannelArchived = <
|
|
19
|
+
StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics,
|
|
20
|
+
>(
|
|
21
|
+
channel: Channel<StreamChatGenerics>,
|
|
22
|
+
) => {
|
|
23
|
+
if (!channel) return false;
|
|
24
|
+
|
|
25
|
+
const member = channel.state.membership;
|
|
26
|
+
|
|
27
|
+
return !!member?.archived_at;
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
export const shouldConsiderArchivedChannels = <
|
|
31
|
+
StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics,
|
|
32
|
+
>(
|
|
33
|
+
filters: ChannelListProps<StreamChatGenerics>['filters'],
|
|
34
|
+
) => {
|
|
35
|
+
if (!filters) return false;
|
|
36
|
+
|
|
37
|
+
return typeof filters.archived === 'boolean';
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
export const extractSortValue = <
|
|
41
|
+
StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics,
|
|
42
|
+
>({
|
|
43
|
+
atIndex,
|
|
44
|
+
sort,
|
|
45
|
+
targetKey,
|
|
46
|
+
}: {
|
|
47
|
+
atIndex: number;
|
|
48
|
+
targetKey: keyof ChannelSortBase<StreamChatGenerics>;
|
|
49
|
+
sort?: ChannelListProps<StreamChatGenerics>['sort'];
|
|
50
|
+
}) => {
|
|
51
|
+
if (!sort) return null;
|
|
52
|
+
let option: null | ChannelSortBase<StreamChatGenerics> = null;
|
|
53
|
+
|
|
54
|
+
if (Array.isArray(sort)) {
|
|
55
|
+
option = sort[atIndex] ?? null;
|
|
56
|
+
} else {
|
|
57
|
+
let index = 0;
|
|
58
|
+
for (const key in sort) {
|
|
59
|
+
if (index !== atIndex) {
|
|
60
|
+
index++;
|
|
61
|
+
continue;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
if (key !== targetKey) {
|
|
65
|
+
return null;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
option = sort;
|
|
69
|
+
|
|
70
|
+
break;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
return option?.[targetKey] ?? null;
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Returns true only if `{ pinned_at: -1 }` or `{ pinned_at: 1 }` option is first within the `sort` array.
|
|
79
|
+
*/
|
|
80
|
+
export const shouldConsiderPinnedChannels = <
|
|
81
|
+
StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics,
|
|
82
|
+
>(
|
|
83
|
+
sort: ChannelListProps<StreamChatGenerics>['sort'],
|
|
84
|
+
) => {
|
|
85
|
+
const value = extractSortValue({
|
|
86
|
+
atIndex: 0,
|
|
87
|
+
sort,
|
|
88
|
+
targetKey: 'pinned_at',
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
if (typeof value !== 'number') return false;
|
|
92
|
+
|
|
93
|
+
return Math.abs(value) === 1;
|
|
94
|
+
};
|
|
95
|
+
|
|
96
|
+
export function findPinnedAtSortOrder<
|
|
97
|
+
StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics,
|
|
98
|
+
>({ sort }: { sort: ChannelListProps<StreamChatGenerics>['sort'] }) {
|
|
99
|
+
if (!sort) return null;
|
|
100
|
+
|
|
101
|
+
if (Array.isArray(sort)) {
|
|
102
|
+
const [option] = sort;
|
|
103
|
+
|
|
104
|
+
if (!option?.pinned_at) return null;
|
|
105
|
+
|
|
106
|
+
return option.pinned_at;
|
|
107
|
+
} else {
|
|
108
|
+
if (!sort.pinned_at) return null;
|
|
109
|
+
|
|
110
|
+
return sort.pinned_at;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
export function findLastPinnedChannelIndex<
|
|
115
|
+
StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics,
|
|
116
|
+
>({ channels }: { channels: Channel<StreamChatGenerics>[] }) {
|
|
117
|
+
let lastPinnedChannelIndex: number | null = null;
|
|
118
|
+
|
|
119
|
+
for (const channel of channels) {
|
|
120
|
+
if (!isChannelPinned(channel)) break;
|
|
121
|
+
|
|
122
|
+
if (typeof lastPinnedChannelIndex === 'number') {
|
|
123
|
+
lastPinnedChannelIndex++;
|
|
124
|
+
} else {
|
|
125
|
+
lastPinnedChannelIndex = 0;
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
return lastPinnedChannelIndex;
|
|
130
|
+
}
|