stream-chat 9.50.3 → 10.0.0-rc.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/dist/cjs/index.browser.js +19798 -14472
- package/dist/cjs/index.browser.js.map +4 -4
- package/dist/cjs/index.node.js +19817 -14482
- package/dist/cjs/index.node.js.map +4 -4
- package/dist/esm/index.mjs +19795 -14469
- package/dist/esm/index.mjs.map +4 -4
- package/dist/types/ChannelManager.d.ts +221 -0
- package/dist/types/EventHandlerPipeline.d.ts +104 -0
- package/dist/types/api-client.d.ts +26 -0
- package/dist/types/campaign.d.ts +0 -44
- package/dist/types/channel.d.ts +454 -479
- package/dist/types/channel_batch_updater.d.ts +0 -93
- package/dist/types/channel_state.d.ts +53 -201
- package/dist/types/client.d.ts +451 -1920
- package/dist/types/client_state.d.ts +4 -4
- package/dist/types/configuration/InstanceConfigurationService.d.ts +26 -0
- package/dist/types/configuration/index.d.ts +1 -0
- package/dist/types/configuration/types.d.ts +53 -0
- package/dist/types/connection.d.ts +49 -41
- package/dist/types/connection_fallback.d.ts +6 -4
- package/dist/types/constants.d.ts +0 -4
- package/dist/types/custom_types.d.ts +2 -0
- package/dist/types/entityStore/EntityStore.d.ts +111 -0
- package/dist/types/entityStore/StoreBackedItemIndex.d.ts +60 -0
- package/dist/types/entityStore/applyReactionLocally.d.ts +26 -0
- package/dist/types/entityStore/index.d.ts +2 -0
- package/dist/types/errors.d.ts +10 -2
- package/dist/types/gen/chat/ChannelApi.d.ts +45 -0
- package/dist/types/gen/chat/ChatApi.d.ts +334 -0
- package/dist/types/gen/model-decoders/decoders.d.ts +3 -0
- package/dist/types/gen/model-decoders/event-decoder-mapping.d.ts +6 -0
- package/dist/types/gen/models/index.d.ts +8836 -0
- package/dist/types/gen/moderation/ModerationApi.d.ts +50 -0
- package/dist/types/gen-imports.d.ts +3 -0
- package/dist/types/index.d.ts +8 -7
- package/dist/types/insights.d.ts +9 -8
- package/dist/types/logger.d.ts +9 -0
- package/dist/types/messageComposer/LocationComposer.d.ts +7 -4
- package/dist/types/messageComposer/attachmentIdentity.d.ts +2 -2
- package/dist/types/messageComposer/attachmentManager.d.ts +8 -4
- package/dist/types/messageComposer/configuration/types.d.ts +11 -11
- package/dist/types/messageComposer/linkPreviewsManager.d.ts +25 -13
- package/dist/types/messageComposer/messageComposer.d.ts +10 -10
- package/dist/types/messageComposer/middleware/messageComposer/types.d.ts +3 -3
- package/dist/types/messageComposer/middleware/pollComposer/types.d.ts +4 -7
- package/dist/types/messageComposer/middleware/textComposer/commandUtils.d.ts +3 -3
- package/dist/types/messageComposer/middleware/textComposer/commands.d.ts +7 -7
- package/dist/types/messageComposer/middleware/textComposer/mentions.d.ts +218 -4
- package/dist/types/messageComposer/middleware/textComposer/types.d.ts +9 -4
- package/dist/types/messageComposer/pollComposer.d.ts +5 -4
- package/dist/types/messageComposer/textComposer.d.ts +8 -3
- package/dist/types/messageComposer/types.d.ts +6 -28
- package/dist/types/messageDelivery/MessageDeliveryReporter.d.ts +40 -25
- package/dist/types/messageDelivery/MessageReceiptsTracker.d.ts +53 -12
- package/dist/types/messageOperations/MessageOperationStatePolicy.d.ts +19 -0
- package/dist/types/messageOperations/MessageOperations.d.ts +17 -0
- package/dist/types/messageOperations/index.d.ts +3 -0
- package/dist/types/messageOperations/types.d.ts +49 -0
- package/dist/types/moderation.d.ts +21 -203
- package/dist/types/notifications/types.d.ts +8 -7
- package/dist/types/offline-support/offline_support_api.d.ts +111 -87
- package/dist/types/offline-support/offline_sync_manager.d.ts +0 -7
- package/dist/types/offline-support/types.d.ts +19 -23
- package/dist/types/offline-support/util.d.ts +4 -2
- package/dist/types/pagination/FilterBuilder.d.ts +1 -1
- package/dist/types/pagination/ItemIndex.d.ts +25 -0
- package/dist/types/pagination/cursorDerivation/createdAtAroundPaginationFlags.d.ts +9 -0
- package/dist/types/pagination/cursorDerivation/idAroundPaginationFlags.d.ts +6 -0
- package/dist/types/pagination/cursorDerivation/index.d.ts +1 -0
- package/dist/types/pagination/cursorDerivation/linearPaginationFlags.d.ts +6 -0
- package/dist/types/pagination/filterCompiler.d.ts +7 -0
- package/dist/types/pagination/index.d.ts +1 -3
- package/dist/types/pagination/paginators/BasePaginator.d.ts +848 -0
- package/dist/types/pagination/paginators/ChannelPaginator.d.ts +212 -0
- package/dist/types/pagination/paginators/MessageIntervalPaginator.d.ts +282 -0
- package/dist/types/pagination/paginators/MessagePaginator.d.ts +208 -0
- package/dist/types/pagination/paginators/PinnedMessagePaginator.d.ts +39 -0
- package/dist/types/pagination/paginators/ReminderPaginator.d.ts +19 -0
- package/dist/types/pagination/paginators/UserGroupPaginator.d.ts +24 -0
- package/dist/types/pagination/paginators/index.d.ts +7 -0
- package/dist/types/pagination/paginators/stateThrottling.d.ts +2 -0
- package/dist/types/pagination/sortCompiler.d.ts +49 -0
- package/dist/types/pagination/types.normalization.d.ts +11 -0
- package/dist/types/pagination/utility.normalization.d.ts +18 -0
- package/dist/types/pagination/utility.queryChannel.d.ts +26 -0
- package/dist/types/pagination/utility.search.d.ts +13 -0
- package/dist/types/permissions.d.ts +1 -1
- package/dist/types/poll.d.ts +29 -32
- package/dist/types/poll_manager.d.ts +2 -2
- package/dist/types/reminders/Reminder.d.ts +2 -5
- package/dist/types/reminders/ReminderManager.d.ts +2 -9
- package/dist/types/search/MessageSearchSource.d.ts +4 -4
- package/dist/types/search/UserSearchSource.d.ts +1 -1
- package/dist/types/search/types.d.ts +3 -3
- package/dist/types/segment.d.ts +0 -34
- package/dist/types/signing.d.ts +105 -65
- package/dist/types/store.d.ts +1 -0
- package/dist/types/thread.d.ts +70 -34
- package/dist/types/thread_manager.d.ts +3 -3
- package/dist/types/token_manager.d.ts +15 -10
- package/dist/types/types.d.ts +197 -3404
- package/dist/types/utils/FixedSizeQueueCache.d.ts +12 -6
- package/dist/types/utils/WithSubscriptions.d.ts +2 -1
- package/dist/types/utils/concurrency.d.ts +4 -4
- package/dist/types/utils/mergeWith/mergeWith.d.ts +3 -3
- package/dist/types/utils/mergeWith/mergeWithCore.d.ts +8 -3
- package/dist/types/utils/retryable.d.ts +34 -0
- package/dist/types/utils/throttling/throttle.d.ts +36 -0
- package/dist/types/utils.d.ts +100 -194
- package/package.json +7 -3
- package/src/ChannelManager.ts +724 -0
- package/src/CooldownTimer.ts +2 -2
- package/src/EventHandlerPipeline.ts +228 -0
- package/src/LiveLocationManager.ts +12 -11
- package/src/api-client.ts +275 -0
- package/src/campaign.ts +1 -77
- package/src/channel.ts +1344 -1282
- package/src/channel_batch_updater.ts +1 -211
- package/src/channel_state.ts +144 -1013
- package/src/client.ts +936 -3995
- package/src/client_state.ts +4 -4
- package/src/configuration/InstanceConfigurationService.ts +73 -0
- package/src/configuration/index.ts +1 -0
- package/src/configuration/types.ts +81 -0
- package/src/connection.ts +145 -94
- package/src/connection_fallback.ts +29 -27
- package/src/constants.ts +1 -5
- package/src/custom_types.ts +4 -1
- package/src/entityStore/EntityStore.ts +208 -0
- package/src/entityStore/StoreBackedItemIndex.ts +115 -0
- package/src/entityStore/applyReactionLocally.ts +113 -0
- package/src/entityStore/index.ts +2 -0
- package/src/errors.ts +14 -2
- package/src/gen/chat/ChannelApi.ts +275 -0
- package/src/gen/chat/ChatApi.ts +2554 -0
- package/src/gen/model-decoders/decoders.ts +2680 -0
- package/src/gen/model-decoders/event-decoder-mapping.ts +198 -0
- package/src/gen/models/index.ts +12673 -0
- package/src/gen/moderation/ModerationApi.ts +607 -0
- package/src/gen-imports.ts +3 -0
- package/src/index.ts +11 -12
- package/src/insights.ts +6 -5
- package/src/logger.ts +28 -0
- package/src/messageComposer/LocationComposer.ts +9 -5
- package/src/messageComposer/MessageComposerEffectHandlers.ts +1 -0
- package/src/messageComposer/attachmentIdentity.ts +16 -9
- package/src/messageComposer/attachmentManager.ts +13 -8
- package/src/messageComposer/configuration/types.ts +11 -11
- package/src/messageComposer/linkPreviewsManager.ts +9 -10
- package/src/messageComposer/messageComposer.ts +57 -53
- package/src/messageComposer/middleware/messageComposer/attachments.ts +1 -2
- package/src/messageComposer/middleware/messageComposer/cleanData.ts +1 -1
- package/src/messageComposer/middleware/messageComposer/compositionValidation.ts +2 -2
- package/src/messageComposer/middleware/messageComposer/messageComposerState.ts +2 -2
- package/src/messageComposer/middleware/messageComposer/sharedLocation.ts +4 -3
- package/src/messageComposer/middleware/messageComposer/textComposer.ts +2 -2
- package/src/messageComposer/middleware/messageComposer/types.ts +3 -4
- package/src/messageComposer/middleware/messageComposer/userDataInjection.ts +9 -5
- package/src/messageComposer/middleware/pollComposer/state.ts +0 -2
- package/src/messageComposer/middleware/pollComposer/types.ts +4 -7
- package/src/messageComposer/middleware/textComposer/TextComposerMiddlewareExecutor.ts +10 -1
- package/src/messageComposer/middleware/textComposer/commandEffects.ts +4 -4
- package/src/messageComposer/middleware/textComposer/commandUtils.ts +3 -6
- package/src/messageComposer/middleware/textComposer/commands.ts +3 -3
- package/src/messageComposer/middleware/textComposer/mentionUtils.ts +1 -1
- package/src/messageComposer/middleware/textComposer/mentions.ts +31 -15
- package/src/messageComposer/middleware/textComposer/types.ts +9 -4
- package/src/messageComposer/pollComposer.ts +6 -8
- package/src/messageComposer/textComposer.ts +27 -2
- package/src/messageComposer/types.ts +6 -28
- package/src/messageDelivery/MessageDeliveryReporter.ts +101 -45
- package/src/messageDelivery/MessageReceiptsTracker.ts +294 -21
- package/src/messageOperations/MessageOperationStatePolicy.ts +77 -0
- package/src/messageOperations/MessageOperations.ts +212 -0
- package/src/messageOperations/index.ts +10 -0
- package/src/messageOperations/types.ts +64 -0
- package/src/moderation.ts +38 -431
- package/src/notifications/types.ts +8 -7
- package/src/offline-support/offline_support_api.ts +200 -133
- package/src/offline-support/offline_sync_manager.ts +23 -44
- package/src/offline-support/types.ts +23 -26
- package/src/offline-support/util.ts +5 -4
- package/src/pagination/FilterBuilder.ts +4 -1
- package/src/pagination/ItemIndex.ts +25 -0
- package/src/pagination/cursorDerivation/createdAtAroundPaginationFlags.ts +73 -0
- package/src/pagination/cursorDerivation/idAroundPaginationFlags.ts +53 -0
- package/src/pagination/cursorDerivation/index.ts +1 -0
- package/src/pagination/cursorDerivation/linearPaginationFlags.ts +86 -0
- package/src/pagination/filterCompiler.ts +196 -0
- package/src/pagination/index.ts +1 -3
- package/src/pagination/paginators/BasePaginator.ts +2859 -0
- package/src/pagination/paginators/ChannelPaginator.ts +729 -0
- package/src/pagination/paginators/MessageIntervalPaginator.ts +1116 -0
- package/src/pagination/paginators/MessagePaginator.ts +508 -0
- package/src/pagination/paginators/PinnedMessagePaginator.ts +108 -0
- package/src/pagination/paginators/ReminderPaginator.ts +107 -0
- package/src/pagination/paginators/UserGroupPaginator.ts +127 -0
- package/src/pagination/paginators/index.ts +7 -0
- package/src/pagination/paginators/stateThrottling.ts +31 -0
- package/src/pagination/sortCompiler.ts +193 -0
- package/src/pagination/types.normalization.ts +14 -0
- package/src/pagination/utility.normalization.ts +106 -0
- package/src/pagination/utility.queryChannel.ts +84 -0
- package/src/pagination/utility.search.ts +80 -0
- package/src/permissions.ts +7 -8
- package/src/poll.ts +101 -110
- package/src/poll_manager.ts +14 -8
- package/src/reminders/Reminder.ts +2 -5
- package/src/reminders/ReminderManager.ts +19 -21
- package/src/search/BaseSearchSource.ts +0 -3
- package/src/search/ChannelMemberSearchSource.ts +7 -1
- package/src/search/ChannelSearchSource.ts +10 -3
- package/src/search/MessageSearchSource.ts +29 -30
- package/src/search/UserSearchSource.ts +12 -8
- package/src/search/types.ts +3 -4
- package/src/segment.ts +1 -95
- package/src/signing.ts +107 -67
- package/src/store.ts +2 -1
- package/src/thread.ts +562 -238
- package/src/thread_manager.ts +37 -16
- package/src/token_manager.ts +21 -10
- package/src/types.ts +364 -4533
- package/src/uploadManager.ts +8 -0
- package/src/utils/FixedSizeQueueCache.ts +12 -6
- package/src/utils/WithSubscriptions.ts +2 -1
- package/src/utils/concurrency.ts +4 -4
- package/src/utils/mergeWith/mergeWith.ts +3 -3
- package/src/utils/mergeWith/mergeWithCore.ts +140 -164
- package/src/utils/mergeWith/mergeWithDiff.ts +3 -3
- package/src/utils/retryable.ts +117 -0
- package/src/utils/throttling/throttle.ts +130 -0
- package/src/utils.ts +208 -754
- package/dist/types/channel_manager.d.ts +0 -122
- package/dist/types/events.d.ts +0 -72
- package/dist/types/pagination/BasePaginator.d.ts +0 -69
- package/dist/types/pagination/ReminderPaginator.d.ts +0 -16
- package/dist/types/pagination/UserGroupPaginator.d.ts +0 -21
- package/src/channel_manager.ts +0 -830
- package/src/events.ts +0 -75
- package/src/pagination/BasePaginator.ts +0 -184
- package/src/pagination/ReminderPaginator.ts +0 -56
- package/src/pagination/UserGroupPaginator.ts +0 -93
package/src/channel_manager.ts
DELETED
|
@@ -1,830 +0,0 @@
|
|
|
1
|
-
import type { QueryChannelsResponseWithChannels, StreamChat } from './client';
|
|
2
|
-
import type {
|
|
3
|
-
ChannelFilters,
|
|
4
|
-
ChannelOptions,
|
|
5
|
-
ChannelSort,
|
|
6
|
-
ChannelStateOptions,
|
|
7
|
-
Event,
|
|
8
|
-
QueryChannelsAPIResponse,
|
|
9
|
-
} from './types';
|
|
10
|
-
import type { ValueOrPatch } from './store';
|
|
11
|
-
import { isPatch, StateStore } from './store';
|
|
12
|
-
import type { Channel } from './channel';
|
|
13
|
-
import {
|
|
14
|
-
extractSortValue,
|
|
15
|
-
findLastPinnedChannelIndex,
|
|
16
|
-
getAndWatchChannel,
|
|
17
|
-
isChannelArchived,
|
|
18
|
-
isChannelPinned,
|
|
19
|
-
promoteChannel,
|
|
20
|
-
shouldConsiderArchivedChannels,
|
|
21
|
-
shouldConsiderPinnedChannels,
|
|
22
|
-
sleep,
|
|
23
|
-
uniqBy,
|
|
24
|
-
} from './utils';
|
|
25
|
-
import { generateUUIDv4 } from './utils';
|
|
26
|
-
import {
|
|
27
|
-
DEFAULT_QUERY_CHANNELS_MS_BETWEEN_RETRIES,
|
|
28
|
-
DEFAULT_QUERY_CHANNELS_RETRY_COUNT,
|
|
29
|
-
} from './constants';
|
|
30
|
-
import { WithSubscriptions } from './utils/WithSubscriptions';
|
|
31
|
-
|
|
32
|
-
export type ChannelManagerPagination = {
|
|
33
|
-
filters: ChannelFilters;
|
|
34
|
-
hasNext: boolean;
|
|
35
|
-
isLoading: boolean;
|
|
36
|
-
isLoadingNext: boolean;
|
|
37
|
-
options: ChannelOptions;
|
|
38
|
-
responseFilters?: ChannelFilters;
|
|
39
|
-
responseSort?: ChannelSort;
|
|
40
|
-
sort: ChannelSort;
|
|
41
|
-
};
|
|
42
|
-
|
|
43
|
-
export type ChannelManagerState = {
|
|
44
|
-
channels: Channel[];
|
|
45
|
-
/**
|
|
46
|
-
* This value will become true the first time queryChannels is successfully executed and
|
|
47
|
-
* will remain false otherwise. It's used as a control property regarding whether the list
|
|
48
|
-
* has been initialized yet (i.e a query has already been done at least once) or not. We do
|
|
49
|
-
* this to prevent state.channels from being forced to be nullable.
|
|
50
|
-
*/
|
|
51
|
-
initialized: boolean;
|
|
52
|
-
pagination: ChannelManagerPagination;
|
|
53
|
-
error: Error | undefined;
|
|
54
|
-
};
|
|
55
|
-
|
|
56
|
-
export type ChannelSetterParameterType = ValueOrPatch<ChannelManagerState['channels']>;
|
|
57
|
-
export type ChannelSetterType = (arg: ChannelSetterParameterType) => void;
|
|
58
|
-
|
|
59
|
-
export type GenericEventHandlerType<T extends unknown[]> = (
|
|
60
|
-
...args: T
|
|
61
|
-
) => void | (() => void) | ((...args: T) => Promise<void>) | Promise<void>;
|
|
62
|
-
export type EventHandlerType = GenericEventHandlerType<[Event]>;
|
|
63
|
-
export type EventHandlerOverrideType = GenericEventHandlerType<
|
|
64
|
-
[ChannelSetterType, Event]
|
|
65
|
-
>;
|
|
66
|
-
|
|
67
|
-
export type ChannelManagerEventTypes =
|
|
68
|
-
| 'notification.added_to_channel'
|
|
69
|
-
| 'notification.message_new'
|
|
70
|
-
| 'notification.removed_from_channel'
|
|
71
|
-
| 'message.new'
|
|
72
|
-
| 'member.updated'
|
|
73
|
-
| 'channel.deleted'
|
|
74
|
-
| 'channel.hidden'
|
|
75
|
-
| 'channel.truncated'
|
|
76
|
-
| 'channel.visible'
|
|
77
|
-
| 'channel.updated';
|
|
78
|
-
|
|
79
|
-
export type ChannelManagerEventHandlerNames =
|
|
80
|
-
| 'channelDeletedHandler'
|
|
81
|
-
| 'channelHiddenHandler'
|
|
82
|
-
| 'channelTruncatedHandler'
|
|
83
|
-
| 'channelUpdatedHandler'
|
|
84
|
-
| 'channelVisibleHandler'
|
|
85
|
-
| 'newMessageHandler'
|
|
86
|
-
| 'memberUpdatedHandler'
|
|
87
|
-
| 'notificationAddedToChannelHandler'
|
|
88
|
-
| 'notificationNewMessageHandler'
|
|
89
|
-
| 'notificationRemovedFromChannelHandler';
|
|
90
|
-
|
|
91
|
-
export type ChannelManagerEventHandlerOverrides = Partial<
|
|
92
|
-
Record<ChannelManagerEventHandlerNames, EventHandlerOverrideType>
|
|
93
|
-
>;
|
|
94
|
-
|
|
95
|
-
export type ExecuteChannelsQueryPayload = Pick<
|
|
96
|
-
ChannelManagerPagination,
|
|
97
|
-
'filters' | 'sort' | 'options'
|
|
98
|
-
> & { stateOptions: ChannelStateOptions };
|
|
99
|
-
|
|
100
|
-
export const channelManagerEventToHandlerMapping: {
|
|
101
|
-
[key in ChannelManagerEventTypes]: ChannelManagerEventHandlerNames;
|
|
102
|
-
} = {
|
|
103
|
-
'channel.deleted': 'channelDeletedHandler',
|
|
104
|
-
'channel.hidden': 'channelHiddenHandler',
|
|
105
|
-
'channel.truncated': 'channelTruncatedHandler',
|
|
106
|
-
'channel.updated': 'channelUpdatedHandler',
|
|
107
|
-
'channel.visible': 'channelVisibleHandler',
|
|
108
|
-
'message.new': 'newMessageHandler',
|
|
109
|
-
'member.updated': 'memberUpdatedHandler',
|
|
110
|
-
'notification.added_to_channel': 'notificationAddedToChannelHandler',
|
|
111
|
-
'notification.message_new': 'notificationNewMessageHandler',
|
|
112
|
-
'notification.removed_from_channel': 'notificationRemovedFromChannelHandler',
|
|
113
|
-
};
|
|
114
|
-
|
|
115
|
-
export type ChannelManagerOptions = {
|
|
116
|
-
/**
|
|
117
|
-
* Aborts a channels query that is already in progress and runs the new one.
|
|
118
|
-
*/
|
|
119
|
-
abortInFlightQuery?: boolean;
|
|
120
|
-
/**
|
|
121
|
-
* Allows channel promotion to be applied where applicable for channels that are
|
|
122
|
-
* currently not part of the channel list within the state. A good example of
|
|
123
|
-
* this would be a channel that is being watched and it receives a new message,
|
|
124
|
-
* but is not part of the list initially.
|
|
125
|
-
*/
|
|
126
|
-
allowNotLoadedChannelPromotionForEvent?: {
|
|
127
|
-
'channel.visible': boolean;
|
|
128
|
-
'message.new': boolean;
|
|
129
|
-
'notification.added_to_channel': boolean;
|
|
130
|
-
'notification.message_new': boolean;
|
|
131
|
-
};
|
|
132
|
-
/**
|
|
133
|
-
* Allows us to lock the order of channels within the list. Any event that would
|
|
134
|
-
* change the order of channels within the list will do nothing.
|
|
135
|
-
*/
|
|
136
|
-
lockChannelOrder?: boolean;
|
|
137
|
-
};
|
|
138
|
-
|
|
139
|
-
export type QueryChannelsRequestOutput = Channel[] | QueryChannelsResponseWithChannels;
|
|
140
|
-
|
|
141
|
-
export type QueryChannelsRequestType = (
|
|
142
|
-
filters: ChannelFilters,
|
|
143
|
-
sort?: ChannelSort,
|
|
144
|
-
options?: ChannelOptions,
|
|
145
|
-
stateOptions?: ChannelStateOptions,
|
|
146
|
-
) => Promise<QueryChannelsRequestOutput>;
|
|
147
|
-
|
|
148
|
-
export const DEFAULT_CHANNEL_MANAGER_OPTIONS = {
|
|
149
|
-
abortInFlightQuery: false,
|
|
150
|
-
allowNotLoadedChannelPromotionForEvent: {
|
|
151
|
-
'channel.visible': true,
|
|
152
|
-
'message.new': true,
|
|
153
|
-
'notification.added_to_channel': true,
|
|
154
|
-
'notification.message_new': true,
|
|
155
|
-
},
|
|
156
|
-
lockChannelOrder: false,
|
|
157
|
-
};
|
|
158
|
-
|
|
159
|
-
export const DEFAULT_CHANNEL_MANAGER_PAGINATION_OPTIONS = {
|
|
160
|
-
offset: 0,
|
|
161
|
-
};
|
|
162
|
-
|
|
163
|
-
const mapPredefinedFilterSortToChannelSort = (
|
|
164
|
-
sort: NonNullable<QueryChannelsAPIResponse['predefined_filter']>['sort'],
|
|
165
|
-
): ChannelSort =>
|
|
166
|
-
(sort ?? []).map(({ direction = 1, field }) => ({
|
|
167
|
-
[field]: direction,
|
|
168
|
-
})) as ChannelSort;
|
|
169
|
-
|
|
170
|
-
const getResponsePaginationParams = ({
|
|
171
|
-
queryChannelsResponse,
|
|
172
|
-
sort,
|
|
173
|
-
}: {
|
|
174
|
-
queryChannelsResponse?: Pick<QueryChannelsAPIResponse, 'predefined_filter'>;
|
|
175
|
-
sort: ChannelSort;
|
|
176
|
-
}): Pick<ChannelManagerPagination, 'responseFilters' | 'responseSort'> => {
|
|
177
|
-
const predefinedFilter = queryChannelsResponse?.predefined_filter;
|
|
178
|
-
|
|
179
|
-
if (!predefinedFilter) {
|
|
180
|
-
return {};
|
|
181
|
-
}
|
|
182
|
-
|
|
183
|
-
return {
|
|
184
|
-
responseFilters: predefinedFilter.filter as ChannelFilters,
|
|
185
|
-
responseSort:
|
|
186
|
-
predefinedFilter.sort !== undefined
|
|
187
|
-
? mapPredefinedFilterSortToChannelSort(predefinedFilter.sort)
|
|
188
|
-
: sort,
|
|
189
|
-
};
|
|
190
|
-
};
|
|
191
|
-
|
|
192
|
-
const getResponseFiltersAndSort = (
|
|
193
|
-
pagination: ChannelManagerPagination,
|
|
194
|
-
): Pick<ChannelManagerPagination, 'filters' | 'sort'> => ({
|
|
195
|
-
filters: pagination.responseFilters ?? pagination.filters,
|
|
196
|
-
sort: pagination.responseSort ?? pagination.sort,
|
|
197
|
-
});
|
|
198
|
-
|
|
199
|
-
const omitResponsePaginationParams = (pagination: ChannelManagerPagination) => {
|
|
200
|
-
const paginationWithoutResponseParams = { ...pagination };
|
|
201
|
-
delete paginationWithoutResponseParams.responseFilters;
|
|
202
|
-
delete paginationWithoutResponseParams.responseSort;
|
|
203
|
-
|
|
204
|
-
return paginationWithoutResponseParams;
|
|
205
|
-
};
|
|
206
|
-
|
|
207
|
-
const isQueryChannelsResponseWithChannels = (
|
|
208
|
-
response: QueryChannelsRequestOutput,
|
|
209
|
-
): response is QueryChannelsResponseWithChannels => !Array.isArray(response);
|
|
210
|
-
|
|
211
|
-
/**
|
|
212
|
-
* A class that manages a list of channels and changes it based on configuration and WS events. The
|
|
213
|
-
* list of channels is reactive as well as the pagination and it can be subscribed to for state updates.
|
|
214
|
-
*
|
|
215
|
-
* @internal
|
|
216
|
-
*/
|
|
217
|
-
export class ChannelManager extends WithSubscriptions {
|
|
218
|
-
public readonly state: StateStore<ChannelManagerState>;
|
|
219
|
-
private client: StreamChat;
|
|
220
|
-
private eventHandlers: Map<string, EventHandlerType> = new Map();
|
|
221
|
-
private eventHandlerOverrides: Map<string, EventHandlerOverrideType> = new Map();
|
|
222
|
-
private queryChannelsRequest: QueryChannelsRequestType;
|
|
223
|
-
private options: ChannelManagerOptions = {};
|
|
224
|
-
private stateOptions: ChannelStateOptions = {};
|
|
225
|
-
private id: string;
|
|
226
|
-
|
|
227
|
-
constructor({
|
|
228
|
-
client,
|
|
229
|
-
eventHandlerOverrides = {},
|
|
230
|
-
options = {},
|
|
231
|
-
queryChannelsOverride,
|
|
232
|
-
}: {
|
|
233
|
-
client: StreamChat;
|
|
234
|
-
eventHandlerOverrides?: ChannelManagerEventHandlerOverrides;
|
|
235
|
-
options?: ChannelManagerOptions;
|
|
236
|
-
queryChannelsOverride?: QueryChannelsRequestType;
|
|
237
|
-
}) {
|
|
238
|
-
super();
|
|
239
|
-
|
|
240
|
-
this.id = `channel-manager-${generateUUIDv4()}`;
|
|
241
|
-
this.client = client;
|
|
242
|
-
this.state = new StateStore<ChannelManagerState>({
|
|
243
|
-
channels: [],
|
|
244
|
-
pagination: {
|
|
245
|
-
isLoading: false,
|
|
246
|
-
isLoadingNext: false,
|
|
247
|
-
hasNext: false,
|
|
248
|
-
filters: {},
|
|
249
|
-
sort: {},
|
|
250
|
-
options: DEFAULT_CHANNEL_MANAGER_PAGINATION_OPTIONS,
|
|
251
|
-
},
|
|
252
|
-
initialized: false,
|
|
253
|
-
error: undefined,
|
|
254
|
-
});
|
|
255
|
-
this.setEventHandlerOverrides(eventHandlerOverrides);
|
|
256
|
-
this.setOptions(options);
|
|
257
|
-
this.queryChannelsRequest =
|
|
258
|
-
queryChannelsOverride ?? ((...params) => this.client.queryChannels(...params));
|
|
259
|
-
this.eventHandlers = new Map(
|
|
260
|
-
Object.entries<EventHandlerType>({
|
|
261
|
-
channelDeletedHandler: this.channelDeletedHandler,
|
|
262
|
-
channelHiddenHandler: this.channelHiddenHandler,
|
|
263
|
-
channelVisibleHandler: this.channelVisibleHandler,
|
|
264
|
-
memberUpdatedHandler: this.memberUpdatedHandler,
|
|
265
|
-
newMessageHandler: this.newMessageHandler,
|
|
266
|
-
notificationAddedToChannelHandler: this.notificationAddedToChannelHandler,
|
|
267
|
-
notificationNewMessageHandler: this.notificationNewMessageHandler,
|
|
268
|
-
notificationRemovedFromChannelHandler: this.notificationRemovedFromChannelHandler,
|
|
269
|
-
}),
|
|
270
|
-
);
|
|
271
|
-
}
|
|
272
|
-
|
|
273
|
-
public setChannels = (valueOrFactory: ChannelSetterParameterType) => {
|
|
274
|
-
this.state.next((current) => {
|
|
275
|
-
const { channels: currentChannels } = current;
|
|
276
|
-
const newChannels = isPatch(valueOrFactory)
|
|
277
|
-
? valueOrFactory(currentChannels)
|
|
278
|
-
: valueOrFactory;
|
|
279
|
-
|
|
280
|
-
// If the references between the two values are the same, just return the
|
|
281
|
-
// current state; otherwise trigger a state change.
|
|
282
|
-
if (currentChannels === newChannels) {
|
|
283
|
-
return current;
|
|
284
|
-
}
|
|
285
|
-
|
|
286
|
-
return { ...current, channels: newChannels };
|
|
287
|
-
});
|
|
288
|
-
const {
|
|
289
|
-
channels,
|
|
290
|
-
pagination: { filters, options, sort },
|
|
291
|
-
} = this.state.getLatestValue();
|
|
292
|
-
this.client.offlineDb?.executeQuerySafely(
|
|
293
|
-
(db) =>
|
|
294
|
-
db.upsertCidsForQuery({
|
|
295
|
-
cids: channels.map((channel) => channel.cid),
|
|
296
|
-
filters,
|
|
297
|
-
options,
|
|
298
|
-
sort,
|
|
299
|
-
}),
|
|
300
|
-
{ method: 'upsertCidsForQuery' },
|
|
301
|
-
);
|
|
302
|
-
};
|
|
303
|
-
|
|
304
|
-
public setEventHandlerOverrides = (
|
|
305
|
-
eventHandlerOverrides: ChannelManagerEventHandlerOverrides = {},
|
|
306
|
-
) => {
|
|
307
|
-
const truthyEventHandlerOverrides = Object.entries(eventHandlerOverrides).reduce<
|
|
308
|
-
Partial<ChannelManagerEventHandlerOverrides>
|
|
309
|
-
>((acc, [key, value]) => {
|
|
310
|
-
if (value) {
|
|
311
|
-
acc[key as keyof ChannelManagerEventHandlerOverrides] = value;
|
|
312
|
-
}
|
|
313
|
-
return acc;
|
|
314
|
-
}, {});
|
|
315
|
-
this.eventHandlerOverrides = new Map(
|
|
316
|
-
Object.entries<EventHandlerOverrideType>(truthyEventHandlerOverrides),
|
|
317
|
-
);
|
|
318
|
-
};
|
|
319
|
-
|
|
320
|
-
public setQueryChannelsRequest = (queryChannelsRequest: QueryChannelsRequestType) => {
|
|
321
|
-
this.queryChannelsRequest = queryChannelsRequest;
|
|
322
|
-
};
|
|
323
|
-
|
|
324
|
-
public setOptions = (options: ChannelManagerOptions = {}) => {
|
|
325
|
-
this.options = { ...DEFAULT_CHANNEL_MANAGER_OPTIONS, ...options };
|
|
326
|
-
};
|
|
327
|
-
|
|
328
|
-
private executeChannelsQuery = async (
|
|
329
|
-
payload: ExecuteChannelsQueryPayload,
|
|
330
|
-
retryCount = 0,
|
|
331
|
-
): Promise<void> => {
|
|
332
|
-
const { filters, sort, options, stateOptions } = payload;
|
|
333
|
-
const { offset, limit } = {
|
|
334
|
-
...DEFAULT_CHANNEL_MANAGER_PAGINATION_OPTIONS,
|
|
335
|
-
...options,
|
|
336
|
-
};
|
|
337
|
-
try {
|
|
338
|
-
const queryChannelsResponse = await this.queryChannelsRequest(
|
|
339
|
-
filters,
|
|
340
|
-
sort,
|
|
341
|
-
options,
|
|
342
|
-
{ ...stateOptions, withResponse: true },
|
|
343
|
-
);
|
|
344
|
-
const channels = isQueryChannelsResponseWithChannels(queryChannelsResponse)
|
|
345
|
-
? queryChannelsResponse.channels
|
|
346
|
-
: queryChannelsResponse;
|
|
347
|
-
const newOffset = offset + (channels?.length ?? 0);
|
|
348
|
-
const newOptions = { ...options, offset: newOffset };
|
|
349
|
-
const { pagination } = this.state.getLatestValue();
|
|
350
|
-
const responsePaginationParams = getResponsePaginationParams({
|
|
351
|
-
queryChannelsResponse: isQueryChannelsResponseWithChannels(queryChannelsResponse)
|
|
352
|
-
? queryChannelsResponse
|
|
353
|
-
: undefined,
|
|
354
|
-
sort,
|
|
355
|
-
});
|
|
356
|
-
const paginationWithoutResponseParams = omitResponsePaginationParams(pagination);
|
|
357
|
-
|
|
358
|
-
this.state.partialNext({
|
|
359
|
-
channels,
|
|
360
|
-
pagination: {
|
|
361
|
-
// Drop response derived filter/sort from the previous query before applying
|
|
362
|
-
// the current response. Non predefined queries do not return this metadata,
|
|
363
|
-
// so keeping the old values would make later WS mutations use stale
|
|
364
|
-
// predefined filter semantics. Also the predefined_filter might change, producing
|
|
365
|
-
// a different combination as well so we always need to first clean up.
|
|
366
|
-
...paginationWithoutResponseParams,
|
|
367
|
-
hasNext: (channels?.length ?? 0) >= (limit ?? 1),
|
|
368
|
-
isLoading: false,
|
|
369
|
-
options: newOptions,
|
|
370
|
-
...responsePaginationParams,
|
|
371
|
-
},
|
|
372
|
-
initialized: true,
|
|
373
|
-
error: undefined,
|
|
374
|
-
});
|
|
375
|
-
this.client.offlineDb?.executeQuerySafely(
|
|
376
|
-
(db) =>
|
|
377
|
-
db.upsertCidsForQuery({
|
|
378
|
-
cids: channels.map((channel) => channel.cid),
|
|
379
|
-
filters: pagination.filters,
|
|
380
|
-
options,
|
|
381
|
-
sort: pagination.sort,
|
|
382
|
-
}),
|
|
383
|
-
{ method: 'upsertCidsForQuery' },
|
|
384
|
-
);
|
|
385
|
-
} catch (err) {
|
|
386
|
-
if (retryCount >= DEFAULT_QUERY_CHANNELS_RETRY_COUNT) {
|
|
387
|
-
console.warn(err);
|
|
388
|
-
|
|
389
|
-
const wrappedError = new Error(
|
|
390
|
-
`Maximum number of retries reached in queryChannels. Last error message is: ${err}`,
|
|
391
|
-
);
|
|
392
|
-
|
|
393
|
-
const state = this.state.getLatestValue();
|
|
394
|
-
// If the offline support is enabled, and there are channels in the DB, we should not error out.
|
|
395
|
-
const isOfflineSupportEnabledWithChannels =
|
|
396
|
-
this.client.offlineDb && state.channels.length > 0;
|
|
397
|
-
|
|
398
|
-
this.state.partialNext({
|
|
399
|
-
error: isOfflineSupportEnabledWithChannels ? undefined : wrappedError,
|
|
400
|
-
pagination: {
|
|
401
|
-
...state.pagination,
|
|
402
|
-
isLoading: false,
|
|
403
|
-
isLoadingNext: false,
|
|
404
|
-
},
|
|
405
|
-
});
|
|
406
|
-
return;
|
|
407
|
-
}
|
|
408
|
-
|
|
409
|
-
await sleep(DEFAULT_QUERY_CHANNELS_MS_BETWEEN_RETRIES);
|
|
410
|
-
|
|
411
|
-
return this.executeChannelsQuery(payload, retryCount + 1);
|
|
412
|
-
}
|
|
413
|
-
};
|
|
414
|
-
|
|
415
|
-
public queryChannels = async (
|
|
416
|
-
filters: ChannelFilters,
|
|
417
|
-
sort: ChannelSort = [],
|
|
418
|
-
options: ChannelOptions = {},
|
|
419
|
-
stateOptions: ChannelStateOptions = {},
|
|
420
|
-
) => {
|
|
421
|
-
const {
|
|
422
|
-
pagination: { isLoading, filters: filtersFromState },
|
|
423
|
-
initialized,
|
|
424
|
-
} = this.state.getLatestValue();
|
|
425
|
-
|
|
426
|
-
if (
|
|
427
|
-
isLoading &&
|
|
428
|
-
!this.options.abortInFlightQuery &&
|
|
429
|
-
// TODO: Figure a proper way to either deeply compare these or
|
|
430
|
-
// create hashes from each.
|
|
431
|
-
JSON.stringify(filtersFromState) === JSON.stringify(filters)
|
|
432
|
-
) {
|
|
433
|
-
return;
|
|
434
|
-
}
|
|
435
|
-
|
|
436
|
-
const executeChannelsQueryPayload = { filters, sort, options, stateOptions };
|
|
437
|
-
|
|
438
|
-
try {
|
|
439
|
-
this.stateOptions = stateOptions;
|
|
440
|
-
this.state.next((currentState) => ({
|
|
441
|
-
...currentState,
|
|
442
|
-
pagination: {
|
|
443
|
-
...omitResponsePaginationParams(currentState.pagination),
|
|
444
|
-
isLoading: true,
|
|
445
|
-
isLoadingNext: false,
|
|
446
|
-
filters,
|
|
447
|
-
sort,
|
|
448
|
-
options,
|
|
449
|
-
},
|
|
450
|
-
error: undefined,
|
|
451
|
-
}));
|
|
452
|
-
|
|
453
|
-
if (this.client.offlineDb?.getChannelsForQuery && this.client.user?.id) {
|
|
454
|
-
if (!initialized) {
|
|
455
|
-
const channelsFromDB = await this.client.offlineDb.getChannelsForQuery({
|
|
456
|
-
userId: this.client.user.id,
|
|
457
|
-
filters,
|
|
458
|
-
options,
|
|
459
|
-
sort,
|
|
460
|
-
});
|
|
461
|
-
|
|
462
|
-
if (channelsFromDB) {
|
|
463
|
-
const offlineChannels = this.client.hydrateActiveChannels(channelsFromDB, {
|
|
464
|
-
offlineMode: true,
|
|
465
|
-
skipInitialization: [], // passing empty array will clear out the existing messages from channel state, this removes the possibility of duplicate messages
|
|
466
|
-
});
|
|
467
|
-
|
|
468
|
-
this.state.partialNext({ channels: offlineChannels });
|
|
469
|
-
}
|
|
470
|
-
}
|
|
471
|
-
|
|
472
|
-
if (!this.client.offlineDb.syncManager.syncStatus) {
|
|
473
|
-
this.client.offlineDb.syncManager.scheduleSyncStatusChangeCallback(
|
|
474
|
-
this.id,
|
|
475
|
-
async () => {
|
|
476
|
-
await this.executeChannelsQuery(executeChannelsQueryPayload);
|
|
477
|
-
},
|
|
478
|
-
);
|
|
479
|
-
return;
|
|
480
|
-
}
|
|
481
|
-
}
|
|
482
|
-
await this.executeChannelsQuery(executeChannelsQueryPayload);
|
|
483
|
-
} catch (error) {
|
|
484
|
-
this.client.logger('error', (error as Error).message);
|
|
485
|
-
this.state.next((currentState) => ({
|
|
486
|
-
...currentState,
|
|
487
|
-
pagination: { ...currentState.pagination, isLoading: false },
|
|
488
|
-
}));
|
|
489
|
-
throw error;
|
|
490
|
-
}
|
|
491
|
-
};
|
|
492
|
-
|
|
493
|
-
public loadNext = async () => {
|
|
494
|
-
const { pagination, initialized } = this.state.getLatestValue();
|
|
495
|
-
const { filters, sort, options, isLoadingNext, hasNext } = pagination;
|
|
496
|
-
|
|
497
|
-
if (!initialized || isLoadingNext || !hasNext) {
|
|
498
|
-
return;
|
|
499
|
-
}
|
|
500
|
-
|
|
501
|
-
try {
|
|
502
|
-
const { offset, limit } = {
|
|
503
|
-
...DEFAULT_CHANNEL_MANAGER_PAGINATION_OPTIONS,
|
|
504
|
-
...options,
|
|
505
|
-
};
|
|
506
|
-
this.state.partialNext({
|
|
507
|
-
pagination: { ...pagination, isLoading: false, isLoadingNext: true },
|
|
508
|
-
});
|
|
509
|
-
const queryChannelsResponse = await this.queryChannelsRequest(
|
|
510
|
-
filters,
|
|
511
|
-
sort,
|
|
512
|
-
options,
|
|
513
|
-
this.stateOptions,
|
|
514
|
-
);
|
|
515
|
-
const nextChannels = isQueryChannelsResponseWithChannels(queryChannelsResponse)
|
|
516
|
-
? queryChannelsResponse.channels
|
|
517
|
-
: queryChannelsResponse;
|
|
518
|
-
const { channels } = this.state.getLatestValue();
|
|
519
|
-
const newOffset = offset + (nextChannels?.length ?? 0);
|
|
520
|
-
const newOptions = { ...options, offset: newOffset };
|
|
521
|
-
|
|
522
|
-
this.state.partialNext({
|
|
523
|
-
channels: uniqBy<Channel>([...(channels || []), ...nextChannels], 'cid'),
|
|
524
|
-
pagination: {
|
|
525
|
-
...pagination,
|
|
526
|
-
hasNext: (nextChannels?.length ?? 0) >= (limit ?? 1),
|
|
527
|
-
isLoading: false,
|
|
528
|
-
isLoadingNext: false,
|
|
529
|
-
options: newOptions,
|
|
530
|
-
},
|
|
531
|
-
});
|
|
532
|
-
} catch (error) {
|
|
533
|
-
this.client.logger('error', (error as Error).message);
|
|
534
|
-
this.state.next((currentState) => ({
|
|
535
|
-
...currentState,
|
|
536
|
-
pagination: {
|
|
537
|
-
...currentState.pagination,
|
|
538
|
-
isLoadingNext: false,
|
|
539
|
-
isLoading: false,
|
|
540
|
-
},
|
|
541
|
-
}));
|
|
542
|
-
throw error;
|
|
543
|
-
}
|
|
544
|
-
};
|
|
545
|
-
|
|
546
|
-
private notificationAddedToChannelHandler = async (event: Event) => {
|
|
547
|
-
const { id, type, members } = event?.channel ?? {};
|
|
548
|
-
|
|
549
|
-
if (
|
|
550
|
-
!type ||
|
|
551
|
-
!this.options.allowNotLoadedChannelPromotionForEvent?.[
|
|
552
|
-
'notification.added_to_channel'
|
|
553
|
-
]
|
|
554
|
-
) {
|
|
555
|
-
return;
|
|
556
|
-
}
|
|
557
|
-
|
|
558
|
-
const channel = await getAndWatchChannel({
|
|
559
|
-
client: this.client,
|
|
560
|
-
id,
|
|
561
|
-
members: members?.reduce<string[]>((acc, { user, user_id }) => {
|
|
562
|
-
const userId = user_id || user?.id;
|
|
563
|
-
if (userId) {
|
|
564
|
-
acc.push(userId);
|
|
565
|
-
}
|
|
566
|
-
return acc;
|
|
567
|
-
}, []),
|
|
568
|
-
type,
|
|
569
|
-
});
|
|
570
|
-
|
|
571
|
-
const { pagination, channels } = this.state.getLatestValue();
|
|
572
|
-
if (!channels) {
|
|
573
|
-
return;
|
|
574
|
-
}
|
|
575
|
-
|
|
576
|
-
const { sort } = getResponseFiltersAndSort(pagination);
|
|
577
|
-
|
|
578
|
-
this.setChannels(
|
|
579
|
-
promoteChannel({
|
|
580
|
-
channels,
|
|
581
|
-
channelToMove: channel,
|
|
582
|
-
sort,
|
|
583
|
-
}),
|
|
584
|
-
);
|
|
585
|
-
};
|
|
586
|
-
|
|
587
|
-
private channelDeletedHandler = (event: Event) => {
|
|
588
|
-
const { channels } = this.state.getLatestValue();
|
|
589
|
-
if (!channels) {
|
|
590
|
-
return;
|
|
591
|
-
}
|
|
592
|
-
|
|
593
|
-
const newChannels = [...channels];
|
|
594
|
-
const channelIndex = newChannels.findIndex(
|
|
595
|
-
(channel) => channel.cid === (event.cid || event.channel?.cid),
|
|
596
|
-
);
|
|
597
|
-
|
|
598
|
-
if (channelIndex < 0) {
|
|
599
|
-
return;
|
|
600
|
-
}
|
|
601
|
-
|
|
602
|
-
newChannels.splice(channelIndex, 1);
|
|
603
|
-
this.setChannels(newChannels);
|
|
604
|
-
};
|
|
605
|
-
|
|
606
|
-
private channelHiddenHandler = this.channelDeletedHandler;
|
|
607
|
-
|
|
608
|
-
private newMessageHandler = (event: Event) => {
|
|
609
|
-
const { pagination, channels } = this.state.getLatestValue();
|
|
610
|
-
if (!channels) {
|
|
611
|
-
return;
|
|
612
|
-
}
|
|
613
|
-
const { filters, sort } = getResponseFiltersAndSort(pagination);
|
|
614
|
-
|
|
615
|
-
const channelType = event.channel_type;
|
|
616
|
-
const channelId = event.channel_id;
|
|
617
|
-
|
|
618
|
-
if (!channelType || !channelId) {
|
|
619
|
-
return;
|
|
620
|
-
}
|
|
621
|
-
|
|
622
|
-
const targetChannel = this.client.channel(channelType, channelId);
|
|
623
|
-
const targetChannelIndex = channels.indexOf(targetChannel);
|
|
624
|
-
const targetChannelExistsWithinList = targetChannelIndex >= 0;
|
|
625
|
-
|
|
626
|
-
const isTargetChannelPinned = isChannelPinned(targetChannel);
|
|
627
|
-
const isTargetChannelArchived = isChannelArchived(targetChannel);
|
|
628
|
-
|
|
629
|
-
const considerArchivedChannels = shouldConsiderArchivedChannels(filters);
|
|
630
|
-
const considerPinnedChannels = shouldConsiderPinnedChannels(sort);
|
|
631
|
-
|
|
632
|
-
if (
|
|
633
|
-
// filter is defined, target channel is archived and filter option is set to false
|
|
634
|
-
(considerArchivedChannels && isTargetChannelArchived && !filters.archived) ||
|
|
635
|
-
// filter is defined, target channel isn't archived and filter option is set to true
|
|
636
|
-
(considerArchivedChannels && !isTargetChannelArchived && filters.archived) ||
|
|
637
|
-
// sort option is defined, target channel is pinned
|
|
638
|
-
(considerPinnedChannels && isTargetChannelPinned) ||
|
|
639
|
-
// list order is locked
|
|
640
|
-
this.options.lockChannelOrder ||
|
|
641
|
-
// target channel is not within the loaded list and loading from cache is disallowed
|
|
642
|
-
(!targetChannelExistsWithinList &&
|
|
643
|
-
!this.options.allowNotLoadedChannelPromotionForEvent?.['message.new'])
|
|
644
|
-
) {
|
|
645
|
-
return;
|
|
646
|
-
}
|
|
647
|
-
|
|
648
|
-
this.setChannels(
|
|
649
|
-
promoteChannel({
|
|
650
|
-
channels,
|
|
651
|
-
channelToMove: targetChannel,
|
|
652
|
-
channelToMoveIndexWithinChannels: targetChannelIndex,
|
|
653
|
-
sort,
|
|
654
|
-
}),
|
|
655
|
-
);
|
|
656
|
-
};
|
|
657
|
-
|
|
658
|
-
private notificationNewMessageHandler = async (event: Event) => {
|
|
659
|
-
const { id, type } = event?.channel ?? {};
|
|
660
|
-
|
|
661
|
-
if (!id || !type) {
|
|
662
|
-
return;
|
|
663
|
-
}
|
|
664
|
-
|
|
665
|
-
const channel = await getAndWatchChannel({
|
|
666
|
-
client: this.client,
|
|
667
|
-
id,
|
|
668
|
-
type,
|
|
669
|
-
});
|
|
670
|
-
|
|
671
|
-
const { channels, pagination } = this.state.getLatestValue();
|
|
672
|
-
const { filters, sort } = getResponseFiltersAndSort(pagination);
|
|
673
|
-
|
|
674
|
-
const considerArchivedChannels = shouldConsiderArchivedChannels(filters);
|
|
675
|
-
const isTargetChannelArchived = isChannelArchived(channel);
|
|
676
|
-
|
|
677
|
-
if (
|
|
678
|
-
!channels ||
|
|
679
|
-
(considerArchivedChannels && isTargetChannelArchived && !filters.archived) ||
|
|
680
|
-
(considerArchivedChannels && !isTargetChannelArchived && filters.archived) ||
|
|
681
|
-
!this.options.allowNotLoadedChannelPromotionForEvent?.['notification.message_new']
|
|
682
|
-
) {
|
|
683
|
-
return;
|
|
684
|
-
}
|
|
685
|
-
|
|
686
|
-
this.setChannels(
|
|
687
|
-
promoteChannel({
|
|
688
|
-
channels,
|
|
689
|
-
channelToMove: channel,
|
|
690
|
-
sort,
|
|
691
|
-
}),
|
|
692
|
-
);
|
|
693
|
-
};
|
|
694
|
-
|
|
695
|
-
private channelVisibleHandler = async (event: Event) => {
|
|
696
|
-
const { channel_type: channelType, channel_id: channelId } = event;
|
|
697
|
-
|
|
698
|
-
if (!channelType || !channelId) {
|
|
699
|
-
return;
|
|
700
|
-
}
|
|
701
|
-
|
|
702
|
-
const channel = await getAndWatchChannel({
|
|
703
|
-
client: this.client,
|
|
704
|
-
id: event.channel_id,
|
|
705
|
-
type: event.channel_type,
|
|
706
|
-
});
|
|
707
|
-
|
|
708
|
-
const { channels, pagination } = this.state.getLatestValue();
|
|
709
|
-
const { filters, sort } = getResponseFiltersAndSort(pagination);
|
|
710
|
-
|
|
711
|
-
const considerArchivedChannels = shouldConsiderArchivedChannels(filters);
|
|
712
|
-
const isTargetChannelArchived = isChannelArchived(channel);
|
|
713
|
-
|
|
714
|
-
if (
|
|
715
|
-
!channels ||
|
|
716
|
-
(considerArchivedChannels && isTargetChannelArchived && !filters.archived) ||
|
|
717
|
-
(considerArchivedChannels && !isTargetChannelArchived && filters.archived) ||
|
|
718
|
-
!this.options.allowNotLoadedChannelPromotionForEvent?.['channel.visible']
|
|
719
|
-
) {
|
|
720
|
-
return;
|
|
721
|
-
}
|
|
722
|
-
|
|
723
|
-
this.setChannels(
|
|
724
|
-
promoteChannel({
|
|
725
|
-
channels,
|
|
726
|
-
channelToMove: channel,
|
|
727
|
-
sort,
|
|
728
|
-
}),
|
|
729
|
-
);
|
|
730
|
-
};
|
|
731
|
-
|
|
732
|
-
private notificationRemovedFromChannelHandler = this.channelDeletedHandler;
|
|
733
|
-
|
|
734
|
-
private memberUpdatedHandler = (event: Event) => {
|
|
735
|
-
const { pagination, channels } = this.state.getLatestValue();
|
|
736
|
-
const { filters, sort } = getResponseFiltersAndSort(pagination);
|
|
737
|
-
if (
|
|
738
|
-
!event.member?.user ||
|
|
739
|
-
event.member.user.id !== this.client.userID ||
|
|
740
|
-
!event.channel_type ||
|
|
741
|
-
!event.channel_id
|
|
742
|
-
) {
|
|
743
|
-
return;
|
|
744
|
-
}
|
|
745
|
-
const channelType = event.channel_type;
|
|
746
|
-
const channelId = event.channel_id;
|
|
747
|
-
|
|
748
|
-
const considerPinnedChannels = shouldConsiderPinnedChannels(sort);
|
|
749
|
-
const considerArchivedChannels = shouldConsiderArchivedChannels(filters);
|
|
750
|
-
const pinnedAtSort = extractSortValue({ atIndex: 0, sort, targetKey: 'pinned_at' });
|
|
751
|
-
|
|
752
|
-
if (
|
|
753
|
-
!channels ||
|
|
754
|
-
(!considerPinnedChannels && !considerArchivedChannels) ||
|
|
755
|
-
this.options.lockChannelOrder
|
|
756
|
-
) {
|
|
757
|
-
return;
|
|
758
|
-
}
|
|
759
|
-
|
|
760
|
-
const targetChannel = this.client.channel(channelType, channelId);
|
|
761
|
-
// assumes that channel instances are not changing
|
|
762
|
-
const targetChannelIndex = channels.indexOf(targetChannel);
|
|
763
|
-
const targetChannelExistsWithinList = targetChannelIndex >= 0;
|
|
764
|
-
|
|
765
|
-
const isTargetChannelPinned = isChannelPinned(targetChannel);
|
|
766
|
-
const isTargetChannelArchived = isChannelArchived(targetChannel);
|
|
767
|
-
|
|
768
|
-
const newChannels = [...channels];
|
|
769
|
-
|
|
770
|
-
if (targetChannelExistsWithinList) {
|
|
771
|
-
newChannels.splice(targetChannelIndex, 1);
|
|
772
|
-
}
|
|
773
|
-
|
|
774
|
-
// handle archiving (remove channel)
|
|
775
|
-
if (
|
|
776
|
-
// When archived filter true, and channel is unarchived
|
|
777
|
-
(considerArchivedChannels && !isTargetChannelArchived && filters?.archived) ||
|
|
778
|
-
// When archived filter false, and channel is archived
|
|
779
|
-
(considerArchivedChannels && isTargetChannelArchived && !filters?.archived)
|
|
780
|
-
) {
|
|
781
|
-
this.setChannels(newChannels);
|
|
782
|
-
return;
|
|
783
|
-
}
|
|
784
|
-
|
|
785
|
-
// handle pinning
|
|
786
|
-
let lastPinnedChannelIndex: number | null = null;
|
|
787
|
-
|
|
788
|
-
if (pinnedAtSort === 1 || (pinnedAtSort === -1 && !isTargetChannelPinned)) {
|
|
789
|
-
lastPinnedChannelIndex = findLastPinnedChannelIndex({ channels: newChannels });
|
|
790
|
-
}
|
|
791
|
-
const newTargetChannelIndex =
|
|
792
|
-
typeof lastPinnedChannelIndex === 'number' ? lastPinnedChannelIndex + 1 : 0;
|
|
793
|
-
|
|
794
|
-
// skip state update if the position of the channel does not change
|
|
795
|
-
if (channels[newTargetChannelIndex] === targetChannel) {
|
|
796
|
-
return;
|
|
797
|
-
}
|
|
798
|
-
|
|
799
|
-
newChannels.splice(newTargetChannelIndex, 0, targetChannel);
|
|
800
|
-
this.setChannels(newChannels);
|
|
801
|
-
};
|
|
802
|
-
|
|
803
|
-
private subscriptionOrOverride = (event: Event) => {
|
|
804
|
-
const handlerName =
|
|
805
|
-
channelManagerEventToHandlerMapping[event.type as ChannelManagerEventTypes];
|
|
806
|
-
const defaultEventHandler = this.eventHandlers.get(handlerName);
|
|
807
|
-
const eventHandlerOverride = this.eventHandlerOverrides.get(handlerName);
|
|
808
|
-
if (eventHandlerOverride && typeof eventHandlerOverride === 'function') {
|
|
809
|
-
eventHandlerOverride(this.setChannels, event);
|
|
810
|
-
return;
|
|
811
|
-
}
|
|
812
|
-
|
|
813
|
-
if (defaultEventHandler && typeof defaultEventHandler === 'function') {
|
|
814
|
-
defaultEventHandler(event);
|
|
815
|
-
}
|
|
816
|
-
};
|
|
817
|
-
|
|
818
|
-
public registerSubscriptions = () => {
|
|
819
|
-
if (this.hasSubscriptions) {
|
|
820
|
-
// Already listening for events and changes
|
|
821
|
-
return;
|
|
822
|
-
}
|
|
823
|
-
|
|
824
|
-
for (const eventType of Object.keys(channelManagerEventToHandlerMapping)) {
|
|
825
|
-
this.addUnsubscribeFunction(
|
|
826
|
-
this.client.on(eventType, this.subscriptionOrOverride).unsubscribe,
|
|
827
|
-
);
|
|
828
|
-
}
|
|
829
|
-
};
|
|
830
|
-
}
|