@stream-io/feeds-client 0.1.8 → 0.1.9
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/util/index.ts +1 -0
- package/CHANGELOG.md +15 -0
- package/dist/@react-bindings/hooks/util/index.d.ts +1 -0
- package/dist/@react-bindings/hooks/util/useBookmarkActions.d.ts +13 -0
- package/dist/@react-bindings/hooks/util/useReactionActions.d.ts +1 -1
- package/dist/index-react-bindings.browser.cjs +346 -140
- package/dist/index-react-bindings.browser.cjs.map +1 -1
- package/dist/index-react-bindings.browser.js +346 -141
- package/dist/index-react-bindings.browser.js.map +1 -1
- package/dist/index-react-bindings.node.cjs +346 -140
- package/dist/index-react-bindings.node.cjs.map +1 -1
- package/dist/index-react-bindings.node.js +346 -141
- package/dist/index-react-bindings.node.js.map +1 -1
- package/dist/index.browser.cjs +320 -139
- package/dist/index.browser.cjs.map +1 -1
- package/dist/index.browser.js +320 -140
- package/dist/index.browser.js.map +1 -1
- package/dist/index.node.cjs +320 -139
- package/dist/index.node.cjs.map +1 -1
- package/dist/index.node.js +320 -140
- package/dist/index.node.js.map +1 -1
- package/dist/src/Feed.d.ts +40 -9
- package/dist/src/FeedsClient.d.ts +8 -1
- package/dist/src/gen-imports.d.ts +1 -1
- package/dist/src/state-updates/follow-utils.d.ts +19 -0
- package/dist/src/state-updates/state-update-queue.d.ts +15 -0
- package/dist/src/utils.d.ts +1 -0
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +1 -1
- package/src/Feed.ts +226 -192
- package/src/FeedsClient.ts +75 -3
- package/src/gen-imports.ts +1 -1
- package/src/state-updates/activity-reaction-utils.test.ts +1 -0
- package/src/state-updates/activity-utils.test.ts +1 -0
- package/src/state-updates/follow-utils.test.ts +552 -0
- package/src/state-updates/follow-utils.ts +126 -0
- package/src/state-updates/state-update-queue.test.ts +53 -0
- package/src/state-updates/state-update-queue.ts +35 -0
- package/src/utils.test.ts +175 -0
- package/src/utils.ts +20 -0
package/dist/index.browser.cjs
CHANGED
|
@@ -4058,6 +4058,89 @@ const updateBookmarkInActivities = (event, activities, isCurrentUser) => {
|
|
|
4058
4058
|
return updateActivityInActivities(updatedActivity, activities);
|
|
4059
4059
|
};
|
|
4060
4060
|
|
|
4061
|
+
const isFeedResponse = (follow) => {
|
|
4062
|
+
return 'created_by' in follow;
|
|
4063
|
+
};
|
|
4064
|
+
const handleFollowCreated = (follow, currentState, currentFeedId, connectedUserId) => {
|
|
4065
|
+
// filter non-accepted follows (the way getOrCreate does by default)
|
|
4066
|
+
if (follow.status !== 'accepted') {
|
|
4067
|
+
return { changed: false, data: currentState };
|
|
4068
|
+
}
|
|
4069
|
+
let newState = { ...currentState };
|
|
4070
|
+
// this feed followed someone
|
|
4071
|
+
if (follow.source_feed.fid === currentFeedId) {
|
|
4072
|
+
newState = {
|
|
4073
|
+
...newState,
|
|
4074
|
+
// Update FeedResponse fields, that has the new follower/following count
|
|
4075
|
+
...follow.source_feed,
|
|
4076
|
+
};
|
|
4077
|
+
// Only update if following array already exists
|
|
4078
|
+
if (currentState.following !== undefined) {
|
|
4079
|
+
newState.following = [follow, ...currentState.following];
|
|
4080
|
+
}
|
|
4081
|
+
}
|
|
4082
|
+
else if (
|
|
4083
|
+
// someone followed this feed
|
|
4084
|
+
follow.target_feed.fid === currentFeedId) {
|
|
4085
|
+
const source = follow.source_feed;
|
|
4086
|
+
newState = {
|
|
4087
|
+
...newState,
|
|
4088
|
+
// Update FeedResponse fields, that has the new follower/following count
|
|
4089
|
+
...follow.target_feed,
|
|
4090
|
+
};
|
|
4091
|
+
if (source.created_by.id === connectedUserId) {
|
|
4092
|
+
newState.own_follows = currentState.own_follows
|
|
4093
|
+
? currentState.own_follows.concat(follow)
|
|
4094
|
+
: [follow];
|
|
4095
|
+
}
|
|
4096
|
+
// Only update if followers array already exists
|
|
4097
|
+
if (currentState.followers !== undefined) {
|
|
4098
|
+
newState.followers = [follow, ...currentState.followers];
|
|
4099
|
+
}
|
|
4100
|
+
}
|
|
4101
|
+
return { changed: true, data: newState };
|
|
4102
|
+
};
|
|
4103
|
+
const handleFollowDeleted = (follow, currentState, currentFeedId, connectedUserId) => {
|
|
4104
|
+
let newState = { ...currentState };
|
|
4105
|
+
// this feed unfollowed someone
|
|
4106
|
+
if (follow.source_feed.fid === currentFeedId) {
|
|
4107
|
+
newState = {
|
|
4108
|
+
...newState,
|
|
4109
|
+
// Update FeedResponse fields, that has the new follower/following count
|
|
4110
|
+
...follow.source_feed,
|
|
4111
|
+
};
|
|
4112
|
+
// Only update if following array already exists
|
|
4113
|
+
if (currentState.following !== undefined) {
|
|
4114
|
+
newState.following = currentState.following.filter((followItem) => followItem.target_feed.fid !== follow.target_feed.fid);
|
|
4115
|
+
}
|
|
4116
|
+
}
|
|
4117
|
+
else if (
|
|
4118
|
+
// someone unfollowed this feed
|
|
4119
|
+
follow.target_feed.fid === currentFeedId) {
|
|
4120
|
+
const source = follow.source_feed;
|
|
4121
|
+
newState = {
|
|
4122
|
+
...newState,
|
|
4123
|
+
// Update FeedResponse fields, that has the new follower/following count
|
|
4124
|
+
...follow.target_feed,
|
|
4125
|
+
};
|
|
4126
|
+
if (isFeedResponse(source) &&
|
|
4127
|
+
source.created_by.id === connectedUserId &&
|
|
4128
|
+
currentState.own_follows !== undefined) {
|
|
4129
|
+
newState.own_follows = currentState.own_follows.filter((followItem) => followItem.source_feed.fid !== follow.source_feed.fid);
|
|
4130
|
+
}
|
|
4131
|
+
// Only update if followers array already exists
|
|
4132
|
+
if (currentState.followers !== undefined) {
|
|
4133
|
+
newState.followers = currentState.followers.filter((followItem) => followItem.source_feed.fid !== follow.source_feed.fid);
|
|
4134
|
+
}
|
|
4135
|
+
}
|
|
4136
|
+
return { changed: true, data: newState };
|
|
4137
|
+
};
|
|
4138
|
+
const handleFollowUpdated = (currentState) => {
|
|
4139
|
+
// For now, we'll treat follow updates as no-ops since the current implementation does
|
|
4140
|
+
// This can be enhanced later if needed
|
|
4141
|
+
return { changed: false, data: currentState };
|
|
4142
|
+
};
|
|
4143
|
+
|
|
4061
4144
|
const isImageFile = (file) => {
|
|
4062
4145
|
// photoshop files begin with 'image/'
|
|
4063
4146
|
return file.type.startsWith('image/') && !file.type.endsWith('.photoshop');
|
|
@@ -4073,11 +4156,41 @@ const isCommentResponse = (entity) => {
|
|
|
4073
4156
|
const Constants = {
|
|
4074
4157
|
DEFAULT_COMMENT_PAGINATION: 'first',
|
|
4075
4158
|
};
|
|
4159
|
+
const uniqueArrayMerge = (existingArray, arrayToMerge, getKey) => {
|
|
4160
|
+
const existing = new Set();
|
|
4161
|
+
existingArray.forEach((value) => {
|
|
4162
|
+
const key = getKey(value);
|
|
4163
|
+
existing.add(key);
|
|
4164
|
+
});
|
|
4165
|
+
const filteredArrayToMerge = arrayToMerge.filter((value) => {
|
|
4166
|
+
const key = getKey(value);
|
|
4167
|
+
return !existing.has(key);
|
|
4168
|
+
});
|
|
4169
|
+
return existingArray.concat(filteredArrayToMerge);
|
|
4170
|
+
};
|
|
4171
|
+
|
|
4172
|
+
const shouldUpdateState = ({ stateUpdateId, stateUpdateQueue, watch, }) => {
|
|
4173
|
+
if (!watch) {
|
|
4174
|
+
return true;
|
|
4175
|
+
}
|
|
4176
|
+
if (watch && stateUpdateQueue.has(stateUpdateId)) {
|
|
4177
|
+
stateUpdateQueue.delete(stateUpdateId);
|
|
4178
|
+
return false;
|
|
4179
|
+
}
|
|
4180
|
+
stateUpdateQueue.add(stateUpdateId);
|
|
4181
|
+
return true;
|
|
4182
|
+
};
|
|
4183
|
+
const getStateUpdateQueueIdForFollow = (follow) => {
|
|
4184
|
+
return `follow${follow.source_feed.fid}-${follow.target_feed.fid}`;
|
|
4185
|
+
};
|
|
4186
|
+
const getStateUpdateQueueIdForUnfollow = (follow) => {
|
|
4187
|
+
return `unfollow${follow.source_feed.fid}-${follow.target_feed.fid}`;
|
|
4188
|
+
};
|
|
4076
4189
|
|
|
4077
4190
|
class Feed extends FeedApi {
|
|
4078
|
-
constructor(client, groupId, id, data) {
|
|
4079
|
-
// Need this ugly cast because fileUpload endpoints :(
|
|
4191
|
+
constructor(client, groupId, id, data, watch = false) {
|
|
4080
4192
|
super(client, groupId, id);
|
|
4193
|
+
this.stateUpdateQueue = new Set();
|
|
4081
4194
|
this.eventHandlers = {
|
|
4082
4195
|
'feeds.activity.added': (event) => {
|
|
4083
4196
|
const currentActivities = this.currentState.activities;
|
|
@@ -4223,74 +4336,14 @@ class Feed extends FeedApi {
|
|
|
4223
4336
|
'feeds.feed_group.changed': Feed.noop,
|
|
4224
4337
|
'feeds.feed_group.deleted': Feed.noop,
|
|
4225
4338
|
'feeds.follow.created': (event) => {
|
|
4226
|
-
|
|
4227
|
-
if (event.follow.status !== 'accepted')
|
|
4228
|
-
return;
|
|
4229
|
-
// this feed followed someone
|
|
4230
|
-
if (event.follow.source_feed.fid === this.fid) {
|
|
4231
|
-
this.state.next((currentState) => {
|
|
4232
|
-
const newState = {
|
|
4233
|
-
...currentState,
|
|
4234
|
-
...event.follow.source_feed,
|
|
4235
|
-
};
|
|
4236
|
-
if (!checkHasAnotherPage(currentState.following, currentState.following_pagination?.next)) {
|
|
4237
|
-
// TODO: respect sort
|
|
4238
|
-
newState.following = currentState.following
|
|
4239
|
-
? currentState.following.concat(event.follow)
|
|
4240
|
-
: [event.follow];
|
|
4241
|
-
}
|
|
4242
|
-
return newState;
|
|
4243
|
-
});
|
|
4244
|
-
}
|
|
4245
|
-
else if (
|
|
4246
|
-
// someone followed this feed
|
|
4247
|
-
event.follow.target_feed.fid === this.fid) {
|
|
4248
|
-
const source = event.follow.source_feed;
|
|
4249
|
-
const connectedUser = this.client.state.getLatestValue().connected_user;
|
|
4250
|
-
this.state.next((currentState) => {
|
|
4251
|
-
const newState = { ...currentState, ...event.follow.target_feed };
|
|
4252
|
-
if (source.created_by.id === connectedUser?.id) {
|
|
4253
|
-
newState.own_follows = currentState.own_follows
|
|
4254
|
-
? currentState.own_follows.concat(event.follow)
|
|
4255
|
-
: [event.follow];
|
|
4256
|
-
}
|
|
4257
|
-
if (!checkHasAnotherPage(currentState.followers, currentState.followers_pagination?.next)) {
|
|
4258
|
-
// TODO: respect sort
|
|
4259
|
-
newState.followers = currentState.followers
|
|
4260
|
-
? currentState.followers.concat(event.follow)
|
|
4261
|
-
: [event.follow];
|
|
4262
|
-
}
|
|
4263
|
-
return newState;
|
|
4264
|
-
});
|
|
4265
|
-
}
|
|
4339
|
+
this.handleFollowCreated(event.follow);
|
|
4266
4340
|
},
|
|
4267
4341
|
'feeds.follow.deleted': (event) => {
|
|
4268
|
-
|
|
4269
|
-
|
|
4270
|
-
|
|
4271
|
-
|
|
4272
|
-
...currentState,
|
|
4273
|
-
...event.follow.source_feed,
|
|
4274
|
-
following: currentState.following?.filter((follow) => follow.target_feed.fid !== event.follow.target_feed.fid),
|
|
4275
|
-
};
|
|
4276
|
-
});
|
|
4277
|
-
}
|
|
4278
|
-
else if (
|
|
4279
|
-
// someone unfollowed this feed
|
|
4280
|
-
event.follow.target_feed.fid === this.fid) {
|
|
4281
|
-
const source = event.follow.source_feed;
|
|
4282
|
-
const connectedUser = this.client.state.getLatestValue().connected_user;
|
|
4283
|
-
this.state.next((currentState) => {
|
|
4284
|
-
const newState = { ...currentState, ...event.follow.target_feed };
|
|
4285
|
-
if (source.created_by.id === connectedUser?.id) {
|
|
4286
|
-
newState.own_follows = currentState.own_follows?.filter((follow) => follow.source_feed.fid !== event.follow.source_feed.fid);
|
|
4287
|
-
}
|
|
4288
|
-
newState.followers = currentState.followers?.filter((follow) => follow.source_feed.fid !== event.follow.source_feed.fid);
|
|
4289
|
-
return newState;
|
|
4290
|
-
});
|
|
4291
|
-
}
|
|
4342
|
+
this.handleFollowDeleted(event.follow);
|
|
4343
|
+
},
|
|
4344
|
+
'feeds.follow.updated': (_event) => {
|
|
4345
|
+
handleFollowUpdated(this.currentState);
|
|
4292
4346
|
},
|
|
4293
|
-
'feeds.follow.updated': Feed.noop,
|
|
4294
4347
|
'feeds.comment.reaction.added': this.handleCommentReactionEvent.bind(this),
|
|
4295
4348
|
'feeds.comment.reaction.deleted': this.handleCommentReactionEvent.bind(this),
|
|
4296
4349
|
'feeds.comment.reaction.updated': Feed.noop,
|
|
@@ -4298,13 +4351,11 @@ class Feed extends FeedApi {
|
|
|
4298
4351
|
const { connected_user: connectedUser } = this.client.state.getLatestValue();
|
|
4299
4352
|
this.state.next((currentState) => {
|
|
4300
4353
|
let newState;
|
|
4301
|
-
if (
|
|
4354
|
+
if (typeof currentState.members !== 'undefined') {
|
|
4302
4355
|
newState ?? (newState = {
|
|
4303
4356
|
...currentState,
|
|
4304
4357
|
});
|
|
4305
|
-
newState.members =
|
|
4306
|
-
event.member,
|
|
4307
|
-
];
|
|
4358
|
+
newState.members = [event.member, ...currentState.members];
|
|
4308
4359
|
}
|
|
4309
4360
|
if (connectedUser?.id === event.member.user.id) {
|
|
4310
4361
|
newState ?? (newState = {
|
|
@@ -4387,6 +4438,7 @@ class Feed extends FeedApi {
|
|
|
4387
4438
|
is_loading: false,
|
|
4388
4439
|
is_loading_activities: false,
|
|
4389
4440
|
comments_by_entity_id: {},
|
|
4441
|
+
watch,
|
|
4390
4442
|
});
|
|
4391
4443
|
this.client = client;
|
|
4392
4444
|
}
|
|
@@ -4466,6 +4518,8 @@ class Feed extends FeedApi {
|
|
|
4466
4518
|
}
|
|
4467
4519
|
}
|
|
4468
4520
|
else {
|
|
4521
|
+
// Empty queue when reinitializing the state
|
|
4522
|
+
this.stateUpdateQueue.clear();
|
|
4469
4523
|
const responseCopy = {
|
|
4470
4524
|
...response,
|
|
4471
4525
|
...response.feed,
|
|
@@ -4484,7 +4538,11 @@ class Feed extends FeedApi {
|
|
|
4484
4538
|
if (!request?.following_pagination?.limit) {
|
|
4485
4539
|
delete nextState.following;
|
|
4486
4540
|
}
|
|
4541
|
+
if (response.members.length === 0 && response.feed.member_count > 0) {
|
|
4542
|
+
delete nextState.members;
|
|
4543
|
+
}
|
|
4487
4544
|
nextState.last_get_or_create_request_config = request;
|
|
4545
|
+
nextState.watch = request?.watch ? request.watch : currentState.watch;
|
|
4488
4546
|
return nextState;
|
|
4489
4547
|
});
|
|
4490
4548
|
}
|
|
@@ -4498,6 +4556,56 @@ class Feed extends FeedApi {
|
|
|
4498
4556
|
});
|
|
4499
4557
|
}
|
|
4500
4558
|
}
|
|
4559
|
+
/**
|
|
4560
|
+
* @internal
|
|
4561
|
+
*/
|
|
4562
|
+
handleFollowCreated(follow) {
|
|
4563
|
+
if (!shouldUpdateState({
|
|
4564
|
+
stateUpdateId: getStateUpdateQueueIdForFollow(follow),
|
|
4565
|
+
stateUpdateQueue: this.stateUpdateQueue,
|
|
4566
|
+
watch: this.currentState.watch,
|
|
4567
|
+
})) {
|
|
4568
|
+
return;
|
|
4569
|
+
}
|
|
4570
|
+
const connectedUser = this.client.state.getLatestValue().connected_user;
|
|
4571
|
+
const result = handleFollowCreated(follow, this.currentState, this.fid, connectedUser?.id);
|
|
4572
|
+
if (result.changed) {
|
|
4573
|
+
this.state.next(result.data);
|
|
4574
|
+
}
|
|
4575
|
+
}
|
|
4576
|
+
/**
|
|
4577
|
+
* @internal
|
|
4578
|
+
*/
|
|
4579
|
+
handleFollowDeleted(follow) {
|
|
4580
|
+
if (!shouldUpdateState({
|
|
4581
|
+
stateUpdateId: getStateUpdateQueueIdForUnfollow(follow),
|
|
4582
|
+
stateUpdateQueue: this.stateUpdateQueue,
|
|
4583
|
+
watch: this.currentState.watch,
|
|
4584
|
+
})) {
|
|
4585
|
+
return;
|
|
4586
|
+
}
|
|
4587
|
+
const connectedUser = this.client.state.getLatestValue().connected_user;
|
|
4588
|
+
const result = handleFollowDeleted(follow, this.currentState, this.fid, connectedUser?.id);
|
|
4589
|
+
{
|
|
4590
|
+
this.state.next(result.data);
|
|
4591
|
+
}
|
|
4592
|
+
}
|
|
4593
|
+
/**
|
|
4594
|
+
* @internal
|
|
4595
|
+
*/
|
|
4596
|
+
handleWatchStopped() {
|
|
4597
|
+
this.state.partialNext({
|
|
4598
|
+
watch: false,
|
|
4599
|
+
});
|
|
4600
|
+
}
|
|
4601
|
+
/**
|
|
4602
|
+
* @internal
|
|
4603
|
+
*/
|
|
4604
|
+
handleWatchStarted() {
|
|
4605
|
+
this.state.partialNext({
|
|
4606
|
+
watch: true,
|
|
4607
|
+
});
|
|
4608
|
+
}
|
|
4501
4609
|
handleBookmarkAdded(event) {
|
|
4502
4610
|
const currentActivities = this.currentState.activities;
|
|
4503
4611
|
const { connected_user: connectedUser } = this.client.state.getLatestValue();
|
|
@@ -4542,70 +4650,85 @@ class Feed extends FeedApi {
|
|
|
4542
4650
|
}
|
|
4543
4651
|
return commentIndex;
|
|
4544
4652
|
}
|
|
4545
|
-
|
|
4546
|
-
|
|
4547
|
-
|
|
4548
|
-
|
|
4549
|
-
|
|
4550
|
-
|
|
4551
|
-
|
|
4552
|
-
|
|
4553
|
-
|
|
4554
|
-
|
|
4555
|
-
|
|
4556
|
-
|
|
4557
|
-
|
|
4653
|
+
/**
|
|
4654
|
+
* Load child comments of entity (activity or comment) into the state, if the target entity is comment,
|
|
4655
|
+
* `entityParentId` should be provided (`CommentResponse.parent_id ?? CommentResponse.object_id`).
|
|
4656
|
+
*/
|
|
4657
|
+
loadCommentsIntoState(data) {
|
|
4658
|
+
// add initial (top level) object for processing
|
|
4659
|
+
const traverseArray = [
|
|
4660
|
+
{
|
|
4661
|
+
entityId: data.entityId,
|
|
4662
|
+
entityParentId: data.entityParentId,
|
|
4663
|
+
comments: data.comments,
|
|
4664
|
+
next: data.next,
|
|
4665
|
+
},
|
|
4666
|
+
];
|
|
4558
4667
|
this.state.next((currentState) => {
|
|
4559
|
-
const
|
|
4560
|
-
|
|
4561
|
-
|
|
4562
|
-
|
|
4563
|
-
|
|
4668
|
+
const newCommentsByEntityId = {
|
|
4669
|
+
...currentState.comments_by_entity_id,
|
|
4670
|
+
};
|
|
4671
|
+
while (traverseArray.length) {
|
|
4672
|
+
const item = traverseArray.pop();
|
|
4673
|
+
const entityId = item.entityId;
|
|
4674
|
+
// go over entity comments and generate new objects
|
|
4675
|
+
// for further processing if there are any replies
|
|
4676
|
+
item.comments.forEach((comment) => {
|
|
4677
|
+
if (!comment.replies?.length)
|
|
4678
|
+
return;
|
|
4679
|
+
traverseArray.push({
|
|
4680
|
+
entityId: comment.id,
|
|
4681
|
+
entityParentId: entityId,
|
|
4682
|
+
comments: comment.replies,
|
|
4683
|
+
next: comment.meta?.next_cursor,
|
|
4684
|
+
});
|
|
4685
|
+
});
|
|
4686
|
+
// omit replies & meta from the comments (transform ThreadedCommentResponse to CommentResponse)
|
|
4687
|
+
// this is somehow faster than copying the whole
|
|
4688
|
+
// object and deleting the desired properties
|
|
4689
|
+
const newComments = item.comments.map(({ replies: _r, meta: _m, ...restOfTheCommentResponse }) => restOfTheCommentResponse);
|
|
4690
|
+
newCommentsByEntityId[entityId] = {
|
|
4691
|
+
...newCommentsByEntityId[entityId],
|
|
4692
|
+
entity_parent_id: item.entityParentId,
|
|
4693
|
+
pagination: {
|
|
4694
|
+
...newCommentsByEntityId[entityId]?.pagination,
|
|
4695
|
+
next: item.next,
|
|
4696
|
+
sort: data.sort,
|
|
4697
|
+
},
|
|
4698
|
+
comments: newCommentsByEntityId[entityId]?.comments
|
|
4699
|
+
? newCommentsByEntityId[entityId].comments?.concat(newComments)
|
|
4700
|
+
: newComments,
|
|
4701
|
+
};
|
|
4702
|
+
}
|
|
4564
4703
|
return {
|
|
4565
4704
|
...currentState,
|
|
4566
|
-
|
|
4705
|
+
comments_by_entity_id: newCommentsByEntityId,
|
|
4567
4706
|
};
|
|
4568
4707
|
});
|
|
4569
4708
|
}
|
|
4570
|
-
async loadNextPageComments({
|
|
4709
|
+
async loadNextPageComments({ entityId, base, sort, entityParentId, }) {
|
|
4571
4710
|
let error;
|
|
4572
4711
|
try {
|
|
4573
4712
|
this.state.next((currentState) => ({
|
|
4574
4713
|
...currentState,
|
|
4575
4714
|
comments_by_entity_id: {
|
|
4576
4715
|
...currentState.comments_by_entity_id,
|
|
4577
|
-
[
|
|
4578
|
-
...currentState.comments_by_entity_id[
|
|
4716
|
+
[entityId]: {
|
|
4717
|
+
...currentState.comments_by_entity_id[entityId],
|
|
4579
4718
|
pagination: {
|
|
4580
|
-
...currentState.comments_by_entity_id[
|
|
4719
|
+
...currentState.comments_by_entity_id[entityId]?.pagination,
|
|
4581
4720
|
loading_next_page: true,
|
|
4582
4721
|
},
|
|
4583
4722
|
},
|
|
4584
4723
|
},
|
|
4585
4724
|
}));
|
|
4586
|
-
const { next
|
|
4587
|
-
this.
|
|
4588
|
-
|
|
4589
|
-
|
|
4590
|
-
|
|
4591
|
-
|
|
4592
|
-
|
|
4593
|
-
newPagination.sort = sort;
|
|
4594
|
-
}
|
|
4595
|
-
return {
|
|
4596
|
-
...currentState,
|
|
4597
|
-
comments_by_entity_id: {
|
|
4598
|
-
...currentState.comments_by_entity_id,
|
|
4599
|
-
[forId]: {
|
|
4600
|
-
...currentState.comments_by_entity_id[forId],
|
|
4601
|
-
parent_id: parentId,
|
|
4602
|
-
pagination: newPagination,
|
|
4603
|
-
comments: currentState.comments_by_entity_id[forId]?.comments
|
|
4604
|
-
? currentState.comments_by_entity_id[forId].comments?.concat(comments)
|
|
4605
|
-
: comments,
|
|
4606
|
-
},
|
|
4607
|
-
},
|
|
4608
|
-
};
|
|
4725
|
+
const { next, comments } = await base();
|
|
4726
|
+
this.loadCommentsIntoState({
|
|
4727
|
+
entityId,
|
|
4728
|
+
comments,
|
|
4729
|
+
entityParentId,
|
|
4730
|
+
next,
|
|
4731
|
+
sort,
|
|
4609
4732
|
});
|
|
4610
4733
|
}
|
|
4611
4734
|
catch (e) {
|
|
@@ -4616,10 +4739,10 @@ class Feed extends FeedApi {
|
|
|
4616
4739
|
...currentState,
|
|
4617
4740
|
comments_by_entity_id: {
|
|
4618
4741
|
...currentState.comments_by_entity_id,
|
|
4619
|
-
[
|
|
4620
|
-
...currentState.comments_by_entity_id[
|
|
4742
|
+
[entityId]: {
|
|
4743
|
+
...currentState.comments_by_entity_id[entityId],
|
|
4621
4744
|
pagination: {
|
|
4622
|
-
...currentState.comments_by_entity_id[
|
|
4745
|
+
...currentState.comments_by_entity_id[entityId]?.pagination,
|
|
4623
4746
|
loading_next_page: false,
|
|
4624
4747
|
},
|
|
4625
4748
|
},
|
|
@@ -4642,7 +4765,7 @@ class Feed extends FeedApi {
|
|
|
4642
4765
|
return;
|
|
4643
4766
|
}
|
|
4644
4767
|
await this.loadNextPageComments({
|
|
4645
|
-
|
|
4768
|
+
entityId: activity.id,
|
|
4646
4769
|
base: () => this.client.getComments({
|
|
4647
4770
|
...request,
|
|
4648
4771
|
sort,
|
|
@@ -4665,7 +4788,7 @@ class Feed extends FeedApi {
|
|
|
4665
4788
|
return;
|
|
4666
4789
|
}
|
|
4667
4790
|
await this.loadNextPageComments({
|
|
4668
|
-
|
|
4791
|
+
entityId: comment.id,
|
|
4669
4792
|
base: () => this.client.getCommentReplies({
|
|
4670
4793
|
...request,
|
|
4671
4794
|
comment_id: comment.id,
|
|
@@ -4675,7 +4798,7 @@ class Feed extends FeedApi {
|
|
|
4675
4798
|
Constants.DEFAULT_COMMENT_PAGINATION,
|
|
4676
4799
|
next: currentNextCursor,
|
|
4677
4800
|
}),
|
|
4678
|
-
|
|
4801
|
+
entityParentId: comment.parent_id ?? comment.object_id,
|
|
4679
4802
|
sort,
|
|
4680
4803
|
});
|
|
4681
4804
|
}
|
|
@@ -4705,17 +4828,19 @@ class Feed extends FeedApi {
|
|
|
4705
4828
|
next: currentNextCursor,
|
|
4706
4829
|
sort,
|
|
4707
4830
|
});
|
|
4708
|
-
this.state.next((currentState) =>
|
|
4709
|
-
|
|
4710
|
-
|
|
4711
|
-
|
|
4712
|
-
|
|
4713
|
-
|
|
4714
|
-
|
|
4715
|
-
|
|
4716
|
-
|
|
4717
|
-
|
|
4718
|
-
|
|
4831
|
+
this.state.next((currentState) => {
|
|
4832
|
+
return {
|
|
4833
|
+
...currentState,
|
|
4834
|
+
[type]: currentState[type] === undefined
|
|
4835
|
+
? follows
|
|
4836
|
+
: uniqueArrayMerge(currentState[type], follows, (follow) => `${follow.source_feed.fid}-${follow.target_feed.fid}`),
|
|
4837
|
+
[paginationKey]: {
|
|
4838
|
+
...currentState[paginationKey],
|
|
4839
|
+
next: newNextCursor,
|
|
4840
|
+
sort,
|
|
4841
|
+
},
|
|
4842
|
+
};
|
|
4843
|
+
});
|
|
4719
4844
|
}
|
|
4720
4845
|
catch (e) {
|
|
4721
4846
|
error = e;
|
|
@@ -4768,7 +4893,7 @@ class Feed extends FeedApi {
|
|
|
4768
4893
|
this.state.next((currentState) => ({
|
|
4769
4894
|
...currentState,
|
|
4770
4895
|
members: currentState.members
|
|
4771
|
-
? currentState.members
|
|
4896
|
+
? uniqueArrayMerge(currentState.members, members, ({ user }) => user.id)
|
|
4772
4897
|
: members,
|
|
4773
4898
|
member_pagination: {
|
|
4774
4899
|
...currentState.member_pagination,
|
|
@@ -5355,13 +5480,17 @@ class FeedsClient extends FeedsApi {
|
|
|
5355
5480
|
};
|
|
5356
5481
|
this.eventDispatcher.dispatch(networkEvent);
|
|
5357
5482
|
};
|
|
5358
|
-
this.getOrCreateActiveFeed = (group, id, data) => {
|
|
5483
|
+
this.getOrCreateActiveFeed = (group, id, data, watch) => {
|
|
5359
5484
|
const fid = `${group}:${id}`;
|
|
5360
5485
|
if (this.activeFeeds[fid]) {
|
|
5361
|
-
|
|
5486
|
+
const feed = this.activeFeeds[fid];
|
|
5487
|
+
if (watch && !feed.currentState.watch) {
|
|
5488
|
+
feed.handleWatchStarted();
|
|
5489
|
+
}
|
|
5490
|
+
return feed;
|
|
5362
5491
|
}
|
|
5363
5492
|
else {
|
|
5364
|
-
const feed = new Feed(this, group, id, data);
|
|
5493
|
+
const feed = new Feed(this, group, id, data, watch);
|
|
5365
5494
|
this.activeFeeds[fid] = feed;
|
|
5366
5495
|
return feed;
|
|
5367
5496
|
}
|
|
@@ -5390,6 +5519,11 @@ class FeedsClient extends FeedsApi {
|
|
|
5390
5519
|
}
|
|
5391
5520
|
}
|
|
5392
5521
|
}
|
|
5522
|
+
else {
|
|
5523
|
+
for (const activeFeed of Object.values(this.activeFeeds)) {
|
|
5524
|
+
activeFeed.handleWatchStopped();
|
|
5525
|
+
}
|
|
5526
|
+
}
|
|
5393
5527
|
break;
|
|
5394
5528
|
}
|
|
5395
5529
|
case 'feeds.feed.created': {
|
|
@@ -5493,7 +5627,7 @@ class FeedsClient extends FeedsApi {
|
|
|
5493
5627
|
}
|
|
5494
5628
|
async queryFeeds(request) {
|
|
5495
5629
|
const response = await this.feedsQueryFeeds(request);
|
|
5496
|
-
const feeds = response.feeds.map((f) => this.getOrCreateActiveFeed(f.group_id, f.id, f));
|
|
5630
|
+
const feeds = response.feeds.map((f) => this.getOrCreateActiveFeed(f.group_id, f.id, f, request?.watch));
|
|
5497
5631
|
return {
|
|
5498
5632
|
feeds,
|
|
5499
5633
|
next: response.next,
|
|
@@ -5502,6 +5636,52 @@ class FeedsClient extends FeedsApi {
|
|
|
5502
5636
|
duration: response.duration,
|
|
5503
5637
|
};
|
|
5504
5638
|
}
|
|
5639
|
+
// For follow API endpoints we update the state after HTTP response to allow queryFeeds with watch: false
|
|
5640
|
+
async follow(request) {
|
|
5641
|
+
const response = await super.follow(request);
|
|
5642
|
+
[response.follow.source_feed.fid, response.follow.target_feed.fid].forEach((fid) => {
|
|
5643
|
+
const feed = this.activeFeeds[fid];
|
|
5644
|
+
if (feed) {
|
|
5645
|
+
feed.handleFollowCreated(response.follow);
|
|
5646
|
+
}
|
|
5647
|
+
});
|
|
5648
|
+
return response;
|
|
5649
|
+
}
|
|
5650
|
+
async followBatch(request) {
|
|
5651
|
+
const response = await super.followBatch(request);
|
|
5652
|
+
response.follows.forEach((follow) => {
|
|
5653
|
+
const feed = this.activeFeeds[follow.source_feed.fid];
|
|
5654
|
+
if (feed) {
|
|
5655
|
+
feed.handleFollowCreated(follow);
|
|
5656
|
+
}
|
|
5657
|
+
});
|
|
5658
|
+
return response;
|
|
5659
|
+
}
|
|
5660
|
+
async unfollow(request) {
|
|
5661
|
+
const response = await super.unfollow(request);
|
|
5662
|
+
[request.source, request.target].forEach((fid) => {
|
|
5663
|
+
const feed = this.activeFeeds[fid];
|
|
5664
|
+
if (feed) {
|
|
5665
|
+
feed.handleFollowDeleted({
|
|
5666
|
+
source_feed: { fid: request.source },
|
|
5667
|
+
target_feed: { fid: request.target },
|
|
5668
|
+
});
|
|
5669
|
+
}
|
|
5670
|
+
});
|
|
5671
|
+
return response;
|
|
5672
|
+
}
|
|
5673
|
+
async stopWatchingFeed(request) {
|
|
5674
|
+
const connectionId = await this.connectionIdManager.getConnectionId();
|
|
5675
|
+
const response = await super.stopWatchingFeed({
|
|
5676
|
+
...request,
|
|
5677
|
+
connection_id: connectionId,
|
|
5678
|
+
});
|
|
5679
|
+
const feed = this.activeFeeds[`${request.feed_group_id}:${request.feed_id}`];
|
|
5680
|
+
if (feed) {
|
|
5681
|
+
feed.handleWatchStopped();
|
|
5682
|
+
}
|
|
5683
|
+
return response;
|
|
5684
|
+
}
|
|
5505
5685
|
findActiveFeedByActivityId(activityId) {
|
|
5506
5686
|
return Object.values(this.activeFeeds).filter((feed) => feed.currentState.activities?.some((activity) => activity.id === activityId));
|
|
5507
5687
|
}
|
|
@@ -6034,4 +6214,5 @@ exports.isImageFile = isImageFile;
|
|
|
6034
6214
|
exports.isPatch = isPatch;
|
|
6035
6215
|
exports.isVideoFile = isVideoFile;
|
|
6036
6216
|
exports.isVoteAnswer = isVoteAnswer;
|
|
6217
|
+
exports.uniqueArrayMerge = uniqueArrayMerge;
|
|
6037
6218
|
//# sourceMappingURL=index.browser.cjs.map
|