@stream-io/feeds-client 0.2.1 → 0.2.3
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/@react-bindings/hooks/feed-state-hooks/index.ts +4 -0
- package/CHANGELOG.md +16 -0
- package/dist/@react-bindings/contexts/StreamSearchContext.d.ts +1 -1
- package/dist/@react-bindings/contexts/StreamSearchResultsContext.d.ts +1 -1
- package/dist/@react-bindings/hooks/feed-state-hooks/index.d.ts +4 -0
- package/dist/@react-bindings/hooks/feed-state-hooks/useAggregatedActivities.d.ts +11 -0
- package/dist/@react-bindings/hooks/feed-state-hooks/useIsAggregatedActivityRead.d.ts +6 -0
- package/dist/@react-bindings/hooks/feed-state-hooks/useIsAggregatedActivitySeen.d.ts +6 -0
- package/dist/@react-bindings/hooks/feed-state-hooks/useNotificationStatus.d.ts +13 -0
- package/dist/@react-bindings/hooks/search-state-hooks/useSearchQuery.d.ts +1 -1
- package/dist/@react-bindings/hooks/search-state-hooks/useSearchResult.d.ts +1 -1
- package/dist/@react-bindings/hooks/search-state-hooks/useSearchSources.d.ts +2 -2
- package/dist/@react-bindings/wrappers/StreamFeed.d.ts +1 -1
- package/dist/@react-bindings/wrappers/StreamSearch.d.ts +1 -1
- package/dist/@react-bindings/wrappers/StreamSearchResults.d.ts +1 -1
- package/dist/index-react-bindings.browser.cjs +178 -35
- package/dist/index-react-bindings.browser.cjs.map +1 -1
- package/dist/index-react-bindings.browser.js +175 -36
- package/dist/index-react-bindings.browser.js.map +1 -1
- package/dist/index-react-bindings.node.cjs +178 -35
- package/dist/index-react-bindings.node.cjs.map +1 -1
- package/dist/index-react-bindings.node.js +175 -36
- package/dist/index-react-bindings.node.js.map +1 -1
- package/dist/index.browser.cjs +328 -180
- package/dist/index.browser.cjs.map +1 -1
- package/dist/index.browser.js +328 -181
- package/dist/index.browser.js.map +1 -1
- package/dist/index.d.ts +1 -5
- package/dist/index.node.cjs +328 -180
- package/dist/index.node.cjs.map +1 -1
- package/dist/index.node.js +328 -181
- package/dist/index.node.js.map +1 -1
- package/dist/src/common/{ActivitySearchSource.d.ts → search/ActivitySearchSource.d.ts} +3 -3
- package/dist/src/common/{BaseSearchSource.d.ts → search/BaseSearchSource.d.ts} +41 -35
- package/dist/src/common/{FeedSearchSource.d.ts → search/FeedSearchSource.d.ts} +3 -3
- package/dist/src/common/{SearchController.d.ts → search/SearchController.d.ts} +1 -3
- package/dist/src/common/{UserSearchSource.d.ts → search/UserSearchSource.d.ts} +4 -4
- package/dist/src/common/search/index.d.ts +6 -0
- package/dist/src/common/search/types.d.ts +22 -0
- package/dist/src/common/types.d.ts +1 -0
- package/dist/src/feed/event-handlers/activity/handle-activity-deleted.d.ts +5 -12
- package/dist/src/feed/event-handlers/activity/handle-activity-marked.d.ts +11 -0
- package/dist/src/feed/event-handlers/activity/index.d.ts +1 -0
- package/dist/src/feed/event-handlers/notification-feed/handle-notification-feed-updated.d.ts +8 -1
- package/dist/src/feed/feed.d.ts +2 -2
- package/dist/src/gen/models/index.d.ts +58 -26
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/index.ts +1 -5
- package/package.json +1 -1
- package/src/common/{ActivitySearchSource.ts → search/ActivitySearchSource.ts} +3 -3
- package/src/common/{BaseSearchSource.ts → search/BaseSearchSource.ts} +137 -69
- package/src/common/{FeedSearchSource.ts → search/FeedSearchSource.ts} +3 -3
- package/src/common/{SearchController.ts → search/SearchController.ts} +2 -7
- package/src/common/{UserSearchSource.ts → search/UserSearchSource.ts} +3 -3
- package/src/common/search/index.ts +6 -0
- package/src/common/search/types.ts +21 -0
- package/src/common/types.ts +2 -0
- package/src/feed/event-handlers/activity/activity-marked-utils.test.ts +208 -0
- package/src/feed/event-handlers/activity/activity-utils.test.ts +2 -2
- package/src/feed/event-handlers/activity/handle-activity-added.test.ts +86 -0
- package/src/feed/event-handlers/activity/handle-activity-deleted.test.ts +117 -0
- package/src/feed/event-handlers/activity/handle-activity-deleted.ts +8 -4
- package/src/feed/event-handlers/activity/handle-activity-marked.ts +68 -0
- package/src/feed/event-handlers/activity/handle-activity-reaction-added.test.ts +15 -15
- package/src/feed/event-handlers/activity/handle-activity-reaction-deleted.test.ts +14 -14
- package/src/feed/event-handlers/activity/handle-activity-unpinned.test.ts +4 -3
- package/src/feed/event-handlers/activity/handle-activity-updated.test.ts +4 -4
- package/src/feed/event-handlers/activity/index.ts +2 -1
- package/src/feed/event-handlers/bookmark/handle-bookmark-added.test.ts +14 -14
- package/src/feed/event-handlers/bookmark/handle-bookmark-deleted.test.ts +14 -14
- package/src/feed/event-handlers/bookmark/handle-bookmark-updated.test.ts +16 -16
- package/src/feed/event-handlers/comment/handle-comment-added.test.ts +147 -0
- package/src/feed/event-handlers/comment/handle-comment-deleted.test.ts +133 -0
- package/src/feed/event-handlers/comment/handle-comment-deleted.ts +24 -10
- package/src/feed/event-handlers/comment/handle-comment-reaction.test.ts +315 -0
- package/src/feed/event-handlers/comment/handle-comment-updated.test.ts +131 -0
- package/src/feed/event-handlers/feed-member/handle-feed-member-added.test.ts +75 -0
- package/src/feed/event-handlers/feed-member/handle-feed-member-removed.test.ts +82 -0
- package/src/feed/event-handlers/feed-member/handle-feed-member-removed.ts +19 -9
- package/src/feed/event-handlers/feed-member/handle-feed-member-updated.test.ts +84 -0
- package/src/feed/event-handlers/follow/handle-follow-created.test.ts +7 -7
- package/src/feed/event-handlers/follow/handle-follow-deleted.test.ts +2 -2
- package/src/feed/event-handlers/follow/handle-follow-updated.test.ts +1 -1
- package/src/feed/event-handlers/notification-feed/handle-notification-feed-updated.test.ts +120 -0
- package/src/feed/event-handlers/notification-feed/handle-notification-feed-updated.ts +47 -3
- package/src/feed/feed.ts +4 -2
- package/src/gen/feeds/FeedsApi.ts +6 -0
- package/src/gen/model-decoders/decoders.ts +12 -0
- package/src/gen/models/index.ts +90 -34
- package/src/test-utils/response-generators.ts +230 -0
- package/dist/src/test-utils/index.d.ts +0 -1
- package/dist/src/test-utils/response-generators.d.ts +0 -54
package/dist/index.browser.cjs
CHANGED
|
@@ -415,6 +415,7 @@ decoders.Command = (input) => {
|
|
|
415
415
|
decoders.CommentAddedEvent = (input) => {
|
|
416
416
|
const typeMappings = {
|
|
417
417
|
created_at: { type: 'DatetimeType', isSingle: true },
|
|
418
|
+
activity: { type: 'ActivityResponse', isSingle: true },
|
|
418
419
|
comment: { type: 'CommentResponse', isSingle: true },
|
|
419
420
|
received_at: { type: 'DatetimeType', isSingle: true },
|
|
420
421
|
};
|
|
@@ -431,6 +432,7 @@ decoders.CommentDeletedEvent = (input) => {
|
|
|
431
432
|
decoders.CommentReactionAddedEvent = (input) => {
|
|
432
433
|
const typeMappings = {
|
|
433
434
|
created_at: { type: 'DatetimeType', isSingle: true },
|
|
435
|
+
activity: { type: 'ActivityResponse', isSingle: true },
|
|
434
436
|
comment: { type: 'CommentResponse', isSingle: true },
|
|
435
437
|
reaction: { type: 'FeedsReactionResponse', isSingle: true },
|
|
436
438
|
received_at: { type: 'DatetimeType', isSingle: true },
|
|
@@ -449,6 +451,7 @@ decoders.CommentReactionDeletedEvent = (input) => {
|
|
|
449
451
|
decoders.CommentReactionUpdatedEvent = (input) => {
|
|
450
452
|
const typeMappings = {
|
|
451
453
|
created_at: { type: 'DatetimeType', isSingle: true },
|
|
454
|
+
activity: { type: 'ActivityResponse', isSingle: true },
|
|
452
455
|
comment: { type: 'CommentResponse', isSingle: true },
|
|
453
456
|
reaction: { type: 'FeedsReactionResponse', isSingle: true },
|
|
454
457
|
received_at: { type: 'DatetimeType', isSingle: true },
|
|
@@ -811,6 +814,7 @@ decoders.Message = (input) => {
|
|
|
811
814
|
pin_expires: { type: 'DatetimeType', isSingle: true },
|
|
812
815
|
pinned_at: { type: 'DatetimeType', isSingle: true },
|
|
813
816
|
thread_participants: { type: 'User', isSingle: false },
|
|
817
|
+
member: { type: 'ChannelMember', isSingle: true },
|
|
814
818
|
pinned_by: { type: 'User', isSingle: true },
|
|
815
819
|
poll: { type: 'Poll', isSingle: true },
|
|
816
820
|
quoted_message: { type: 'Message', isSingle: true },
|
|
@@ -864,6 +868,8 @@ decoders.ModerationCustomActionEvent = (input) => {
|
|
|
864
868
|
};
|
|
865
869
|
decoders.ModerationFlagResponse = (input) => {
|
|
866
870
|
const typeMappings = {
|
|
871
|
+
created_at: { type: 'DatetimeType', isSingle: true },
|
|
872
|
+
updated_at: { type: 'DatetimeType', isSingle: true },
|
|
867
873
|
review_queue_item: { type: 'ReviewQueueItemResponse', isSingle: true },
|
|
868
874
|
user: { type: 'UserResponse', isSingle: true },
|
|
869
875
|
};
|
|
@@ -1630,6 +1636,7 @@ class FeedsApi {
|
|
|
1630
1636
|
const body = {
|
|
1631
1637
|
type: request?.type,
|
|
1632
1638
|
create_notification_activity: request?.create_notification_activity,
|
|
1639
|
+
skip_push: request?.skip_push,
|
|
1633
1640
|
custom: request?.custom,
|
|
1634
1641
|
};
|
|
1635
1642
|
const response = await this.apiClient.sendRequest('POST', '/api/v2/feeds/activities/{activity_id}/reactions', pathParams, undefined, body, 'application/json');
|
|
@@ -1776,6 +1783,7 @@ class FeedsApi {
|
|
|
1776
1783
|
object_type: request?.object_type,
|
|
1777
1784
|
create_notification_activity: request?.create_notification_activity,
|
|
1778
1785
|
parent_id: request?.parent_id,
|
|
1786
|
+
skip_push: request?.skip_push,
|
|
1779
1787
|
attachments: request?.attachments,
|
|
1780
1788
|
mentioned_user_ids: request?.mentioned_user_ids,
|
|
1781
1789
|
custom: request?.custom,
|
|
@@ -1829,6 +1837,7 @@ class FeedsApi {
|
|
|
1829
1837
|
};
|
|
1830
1838
|
const body = {
|
|
1831
1839
|
comment: request?.comment,
|
|
1840
|
+
skip_push: request?.skip_push,
|
|
1832
1841
|
custom: request?.custom,
|
|
1833
1842
|
};
|
|
1834
1843
|
const response = await this.apiClient.sendRequest('PATCH', '/api/v2/feeds/comments/{id}', pathParams, undefined, body, 'application/json');
|
|
@@ -1842,6 +1851,7 @@ class FeedsApi {
|
|
|
1842
1851
|
const body = {
|
|
1843
1852
|
type: request?.type,
|
|
1844
1853
|
create_notification_activity: request?.create_notification_activity,
|
|
1854
|
+
skip_push: request?.skip_push,
|
|
1845
1855
|
custom: request?.custom,
|
|
1846
1856
|
};
|
|
1847
1857
|
const response = await this.apiClient.sendRequest('POST', '/api/v2/feeds/comments/{id}/reactions', pathParams, undefined, body, 'application/json');
|
|
@@ -2082,6 +2092,7 @@ class FeedsApi {
|
|
|
2082
2092
|
create_notification_activity: request?.create_notification_activity,
|
|
2083
2093
|
follower_role: request?.follower_role,
|
|
2084
2094
|
push_preference: request?.push_preference,
|
|
2095
|
+
skip_push: request?.skip_push,
|
|
2085
2096
|
custom: request?.custom,
|
|
2086
2097
|
};
|
|
2087
2098
|
const response = await this.apiClient.sendRequest('PATCH', '/api/v2/feeds/follows', undefined, undefined, body, 'application/json');
|
|
@@ -2094,6 +2105,7 @@ class FeedsApi {
|
|
|
2094
2105
|
target: request?.target,
|
|
2095
2106
|
create_notification_activity: request?.create_notification_activity,
|
|
2096
2107
|
push_preference: request?.push_preference,
|
|
2108
|
+
skip_push: request?.skip_push,
|
|
2097
2109
|
custom: request?.custom,
|
|
2098
2110
|
};
|
|
2099
2111
|
const response = await this.apiClient.sendRequest('POST', '/api/v2/feeds/follows', undefined, undefined, body, 'application/json');
|
|
@@ -4520,20 +4532,29 @@ function handleCommentAdded(event) {
|
|
|
4520
4532
|
function handleCommentDeleted({ comment }) {
|
|
4521
4533
|
const entityId = comment.parent_id ?? comment.object_id;
|
|
4522
4534
|
this.state.next((currentState) => {
|
|
4523
|
-
|
|
4524
|
-
...currentState.comments_by_entity_id,
|
|
4525
|
-
[entityId]: {
|
|
4526
|
-
...currentState.comments_by_entity_id[entityId],
|
|
4527
|
-
},
|
|
4528
|
-
};
|
|
4535
|
+
let newCommentsByEntityId;
|
|
4529
4536
|
const index = this.getCommentIndex(comment, currentState);
|
|
4530
|
-
if (
|
|
4537
|
+
if (index !== -1) {
|
|
4538
|
+
newCommentsByEntityId ?? (newCommentsByEntityId = {
|
|
4539
|
+
...currentState.comments_by_entity_id,
|
|
4540
|
+
[entityId]: {
|
|
4541
|
+
...currentState.comments_by_entity_id[entityId],
|
|
4542
|
+
},
|
|
4543
|
+
});
|
|
4531
4544
|
newCommentsByEntityId[entityId].comments = [
|
|
4532
4545
|
...newCommentsByEntityId[entityId].comments,
|
|
4533
4546
|
];
|
|
4534
4547
|
newCommentsByEntityId[entityId]?.comments?.splice(index, 1);
|
|
4535
4548
|
}
|
|
4536
|
-
|
|
4549
|
+
if (typeof currentState.comments_by_entity_id[comment.id] !== 'undefined') {
|
|
4550
|
+
newCommentsByEntityId ?? (newCommentsByEntityId = {
|
|
4551
|
+
...currentState.comments_by_entity_id,
|
|
4552
|
+
});
|
|
4553
|
+
delete newCommentsByEntityId[comment.id];
|
|
4554
|
+
}
|
|
4555
|
+
if (!newCommentsByEntityId) {
|
|
4556
|
+
return currentState;
|
|
4557
|
+
}
|
|
4537
4558
|
return {
|
|
4538
4559
|
...currentState,
|
|
4539
4560
|
comments_by_entity_id: newCommentsByEntityId,
|
|
@@ -4654,14 +4675,20 @@ function handleFeedMemberUpdated(event) {
|
|
|
4654
4675
|
function handleFeedMemberRemoved(event) {
|
|
4655
4676
|
const { connected_user: connectedUser } = this.client.state.getLatestValue();
|
|
4656
4677
|
this.state.next((currentState) => {
|
|
4657
|
-
|
|
4658
|
-
|
|
4659
|
-
|
|
4660
|
-
|
|
4661
|
-
|
|
4678
|
+
let newState;
|
|
4679
|
+
if (typeof currentState.members !== 'undefined') {
|
|
4680
|
+
const filtered = currentState.members.filter((member) => member.user.id !== event.member_id);
|
|
4681
|
+
if (filtered.length !== currentState.members.length) {
|
|
4682
|
+
newState ?? (newState = { ...currentState });
|
|
4683
|
+
newState.members = filtered;
|
|
4684
|
+
}
|
|
4685
|
+
}
|
|
4686
|
+
if (connectedUser?.id === event.member_id &&
|
|
4687
|
+
typeof currentState.own_membership !== 'undefined') {
|
|
4688
|
+
newState ?? (newState = { ...currentState });
|
|
4662
4689
|
delete newState.own_membership;
|
|
4663
4690
|
}
|
|
4664
|
-
return newState;
|
|
4691
|
+
return newState ?? currentState;
|
|
4665
4692
|
});
|
|
4666
4693
|
}
|
|
4667
4694
|
|
|
@@ -4898,7 +4925,7 @@ const removePinnedActivityFromState = (activityResponse, pinnedActivities) => {
|
|
|
4898
4925
|
if (index !== -1) {
|
|
4899
4926
|
const newActivities = [...pinnedActivities];
|
|
4900
4927
|
newActivities.splice(index, 1);
|
|
4901
|
-
return { changed: true,
|
|
4928
|
+
return { changed: true, pinned_activities: newActivities };
|
|
4902
4929
|
}
|
|
4903
4930
|
else {
|
|
4904
4931
|
return { changed: false, pinned_activities: pinnedActivities };
|
|
@@ -5088,13 +5115,80 @@ function handleActivityReactionDeleted(event) {
|
|
|
5088
5115
|
}
|
|
5089
5116
|
}
|
|
5090
5117
|
|
|
5118
|
+
const updateNotificationStatusFromActivityMarked = (event, currentNotificationStatus, aggregatedActivities = []) => {
|
|
5119
|
+
if (!currentNotificationStatus) {
|
|
5120
|
+
return {
|
|
5121
|
+
changed: false,
|
|
5122
|
+
};
|
|
5123
|
+
}
|
|
5124
|
+
const newState = {
|
|
5125
|
+
...currentNotificationStatus,
|
|
5126
|
+
};
|
|
5127
|
+
if (event.mark_all_read) {
|
|
5128
|
+
const allGroupIds = aggregatedActivities.map((activity) => activity.group);
|
|
5129
|
+
newState.read_activities = [
|
|
5130
|
+
...new Set([
|
|
5131
|
+
...(currentNotificationStatus.read_activities ?? []),
|
|
5132
|
+
...allGroupIds,
|
|
5133
|
+
]),
|
|
5134
|
+
];
|
|
5135
|
+
}
|
|
5136
|
+
if (event.mark_read && event.mark_read.length > 0) {
|
|
5137
|
+
newState.read_activities = [
|
|
5138
|
+
...new Set([
|
|
5139
|
+
...(currentNotificationStatus?.read_activities ?? []),
|
|
5140
|
+
...event.mark_read,
|
|
5141
|
+
]),
|
|
5142
|
+
];
|
|
5143
|
+
}
|
|
5144
|
+
if (event.mark_all_seen) {
|
|
5145
|
+
newState.last_seen_at = new Date();
|
|
5146
|
+
}
|
|
5147
|
+
return {
|
|
5148
|
+
changed: true,
|
|
5149
|
+
data: { notification_status: newState },
|
|
5150
|
+
};
|
|
5151
|
+
};
|
|
5152
|
+
function handleActivityMarked(event) {
|
|
5153
|
+
const result = updateNotificationStatusFromActivityMarked(event, this.currentState.notification_status, this.currentState.aggregated_activities);
|
|
5154
|
+
if (result.changed) {
|
|
5155
|
+
this.state.partialNext({
|
|
5156
|
+
notification_status: result.data?.notification_status,
|
|
5157
|
+
});
|
|
5158
|
+
}
|
|
5159
|
+
}
|
|
5160
|
+
|
|
5091
5161
|
function handleFeedUpdated(event) {
|
|
5092
5162
|
this.state.partialNext({ ...event.feed });
|
|
5093
5163
|
}
|
|
5094
5164
|
|
|
5165
|
+
const updateNotificationFeedFromEvent = (event) => {
|
|
5166
|
+
const updates = {};
|
|
5167
|
+
if (event.notification_status) {
|
|
5168
|
+
updates.notification_status = event.notification_status;
|
|
5169
|
+
}
|
|
5170
|
+
if (event.aggregated_activities) {
|
|
5171
|
+
updates.aggregated_activities = event.aggregated_activities;
|
|
5172
|
+
}
|
|
5173
|
+
// Only return changed if we have actual updates
|
|
5174
|
+
if (Object.keys(updates).length > 0) {
|
|
5175
|
+
return {
|
|
5176
|
+
changed: true,
|
|
5177
|
+
data: updates,
|
|
5178
|
+
};
|
|
5179
|
+
}
|
|
5180
|
+
return {
|
|
5181
|
+
changed: false,
|
|
5182
|
+
};
|
|
5183
|
+
};
|
|
5095
5184
|
function handleNotificationFeedUpdated(event) {
|
|
5096
|
-
|
|
5097
|
-
|
|
5185
|
+
const result = updateNotificationFeedFromEvent(event);
|
|
5186
|
+
if (result.changed) {
|
|
5187
|
+
this.state.partialNext({
|
|
5188
|
+
notification_status: result.data?.notification_status,
|
|
5189
|
+
aggregated_activities: result.data?.aggregated_activities,
|
|
5190
|
+
});
|
|
5191
|
+
}
|
|
5098
5192
|
}
|
|
5099
5193
|
|
|
5100
5194
|
function handleWatchStarted() {
|
|
@@ -5149,7 +5243,7 @@ class Feed extends FeedApi {
|
|
|
5149
5243
|
'feeds.poll.vote_removed': Feed.noop,
|
|
5150
5244
|
'feeds.activity.pinned': Feed.noop,
|
|
5151
5245
|
'feeds.activity.unpinned': Feed.noop,
|
|
5152
|
-
'feeds.activity.marked':
|
|
5246
|
+
'feeds.activity.marked': handleActivityMarked.bind(this),
|
|
5153
5247
|
'moderation.custom_action': Feed.noop,
|
|
5154
5248
|
'moderation.flagged': Feed.noop,
|
|
5155
5249
|
'moderation.mark_reviewed': Feed.noop,
|
|
@@ -6035,16 +6129,120 @@ const FeedOwnCapability = {
|
|
|
6035
6129
|
UPDATE_FEED_MEMBERS: 'update-feed-members',
|
|
6036
6130
|
};
|
|
6037
6131
|
|
|
6132
|
+
class SearchController {
|
|
6133
|
+
constructor({ config, sources } = {}) {
|
|
6134
|
+
this.addSource = (source) => {
|
|
6135
|
+
this.state.partialNext({
|
|
6136
|
+
sources: [...this.sources, source],
|
|
6137
|
+
});
|
|
6138
|
+
};
|
|
6139
|
+
this.getSource = (sourceType) => this.sources.find((s) => s.type === sourceType);
|
|
6140
|
+
this.removeSource = (sourceType) => {
|
|
6141
|
+
const newSources = this.sources.filter((s) => s.type !== sourceType);
|
|
6142
|
+
if (newSources.length === this.sources.length)
|
|
6143
|
+
return;
|
|
6144
|
+
this.state.partialNext({ sources: newSources });
|
|
6145
|
+
};
|
|
6146
|
+
this.activateSource = (sourceType) => {
|
|
6147
|
+
const source = this.getSource(sourceType);
|
|
6148
|
+
if (!source || source.isActive)
|
|
6149
|
+
return;
|
|
6150
|
+
if (this.config.keepSingleActiveSource) {
|
|
6151
|
+
this.sources.forEach((s) => {
|
|
6152
|
+
if (s.type !== sourceType) {
|
|
6153
|
+
s.deactivate();
|
|
6154
|
+
}
|
|
6155
|
+
});
|
|
6156
|
+
}
|
|
6157
|
+
source.activate();
|
|
6158
|
+
this.state.partialNext({ sources: [...this.sources] });
|
|
6159
|
+
};
|
|
6160
|
+
this.deactivateSource = (sourceType) => {
|
|
6161
|
+
const source = this.getSource(sourceType);
|
|
6162
|
+
if (!source?.isActive)
|
|
6163
|
+
return;
|
|
6164
|
+
if (this.activeSources.length === 1)
|
|
6165
|
+
return;
|
|
6166
|
+
source.deactivate();
|
|
6167
|
+
this.state.partialNext({ sources: [...this.sources] });
|
|
6168
|
+
};
|
|
6169
|
+
this.activate = () => {
|
|
6170
|
+
if (!this.activeSources.length) {
|
|
6171
|
+
const sourcesToActivate = this.config.keepSingleActiveSource
|
|
6172
|
+
? this.sources.slice(0, 1)
|
|
6173
|
+
: this.sources;
|
|
6174
|
+
sourcesToActivate.forEach((s) => s.activate());
|
|
6175
|
+
}
|
|
6176
|
+
if (this.isActive)
|
|
6177
|
+
return;
|
|
6178
|
+
this.state.partialNext({ isActive: true });
|
|
6179
|
+
};
|
|
6180
|
+
this.search = async (searchQuery) => {
|
|
6181
|
+
const searchedSources = this.activeSources;
|
|
6182
|
+
this.state.partialNext({
|
|
6183
|
+
searchQuery,
|
|
6184
|
+
});
|
|
6185
|
+
await Promise.all(searchedSources.map((source) => source.search(searchQuery)));
|
|
6186
|
+
};
|
|
6187
|
+
this.cancelSearchQueries = () => {
|
|
6188
|
+
this.activeSources.forEach((s) => s.cancelScheduledQuery());
|
|
6189
|
+
};
|
|
6190
|
+
this.clear = () => {
|
|
6191
|
+
this.cancelSearchQueries();
|
|
6192
|
+
this.sources.forEach((source) => source.state.next({ ...source.initialState, isActive: source.isActive }));
|
|
6193
|
+
this.state.next((current) => ({
|
|
6194
|
+
...current,
|
|
6195
|
+
isActive: true,
|
|
6196
|
+
queriesInProgress: [],
|
|
6197
|
+
searchQuery: '',
|
|
6198
|
+
}));
|
|
6199
|
+
};
|
|
6200
|
+
this.exit = () => {
|
|
6201
|
+
this.cancelSearchQueries();
|
|
6202
|
+
this.sources.forEach((source) => source.state.next({ ...source.initialState, isActive: source.isActive }));
|
|
6203
|
+
this.state.next((current) => ({
|
|
6204
|
+
...current,
|
|
6205
|
+
isActive: false,
|
|
6206
|
+
queriesInProgress: [],
|
|
6207
|
+
searchQuery: '',
|
|
6208
|
+
}));
|
|
6209
|
+
};
|
|
6210
|
+
this.state = new StateStore({
|
|
6211
|
+
isActive: false,
|
|
6212
|
+
searchQuery: '',
|
|
6213
|
+
sources: sources ?? [],
|
|
6214
|
+
});
|
|
6215
|
+
this._internalState = new StateStore({});
|
|
6216
|
+
this.config = { keepSingleActiveSource: true, ...config };
|
|
6217
|
+
}
|
|
6218
|
+
get hasNext() {
|
|
6219
|
+
return this.sources.some((source) => source.hasNext);
|
|
6220
|
+
}
|
|
6221
|
+
get sources() {
|
|
6222
|
+
return this.state.getLatestValue().sources;
|
|
6223
|
+
}
|
|
6224
|
+
get activeSources() {
|
|
6225
|
+
return this.state.getLatestValue().sources.filter((s) => s.isActive);
|
|
6226
|
+
}
|
|
6227
|
+
get isActive() {
|
|
6228
|
+
return this.state.getLatestValue().isActive;
|
|
6229
|
+
}
|
|
6230
|
+
get searchQuery() {
|
|
6231
|
+
return this.state.getLatestValue().searchQuery;
|
|
6232
|
+
}
|
|
6233
|
+
get searchSourceTypes() {
|
|
6234
|
+
return this.sources.map((s) => s.type);
|
|
6235
|
+
}
|
|
6236
|
+
}
|
|
6237
|
+
|
|
6038
6238
|
const DEFAULT_SEARCH_SOURCE_OPTIONS = {
|
|
6039
6239
|
debounceMs: 300,
|
|
6040
6240
|
pageSize: 10,
|
|
6041
6241
|
allowEmptySearchString: false,
|
|
6242
|
+
resetOnNewSearchQuery: true,
|
|
6042
6243
|
};
|
|
6043
|
-
class
|
|
6244
|
+
class BaseSearchSourceBase {
|
|
6044
6245
|
constructor(options) {
|
|
6045
|
-
this.setDebounceOptions = ({ debounceMs }) => {
|
|
6046
|
-
this.searchDebounced = debounce(this.executeQuery.bind(this), debounceMs);
|
|
6047
|
-
};
|
|
6048
6246
|
this.activate = () => {
|
|
6049
6247
|
if (this.isActive)
|
|
6050
6248
|
return;
|
|
@@ -6063,15 +6261,11 @@ class BaseSearchSource {
|
|
|
6063
6261
|
(this.hasNext || hasNewSearchQuery) &&
|
|
6064
6262
|
(this.allowEmptySearchString || searchString));
|
|
6065
6263
|
};
|
|
6066
|
-
|
|
6067
|
-
const { debounceMs, pageSize, allowEmptySearchString } = {
|
|
6068
|
-
...DEFAULT_SEARCH_SOURCE_OPTIONS,
|
|
6069
|
-
...options,
|
|
6070
|
-
};
|
|
6264
|
+
const { pageSize, allowEmptySearchString, resetOnNewSearchQuery } = { ...DEFAULT_SEARCH_SOURCE_OPTIONS, ...options };
|
|
6071
6265
|
this.pageSize = pageSize;
|
|
6072
6266
|
this.allowEmptySearchString = allowEmptySearchString;
|
|
6267
|
+
this.resetOnNewSearchQuery = resetOnNewSearchQuery;
|
|
6073
6268
|
this.state = new StateStore(this.initialState);
|
|
6074
|
-
this.setDebounceOptions({ debounceMs });
|
|
6075
6269
|
}
|
|
6076
6270
|
get lastQueryError() {
|
|
6077
6271
|
return this.state.getLatestValue().lastQueryError;
|
|
@@ -6113,10 +6307,14 @@ class BaseSearchSource {
|
|
|
6113
6307
|
return this.state.getLatestValue().searchQuery;
|
|
6114
6308
|
}
|
|
6115
6309
|
getStateBeforeFirstQuery(newSearchString) {
|
|
6310
|
+
const initialState = this.initialState;
|
|
6311
|
+
const oldItems = this.items;
|
|
6312
|
+
const items = this.resetOnNewSearchQuery ? initialState.items : oldItems;
|
|
6116
6313
|
return {
|
|
6117
6314
|
...this.initialState,
|
|
6315
|
+
items,
|
|
6118
6316
|
isActive: this.isActive,
|
|
6119
|
-
isLoading: true,
|
|
6317
|
+
isLoading: this.resetOnNewSearchQuery ? true : !oldItems,
|
|
6120
6318
|
searchQuery: newSearchString,
|
|
6121
6319
|
};
|
|
6122
6320
|
}
|
|
@@ -6129,12 +6327,10 @@ class BaseSearchSource {
|
|
|
6129
6327
|
isLoading: false,
|
|
6130
6328
|
items: isFirstPage
|
|
6131
6329
|
? stateUpdate.items
|
|
6132
|
-
: [...(this.items ?? []), ...(stateUpdate.items
|
|
6330
|
+
: [...(this.items ?? []), ...(stateUpdate.items || [])],
|
|
6133
6331
|
};
|
|
6134
6332
|
}
|
|
6135
|
-
|
|
6136
|
-
if (!this.canExecuteQuery(newSearchString))
|
|
6137
|
-
return;
|
|
6333
|
+
prepareStateForQuery(newSearchString) {
|
|
6138
6334
|
const hasNewSearchQuery = typeof newSearchString !== 'undefined';
|
|
6139
6335
|
const searchString = newSearchString ?? this.searchQuery;
|
|
6140
6336
|
if (hasNewSearchQuery) {
|
|
@@ -6143,20 +6339,50 @@ class BaseSearchSource {
|
|
|
6143
6339
|
else {
|
|
6144
6340
|
this.state.partialNext({ isLoading: true });
|
|
6145
6341
|
}
|
|
6342
|
+
return { searchString, hasNewSearchQuery };
|
|
6343
|
+
}
|
|
6344
|
+
updatePaginationStateFromQuery(result) {
|
|
6345
|
+
const { items, next } = result;
|
|
6146
6346
|
const stateUpdate = {};
|
|
6347
|
+
if (next || next === null) {
|
|
6348
|
+
stateUpdate.next = next;
|
|
6349
|
+
stateUpdate.hasNext = !!next;
|
|
6350
|
+
}
|
|
6351
|
+
else {
|
|
6352
|
+
stateUpdate.offset = (this.offset ?? 0) + items.length;
|
|
6353
|
+
stateUpdate.hasNext = items.length === this.pageSize;
|
|
6354
|
+
}
|
|
6355
|
+
return stateUpdate;
|
|
6356
|
+
}
|
|
6357
|
+
resetState() {
|
|
6358
|
+
this.state.next(this.initialState);
|
|
6359
|
+
}
|
|
6360
|
+
resetStateAndActivate() {
|
|
6361
|
+
this.resetState();
|
|
6362
|
+
this.activate();
|
|
6363
|
+
}
|
|
6364
|
+
}
|
|
6365
|
+
class BaseSearchSource extends BaseSearchSourceBase {
|
|
6366
|
+
constructor(options) {
|
|
6367
|
+
const { debounceMs } = { ...DEFAULT_SEARCH_SOURCE_OPTIONS, ...options };
|
|
6368
|
+
super(options);
|
|
6369
|
+
this.setDebounceOptions = ({ debounceMs }) => {
|
|
6370
|
+
this.searchDebounced = debounce(this.executeQuery.bind(this), debounceMs);
|
|
6371
|
+
};
|
|
6372
|
+
this.search = (searchQuery) => this.searchDebounced(searchQuery);
|
|
6373
|
+
this.setDebounceOptions({ debounceMs });
|
|
6374
|
+
}
|
|
6375
|
+
async executeQuery(newSearchString) {
|
|
6376
|
+
if (!this.canExecuteQuery(newSearchString))
|
|
6377
|
+
return;
|
|
6378
|
+
const { hasNewSearchQuery, searchString } = this.prepareStateForQuery(newSearchString);
|
|
6379
|
+
let stateUpdate = {};
|
|
6147
6380
|
try {
|
|
6148
6381
|
const results = await this.query(searchString);
|
|
6149
6382
|
if (!results)
|
|
6150
6383
|
return;
|
|
6151
|
-
const { items
|
|
6152
|
-
|
|
6153
|
-
stateUpdate.next = next;
|
|
6154
|
-
stateUpdate.hasNext = !!next;
|
|
6155
|
-
}
|
|
6156
|
-
else {
|
|
6157
|
-
stateUpdate.offset = (this.offset ?? 0) + items.length;
|
|
6158
|
-
stateUpdate.hasNext = items.length === this.pageSize;
|
|
6159
|
-
}
|
|
6384
|
+
const { items } = results;
|
|
6385
|
+
stateUpdate = this.updatePaginationStateFromQuery(results);
|
|
6160
6386
|
stateUpdate.items = await this.filterQueryResults(items);
|
|
6161
6387
|
}
|
|
6162
6388
|
catch (e) {
|
|
@@ -6169,118 +6395,39 @@ class BaseSearchSource {
|
|
|
6169
6395
|
cancelScheduledQuery() {
|
|
6170
6396
|
this.searchDebounced.cancel();
|
|
6171
6397
|
}
|
|
6172
|
-
resetState() {
|
|
6173
|
-
this.state.next(this.initialState);
|
|
6174
|
-
}
|
|
6175
|
-
resetStateAndActivate() {
|
|
6176
|
-
this.resetState();
|
|
6177
|
-
this.activate();
|
|
6178
|
-
}
|
|
6179
6398
|
}
|
|
6180
|
-
|
|
6181
|
-
|
|
6182
|
-
|
|
6183
|
-
|
|
6184
|
-
|
|
6185
|
-
|
|
6186
|
-
});
|
|
6187
|
-
};
|
|
6188
|
-
this.getSource = (sourceType) => this.sources.find((s) => s.type === sourceType);
|
|
6189
|
-
this.removeSource = (sourceType) => {
|
|
6190
|
-
const newSources = this.sources.filter((s) => s.type !== sourceType);
|
|
6191
|
-
if (newSources.length === this.sources.length)
|
|
6192
|
-
return;
|
|
6193
|
-
this.state.partialNext({ sources: newSources });
|
|
6194
|
-
};
|
|
6195
|
-
this.activateSource = (sourceType) => {
|
|
6196
|
-
const source = this.getSource(sourceType);
|
|
6197
|
-
if (!source || source.isActive)
|
|
6198
|
-
return;
|
|
6199
|
-
if (this.config.keepSingleActiveSource) {
|
|
6200
|
-
this.sources.forEach((s) => {
|
|
6201
|
-
if (s.type !== sourceType) {
|
|
6202
|
-
s.deactivate();
|
|
6203
|
-
}
|
|
6204
|
-
});
|
|
6205
|
-
}
|
|
6206
|
-
source.activate();
|
|
6207
|
-
this.state.partialNext({ sources: [...this.sources] });
|
|
6208
|
-
};
|
|
6209
|
-
this.deactivateSource = (sourceType) => {
|
|
6210
|
-
const source = this.getSource(sourceType);
|
|
6211
|
-
if (!source?.isActive)
|
|
6212
|
-
return;
|
|
6213
|
-
if (this.activeSources.length === 1)
|
|
6214
|
-
return;
|
|
6215
|
-
source.deactivate();
|
|
6216
|
-
this.state.partialNext({ sources: [...this.sources] });
|
|
6217
|
-
};
|
|
6218
|
-
this.activate = () => {
|
|
6219
|
-
if (!this.activeSources.length) {
|
|
6220
|
-
const sourcesToActivate = this.config.keepSingleActiveSource
|
|
6221
|
-
? this.sources.slice(0, 1)
|
|
6222
|
-
: this.sources;
|
|
6223
|
-
sourcesToActivate.forEach((s) => s.activate());
|
|
6224
|
-
}
|
|
6225
|
-
if (this.isActive)
|
|
6226
|
-
return;
|
|
6227
|
-
this.state.partialNext({ isActive: true });
|
|
6228
|
-
};
|
|
6229
|
-
this.search = async (searchQuery) => {
|
|
6230
|
-
const searchedSources = this.activeSources;
|
|
6231
|
-
this.state.partialNext({
|
|
6232
|
-
searchQuery,
|
|
6233
|
-
});
|
|
6234
|
-
await Promise.all(searchedSources.map((source) => source.search(searchQuery)));
|
|
6235
|
-
};
|
|
6236
|
-
this.cancelSearchQueries = () => {
|
|
6237
|
-
this.activeSources.forEach((s) => s.cancelScheduledQuery());
|
|
6238
|
-
};
|
|
6239
|
-
this.clear = () => {
|
|
6240
|
-
this.cancelSearchQueries();
|
|
6241
|
-
this.sources.forEach((source) => source.state.next({ ...source.initialState, isActive: source.isActive }));
|
|
6242
|
-
this.state.next((current) => ({
|
|
6243
|
-
...current,
|
|
6244
|
-
isActive: true,
|
|
6245
|
-
queriesInProgress: [],
|
|
6246
|
-
searchQuery: '',
|
|
6247
|
-
}));
|
|
6248
|
-
};
|
|
6249
|
-
this.exit = () => {
|
|
6250
|
-
this.cancelSearchQueries();
|
|
6251
|
-
this.sources.forEach((source) => source.state.next({ ...source.initialState, isActive: source.isActive }));
|
|
6252
|
-
this.state.next((current) => ({
|
|
6253
|
-
...current,
|
|
6254
|
-
isActive: false,
|
|
6255
|
-
queriesInProgress: [],
|
|
6256
|
-
searchQuery: '',
|
|
6257
|
-
}));
|
|
6399
|
+
class BaseSearchSourceSync extends BaseSearchSourceBase {
|
|
6400
|
+
constructor(options) {
|
|
6401
|
+
const { debounceMs } = { ...DEFAULT_SEARCH_SOURCE_OPTIONS, ...options };
|
|
6402
|
+
super(options);
|
|
6403
|
+
this.setDebounceOptions = ({ debounceMs }) => {
|
|
6404
|
+
this.searchDebounced = debounce(this.executeQuery.bind(this), debounceMs);
|
|
6258
6405
|
};
|
|
6259
|
-
this.
|
|
6260
|
-
|
|
6261
|
-
searchQuery: '',
|
|
6262
|
-
sources: sources ?? [],
|
|
6263
|
-
});
|
|
6264
|
-
this._internalState = new StateStore({});
|
|
6265
|
-
this.config = { keepSingleActiveSource: true, ...config };
|
|
6266
|
-
}
|
|
6267
|
-
get hasNext() {
|
|
6268
|
-
return this.sources.some((source) => source.hasNext);
|
|
6269
|
-
}
|
|
6270
|
-
get sources() {
|
|
6271
|
-
return this.state.getLatestValue().sources;
|
|
6272
|
-
}
|
|
6273
|
-
get activeSources() {
|
|
6274
|
-
return this.state.getLatestValue().sources.filter((s) => s.isActive);
|
|
6275
|
-
}
|
|
6276
|
-
get isActive() {
|
|
6277
|
-
return this.state.getLatestValue().isActive;
|
|
6406
|
+
this.search = (searchQuery) => this.searchDebounced(searchQuery);
|
|
6407
|
+
this.setDebounceOptions({ debounceMs });
|
|
6278
6408
|
}
|
|
6279
|
-
|
|
6280
|
-
|
|
6409
|
+
executeQuery(newSearchString) {
|
|
6410
|
+
if (!this.canExecuteQuery(newSearchString))
|
|
6411
|
+
return;
|
|
6412
|
+
const { hasNewSearchQuery, searchString } = this.prepareStateForQuery(newSearchString);
|
|
6413
|
+
let stateUpdate = {};
|
|
6414
|
+
try {
|
|
6415
|
+
const results = this.query(searchString);
|
|
6416
|
+
if (!results)
|
|
6417
|
+
return;
|
|
6418
|
+
const { items } = results;
|
|
6419
|
+
stateUpdate = this.updatePaginationStateFromQuery(results);
|
|
6420
|
+
stateUpdate.items = this.filterQueryResults(items);
|
|
6421
|
+
}
|
|
6422
|
+
catch (e) {
|
|
6423
|
+
stateUpdate.lastQueryError = e;
|
|
6424
|
+
}
|
|
6425
|
+
finally {
|
|
6426
|
+
this.state.next(this.getStateAfterQuery(stateUpdate, hasNewSearchQuery));
|
|
6427
|
+
}
|
|
6281
6428
|
}
|
|
6282
|
-
|
|
6283
|
-
|
|
6429
|
+
cancelScheduledQuery() {
|
|
6430
|
+
this.searchDebounced.cancel();
|
|
6284
6431
|
}
|
|
6285
6432
|
}
|
|
6286
6433
|
|
|
@@ -6309,36 +6456,6 @@ class ActivitySearchSource extends BaseSearchSource {
|
|
|
6309
6456
|
}
|
|
6310
6457
|
}
|
|
6311
6458
|
|
|
6312
|
-
class UserSearchSource extends BaseSearchSource {
|
|
6313
|
-
constructor(client, options) {
|
|
6314
|
-
super(options);
|
|
6315
|
-
this.type = 'user';
|
|
6316
|
-
this.client = client;
|
|
6317
|
-
}
|
|
6318
|
-
async query(searchQuery) {
|
|
6319
|
-
const { connected_user: connectedUser } = this.client.state.getLatestValue();
|
|
6320
|
-
if (!connectedUser)
|
|
6321
|
-
return { items: [] };
|
|
6322
|
-
const { users: items } = await this.client.queryUsers({
|
|
6323
|
-
payload: {
|
|
6324
|
-
filter_conditions: {
|
|
6325
|
-
...(!this.allowEmptySearchString || searchQuery.length > 0
|
|
6326
|
-
? {
|
|
6327
|
-
name: {
|
|
6328
|
-
$autocomplete: searchQuery,
|
|
6329
|
-
},
|
|
6330
|
-
}
|
|
6331
|
-
: {}),
|
|
6332
|
-
},
|
|
6333
|
-
},
|
|
6334
|
-
});
|
|
6335
|
-
return { items, next: undefined };
|
|
6336
|
-
}
|
|
6337
|
-
filterQueryResults(items) {
|
|
6338
|
-
return items;
|
|
6339
|
-
}
|
|
6340
|
-
}
|
|
6341
|
-
|
|
6342
6459
|
class FeedSearchSource extends BaseSearchSource {
|
|
6343
6460
|
constructor(client, options) {
|
|
6344
6461
|
super(options);
|
|
@@ -6372,8 +6489,39 @@ class FeedSearchSource extends BaseSearchSource {
|
|
|
6372
6489
|
}
|
|
6373
6490
|
}
|
|
6374
6491
|
|
|
6492
|
+
class UserSearchSource extends BaseSearchSource {
|
|
6493
|
+
constructor(client, options) {
|
|
6494
|
+
super(options);
|
|
6495
|
+
this.type = 'user';
|
|
6496
|
+
this.client = client;
|
|
6497
|
+
}
|
|
6498
|
+
async query(searchQuery) {
|
|
6499
|
+
const { connected_user: connectedUser } = this.client.state.getLatestValue();
|
|
6500
|
+
if (!connectedUser)
|
|
6501
|
+
return { items: [] };
|
|
6502
|
+
const { users: items } = await this.client.queryUsers({
|
|
6503
|
+
payload: {
|
|
6504
|
+
filter_conditions: {
|
|
6505
|
+
...(!this.allowEmptySearchString || searchQuery.length > 0
|
|
6506
|
+
? {
|
|
6507
|
+
name: {
|
|
6508
|
+
$autocomplete: searchQuery,
|
|
6509
|
+
},
|
|
6510
|
+
}
|
|
6511
|
+
: {}),
|
|
6512
|
+
},
|
|
6513
|
+
},
|
|
6514
|
+
});
|
|
6515
|
+
return { items, next: undefined };
|
|
6516
|
+
}
|
|
6517
|
+
filterQueryResults(items) {
|
|
6518
|
+
return items;
|
|
6519
|
+
}
|
|
6520
|
+
}
|
|
6521
|
+
|
|
6375
6522
|
exports.ActivitySearchSource = ActivitySearchSource;
|
|
6376
6523
|
exports.BaseSearchSource = BaseSearchSource;
|
|
6524
|
+
exports.BaseSearchSourceSync = BaseSearchSourceSync;
|
|
6377
6525
|
exports.ChannelOwnCapability = ChannelOwnCapability;
|
|
6378
6526
|
exports.Constants = Constants;
|
|
6379
6527
|
exports.Feed = Feed;
|