@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.
Files changed (92) hide show
  1. package/@react-bindings/hooks/feed-state-hooks/index.ts +4 -0
  2. package/CHANGELOG.md +16 -0
  3. package/dist/@react-bindings/contexts/StreamSearchContext.d.ts +1 -1
  4. package/dist/@react-bindings/contexts/StreamSearchResultsContext.d.ts +1 -1
  5. package/dist/@react-bindings/hooks/feed-state-hooks/index.d.ts +4 -0
  6. package/dist/@react-bindings/hooks/feed-state-hooks/useAggregatedActivities.d.ts +11 -0
  7. package/dist/@react-bindings/hooks/feed-state-hooks/useIsAggregatedActivityRead.d.ts +6 -0
  8. package/dist/@react-bindings/hooks/feed-state-hooks/useIsAggregatedActivitySeen.d.ts +6 -0
  9. package/dist/@react-bindings/hooks/feed-state-hooks/useNotificationStatus.d.ts +13 -0
  10. package/dist/@react-bindings/hooks/search-state-hooks/useSearchQuery.d.ts +1 -1
  11. package/dist/@react-bindings/hooks/search-state-hooks/useSearchResult.d.ts +1 -1
  12. package/dist/@react-bindings/hooks/search-state-hooks/useSearchSources.d.ts +2 -2
  13. package/dist/@react-bindings/wrappers/StreamFeed.d.ts +1 -1
  14. package/dist/@react-bindings/wrappers/StreamSearch.d.ts +1 -1
  15. package/dist/@react-bindings/wrappers/StreamSearchResults.d.ts +1 -1
  16. package/dist/index-react-bindings.browser.cjs +178 -35
  17. package/dist/index-react-bindings.browser.cjs.map +1 -1
  18. package/dist/index-react-bindings.browser.js +175 -36
  19. package/dist/index-react-bindings.browser.js.map +1 -1
  20. package/dist/index-react-bindings.node.cjs +178 -35
  21. package/dist/index-react-bindings.node.cjs.map +1 -1
  22. package/dist/index-react-bindings.node.js +175 -36
  23. package/dist/index-react-bindings.node.js.map +1 -1
  24. package/dist/index.browser.cjs +328 -180
  25. package/dist/index.browser.cjs.map +1 -1
  26. package/dist/index.browser.js +328 -181
  27. package/dist/index.browser.js.map +1 -1
  28. package/dist/index.d.ts +1 -5
  29. package/dist/index.node.cjs +328 -180
  30. package/dist/index.node.cjs.map +1 -1
  31. package/dist/index.node.js +328 -181
  32. package/dist/index.node.js.map +1 -1
  33. package/dist/src/common/{ActivitySearchSource.d.ts → search/ActivitySearchSource.d.ts} +3 -3
  34. package/dist/src/common/{BaseSearchSource.d.ts → search/BaseSearchSource.d.ts} +41 -35
  35. package/dist/src/common/{FeedSearchSource.d.ts → search/FeedSearchSource.d.ts} +3 -3
  36. package/dist/src/common/{SearchController.d.ts → search/SearchController.d.ts} +1 -3
  37. package/dist/src/common/{UserSearchSource.d.ts → search/UserSearchSource.d.ts} +4 -4
  38. package/dist/src/common/search/index.d.ts +6 -0
  39. package/dist/src/common/search/types.d.ts +22 -0
  40. package/dist/src/common/types.d.ts +1 -0
  41. package/dist/src/feed/event-handlers/activity/handle-activity-deleted.d.ts +5 -12
  42. package/dist/src/feed/event-handlers/activity/handle-activity-marked.d.ts +11 -0
  43. package/dist/src/feed/event-handlers/activity/index.d.ts +1 -0
  44. package/dist/src/feed/event-handlers/notification-feed/handle-notification-feed-updated.d.ts +8 -1
  45. package/dist/src/feed/feed.d.ts +2 -2
  46. package/dist/src/gen/models/index.d.ts +58 -26
  47. package/dist/tsconfig.tsbuildinfo +1 -1
  48. package/index.ts +1 -5
  49. package/package.json +1 -1
  50. package/src/common/{ActivitySearchSource.ts → search/ActivitySearchSource.ts} +3 -3
  51. package/src/common/{BaseSearchSource.ts → search/BaseSearchSource.ts} +137 -69
  52. package/src/common/{FeedSearchSource.ts → search/FeedSearchSource.ts} +3 -3
  53. package/src/common/{SearchController.ts → search/SearchController.ts} +2 -7
  54. package/src/common/{UserSearchSource.ts → search/UserSearchSource.ts} +3 -3
  55. package/src/common/search/index.ts +6 -0
  56. package/src/common/search/types.ts +21 -0
  57. package/src/common/types.ts +2 -0
  58. package/src/feed/event-handlers/activity/activity-marked-utils.test.ts +208 -0
  59. package/src/feed/event-handlers/activity/activity-utils.test.ts +2 -2
  60. package/src/feed/event-handlers/activity/handle-activity-added.test.ts +86 -0
  61. package/src/feed/event-handlers/activity/handle-activity-deleted.test.ts +117 -0
  62. package/src/feed/event-handlers/activity/handle-activity-deleted.ts +8 -4
  63. package/src/feed/event-handlers/activity/handle-activity-marked.ts +68 -0
  64. package/src/feed/event-handlers/activity/handle-activity-reaction-added.test.ts +15 -15
  65. package/src/feed/event-handlers/activity/handle-activity-reaction-deleted.test.ts +14 -14
  66. package/src/feed/event-handlers/activity/handle-activity-unpinned.test.ts +4 -3
  67. package/src/feed/event-handlers/activity/handle-activity-updated.test.ts +4 -4
  68. package/src/feed/event-handlers/activity/index.ts +2 -1
  69. package/src/feed/event-handlers/bookmark/handle-bookmark-added.test.ts +14 -14
  70. package/src/feed/event-handlers/bookmark/handle-bookmark-deleted.test.ts +14 -14
  71. package/src/feed/event-handlers/bookmark/handle-bookmark-updated.test.ts +16 -16
  72. package/src/feed/event-handlers/comment/handle-comment-added.test.ts +147 -0
  73. package/src/feed/event-handlers/comment/handle-comment-deleted.test.ts +133 -0
  74. package/src/feed/event-handlers/comment/handle-comment-deleted.ts +24 -10
  75. package/src/feed/event-handlers/comment/handle-comment-reaction.test.ts +315 -0
  76. package/src/feed/event-handlers/comment/handle-comment-updated.test.ts +131 -0
  77. package/src/feed/event-handlers/feed-member/handle-feed-member-added.test.ts +75 -0
  78. package/src/feed/event-handlers/feed-member/handle-feed-member-removed.test.ts +82 -0
  79. package/src/feed/event-handlers/feed-member/handle-feed-member-removed.ts +19 -9
  80. package/src/feed/event-handlers/feed-member/handle-feed-member-updated.test.ts +84 -0
  81. package/src/feed/event-handlers/follow/handle-follow-created.test.ts +7 -7
  82. package/src/feed/event-handlers/follow/handle-follow-deleted.test.ts +2 -2
  83. package/src/feed/event-handlers/follow/handle-follow-updated.test.ts +1 -1
  84. package/src/feed/event-handlers/notification-feed/handle-notification-feed-updated.test.ts +120 -0
  85. package/src/feed/event-handlers/notification-feed/handle-notification-feed-updated.ts +47 -3
  86. package/src/feed/feed.ts +4 -2
  87. package/src/gen/feeds/FeedsApi.ts +6 -0
  88. package/src/gen/model-decoders/decoders.ts +12 -0
  89. package/src/gen/models/index.ts +90 -34
  90. package/src/test-utils/response-generators.ts +230 -0
  91. package/dist/src/test-utils/index.d.ts +0 -1
  92. package/dist/src/test-utils/response-generators.d.ts +0 -54
@@ -686,6 +686,7 @@ decoders.Command = (input) => {
686
686
  decoders.CommentAddedEvent = (input) => {
687
687
  const typeMappings = {
688
688
  created_at: { type: 'DatetimeType', isSingle: true },
689
+ activity: { type: 'ActivityResponse', isSingle: true },
689
690
  comment: { type: 'CommentResponse', isSingle: true },
690
691
  received_at: { type: 'DatetimeType', isSingle: true },
691
692
  };
@@ -702,6 +703,7 @@ decoders.CommentDeletedEvent = (input) => {
702
703
  decoders.CommentReactionAddedEvent = (input) => {
703
704
  const typeMappings = {
704
705
  created_at: { type: 'DatetimeType', isSingle: true },
706
+ activity: { type: 'ActivityResponse', isSingle: true },
705
707
  comment: { type: 'CommentResponse', isSingle: true },
706
708
  reaction: { type: 'FeedsReactionResponse', isSingle: true },
707
709
  received_at: { type: 'DatetimeType', isSingle: true },
@@ -720,6 +722,7 @@ decoders.CommentReactionDeletedEvent = (input) => {
720
722
  decoders.CommentReactionUpdatedEvent = (input) => {
721
723
  const typeMappings = {
722
724
  created_at: { type: 'DatetimeType', isSingle: true },
725
+ activity: { type: 'ActivityResponse', isSingle: true },
723
726
  comment: { type: 'CommentResponse', isSingle: true },
724
727
  reaction: { type: 'FeedsReactionResponse', isSingle: true },
725
728
  received_at: { type: 'DatetimeType', isSingle: true },
@@ -1082,6 +1085,7 @@ decoders.Message = (input) => {
1082
1085
  pin_expires: { type: 'DatetimeType', isSingle: true },
1083
1086
  pinned_at: { type: 'DatetimeType', isSingle: true },
1084
1087
  thread_participants: { type: 'User', isSingle: false },
1088
+ member: { type: 'ChannelMember', isSingle: true },
1085
1089
  pinned_by: { type: 'User', isSingle: true },
1086
1090
  poll: { type: 'Poll', isSingle: true },
1087
1091
  quoted_message: { type: 'Message', isSingle: true },
@@ -1135,6 +1139,8 @@ decoders.ModerationCustomActionEvent = (input) => {
1135
1139
  };
1136
1140
  decoders.ModerationFlagResponse = (input) => {
1137
1141
  const typeMappings = {
1142
+ created_at: { type: 'DatetimeType', isSingle: true },
1143
+ updated_at: { type: 'DatetimeType', isSingle: true },
1138
1144
  review_queue_item: { type: 'ReviewQueueItemResponse', isSingle: true },
1139
1145
  user: { type: 'UserResponse', isSingle: true },
1140
1146
  };
@@ -1901,6 +1907,7 @@ class FeedsApi {
1901
1907
  const body = {
1902
1908
  type: request?.type,
1903
1909
  create_notification_activity: request?.create_notification_activity,
1910
+ skip_push: request?.skip_push,
1904
1911
  custom: request?.custom,
1905
1912
  };
1906
1913
  const response = await this.apiClient.sendRequest('POST', '/api/v2/feeds/activities/{activity_id}/reactions', pathParams, undefined, body, 'application/json');
@@ -2047,6 +2054,7 @@ class FeedsApi {
2047
2054
  object_type: request?.object_type,
2048
2055
  create_notification_activity: request?.create_notification_activity,
2049
2056
  parent_id: request?.parent_id,
2057
+ skip_push: request?.skip_push,
2050
2058
  attachments: request?.attachments,
2051
2059
  mentioned_user_ids: request?.mentioned_user_ids,
2052
2060
  custom: request?.custom,
@@ -2100,6 +2108,7 @@ class FeedsApi {
2100
2108
  };
2101
2109
  const body = {
2102
2110
  comment: request?.comment,
2111
+ skip_push: request?.skip_push,
2103
2112
  custom: request?.custom,
2104
2113
  };
2105
2114
  const response = await this.apiClient.sendRequest('PATCH', '/api/v2/feeds/comments/{id}', pathParams, undefined, body, 'application/json');
@@ -2113,6 +2122,7 @@ class FeedsApi {
2113
2122
  const body = {
2114
2123
  type: request?.type,
2115
2124
  create_notification_activity: request?.create_notification_activity,
2125
+ skip_push: request?.skip_push,
2116
2126
  custom: request?.custom,
2117
2127
  };
2118
2128
  const response = await this.apiClient.sendRequest('POST', '/api/v2/feeds/comments/{id}/reactions', pathParams, undefined, body, 'application/json');
@@ -2353,6 +2363,7 @@ class FeedsApi {
2353
2363
  create_notification_activity: request?.create_notification_activity,
2354
2364
  follower_role: request?.follower_role,
2355
2365
  push_preference: request?.push_preference,
2366
+ skip_push: request?.skip_push,
2356
2367
  custom: request?.custom,
2357
2368
  };
2358
2369
  const response = await this.apiClient.sendRequest('PATCH', '/api/v2/feeds/follows', undefined, undefined, body, 'application/json');
@@ -2365,6 +2376,7 @@ class FeedsApi {
2365
2376
  target: request?.target,
2366
2377
  create_notification_activity: request?.create_notification_activity,
2367
2378
  push_preference: request?.push_preference,
2379
+ skip_push: request?.skip_push,
2368
2380
  custom: request?.custom,
2369
2381
  };
2370
2382
  const response = await this.apiClient.sendRequest('POST', '/api/v2/feeds/follows', undefined, undefined, body, 'application/json');
@@ -4503,20 +4515,29 @@ function handleCommentAdded(event) {
4503
4515
  function handleCommentDeleted({ comment }) {
4504
4516
  const entityId = comment.parent_id ?? comment.object_id;
4505
4517
  this.state.next((currentState) => {
4506
- const newCommentsByEntityId = {
4507
- ...currentState.comments_by_entity_id,
4508
- [entityId]: {
4509
- ...currentState.comments_by_entity_id[entityId],
4510
- },
4511
- };
4518
+ let newCommentsByEntityId;
4512
4519
  const index = this.getCommentIndex(comment, currentState);
4513
- if (newCommentsByEntityId?.[entityId]?.comments?.length && index !== -1) {
4520
+ if (index !== -1) {
4521
+ newCommentsByEntityId ?? (newCommentsByEntityId = {
4522
+ ...currentState.comments_by_entity_id,
4523
+ [entityId]: {
4524
+ ...currentState.comments_by_entity_id[entityId],
4525
+ },
4526
+ });
4514
4527
  newCommentsByEntityId[entityId].comments = [
4515
4528
  ...newCommentsByEntityId[entityId].comments,
4516
4529
  ];
4517
4530
  newCommentsByEntityId[entityId]?.comments?.splice(index, 1);
4518
4531
  }
4519
- delete newCommentsByEntityId[comment.id];
4532
+ if (typeof currentState.comments_by_entity_id[comment.id] !== 'undefined') {
4533
+ newCommentsByEntityId ?? (newCommentsByEntityId = {
4534
+ ...currentState.comments_by_entity_id,
4535
+ });
4536
+ delete newCommentsByEntityId[comment.id];
4537
+ }
4538
+ if (!newCommentsByEntityId) {
4539
+ return currentState;
4540
+ }
4520
4541
  return {
4521
4542
  ...currentState,
4522
4543
  comments_by_entity_id: newCommentsByEntityId,
@@ -4637,14 +4658,20 @@ function handleFeedMemberUpdated(event) {
4637
4658
  function handleFeedMemberRemoved(event) {
4638
4659
  const { connected_user: connectedUser } = this.client.state.getLatestValue();
4639
4660
  this.state.next((currentState) => {
4640
- const newState = {
4641
- ...currentState,
4642
- members: currentState.members?.filter((member) => member.user.id !== event.user?.id),
4643
- };
4644
- if (connectedUser?.id === event.member_id) {
4661
+ let newState;
4662
+ if (typeof currentState.members !== 'undefined') {
4663
+ const filtered = currentState.members.filter((member) => member.user.id !== event.member_id);
4664
+ if (filtered.length !== currentState.members.length) {
4665
+ newState ?? (newState = { ...currentState });
4666
+ newState.members = filtered;
4667
+ }
4668
+ }
4669
+ if (connectedUser?.id === event.member_id &&
4670
+ typeof currentState.own_membership !== 'undefined') {
4671
+ newState ?? (newState = { ...currentState });
4645
4672
  delete newState.own_membership;
4646
4673
  }
4647
- return newState;
4674
+ return newState ?? currentState;
4648
4675
  });
4649
4676
  }
4650
4677
 
@@ -4881,7 +4908,7 @@ const removePinnedActivityFromState = (activityResponse, pinnedActivities) => {
4881
4908
  if (index !== -1) {
4882
4909
  const newActivities = [...pinnedActivities];
4883
4910
  newActivities.splice(index, 1);
4884
- return { changed: true, activities: newActivities };
4911
+ return { changed: true, pinned_activities: newActivities };
4885
4912
  }
4886
4913
  else {
4887
4914
  return { changed: false, pinned_activities: pinnedActivities };
@@ -5071,13 +5098,80 @@ function handleActivityReactionDeleted(event) {
5071
5098
  }
5072
5099
  }
5073
5100
 
5101
+ const updateNotificationStatusFromActivityMarked = (event, currentNotificationStatus, aggregatedActivities = []) => {
5102
+ if (!currentNotificationStatus) {
5103
+ return {
5104
+ changed: false,
5105
+ };
5106
+ }
5107
+ const newState = {
5108
+ ...currentNotificationStatus,
5109
+ };
5110
+ if (event.mark_all_read) {
5111
+ const allGroupIds = aggregatedActivities.map((activity) => activity.group);
5112
+ newState.read_activities = [
5113
+ ...new Set([
5114
+ ...(currentNotificationStatus.read_activities ?? []),
5115
+ ...allGroupIds,
5116
+ ]),
5117
+ ];
5118
+ }
5119
+ if (event.mark_read && event.mark_read.length > 0) {
5120
+ newState.read_activities = [
5121
+ ...new Set([
5122
+ ...(currentNotificationStatus?.read_activities ?? []),
5123
+ ...event.mark_read,
5124
+ ]),
5125
+ ];
5126
+ }
5127
+ if (event.mark_all_seen) {
5128
+ newState.last_seen_at = new Date();
5129
+ }
5130
+ return {
5131
+ changed: true,
5132
+ data: { notification_status: newState },
5133
+ };
5134
+ };
5135
+ function handleActivityMarked(event) {
5136
+ const result = updateNotificationStatusFromActivityMarked(event, this.currentState.notification_status, this.currentState.aggregated_activities);
5137
+ if (result.changed) {
5138
+ this.state.partialNext({
5139
+ notification_status: result.data?.notification_status,
5140
+ });
5141
+ }
5142
+ }
5143
+
5074
5144
  function handleFeedUpdated(event) {
5075
5145
  this.state.partialNext({ ...event.feed });
5076
5146
  }
5077
5147
 
5148
+ const updateNotificationFeedFromEvent = (event) => {
5149
+ const updates = {};
5150
+ if (event.notification_status) {
5151
+ updates.notification_status = event.notification_status;
5152
+ }
5153
+ if (event.aggregated_activities) {
5154
+ updates.aggregated_activities = event.aggregated_activities;
5155
+ }
5156
+ // Only return changed if we have actual updates
5157
+ if (Object.keys(updates).length > 0) {
5158
+ return {
5159
+ changed: true,
5160
+ data: updates,
5161
+ };
5162
+ }
5163
+ return {
5164
+ changed: false,
5165
+ };
5166
+ };
5078
5167
  function handleNotificationFeedUpdated(event) {
5079
- console.info('notification feed updated', event);
5080
- // TODO: handle notification feed updates
5168
+ const result = updateNotificationFeedFromEvent(event);
5169
+ if (result.changed) {
5170
+ this.state.partialNext({
5171
+ notification_status: result.data?.notification_status,
5172
+ aggregated_activities: result.data?.aggregated_activities,
5173
+ });
5174
+ }
5081
5175
  }
5082
5176
 
5083
5177
  function handleWatchStarted() {
@@ -5132,7 +5226,7 @@ class Feed extends FeedApi {
5132
5226
  'feeds.poll.vote_removed': Feed.noop,
5133
5227
  'feeds.activity.pinned': Feed.noop,
5134
5228
  'feeds.activity.unpinned': Feed.noop,
5135
- 'feeds.activity.marked': Feed.noop,
5229
+ 'feeds.activity.marked': handleActivityMarked.bind(this),
5136
5230
  'moderation.custom_action': Feed.noop,
5137
5231
  'moderation.flagged': Feed.noop,
5138
5232
  'moderation.mark_reviewed': Feed.noop,
@@ -6004,10 +6098,10 @@ const useFeedsClient = () => {
6004
6098
  */
6005
6099
  const useClientConnectedUser = () => {
6006
6100
  const client = useFeedsClient();
6007
- const { user } = useStateStore(client?.state, selector$a) ?? {};
6101
+ const { user } = useStateStore(client?.state, selector$c) ?? {};
6008
6102
  return user;
6009
6103
  };
6010
- const selector$a = (nextState) => ({
6104
+ const selector$c = (nextState) => ({
6011
6105
  user: nextState.connected_user,
6012
6106
  });
6013
6107
 
@@ -6016,10 +6110,10 @@ const selector$a = (nextState) => ({
6016
6110
  */
6017
6111
  const useWsConnectionState = () => {
6018
6112
  const client = useFeedsClient();
6019
- const { is_healthy } = useStateStore(client?.state, selector$9) ?? {};
6113
+ const { is_healthy } = useStateStore(client?.state, selector$b) ?? {};
6020
6114
  return { is_healthy };
6021
6115
  };
6022
- const selector$9 = (nextState) => ({
6116
+ const selector$b = (nextState) => ({
6023
6117
  is_healthy: nextState.is_ws_connection_healthy,
6024
6118
  });
6025
6119
 
@@ -6069,7 +6163,7 @@ const useStableCallback = (callback) => {
6069
6163
  const useFeedActivities = (feedFromProps) => {
6070
6164
  const feedFromContext = useFeedContext();
6071
6165
  const feed = feedFromProps ?? feedFromContext;
6072
- const data = useStateStore(feed?.state, selector$8);
6166
+ const data = useStateStore(feed?.state, selector$a);
6073
6167
  const loadNextPage = useStableCallback(async () => {
6074
6168
  if (!feed || !data?.has_next_page || data?.is_loading) {
6075
6169
  return;
@@ -6078,7 +6172,7 @@ const useFeedActivities = (feedFromProps) => {
6078
6172
  });
6079
6173
  return useMemo(() => ({ ...data, loadNextPage }), [data, loadNextPage]);
6080
6174
  };
6081
- const selector$8 = ({ is_loading_activities, next, activities = [] }) => ({
6175
+ const selector$a = ({ is_loading_activities, next, activities = [] }) => ({
6082
6176
  is_loading: is_loading_activities,
6083
6177
  has_next_page: typeof next !== 'undefined',
6084
6178
  activities,
@@ -6151,13 +6245,13 @@ const FeedOwnCapability = {
6151
6245
  };
6152
6246
 
6153
6247
  const stableEmptyArray = [];
6154
- const selector$7 = (currentState) => ({
6248
+ const selector$9 = (currentState) => ({
6155
6249
  oc: currentState.own_capabilities ?? stableEmptyArray,
6156
6250
  });
6157
6251
  const useOwnCapabilities = (feedFromProps) => {
6158
6252
  const feedFromContext = useFeedContext();
6159
6253
  const feed = feedFromProps ?? feedFromContext;
6160
- const { oc = stableEmptyArray } = useStateStore(feed?.state, selector$7) ?? {};
6254
+ const { oc = stableEmptyArray } = useStateStore(feed?.state, selector$9) ?? {};
6161
6255
  return useMemo(() => ({
6162
6256
  can_add_activity: oc.indexOf(FeedOwnCapability.ADD_ACTIVITY) > -1,
6163
6257
  can_add_activity_reaction: oc.indexOf(FeedOwnCapability.ADD_ACTIVITY_REACTION) > -1,
@@ -6192,7 +6286,7 @@ const useOwnCapabilities = (feedFromProps) => {
6192
6286
  }), [oc]);
6193
6287
  };
6194
6288
 
6195
- const selector$6 = ({ follower_count, followers, followers_pagination, }) => ({
6289
+ const selector$8 = ({ follower_count, followers, followers_pagination, }) => ({
6196
6290
  follower_count,
6197
6291
  followers,
6198
6292
  followers_pagination,
@@ -6200,7 +6294,7 @@ const selector$6 = ({ follower_count, followers, followers_pagination, }) => ({
6200
6294
  function useFollowers(feedFromProps) {
6201
6295
  const feedFromContext = useFeedContext();
6202
6296
  const feed = feedFromProps ?? feedFromContext;
6203
- const data = useStateStore(feed?.state, selector$6);
6297
+ const data = useStateStore(feed?.state, selector$8);
6204
6298
  const loadNextPage = useCallback((...options) => feed?.loadNextPageFollowers(...options), [feed]);
6205
6299
  return useMemo(() => {
6206
6300
  if (!data) {
@@ -6215,7 +6309,7 @@ function useFollowers(feedFromProps) {
6215
6309
  }, [data, loadNextPage]);
6216
6310
  }
6217
6311
 
6218
- const selector$5 = ({ following_count, following, following_pagination, }) => ({
6312
+ const selector$7 = ({ following_count, following, following_pagination, }) => ({
6219
6313
  following_count,
6220
6314
  following,
6221
6315
  following_pagination,
@@ -6223,7 +6317,7 @@ const selector$5 = ({ following_count, following, following_pagination, }) => ({
6223
6317
  function useFollowing(feedFromProps) {
6224
6318
  const feedFromContext = useFeedContext();
6225
6319
  const feed = feedFromProps ?? feedFromContext;
6226
- const data = useStateStore(feed?.state, selector$5);
6320
+ const data = useStateStore(feed?.state, selector$7);
6227
6321
  const loadNextPage = useCallback((...options) => feed?.loadNextPageFollowing(...options), [feed]);
6228
6322
  return useMemo(() => {
6229
6323
  if (!data) {
@@ -6245,9 +6339,9 @@ function useFollowing(feedFromProps) {
6245
6339
  const useFeedMetadata = (feedFromProps) => {
6246
6340
  const feedFromContext = useFeedContext();
6247
6341
  const feed = feedFromProps ?? feedFromContext;
6248
- return useStateStore(feed?.state, selector$4);
6342
+ return useStateStore(feed?.state, selector$6);
6249
6343
  };
6250
- const selector$4 = ({ follower_count = 0, following_count = 0, created_by, created_at, updated_at, }) => ({
6344
+ const selector$6 = ({ follower_count = 0, following_count = 0, created_by, created_at, updated_at, }) => ({
6251
6345
  created_by,
6252
6346
  follower_count,
6253
6347
  following_count,
@@ -6262,12 +6356,57 @@ const selector$4 = ({ follower_count = 0, following_count = 0, created_by, creat
6262
6356
  const useOwnFollows = (feedFromProps) => {
6263
6357
  const feedFromContext = useFeedContext();
6264
6358
  const feed = feedFromProps ?? feedFromContext;
6265
- return useStateStore(feed?.state, selector$3);
6359
+ return useStateStore(feed?.state, selector$5);
6266
6360
  };
6267
- const selector$3 = ({ own_follows }) => ({
6361
+ const selector$5 = ({ own_follows }) => ({
6268
6362
  own_follows,
6269
6363
  });
6270
6364
 
6365
+ const selector$4 = ({ notification_status }) => ({
6366
+ unread: notification_status?.unread ?? 0,
6367
+ unseen: notification_status?.unseen ?? 0,
6368
+ last_read_at: notification_status?.last_read_at,
6369
+ last_seen_at: notification_status?.last_seen_at,
6370
+ read_activities: notification_status?.read_activities,
6371
+ seen_activities: notification_status?.seen_activities,
6372
+ });
6373
+ function useNotificationStatus(feedFromProps) {
6374
+ const feedFromContext = useFeedContext();
6375
+ const feed = feedFromProps ?? feedFromContext;
6376
+ return useStateStore(feed?.state, selector$4);
6377
+ }
6378
+
6379
+ const selector$3 = ({ aggregated_activities }) => ({
6380
+ aggregated_activities,
6381
+ });
6382
+ function useAggregatedActivities(feedFromProps) {
6383
+ const feedFromContext = useFeedContext();
6384
+ const feed = feedFromProps ?? feedFromContext;
6385
+ return useStateStore(feed?.state, selector$3);
6386
+ }
6387
+
6388
+ const useIsAggregatedActivityRead = ({ feed: feedFromProps, aggregatedActivity, }) => {
6389
+ const feedFromContext = useFeedContext();
6390
+ const feed = feedFromProps ?? feedFromContext;
6391
+ const { read_activities: readActivities, /* last_read_at: lastReadAt */ } = useNotificationStatus(feed) ?? {};
6392
+ const group = aggregatedActivity.group;
6393
+ return useMemo(() =>
6394
+ // FIXME: This part of the condition does not work as marking individual groups as read also updates the last_read_at. Should be uncommented once it's fixed on the backend.
6395
+ // (lastReadAt &&
6396
+ // aggregatedActivity.updated_at.getTime() <= lastReadAt.getTime()) ||
6397
+ (readActivities ?? []).includes(group), [readActivities, group]);
6398
+ };
6399
+
6400
+ const useIsAggregatedActivitySeen = ({ feed: feedFromProps, aggregatedActivity, }) => {
6401
+ const feedFromContext = useFeedContext();
6402
+ const feed = feedFromProps ?? feedFromContext;
6403
+ const { seen_activities: seenActivities, last_seen_at: lastSeenAt } = useNotificationStatus(feed) ?? {};
6404
+ const group = aggregatedActivity.group;
6405
+ return useMemo(() => (lastSeenAt &&
6406
+ aggregatedActivity.updated_at.getTime() < lastSeenAt.getTime()) ||
6407
+ (seenActivities ?? []).includes(group), [lastSeenAt, aggregatedActivity.updated_at, seenActivities, group]);
6408
+ };
6409
+
6271
6410
  const StreamSearchResultsContext = createContext(undefined);
6272
6411
  /**
6273
6412
  * Hook to access the nearest SearchSource instance.
@@ -6384,7 +6523,7 @@ const StreamFeeds = ({ client, children }) => {
6384
6523
  };
6385
6524
  StreamFeeds.displayName = 'StreamFeeds';
6386
6525
 
6387
- const StreamFeed = ({ feed, children }) => {
6526
+ const StreamFeed = ({ feed, children, }) => {
6388
6527
  return (jsx(StreamFeedContext.Provider, { value: feed, children: children }));
6389
6528
  };
6390
6529
  StreamFeed.displayName = 'StreamFeed';
@@ -6399,5 +6538,5 @@ const StreamSearchResults = ({ source, children, }) => {
6399
6538
  };
6400
6539
  StreamSearchResults.displayName = 'StreamSearchResults';
6401
6540
 
6402
- export { StreamFeed, StreamFeedContext, StreamFeeds, StreamFeedsContext, StreamSearch, StreamSearchContext, StreamSearchResults, StreamSearchResultsContext, useBookmarkActions, useClientConnectedUser, useComments, useCreateFeedsClient, useFeedActivities, useFeedContext, useFeedMetadata, useFeedsClient, useFollowers, useFollowing, useOwnCapabilities, useOwnFollows, useReactionActions, useSearchContext, useSearchQuery, useSearchResult, useSearchResultsContext, useSearchSources, useStateStore, useWsConnectionState };
6541
+ export { StreamFeed, StreamFeedContext, StreamFeeds, StreamFeedsContext, StreamSearch, StreamSearchContext, StreamSearchResults, StreamSearchResultsContext, useAggregatedActivities, useBookmarkActions, useClientConnectedUser, useComments, useCreateFeedsClient, useFeedActivities, useFeedContext, useFeedMetadata, useFeedsClient, useFollowers, useFollowing, useIsAggregatedActivityRead, useIsAggregatedActivitySeen, useNotificationStatus, useOwnCapabilities, useOwnFollows, useReactionActions, useSearchContext, useSearchQuery, useSearchResult, useSearchResultsContext, useSearchSources, useStateStore, useWsConnectionState };
6403
6542
  //# sourceMappingURL=index-react-bindings.browser.js.map