@stream-io/feeds-client 0.2.0 → 0.2.1

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.
Files changed (58) hide show
  1. package/CHANGELOG.md +8 -0
  2. package/dist/index-react-bindings.browser.cjs +365 -207
  3. package/dist/index-react-bindings.browser.cjs.map +1 -1
  4. package/dist/index-react-bindings.browser.js +365 -207
  5. package/dist/index-react-bindings.browser.js.map +1 -1
  6. package/dist/index-react-bindings.node.cjs +365 -207
  7. package/dist/index-react-bindings.node.cjs.map +1 -1
  8. package/dist/index-react-bindings.node.js +365 -207
  9. package/dist/index-react-bindings.node.js.map +1 -1
  10. package/dist/index.browser.cjs +366 -207
  11. package/dist/index.browser.cjs.map +1 -1
  12. package/dist/index.browser.js +366 -208
  13. package/dist/index.browser.js.map +1 -1
  14. package/dist/index.node.cjs +366 -207
  15. package/dist/index.node.cjs.map +1 -1
  16. package/dist/index.node.js +366 -208
  17. package/dist/index.node.js.map +1 -1
  18. package/dist/src/feed/event-handlers/activity/handle-activity-deleted.d.ts +12 -3
  19. package/dist/src/feed/event-handlers/activity/handle-activity-pinned.d.ts +3 -0
  20. package/dist/src/feed/event-handlers/activity/handle-activity-reaction-added.d.ts +10 -6
  21. package/dist/src/feed/event-handlers/activity/handle-activity-reaction-deleted.d.ts +10 -6
  22. package/dist/src/feed/event-handlers/activity/handle-activity-unpinned.d.ts +3 -0
  23. package/dist/src/feed/event-handlers/activity/handle-activity-updated.d.ts +7 -3
  24. package/dist/src/feed/event-handlers/bookmark/handle-bookmark-added.d.ts +10 -6
  25. package/dist/src/feed/event-handlers/bookmark/handle-bookmark-deleted.d.ts +10 -6
  26. package/dist/src/feed/event-handlers/bookmark/handle-bookmark-updated.d.ts +10 -6
  27. package/dist/src/gen/models/index.d.ts +36 -1
  28. package/dist/src/test-utils/response-generators.d.ts +46 -1
  29. package/dist/src/utils/index.d.ts +1 -0
  30. package/dist/src/utils/update-entity-in-array.d.ts +27 -0
  31. package/dist/tsconfig.tsbuildinfo +1 -1
  32. package/package.json +1 -1
  33. package/src/feed/event-handlers/activity/activity-reaction-utils.test.ts +108 -96
  34. package/src/feed/event-handlers/activity/activity-utils.test.ts +84 -122
  35. package/src/feed/event-handlers/activity/handle-activity-deleted.ts +43 -10
  36. package/src/feed/event-handlers/activity/handle-activity-pinned.test.ts +60 -0
  37. package/src/feed/event-handlers/activity/handle-activity-pinned.ts +30 -0
  38. package/src/feed/event-handlers/activity/handle-activity-reaction-added.test.ts +157 -0
  39. package/src/feed/event-handlers/activity/handle-activity-reaction-added.ts +82 -40
  40. package/src/feed/event-handlers/activity/handle-activity-reaction-deleted.test.ts +200 -0
  41. package/src/feed/event-handlers/activity/handle-activity-reaction-deleted.ts +89 -51
  42. package/src/feed/event-handlers/activity/handle-activity-unpinned.test.ts +94 -0
  43. package/src/feed/event-handlers/activity/handle-activity-unpinned.ts +30 -0
  44. package/src/feed/event-handlers/activity/handle-activity-updated.test.ts +115 -0
  45. package/src/feed/event-handlers/activity/handle-activity-updated.ts +73 -35
  46. package/src/feed/event-handlers/bookmark/bookmark-utils.test.ts +121 -109
  47. package/src/feed/event-handlers/bookmark/handle-bookmark-added.test.ts +178 -0
  48. package/src/feed/event-handlers/bookmark/handle-bookmark-added.ts +82 -39
  49. package/src/feed/event-handlers/bookmark/handle-bookmark-deleted.test.ts +188 -0
  50. package/src/feed/event-handlers/bookmark/handle-bookmark-deleted.ts +86 -48
  51. package/src/feed/event-handlers/bookmark/handle-bookmark-updated.test.ts +196 -0
  52. package/src/feed/event-handlers/bookmark/handle-bookmark-updated.ts +83 -44
  53. package/src/gen/model-decoders/decoders.ts +13 -0
  54. package/src/gen/models/index.ts +73 -2
  55. package/src/gen/moderation/ModerationApi.ts +1 -0
  56. package/src/test-utils/response-generators.ts +260 -0
  57. package/src/utils/index.ts +1 -0
  58. package/src/utils/update-entity-in-array.ts +51 -0
@@ -611,6 +611,7 @@ decoders.Channel = (input) => {
611
611
  updated_at: { type: 'DatetimeType', isSingle: true },
612
612
  deleted_at: { type: 'DatetimeType', isSingle: true },
613
613
  last_message_at: { type: 'DatetimeType', isSingle: true },
614
+ message_count_updated_at: { type: 'DatetimeType', isSingle: true },
614
615
  active_live_locations: { type: 'SharedLocation', isSingle: false },
615
616
  invites: { type: 'ChannelMember', isSingle: false },
616
617
  members: { type: 'ChannelMember', isSingle: false },
@@ -888,6 +889,7 @@ decoders.FeedMemberResponse = (input) => {
888
889
  user: { type: 'UserResponse', isSingle: true },
889
890
  invite_accepted_at: { type: 'DatetimeType', isSingle: true },
890
891
  invite_rejected_at: { type: 'DatetimeType', isSingle: true },
892
+ membership_level: { type: 'MembershipLevelResponse', isSingle: true },
891
893
  };
892
894
  return decode(typeMappings, input);
893
895
  };
@@ -1060,6 +1062,13 @@ decoders.ListDevicesResponse = (input) => {
1060
1062
  };
1061
1063
  return decode(typeMappings, input);
1062
1064
  };
1065
+ decoders.MembershipLevelResponse = (input) => {
1066
+ const typeMappings = {
1067
+ created_at: { type: 'DatetimeType', isSingle: true },
1068
+ updated_at: { type: 'DatetimeType', isSingle: true },
1069
+ };
1070
+ return decode(typeMappings, input);
1071
+ };
1063
1072
  decoders.Message = (input) => {
1064
1073
  const typeMappings = {
1065
1074
  created_at: { type: 'DatetimeType', isSingle: true },
@@ -3810,6 +3819,7 @@ class ModerationApi {
3810
3819
  block_list_config: request?.block_list_config,
3811
3820
  bodyguard_config: request?.bodyguard_config,
3812
3821
  google_vision_config: request?.google_vision_config,
3822
+ llm_config: request?.llm_config,
3813
3823
  rule_builder_config: request?.rule_builder_config,
3814
3824
  velocity_filter_config: request?.velocity_filter_config,
3815
3825
  video_call_rule_config: request?.video_call_rule_config,
@@ -4286,6 +4296,23 @@ function getStateUpdateQueueId(data, prefix) {
4286
4296
  throw new Error(`Cannot create state update queueId for data: ${JSON.stringify(data)}`);
4287
4297
  }
4288
4298
 
4299
+ function updateEntityInArray({ matcher, updater, entities, }) {
4300
+ if (!entities || !entities.length) {
4301
+ return { changed: false, entities };
4302
+ }
4303
+ const index = entities.findIndex(matcher);
4304
+ if (index === -1) {
4305
+ return { changed: false, entities };
4306
+ }
4307
+ const newEntity = updater(entities[index]);
4308
+ if (newEntity === entities[index]) {
4309
+ return { changed: false, entities };
4310
+ }
4311
+ const updatedEntities = [...entities];
4312
+ updatedEntities[index] = newEntity;
4313
+ return { changed: true, entities: updatedEntities };
4314
+ }
4315
+
4289
4316
  const updateStateFollowCreated = (follow, currentState, currentFeedId, connectedUserId) => {
4290
4317
  // filter non-accepted follows (the way getOrCreate does by default)
4291
4318
  if (follow.status !== 'accepted') {
@@ -4621,6 +4648,179 @@ function handleFeedMemberRemoved(event) {
4621
4648
  });
4622
4649
  }
4623
4650
 
4651
+ const sharedUpdateActivity$5 = ({ currentActivity, event, eventBelongsToCurrentUser, }) => {
4652
+ let newOwnBookmarks = currentActivity.own_bookmarks;
4653
+ if (eventBelongsToCurrentUser) {
4654
+ newOwnBookmarks = [...newOwnBookmarks, event.bookmark];
4655
+ }
4656
+ return {
4657
+ ...event.bookmark.activity,
4658
+ own_bookmarks: newOwnBookmarks,
4659
+ own_reactions: currentActivity.own_reactions,
4660
+ };
4661
+ };
4662
+ const addBookmarkToActivities = (event, activities, eventBelongsToCurrentUser) => updateEntityInArray({
4663
+ entities: activities,
4664
+ matcher: (activity) => activity.id === event.bookmark.activity.id,
4665
+ updater: (matchedActivity) => sharedUpdateActivity$5({
4666
+ currentActivity: matchedActivity,
4667
+ event,
4668
+ eventBelongsToCurrentUser,
4669
+ }),
4670
+ });
4671
+ const addBookmarkToPinnedActivities = (event, pinnedActivities, eventBelongsToCurrentUser) => updateEntityInArray({
4672
+ entities: pinnedActivities,
4673
+ matcher: (pinnedActivity) => pinnedActivity.activity.id === event.bookmark.activity.id,
4674
+ updater: (matchedPinnedActivity) => {
4675
+ const newActivity = sharedUpdateActivity$5({
4676
+ currentActivity: matchedPinnedActivity.activity,
4677
+ event,
4678
+ eventBelongsToCurrentUser,
4679
+ });
4680
+ if (newActivity === matchedPinnedActivity.activity) {
4681
+ return matchedPinnedActivity;
4682
+ }
4683
+ return {
4684
+ ...matchedPinnedActivity,
4685
+ activity: newActivity,
4686
+ };
4687
+ },
4688
+ });
4689
+ function handleBookmarkAdded(event) {
4690
+ const { activities: currentActivities, pinned_activities: currentPinnedActivities, } = this.currentState;
4691
+ const { connected_user: connectedUser } = this.client.state.getLatestValue();
4692
+ const eventBelongsToCurrentUser = event.bookmark.user.id === connectedUser?.id;
4693
+ const [result1, result2] = [
4694
+ addBookmarkToActivities(event, currentActivities, eventBelongsToCurrentUser),
4695
+ addBookmarkToPinnedActivities(event, currentPinnedActivities, eventBelongsToCurrentUser),
4696
+ ];
4697
+ if (result1.changed || result2.changed) {
4698
+ this.state.partialNext({
4699
+ activities: result1.entities,
4700
+ pinned_activities: result2.entities,
4701
+ });
4702
+ }
4703
+ }
4704
+
4705
+ // Helper function to check if two bookmarks are the same
4706
+ // A bookmark is identified by activity_id + folder_id + user_id
4707
+ const isSameBookmark = (bookmark1, bookmark2) => {
4708
+ return (bookmark1.user.id === bookmark2.user.id &&
4709
+ bookmark1.activity.id === bookmark2.activity.id &&
4710
+ bookmark1.folder?.id === bookmark2.folder?.id);
4711
+ };
4712
+ const sharedUpdateActivity$4 = ({ currentActivity, event, eventBelongsToCurrentUser, }) => {
4713
+ let newOwnBookmarks = currentActivity.own_bookmarks;
4714
+ if (eventBelongsToCurrentUser) {
4715
+ newOwnBookmarks = currentActivity.own_bookmarks.filter((bookmark) => !isSameBookmark(bookmark, event.bookmark));
4716
+ }
4717
+ return {
4718
+ ...event.bookmark.activity,
4719
+ own_bookmarks: newOwnBookmarks,
4720
+ own_reactions: currentActivity.own_reactions,
4721
+ };
4722
+ };
4723
+ const removeBookmarkFromActivities = (event, activities, eventBelongsToCurrentUser) => updateEntityInArray({
4724
+ entities: activities,
4725
+ matcher: (activity) => activity.id === event.bookmark.activity.id,
4726
+ updater: (matchedActivity) => sharedUpdateActivity$4({
4727
+ currentActivity: matchedActivity,
4728
+ event,
4729
+ eventBelongsToCurrentUser,
4730
+ }),
4731
+ });
4732
+ const removeBookmarkFromPinnedActivities = (event, pinnedActivities, eventBelongsToCurrentUser) => updateEntityInArray({
4733
+ entities: pinnedActivities,
4734
+ matcher: (pinnedActivity) => pinnedActivity.activity.id === event.bookmark.activity.id,
4735
+ updater: (matchedPinnedActivity) => {
4736
+ const newActivity = sharedUpdateActivity$4({
4737
+ currentActivity: matchedPinnedActivity.activity,
4738
+ event,
4739
+ eventBelongsToCurrentUser,
4740
+ });
4741
+ if (newActivity === matchedPinnedActivity.activity) {
4742
+ return matchedPinnedActivity;
4743
+ }
4744
+ return {
4745
+ ...matchedPinnedActivity,
4746
+ activity: newActivity,
4747
+ };
4748
+ },
4749
+ });
4750
+ function handleBookmarkDeleted(event) {
4751
+ const { activities: currentActivities, pinned_activities: currentPinnedActivities, } = this.currentState;
4752
+ const { connected_user: connectedUser } = this.client.state.getLatestValue();
4753
+ const eventBelongsToCurrentUser = event.bookmark.user.id === connectedUser?.id;
4754
+ const [result1, result2] = [
4755
+ removeBookmarkFromActivities(event, currentActivities, eventBelongsToCurrentUser),
4756
+ removeBookmarkFromPinnedActivities(event, currentPinnedActivities, eventBelongsToCurrentUser),
4757
+ ];
4758
+ if (result1.changed || result2.changed) {
4759
+ this.state.partialNext({
4760
+ activities: result1.entities,
4761
+ pinned_activities: result2.entities,
4762
+ });
4763
+ }
4764
+ }
4765
+
4766
+ const sharedUpdateActivity$3 = ({ currentActivity, event, eventBelongsToCurrentUser, }) => {
4767
+ let newOwnBookmarks = currentActivity.own_bookmarks;
4768
+ if (eventBelongsToCurrentUser) {
4769
+ const bookmarkIndex = newOwnBookmarks.findIndex((bookmark) => isSameBookmark(bookmark, event.bookmark));
4770
+ if (bookmarkIndex !== -1) {
4771
+ newOwnBookmarks = [...newOwnBookmarks];
4772
+ newOwnBookmarks[bookmarkIndex] = event.bookmark;
4773
+ }
4774
+ }
4775
+ return {
4776
+ ...event.bookmark.activity,
4777
+ own_bookmarks: newOwnBookmarks,
4778
+ own_reactions: currentActivity.own_reactions,
4779
+ };
4780
+ };
4781
+ const updateBookmarkInActivities = (event, activities, eventBelongsToCurrentUser) => updateEntityInArray({
4782
+ entities: activities,
4783
+ matcher: (activity) => activity.id === event.bookmark.activity.id,
4784
+ updater: (matchedActivity) => sharedUpdateActivity$3({
4785
+ currentActivity: matchedActivity,
4786
+ event,
4787
+ eventBelongsToCurrentUser,
4788
+ }),
4789
+ });
4790
+ const updateBookmarkInPinnedActivities = (event, pinnedActivities, eventBelongsToCurrentUser) => updateEntityInArray({
4791
+ entities: pinnedActivities,
4792
+ matcher: (pinnedActivity) => pinnedActivity.activity.id === event.bookmark.activity.id,
4793
+ updater: (matchedPinnedActivity) => {
4794
+ const newActivity = sharedUpdateActivity$3({
4795
+ currentActivity: matchedPinnedActivity.activity,
4796
+ event,
4797
+ eventBelongsToCurrentUser,
4798
+ });
4799
+ if (newActivity === matchedPinnedActivity.activity) {
4800
+ return matchedPinnedActivity;
4801
+ }
4802
+ return {
4803
+ ...matchedPinnedActivity,
4804
+ activity: newActivity,
4805
+ };
4806
+ },
4807
+ });
4808
+ function handleBookmarkUpdated(event) {
4809
+ const { activities: currentActivities, pinned_activities: currentPinnedActivities, } = this.currentState;
4810
+ const { connected_user: connectedUser } = this.client.state.getLatestValue();
4811
+ const eventBelongsToCurrentUser = event.bookmark.user.id === connectedUser?.id;
4812
+ const [result1, result2] = [
4813
+ updateBookmarkInActivities(event, currentActivities, eventBelongsToCurrentUser),
4814
+ updateBookmarkInPinnedActivities(event, currentPinnedActivities, eventBelongsToCurrentUser),
4815
+ ];
4816
+ if (result1.changed || result2.changed) {
4817
+ this.state.partialNext({
4818
+ activities: result1.entities,
4819
+ pinned_activities: result2.entities,
4820
+ });
4821
+ }
4822
+ }
4823
+
4624
4824
  const addActivitiesToState = (newActivities, activities, position) => {
4625
4825
  let result;
4626
4826
  if (activities === undefined) {
@@ -4665,7 +4865,8 @@ function handleActivityAdded(event) {
4665
4865
  }
4666
4866
 
4667
4867
  const removeActivityFromState = (activityResponse, activities) => {
4668
- const index = activities.findIndex((a) => a.id === activityResponse.id);
4868
+ const index = activities?.findIndex((activity) => activity.id === activityResponse.id) ??
4869
+ -1;
4669
4870
  if (index !== -1) {
4670
4871
  const newActivities = [...activities];
4671
4872
  newActivities.splice(index, 1);
@@ -4675,13 +4876,28 @@ const removeActivityFromState = (activityResponse, activities) => {
4675
4876
  return { changed: false, activities };
4676
4877
  }
4677
4878
  };
4879
+ const removePinnedActivityFromState = (activityResponse, pinnedActivities) => {
4880
+ const index = pinnedActivities?.findIndex((pinnedActivity) => pinnedActivity.activity.id === activityResponse.id) ?? -1;
4881
+ if (index !== -1) {
4882
+ const newActivities = [...pinnedActivities];
4883
+ newActivities.splice(index, 1);
4884
+ return { changed: true, activities: newActivities };
4885
+ }
4886
+ else {
4887
+ return { changed: false, pinned_activities: pinnedActivities };
4888
+ }
4889
+ };
4678
4890
  function handleActivityDeleted(event) {
4679
- const currentActivities = this.currentState.activities;
4680
- if (currentActivities) {
4681
- const result = removeActivityFromState(event.activity, currentActivities);
4682
- if (result.changed) {
4683
- this.state.partialNext({ activities: result.activities });
4684
- }
4891
+ const { activities: currentActivities, pinned_activities: currentPinnedActivities, } = this.currentState;
4892
+ const [result1, result2] = [
4893
+ removeActivityFromState(event.activity, currentActivities),
4894
+ removePinnedActivityFromState(event.activity, currentPinnedActivities),
4895
+ ];
4896
+ if (result1.changed || result2.changed) {
4897
+ this.state.partialNext({
4898
+ activities: result1.activities,
4899
+ pinned_activities: result2.pinned_activities,
4900
+ });
4685
4901
  }
4686
4902
  }
4687
4903
 
@@ -4695,221 +4911,163 @@ function handleActivityRemovedFromFeed(event) {
4695
4911
  }
4696
4912
  }
4697
4913
 
4698
- const updateActivityInState = (updatedActivityResponse, activities, replaceCompletely = false) => {
4699
- const index = activities.findIndex((a) => a.id === updatedActivityResponse.id);
4700
- if (index !== -1) {
4701
- const newActivities = [...activities];
4702
- const activity = activities[index];
4703
- if (replaceCompletely) {
4704
- newActivities[index] = updatedActivityResponse;
4705
- }
4706
- else {
4707
- newActivities[index] = {
4708
- ...updatedActivityResponse,
4709
- own_reactions: activity.own_reactions,
4710
- own_bookmarks: activity.own_bookmarks,
4711
- latest_reactions: activity.latest_reactions,
4712
- reaction_groups: activity.reaction_groups,
4713
- };
4914
+ const sharedUpdateActivity$2 = ({ currentActivity, event, }) => {
4915
+ return {
4916
+ ...event.activity,
4917
+ own_reactions: currentActivity.own_reactions,
4918
+ own_bookmarks: currentActivity.own_bookmarks,
4919
+ };
4920
+ };
4921
+ const updateActivityInState = (event, activities) => updateEntityInArray({
4922
+ entities: activities,
4923
+ matcher: (activity) => activity.id === event.activity.id,
4924
+ updater: (matchedActivity) => sharedUpdateActivity$2({
4925
+ currentActivity: matchedActivity,
4926
+ event,
4927
+ }),
4928
+ });
4929
+ const updatePinnedActivityInState = (event, pinnedActivities) => updateEntityInArray({
4930
+ entities: pinnedActivities,
4931
+ matcher: (pinnedActivity) => pinnedActivity.activity.id === event.activity.id,
4932
+ updater: (matchedPinnedActivity) => {
4933
+ const newActivity = sharedUpdateActivity$2({
4934
+ currentActivity: matchedPinnedActivity.activity,
4935
+ event,
4936
+ });
4937
+ if (newActivity === matchedPinnedActivity.activity) {
4938
+ return matchedPinnedActivity;
4714
4939
  }
4715
- return { changed: true, activities: newActivities };
4716
- }
4717
- else {
4718
- return { changed: false, activities };
4719
- }
4720
- };
4940
+ return {
4941
+ ...matchedPinnedActivity,
4942
+ activity: newActivity,
4943
+ };
4944
+ },
4945
+ });
4721
4946
  function handleActivityUpdated(event) {
4722
- const currentActivities = this.currentState.activities;
4723
- if (currentActivities) {
4724
- const result = updateActivityInState(event.activity, currentActivities);
4725
- if (result.changed) {
4726
- this.client.hydratePollCache([event.activity]);
4727
- this.state.partialNext({ activities: result.activities });
4728
- }
4947
+ const { activities: currentActivities, pinned_activities: currentPinnedActivities, } = this.currentState;
4948
+ const [result1, result2] = [
4949
+ updateActivityInState(event, currentActivities),
4950
+ updatePinnedActivityInState(event, currentPinnedActivities),
4951
+ ];
4952
+ if (result1.changed || result2.changed) {
4953
+ this.client.hydratePollCache([event.activity]);
4954
+ this.state.partialNext({
4955
+ activities: result1.entities,
4956
+ pinned_activities: result2.entities,
4957
+ });
4729
4958
  }
4730
4959
  }
4731
4960
 
4732
- const addReactionToActivity = (event, activity, isCurrentUser) => {
4733
- // Update own_reactions if the reaction is from the current user
4734
- const ownReactions = [...(activity.own_reactions || [])];
4735
- if (isCurrentUser) {
4736
- ownReactions.push(event.reaction);
4961
+ // shared function to update the activity with the new reaction
4962
+ const sharedUpdateActivity$1 = ({ currentActivity, event, eventBelongsToCurrentUser, }) => {
4963
+ let newOwnReactions = currentActivity.own_reactions;
4964
+ if (eventBelongsToCurrentUser) {
4965
+ newOwnReactions = [...currentActivity.own_reactions, event.reaction];
4737
4966
  }
4738
4967
  return {
4739
- ...activity,
4740
- own_reactions: ownReactions,
4741
- latest_reactions: event.activity.latest_reactions,
4742
- reaction_groups: event.activity.reaction_groups,
4743
- changed: true,
4744
- };
4745
- };
4746
- const addReactionToActivities = (event, activities, isCurrentUser) => {
4747
- if (!activities) {
4748
- return { changed: false, activities: [] };
4749
- }
4750
- const activityIndex = activities.findIndex((a) => a.id === event.activity.id);
4751
- if (activityIndex === -1) {
4752
- return { changed: false, activities };
4753
- }
4754
- const activity = activities[activityIndex];
4755
- const updatedActivity = addReactionToActivity(event, activity, isCurrentUser);
4756
- return updateActivityInState(updatedActivity, activities, true);
4757
- };
4968
+ ...event.activity,
4969
+ own_reactions: newOwnReactions,
4970
+ own_bookmarks: currentActivity.own_bookmarks,
4971
+ };
4972
+ };
4973
+ const addReactionToActivities = (event, activities, eventBelongsToCurrentUser) => updateEntityInArray({
4974
+ entities: activities,
4975
+ matcher: (activity) => activity.id === event.activity.id,
4976
+ updater: (matchedActivity) => sharedUpdateActivity$1({
4977
+ currentActivity: matchedActivity,
4978
+ event,
4979
+ eventBelongsToCurrentUser,
4980
+ }),
4981
+ });
4982
+ const addReactionToPinnedActivities = (event, pinnedActivities, eventBelongsToCurrentUser) => updateEntityInArray({
4983
+ entities: pinnedActivities,
4984
+ matcher: (pinnedActivity) => pinnedActivity.activity.id === event.activity.id,
4985
+ updater: (matchedPinnedActivity) => {
4986
+ const newActivity = sharedUpdateActivity$1({
4987
+ currentActivity: matchedPinnedActivity.activity,
4988
+ event,
4989
+ eventBelongsToCurrentUser,
4990
+ });
4991
+ // this should never happen, but just in case
4992
+ if (newActivity === matchedPinnedActivity.activity) {
4993
+ return matchedPinnedActivity;
4994
+ }
4995
+ return {
4996
+ ...matchedPinnedActivity,
4997
+ activity: newActivity,
4998
+ };
4999
+ },
5000
+ });
4758
5001
  function handleActivityReactionAdded(event) {
4759
- const currentActivities = this.currentState.activities;
5002
+ const { activities: currentActivities, pinned_activities: currentPinnedActivities, } = this.currentState;
4760
5003
  const connectedUser = this.client.state.getLatestValue().connected_user;
4761
- const isCurrentUser = Boolean(connectedUser && event.reaction.user.id === connectedUser.id);
4762
- const result = addReactionToActivities(event, currentActivities, isCurrentUser);
4763
- if (result.changed) {
4764
- this.state.partialNext({ activities: result.activities });
4765
- }
4766
- }
4767
-
4768
- const removeReactionFromActivity = (event, activity, isCurrentUser) => {
4769
- // Update own_reactions if the reaction is from the current user
4770
- const ownReactions = isCurrentUser
4771
- ? (activity.own_reactions || []).filter((r) => !(r.type === event.reaction.type &&
4772
- r.user.id === event.reaction.user.id))
4773
- : activity.own_reactions;
4774
- return {
4775
- ...activity,
4776
- own_reactions: ownReactions,
4777
- latest_reactions: event.activity.latest_reactions,
4778
- reaction_groups: event.activity.reaction_groups,
4779
- changed: true,
4780
- };
4781
- };
4782
- const removeReactionFromActivities = (event, activities, isCurrentUser) => {
4783
- if (!activities) {
4784
- return { changed: false, activities: [] };
4785
- }
4786
- const activityIndex = activities.findIndex((a) => a.id === event.activity.id);
4787
- if (activityIndex === -1) {
4788
- return { changed: false, activities };
4789
- }
4790
- const activity = activities[activityIndex];
4791
- const updatedActivity = removeReactionFromActivity(event, activity, isCurrentUser);
4792
- return updateActivityInState(updatedActivity, activities, true);
4793
- };
4794
- function handleActivityReactionDeleted(event) {
4795
- const currentActivities = this.currentState.activities;
4796
- const connectedUser = this.client.state.getLatestValue().connected_user;
4797
- const isCurrentUser = Boolean(connectedUser && event.reaction.user.id === connectedUser.id);
4798
- const result = removeReactionFromActivities(event, currentActivities, isCurrentUser);
4799
- if (result.changed) {
4800
- this.state.partialNext({ activities: result.activities });
4801
- }
4802
- }
4803
-
4804
- const addBookmarkToActivity = (event, activity, isCurrentUser) => {
4805
- // Update own_bookmarks if the bookmark is from the current user
4806
- const ownBookmarks = [...(activity.own_bookmarks || [])];
4807
- if (isCurrentUser) {
4808
- ownBookmarks.push(event.bookmark);
4809
- }
4810
- return {
4811
- ...activity,
4812
- own_bookmarks: ownBookmarks,
4813
- changed: true,
4814
- };
4815
- };
4816
- const addBookmarkToActivities = (event, activities, isCurrentUser) => {
4817
- if (!activities) {
4818
- return { changed: false, activities: [] };
4819
- }
4820
- const activityIndex = activities.findIndex((a) => a.id === event.bookmark.activity.id);
4821
- if (activityIndex === -1) {
4822
- return { changed: false, activities };
4823
- }
4824
- const activity = activities[activityIndex];
4825
- const updatedActivity = addBookmarkToActivity(event, activity, isCurrentUser);
4826
- return updateActivityInState(updatedActivity, activities, true);
4827
- };
4828
- function handleBookmarkAdded(event) {
4829
- const currentActivities = this.currentState.activities;
4830
- const { connected_user: connectedUser } = this.client.state.getLatestValue();
4831
- const isCurrentUser = event.bookmark.user.id === connectedUser?.id;
4832
- const result = addBookmarkToActivities(event, currentActivities, isCurrentUser);
4833
- if (result.changed) {
4834
- this.state.partialNext({ activities: result.activities });
5004
+ const eventBelongsToCurrentUser = typeof connectedUser !== 'undefined' &&
5005
+ event.reaction.user.id === connectedUser.id;
5006
+ const [result1, result2] = [
5007
+ addReactionToActivities(event, currentActivities, eventBelongsToCurrentUser),
5008
+ addReactionToPinnedActivities(event, currentPinnedActivities, eventBelongsToCurrentUser),
5009
+ ];
5010
+ if (result1.changed || result2.changed) {
5011
+ this.state.partialNext({
5012
+ activities: result1.entities,
5013
+ pinned_activities: result2.entities,
5014
+ });
4835
5015
  }
4836
5016
  }
4837
5017
 
4838
- // Helper function to check if two bookmarks are the same
4839
- // A bookmark is identified by activity_id + folder_id + user_id
4840
- const isSameBookmark = (bookmark1, bookmark2) => {
4841
- return (bookmark1.user.id === bookmark2.user.id &&
4842
- bookmark1.activity.id === bookmark2.activity.id &&
4843
- bookmark1.folder?.id === bookmark2.folder?.id);
4844
- };
4845
- const removeBookmarkFromActivities = (event, activities, isCurrentUser) => {
4846
- if (!activities) {
4847
- return { changed: false, activities: [] };
5018
+ const sharedUpdateActivity = ({ currentActivity, event, eventBelongsToCurrentUser, }) => {
5019
+ let newOwnReactions = currentActivity.own_reactions;
5020
+ if (eventBelongsToCurrentUser) {
5021
+ newOwnReactions = currentActivity.own_reactions.filter((reaction) => !(reaction.type === event.reaction.type &&
5022
+ reaction.user.id === event.reaction.user.id));
4848
5023
  }
4849
- const activityIndex = activities.findIndex((a) => a.id === event.bookmark.activity.id);
4850
- if (activityIndex === -1) {
4851
- return { changed: false, activities };
4852
- }
4853
- const activity = activities[activityIndex];
4854
- const updatedActivity = removeBookmarkFromActivity(event, activity, isCurrentUser);
4855
- return updateActivityInState(updatedActivity, activities, true);
4856
- };
4857
- const removeBookmarkFromActivity = (event, activity, isCurrentUser) => {
4858
- // Update own_bookmarks if the bookmark is from the current user
4859
- const ownBookmarks = isCurrentUser
4860
- ? (activity.own_bookmarks || []).filter((bookmark) => !isSameBookmark(bookmark, event.bookmark))
4861
- : activity.own_bookmarks;
4862
5024
  return {
4863
- ...activity,
4864
- own_bookmarks: ownBookmarks,
4865
- changed: true,
4866
- };
4867
- };
4868
- function handleBookmarkDeleted(event) {
4869
- const currentActivities = this.currentState.activities;
4870
- const { connected_user: connectedUser } = this.client.state.getLatestValue();
4871
- const isCurrentUser = event.bookmark.user.id === connectedUser?.id;
4872
- const result = removeBookmarkFromActivities(event, currentActivities, isCurrentUser);
4873
- if (result.changed) {
4874
- this.state.partialNext({ activities: result.activities });
4875
- }
4876
- }
4877
-
4878
- const updateBookmarkInActivity = (event, activity, isCurrentUser) => {
4879
- // Update own_bookmarks if the bookmark is from the current user
4880
- let ownBookmarks = activity.own_bookmarks || [];
4881
- if (isCurrentUser) {
4882
- const bookmarkIndex = ownBookmarks.findIndex((bookmark) => isSameBookmark(bookmark, event.bookmark));
4883
- if (bookmarkIndex !== -1) {
4884
- ownBookmarks = [...ownBookmarks];
4885
- ownBookmarks[bookmarkIndex] = event.bookmark;
5025
+ ...event.activity,
5026
+ own_reactions: newOwnReactions,
5027
+ own_bookmarks: currentActivity.own_bookmarks,
5028
+ };
5029
+ };
5030
+ const removeReactionFromActivities = (event, activities, eventBelongsToCurrentUser) => updateEntityInArray({
5031
+ entities: activities,
5032
+ matcher: (activity) => activity.id === event.activity.id,
5033
+ updater: (matchedActivity) => sharedUpdateActivity({
5034
+ currentActivity: matchedActivity,
5035
+ event,
5036
+ eventBelongsToCurrentUser,
5037
+ }),
5038
+ });
5039
+ const removeReactionFromPinnedActivities = (event, activities, eventBelongsToCurrentUser) => updateEntityInArray({
5040
+ entities: activities,
5041
+ matcher: (pinnedActivity) => pinnedActivity.activity.id === event.activity.id,
5042
+ updater: (matchedPinnedActivity) => {
5043
+ const newActivity = sharedUpdateActivity({
5044
+ currentActivity: matchedPinnedActivity.activity,
5045
+ event,
5046
+ eventBelongsToCurrentUser,
5047
+ });
5048
+ if (newActivity === matchedPinnedActivity.activity) {
5049
+ return matchedPinnedActivity;
4886
5050
  }
4887
- }
4888
- return {
4889
- ...activity,
4890
- own_bookmarks: ownBookmarks,
4891
- changed: true,
4892
- };
4893
- };
4894
- const updateBookmarkInActivities = (event, activities, isCurrentUser) => {
4895
- if (!activities) {
4896
- return { changed: false, activities: [] };
4897
- }
4898
- const activityIndex = activities.findIndex((a) => a.id === event.bookmark.activity.id);
4899
- if (activityIndex === -1) {
4900
- return { changed: false, activities };
4901
- }
4902
- const activity = activities[activityIndex];
4903
- const updatedActivity = updateBookmarkInActivity(event, activity, isCurrentUser);
4904
- return updateActivityInState(updatedActivity, activities, true);
4905
- };
4906
- function handleBookmarkUpdated(event) {
4907
- const currentActivities = this.currentState.activities;
4908
- const { connected_user: connectedUser } = this.client.state.getLatestValue();
4909
- const isCurrentUser = event.bookmark.user.id === connectedUser?.id;
4910
- const result = updateBookmarkInActivities(event, currentActivities, isCurrentUser);
4911
- if (result.changed) {
4912
- this.state.partialNext({ activities: result.activities });
5051
+ return {
5052
+ ...matchedPinnedActivity,
5053
+ activity: newActivity,
5054
+ };
5055
+ },
5056
+ });
5057
+ function handleActivityReactionDeleted(event) {
5058
+ const { activities: currentActivities, pinned_activities: currentPinnedActivities, } = this.currentState;
5059
+ const connectedUser = this.client.state.getLatestValue().connected_user;
5060
+ const eventBelongsToCurrentUser = typeof connectedUser !== 'undefined' &&
5061
+ event.reaction.user.id === connectedUser.id;
5062
+ const [result1, result2] = [
5063
+ removeReactionFromActivities(event, currentActivities, eventBelongsToCurrentUser),
5064
+ removeReactionFromPinnedActivities(event, currentPinnedActivities, eventBelongsToCurrentUser),
5065
+ ];
5066
+ if (result1.changed || result2.changed) {
5067
+ this.state.partialNext({
5068
+ activities: result1.entities,
5069
+ pinned_activities: result2.entities,
5070
+ });
4913
5071
  }
4914
5072
  }
4915
5073