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
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Partition-point ("lower bound") binary search over the index range `[0, length)`.
|
|
3
|
+
*
|
|
4
|
+
* `predicate` must be **monotonic** over the range — `false` for a (possibly empty) prefix, then
|
|
5
|
+
* `true` for the remaining suffix. Returns the first index at which `predicate(index)` holds, or
|
|
6
|
+
* `length` if it never does. O(log length).
|
|
7
|
+
*
|
|
8
|
+
* Unlike `binarySearch`, this locates a *boundary* defined by a predicate rather than a specific
|
|
9
|
+
* item by identity — e.g. "first message at/after a timestamp" over a chronologically sorted array.
|
|
10
|
+
*/
|
|
11
|
+
export function lowerBound(
|
|
12
|
+
length: number,
|
|
13
|
+
predicate: (index: number) => boolean,
|
|
14
|
+
): number {
|
|
15
|
+
let lo = 0;
|
|
16
|
+
let hi = length;
|
|
17
|
+
while (lo < hi) {
|
|
18
|
+
const mid = (lo + hi) >> 1;
|
|
19
|
+
if (predicate(mid)) hi = mid;
|
|
20
|
+
else lo = mid + 1;
|
|
21
|
+
}
|
|
22
|
+
return lo;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export function locateOnPlateauAlternating<T>(
|
|
26
|
+
items: readonly T[],
|
|
27
|
+
needle: T,
|
|
28
|
+
compare: (left: T, right: T) => number,
|
|
29
|
+
getItemId: (x: T) => string,
|
|
30
|
+
insertionIndex: number,
|
|
31
|
+
): number {
|
|
32
|
+
const targetId = getItemId(needle);
|
|
33
|
+
let leftIndex = insertionIndex - 1;
|
|
34
|
+
let rightIndex = insertionIndex;
|
|
35
|
+
|
|
36
|
+
for (let step = 0; ; step++) {
|
|
37
|
+
const searchRight = step % 2 === 0;
|
|
38
|
+
|
|
39
|
+
if (searchRight) {
|
|
40
|
+
if (rightIndex < items.length && compare(items[rightIndex], needle) === 0) {
|
|
41
|
+
if (getItemId(items[rightIndex]) === targetId) return rightIndex;
|
|
42
|
+
rightIndex++;
|
|
43
|
+
continue;
|
|
44
|
+
}
|
|
45
|
+
} else {
|
|
46
|
+
if (leftIndex >= 0 && compare(items[leftIndex], needle) === 0) {
|
|
47
|
+
if (getItemId(items[leftIndex]) === targetId) return leftIndex;
|
|
48
|
+
leftIndex--;
|
|
49
|
+
continue;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
const rightOut =
|
|
54
|
+
rightIndex >= items.length || compare(items[rightIndex], needle) !== 0;
|
|
55
|
+
const leftOut = leftIndex < 0 || compare(items[leftIndex], needle) !== 0;
|
|
56
|
+
if (rightOut && leftOut) break; // plateau exhausted
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
return -1;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
export function locateOnPlateauScanOneSide<T>(
|
|
63
|
+
items: readonly T[],
|
|
64
|
+
needle: T,
|
|
65
|
+
compare: (left: T, right: T) => number,
|
|
66
|
+
getItemId: (x: T) => string,
|
|
67
|
+
insertionIndex: number,
|
|
68
|
+
): number {
|
|
69
|
+
const targetId = getItemId(needle);
|
|
70
|
+
|
|
71
|
+
// scan left
|
|
72
|
+
for (let i = insertionIndex - 1; i >= 0 && compare(items[i], needle) === 0; i--) {
|
|
73
|
+
if (getItemId(items[i]) === targetId) return i;
|
|
74
|
+
}
|
|
75
|
+
// scan right
|
|
76
|
+
for (let i = insertionIndex; i < items.length && compare(items[i], needle) === 0; i++) {
|
|
77
|
+
if (getItemId(items[i]) === targetId) return i;
|
|
78
|
+
}
|
|
79
|
+
return -1;
|
|
80
|
+
}
|
package/src/permissions.ts
CHANGED
|
@@ -56,8 +56,7 @@ export const DenyAll = new Permission(
|
|
|
56
56
|
Deny,
|
|
57
57
|
);
|
|
58
58
|
|
|
59
|
-
|
|
60
|
-
export type Role =
|
|
59
|
+
export type RoleName =
|
|
61
60
|
| 'admin'
|
|
62
61
|
| 'user'
|
|
63
62
|
| 'guest'
|
|
@@ -79,25 +78,25 @@ export const BuiltinPermissions = {
|
|
|
79
78
|
AddLinks: 'Add Links',
|
|
80
79
|
BanUser: 'Ban User',
|
|
81
80
|
CreateChannel: 'Create Channel',
|
|
82
|
-
CreateMessage: 'Create
|
|
81
|
+
CreateMessage: 'Create MessageRequest',
|
|
83
82
|
CreateReaction: 'Create Reaction',
|
|
84
83
|
DeleteAnyAttachment: 'Delete Any Attachment',
|
|
85
84
|
DeleteAnyChannel: 'Delete Any Channel',
|
|
86
|
-
DeleteAnyMessage: 'Delete Any
|
|
85
|
+
DeleteAnyMessage: 'Delete Any MessageRequest',
|
|
87
86
|
DeleteAnyReaction: 'Delete Any Reaction',
|
|
88
87
|
DeleteOwnAttachment: 'Delete Own Attachment',
|
|
89
88
|
DeleteOwnChannel: 'Delete Own Channel',
|
|
90
|
-
DeleteOwnMessage: 'Delete Own
|
|
89
|
+
DeleteOwnMessage: 'Delete Own MessageRequest',
|
|
91
90
|
DeleteOwnReaction: 'Delete Own Reaction',
|
|
92
91
|
ReadAnyChannel: 'Read Any Channel',
|
|
93
92
|
ReadOwnChannel: 'Read Own Channel',
|
|
94
|
-
RunMessageAction: 'Run
|
|
93
|
+
RunMessageAction: 'Run MessageRequest Action',
|
|
95
94
|
UpdateAnyChannel: 'Update Any Channel',
|
|
96
|
-
UpdateAnyMessage: 'Update Any
|
|
95
|
+
UpdateAnyMessage: 'Update Any MessageRequest',
|
|
97
96
|
UpdateMembersAnyChannel: 'Update Members Any Channel',
|
|
98
97
|
UpdateMembersOwnChannel: 'Update Members Own Channel',
|
|
99
98
|
UpdateOwnChannel: 'Update Own Channel',
|
|
100
|
-
UpdateOwnMessage: 'Update Own
|
|
99
|
+
UpdateOwnMessage: 'Update Own MessageRequest',
|
|
101
100
|
UploadAttachment: 'Upload Attachment',
|
|
102
101
|
UseFrozenChannel: 'Send messages and reactions to frozen channels',
|
|
103
102
|
};
|
package/src/poll.ts
CHANGED
|
@@ -1,64 +1,36 @@
|
|
|
1
1
|
import { StateStore } from './store';
|
|
2
2
|
import type { StreamChat } from './client';
|
|
3
3
|
import type {
|
|
4
|
-
|
|
4
|
+
EventPayload,
|
|
5
5
|
PartialPollUpdate,
|
|
6
|
-
PollAnswer,
|
|
7
|
-
PollData,
|
|
8
6
|
PollEnrichData,
|
|
9
7
|
PollOptionData,
|
|
10
|
-
|
|
11
|
-
|
|
8
|
+
PollResponse_old,
|
|
9
|
+
PollVoteResponseData,
|
|
12
10
|
QueryVotesFilters,
|
|
13
11
|
QueryVotesOptions,
|
|
12
|
+
RequireLiteral,
|
|
13
|
+
UpdatePollRequest,
|
|
14
14
|
VoteSort,
|
|
15
|
+
VotingVisibility,
|
|
15
16
|
} from './types';
|
|
17
|
+
import type { PollResponseData as Gen_PollResponseData, WSEvent } from './gen/models';
|
|
16
18
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
poll: PollResponse;
|
|
21
|
-
};
|
|
22
|
-
|
|
23
|
-
type PollUpdatedEvent = PollEvent & {
|
|
24
|
-
type: 'poll.updated';
|
|
25
|
-
};
|
|
26
|
-
|
|
27
|
-
type PollClosedEvent = PollEvent & {
|
|
28
|
-
type: 'poll.closed';
|
|
29
|
-
};
|
|
30
|
-
|
|
31
|
-
type PollVoteEvent = {
|
|
32
|
-
cid: string;
|
|
33
|
-
created_at: string;
|
|
34
|
-
poll: PollResponse;
|
|
35
|
-
poll_vote: PollVote | PollAnswer;
|
|
36
|
-
};
|
|
37
|
-
|
|
38
|
-
type PollVoteCastedEvent = PollVoteEvent & {
|
|
39
|
-
type: 'poll.vote_casted';
|
|
40
|
-
};
|
|
41
|
-
|
|
42
|
-
type PollVoteCastedChanged = PollVoteEvent & {
|
|
43
|
-
type: 'poll.vote_removed';
|
|
44
|
-
};
|
|
45
|
-
|
|
46
|
-
type PollVoteCastedRemoved = PollVoteEvent & {
|
|
47
|
-
type: 'poll.vote_removed';
|
|
48
|
-
};
|
|
49
|
-
|
|
50
|
-
const isPollUpdatedEvent = (e: Event): e is PollUpdatedEvent => e.type === 'poll.updated';
|
|
51
|
-
const isPollClosedEventEvent = (e: Event): e is PollClosedEvent =>
|
|
19
|
+
const isPollUpdatedEvent = (e: WSEvent): e is EventPayload<'poll.updated'> =>
|
|
20
|
+
e.type === 'poll.updated';
|
|
21
|
+
const isPollClosedEventEvent = (e: WSEvent): e is EventPayload<'poll.closed'> =>
|
|
52
22
|
e.type === 'poll.closed';
|
|
53
|
-
const isPollVoteCastedEvent = (e:
|
|
23
|
+
const isPollVoteCastedEvent = (e: WSEvent): e is EventPayload<'poll.vote_casted'> =>
|
|
54
24
|
e.type === 'poll.vote_casted';
|
|
55
|
-
const isPollVoteChangedEvent = (e:
|
|
25
|
+
const isPollVoteChangedEvent = (e: WSEvent): e is EventPayload<'poll.vote_changed'> =>
|
|
56
26
|
e.type === 'poll.vote_changed';
|
|
57
|
-
const isPollVoteRemovedEvent = (e:
|
|
27
|
+
const isPollVoteRemovedEvent = (e: WSEvent): e is EventPayload<'poll.vote_removed'> =>
|
|
58
28
|
e.type === 'poll.vote_removed';
|
|
59
29
|
|
|
60
|
-
export const isVoteAnswer = (
|
|
61
|
-
|
|
30
|
+
export const isVoteAnswer = (
|
|
31
|
+
vote: any | undefined,
|
|
32
|
+
): vote is RequireLiteral<PollVoteResponseData, 'answer_text' | 'is_answer'> =>
|
|
33
|
+
!!vote?.answer_text;
|
|
62
34
|
|
|
63
35
|
export type PollAnswersQueryParams = {
|
|
64
36
|
filter?: QueryVotesFilters;
|
|
@@ -74,16 +46,16 @@ export type PollOptionVotesQueryParams = {
|
|
|
74
46
|
|
|
75
47
|
type OptionId = string;
|
|
76
48
|
|
|
77
|
-
export type PollState = Omit<
|
|
49
|
+
export type PollState = Omit<PollResponse_old, 'own_votes' | 'id'> & {
|
|
78
50
|
lastActivityAt: Date; // todo: would be ideal to get this from the BE
|
|
79
51
|
maxVotedOptionIds: OptionId[];
|
|
80
|
-
ownVotesByOptionId: Record<OptionId,
|
|
81
|
-
ownAnswer?:
|
|
52
|
+
ownVotesByOptionId: Record<OptionId, PollVoteResponseData>;
|
|
53
|
+
ownAnswer?: PollVoteResponseData; // each user can have only one answer
|
|
82
54
|
};
|
|
83
55
|
|
|
84
56
|
type PollInitOptions = {
|
|
85
57
|
client: StreamChat;
|
|
86
|
-
poll:
|
|
58
|
+
poll: Gen_PollResponseData;
|
|
87
59
|
};
|
|
88
60
|
|
|
89
61
|
export class Poll {
|
|
@@ -99,11 +71,10 @@ export class Poll {
|
|
|
99
71
|
}
|
|
100
72
|
|
|
101
73
|
private getInitialStateFromPollResponse = (poll: PollInitOptions['poll']) => {
|
|
102
|
-
|
|
103
|
-
const { own_votes, id, ...pollResponseForState } = poll;
|
|
74
|
+
const { own_votes, id: _id, ...pollResponseForState } = poll;
|
|
104
75
|
const { ownAnswer, ownVotes } = own_votes?.reduce<{
|
|
105
|
-
ownVotes:
|
|
106
|
-
ownAnswer?:
|
|
76
|
+
ownVotes: PollVoteResponseData[];
|
|
77
|
+
ownAnswer?: PollVoteResponseData;
|
|
107
78
|
}>(
|
|
108
79
|
(acc, voteOrAnswer) => {
|
|
109
80
|
if (isVoteAnswer(voteOrAnswer)) {
|
|
@@ -119,9 +90,7 @@ export class Poll {
|
|
|
119
90
|
return {
|
|
120
91
|
...pollResponseForState,
|
|
121
92
|
lastActivityAt: new Date(),
|
|
122
|
-
maxVotedOptionIds: getMaxVotedOptionIds(
|
|
123
|
-
pollResponseForState.vote_counts_by_option as PollResponse['vote_counts_by_option'],
|
|
124
|
-
),
|
|
93
|
+
maxVotedOptionIds: getMaxVotedOptionIds(pollResponseForState.vote_counts_by_option),
|
|
125
94
|
ownAnswer,
|
|
126
95
|
ownVotesByOptionId: getOwnVotesByOptionId(ownVotes),
|
|
127
96
|
};
|
|
@@ -142,17 +111,17 @@ export class Poll {
|
|
|
142
111
|
return this.state.getLatestValue();
|
|
143
112
|
}
|
|
144
113
|
|
|
145
|
-
public handlePollUpdated = (event:
|
|
114
|
+
public handlePollUpdated = (event: EventPayload<'poll.updated'>) => {
|
|
146
115
|
if (event.poll?.id && event.poll.id !== this.id) return;
|
|
147
116
|
if (!isPollUpdatedEvent(event)) return;
|
|
148
|
-
|
|
149
|
-
const { id, ...pollData } = extractPollData(event.poll);
|
|
117
|
+
|
|
118
|
+
const { id: _id, ...pollData } = extractPollData(event.poll);
|
|
150
119
|
// @ts-expect-error type mismatch
|
|
151
120
|
this.state.partialNext({ ...pollData, lastActivityAt: new Date(event.created_at) });
|
|
152
121
|
this.upsertOfflineDb();
|
|
153
122
|
};
|
|
154
123
|
|
|
155
|
-
public handlePollClosed = (event:
|
|
124
|
+
public handlePollClosed = (event: EventPayload<'poll.closed'>) => {
|
|
156
125
|
if (event.poll?.id && event.poll.id !== this.id) return;
|
|
157
126
|
if (!isPollClosedEventEvent(event)) return;
|
|
158
127
|
this.state.partialNext({
|
|
@@ -162,12 +131,12 @@ export class Poll {
|
|
|
162
131
|
this.upsertOfflineDb();
|
|
163
132
|
};
|
|
164
133
|
|
|
165
|
-
public handleVoteCasted = (event:
|
|
134
|
+
public handleVoteCasted = (event: EventPayload<'poll.vote_casted'>) => {
|
|
166
135
|
if (event.poll?.id && event.poll.id !== this.id) return;
|
|
167
136
|
if (!isPollVoteCastedEvent(event)) return;
|
|
168
137
|
const currentState = this.data;
|
|
169
|
-
const isOwnVote = event.poll_vote.user_id === this.client.
|
|
170
|
-
let latestAnswers = [...(currentState.latest_answers as
|
|
138
|
+
const isOwnVote = event.poll_vote.user_id === this.client.userId;
|
|
139
|
+
let latestAnswers = [...(currentState.latest_answers as PollVoteResponseData[])];
|
|
171
140
|
let ownAnswer = currentState.ownAnswer;
|
|
172
141
|
const ownVotesByOptionId = currentState.ownVotesByOptionId;
|
|
173
142
|
let maxVotedOptionIds = currentState.maxVotedOptionIds;
|
|
@@ -198,13 +167,13 @@ export class Poll {
|
|
|
198
167
|
this.upsertOfflineDb();
|
|
199
168
|
};
|
|
200
169
|
|
|
201
|
-
public handleVoteChanged = (event:
|
|
170
|
+
public handleVoteChanged = (event: EventPayload<'poll.vote_changed'>) => {
|
|
202
171
|
// this event is triggered only when event.poll.enforce_unique_vote === true
|
|
203
172
|
if (event.poll?.id && event.poll.id !== this.id) return;
|
|
204
173
|
if (!isPollVoteChangedEvent(event)) return;
|
|
205
174
|
const currentState = this.data;
|
|
206
|
-
const isOwnVote = event.poll_vote.user_id === this.client.
|
|
207
|
-
let latestAnswers = [...(currentState.latest_answers as
|
|
175
|
+
const isOwnVote = event.poll_vote.user_id === this.client.userId;
|
|
176
|
+
let latestAnswers = [...(currentState.latest_answers as PollVoteResponseData[])];
|
|
208
177
|
let ownAnswer = currentState.ownAnswer;
|
|
209
178
|
let ownVotesByOptionId = currentState.ownVotesByOptionId;
|
|
210
179
|
let maxVotedOptionIds = currentState.maxVotedOptionIds;
|
|
@@ -221,7 +190,7 @@ export class Poll {
|
|
|
221
190
|
ownVotesByOptionId = { [event.poll_vote.option_id]: event.poll_vote };
|
|
222
191
|
} else {
|
|
223
192
|
ownVotesByOptionId = Object.entries(ownVotesByOptionId).reduce<
|
|
224
|
-
Record<OptionId,
|
|
193
|
+
Record<OptionId, PollVoteResponseData>
|
|
225
194
|
>((acc, [optionId, vote]) => {
|
|
226
195
|
if (
|
|
227
196
|
optionId !== event.poll_vote.option_id &&
|
|
@@ -258,12 +227,12 @@ export class Poll {
|
|
|
258
227
|
this.upsertOfflineDb();
|
|
259
228
|
};
|
|
260
229
|
|
|
261
|
-
public handleVoteRemoved = (event:
|
|
230
|
+
public handleVoteRemoved = (event: EventPayload<'poll.vote_removed'>) => {
|
|
262
231
|
if (event.poll?.id && event.poll.id !== this.id) return;
|
|
263
232
|
if (!isPollVoteRemovedEvent(event)) return;
|
|
264
233
|
const currentState = this.data;
|
|
265
|
-
const isOwnVote = event.poll_vote.user_id === this.client.
|
|
266
|
-
let latestAnswers = [...(currentState.latest_answers as
|
|
234
|
+
const isOwnVote = event.poll_vote.user_id === this.client.userId;
|
|
235
|
+
let latestAnswers = [...(currentState.latest_answers as PollVoteResponseData[])];
|
|
267
236
|
let ownAnswer = currentState.ownAnswer;
|
|
268
237
|
const ownVotesByOptionId = { ...currentState.ownVotesByOptionId };
|
|
269
238
|
let maxVotedOptionIds = currentState.maxVotedOptionIds;
|
|
@@ -293,29 +262,36 @@ export class Poll {
|
|
|
293
262
|
};
|
|
294
263
|
|
|
295
264
|
query = async (id: string) => {
|
|
296
|
-
const { poll } = await this.client.getPoll(id);
|
|
265
|
+
const { poll } = await this.client.getPoll({ poll_id: id });
|
|
297
266
|
this.state.partialNext({ ...poll, lastActivityAt: new Date() });
|
|
298
267
|
return poll;
|
|
299
268
|
};
|
|
300
269
|
|
|
301
|
-
update = async (data: Exclude<
|
|
302
|
-
await this.client.updatePoll({ ...data, id: this.id });
|
|
270
|
+
update = async (data: Exclude<UpdatePollRequest, 'id'>) =>
|
|
271
|
+
await this.client.updatePoll({ ...data, id: this.id as string });
|
|
303
272
|
|
|
304
273
|
partialUpdate = async (partialPollObject: PartialPollUpdate) =>
|
|
305
|
-
await this.client.
|
|
274
|
+
await this.client.updatePollPartial({
|
|
275
|
+
poll_id: this.id as string,
|
|
276
|
+
...partialPollObject,
|
|
277
|
+
});
|
|
306
278
|
|
|
307
|
-
close = async () =>
|
|
279
|
+
close = async () =>
|
|
280
|
+
await this.client.updatePollPartial({
|
|
281
|
+
poll_id: this.id as string,
|
|
282
|
+
set: { is_closed: true },
|
|
283
|
+
});
|
|
308
284
|
|
|
309
|
-
delete = async () => await this.client.deletePoll(this.id as string);
|
|
285
|
+
delete = async () => await this.client.deletePoll({ poll_id: this.id as string });
|
|
310
286
|
|
|
311
287
|
createOption = async (option: PollOptionData) =>
|
|
312
|
-
await this.client.createPollOption(this.id as string, option);
|
|
288
|
+
await this.client.createPollOption({ poll_id: this.id as string, ...option });
|
|
313
289
|
|
|
314
290
|
updateOption = async (option: PollOptionData) =>
|
|
315
|
-
await this.client.updatePollOption(this.id as string, option);
|
|
291
|
+
await this.client.updatePollOption({ poll_id: this.id as string, ...option });
|
|
316
292
|
|
|
317
|
-
deleteOption = async (
|
|
318
|
-
await this.client.deletePollOption(this.id as string,
|
|
293
|
+
deleteOption = async (option_id: string) =>
|
|
294
|
+
await this.client.deletePollOption({ poll_id: this.id as string, option_id });
|
|
319
295
|
|
|
320
296
|
castVote = async (optionId: string, messageId: string) => {
|
|
321
297
|
const { max_votes_allowed, ownVotesByOptionId } = this.data;
|
|
@@ -336,38 +312,54 @@ export class Poll {
|
|
|
336
312
|
});
|
|
337
313
|
return;
|
|
338
314
|
}
|
|
339
|
-
return await this.client.castPollVote(
|
|
340
|
-
|
|
315
|
+
return await this.client.castPollVote({
|
|
316
|
+
message_id: messageId,
|
|
317
|
+
poll_id: this.id as string,
|
|
318
|
+
vote: { option_id: optionId },
|
|
341
319
|
});
|
|
342
320
|
};
|
|
343
321
|
|
|
344
322
|
removeVote = async (voteId: string, messageId: string) =>
|
|
345
|
-
await this.client.
|
|
323
|
+
await this.client.deletePollVote({
|
|
324
|
+
message_id: messageId,
|
|
325
|
+
poll_id: this.id as string,
|
|
326
|
+
vote_id: voteId,
|
|
327
|
+
});
|
|
346
328
|
|
|
347
329
|
addAnswer = async (answerText: string, messageId: string) =>
|
|
348
|
-
await this.client.
|
|
330
|
+
await this.client.castPollVote({
|
|
331
|
+
message_id: messageId,
|
|
332
|
+
poll_id: this.id as string,
|
|
333
|
+
vote: { answer_text: answerText },
|
|
334
|
+
});
|
|
349
335
|
|
|
350
336
|
removeAnswer = async (answerId: string, messageId: string) =>
|
|
351
|
-
await this.client.
|
|
337
|
+
await this.client.deletePollVote({
|
|
338
|
+
message_id: messageId,
|
|
339
|
+
poll_id: this.id as string,
|
|
340
|
+
vote_id: answerId,
|
|
341
|
+
});
|
|
352
342
|
|
|
353
343
|
queryAnswers = async (params: PollAnswersQueryParams) =>
|
|
354
|
-
await this.client.
|
|
355
|
-
this.id as string,
|
|
356
|
-
params.
|
|
357
|
-
params.
|
|
358
|
-
params.options,
|
|
359
|
-
);
|
|
344
|
+
await this.client.queryPollVotes({
|
|
345
|
+
poll_id: this.id as string,
|
|
346
|
+
sort: params.sort,
|
|
347
|
+
filter: { ...(params.filter ?? {}), is_answer: true },
|
|
348
|
+
...(params.options ?? {}),
|
|
349
|
+
});
|
|
360
350
|
|
|
361
351
|
queryOptionVotes = async (params: PollOptionVotesQueryParams) =>
|
|
362
|
-
await this.client.queryPollVotes(
|
|
363
|
-
this.id as string,
|
|
364
|
-
params.
|
|
365
|
-
params.
|
|
366
|
-
params.options,
|
|
367
|
-
);
|
|
352
|
+
await this.client.queryPollVotes({
|
|
353
|
+
poll_id: this.id as string,
|
|
354
|
+
sort: params.sort,
|
|
355
|
+
filter: params.filter,
|
|
356
|
+
...(params.options ?? {}),
|
|
357
|
+
});
|
|
368
358
|
}
|
|
369
359
|
|
|
370
|
-
function getMaxVotedOptionIds(
|
|
360
|
+
function getMaxVotedOptionIds(
|
|
361
|
+
voteCountsByOption: PollResponse_old['vote_counts_by_option'],
|
|
362
|
+
) {
|
|
371
363
|
let maxVotes = 0;
|
|
372
364
|
let winningOptions: string[] = [];
|
|
373
365
|
for (const [id, count] of Object.entries(voteCountsByOption ?? {})) {
|
|
@@ -381,17 +373,17 @@ function getMaxVotedOptionIds(voteCountsByOption: PollResponse['vote_counts_by_o
|
|
|
381
373
|
return winningOptions;
|
|
382
374
|
}
|
|
383
375
|
|
|
384
|
-
function getOwnVotesByOptionId(ownVotes:
|
|
376
|
+
function getOwnVotesByOptionId(ownVotes: PollVoteResponseData[]) {
|
|
385
377
|
return !ownVotes
|
|
386
|
-
? ({} as Record<OptionId,
|
|
387
|
-
: ownVotes.reduce<Record<OptionId,
|
|
378
|
+
? ({} as Record<OptionId, PollVoteResponseData>)
|
|
379
|
+
: ownVotes.reduce<Record<OptionId, PollVoteResponseData>>((acc, vote) => {
|
|
388
380
|
if (isVoteAnswer(vote) || !vote.option_id) return acc;
|
|
389
381
|
acc[vote.option_id] = vote;
|
|
390
382
|
return acc;
|
|
391
383
|
}, {});
|
|
392
384
|
}
|
|
393
385
|
|
|
394
|
-
export function extractPollData(pollResponse:
|
|
386
|
+
export function extractPollData(pollResponse: Gen_PollResponseData): UpdatePollRequest {
|
|
395
387
|
return {
|
|
396
388
|
allow_answers: pollResponse.allow_answers,
|
|
397
389
|
allow_user_suggested_options: pollResponse.allow_user_suggested_options,
|
|
@@ -402,16 +394,15 @@ export function extractPollData(pollResponse: PollResponse): PollData {
|
|
|
402
394
|
max_votes_allowed: pollResponse.max_votes_allowed,
|
|
403
395
|
name: pollResponse.name,
|
|
404
396
|
options: pollResponse.options,
|
|
405
|
-
voting_visibility: pollResponse.voting_visibility,
|
|
397
|
+
voting_visibility: pollResponse.voting_visibility as VotingVisibility,
|
|
406
398
|
};
|
|
407
399
|
}
|
|
408
400
|
|
|
409
|
-
export function mapPollStateToResponse(poll: Poll):
|
|
401
|
+
export function mapPollStateToResponse(poll: Poll): PollResponse_old {
|
|
410
402
|
const {
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
maxVotedOptionIds,
|
|
403
|
+
lastActivityAt: _lastActivityAt,
|
|
404
|
+
|
|
405
|
+
maxVotedOptionIds: _maxVotedOptionIds,
|
|
415
406
|
ownVotesByOptionId,
|
|
416
407
|
ownAnswer,
|
|
417
408
|
...restState
|
|
@@ -419,7 +410,7 @@ export function mapPollStateToResponse(poll: Poll): PollResponse {
|
|
|
419
410
|
const ownVotes = [
|
|
420
411
|
...Object.values(ownVotesByOptionId),
|
|
421
412
|
...(ownAnswer ? [ownAnswer] : []),
|
|
422
|
-
].sort((a, b) =>
|
|
413
|
+
].sort((a, b) => a.created_at.getTime() - b.created_at.getTime());
|
|
423
414
|
|
|
424
415
|
return {
|
|
425
416
|
...restState,
|
|
@@ -429,7 +420,7 @@ export function mapPollStateToResponse(poll: Poll): PollResponse {
|
|
|
429
420
|
}
|
|
430
421
|
|
|
431
422
|
export function extractPollEnrichedData(
|
|
432
|
-
pollResponse:
|
|
423
|
+
pollResponse: Gen_PollResponseData,
|
|
433
424
|
): Omit<PollEnrichData, 'own_votes' | 'latest_answers'> {
|
|
434
425
|
return {
|
|
435
426
|
answers_count: pollResponse.answers_count,
|
package/src/poll_manager.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import type { StreamChat } from './client';
|
|
2
2
|
import type {
|
|
3
|
-
|
|
3
|
+
CreatePollRequest,
|
|
4
4
|
LocalMessage,
|
|
5
5
|
MessageResponse,
|
|
6
|
-
|
|
6
|
+
PollResponse_old,
|
|
7
7
|
PollSort,
|
|
8
8
|
QueryPollsFilters,
|
|
9
9
|
QueryPollsOptions,
|
|
@@ -46,7 +46,7 @@ export class PollManager extends WithSubscriptions {
|
|
|
46
46
|
this.addUnsubscribeFunction(this.subscribeVoteRemoved());
|
|
47
47
|
};
|
|
48
48
|
|
|
49
|
-
public createPoll = async (poll:
|
|
49
|
+
public createPoll = async (poll: CreatePollRequest) => {
|
|
50
50
|
const { poll: createdPoll } = await this.client.createPoll(poll);
|
|
51
51
|
|
|
52
52
|
if (!createdPoll.vote_counts_by_option) {
|
|
@@ -63,11 +63,13 @@ export class PollManager extends WithSubscriptions {
|
|
|
63
63
|
|
|
64
64
|
// optimistically return the cached poll if it exists and update in the background
|
|
65
65
|
if (cachedPoll) {
|
|
66
|
-
this.client
|
|
66
|
+
this.client
|
|
67
|
+
.getPoll({ poll_id: id })
|
|
68
|
+
.then(({ poll }) => this.setOrOverwriteInCache(poll, true));
|
|
67
69
|
return cachedPoll;
|
|
68
70
|
}
|
|
69
71
|
// fetch it, write to the cache and return otherwise
|
|
70
|
-
const { poll } = await this.client.getPoll(id);
|
|
72
|
+
const { poll } = await this.client.getPoll({ poll_id: id });
|
|
71
73
|
|
|
72
74
|
this.setOrOverwriteInCache(poll);
|
|
73
75
|
|
|
@@ -79,7 +81,11 @@ export class PollManager extends WithSubscriptions {
|
|
|
79
81
|
sort: PollSort = [],
|
|
80
82
|
options: QueryPollsOptions = {},
|
|
81
83
|
) => {
|
|
82
|
-
const { polls, next } = await this.client.queryPolls(
|
|
84
|
+
const { polls, next } = await this.client.queryPolls({
|
|
85
|
+
filter,
|
|
86
|
+
sort,
|
|
87
|
+
...options,
|
|
88
|
+
});
|
|
83
89
|
|
|
84
90
|
const pollInstances = polls.map((poll) => {
|
|
85
91
|
this.setOrOverwriteInCache(poll, true);
|
|
@@ -101,13 +107,13 @@ export class PollManager extends WithSubscriptions {
|
|
|
101
107
|
if (!message.poll) {
|
|
102
108
|
continue;
|
|
103
109
|
}
|
|
104
|
-
const pollResponse = message.poll as
|
|
110
|
+
const pollResponse = message.poll as PollResponse_old;
|
|
105
111
|
this.setOrOverwriteInCache(pollResponse, overwriteState);
|
|
106
112
|
}
|
|
107
113
|
};
|
|
108
114
|
|
|
109
115
|
private setOrOverwriteInCache = (
|
|
110
|
-
pollResponse:
|
|
116
|
+
pollResponse: PollResponse_old,
|
|
111
117
|
overwriteState?: boolean,
|
|
112
118
|
) => {
|
|
113
119
|
if (!this.client._cacheEnabled()) {
|
|
@@ -1,14 +1,11 @@
|
|
|
1
1
|
import { ReminderTimer } from './ReminderTimer';
|
|
2
2
|
import { StateStore } from '../store';
|
|
3
3
|
import type { ReminderTimerConfig } from './ReminderTimer';
|
|
4
|
-
import type { MessageResponse,
|
|
4
|
+
import type { MessageResponse, ReminderResponseData, UserResponse } from '../types';
|
|
5
5
|
|
|
6
6
|
export const timeLeftMs = (remindAt: number) => remindAt - new Date().getTime();
|
|
7
7
|
|
|
8
|
-
export type ReminderResponseBaseOrResponse =
|
|
9
|
-
user?: UserResponse;
|
|
10
|
-
message?: MessageResponse;
|
|
11
|
-
};
|
|
8
|
+
export type ReminderResponseBaseOrResponse = ReminderResponseData;
|
|
12
9
|
|
|
13
10
|
export type ReminderState = {
|
|
14
11
|
channel_cid: string;
|