@amityco/ts-sdk-react-native 7.22.1-c05e1197.0 → 7.23.0

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 (240) hide show
  1. package/dist/@types/core/errors.d.ts +3 -1
  2. package/dist/@types/core/errors.d.ts.map +1 -1
  3. package/dist/@types/core/events.d.ts +7 -1
  4. package/dist/@types/core/events.d.ts.map +1 -1
  5. package/dist/@types/core/model.d.ts +4 -0
  6. package/dist/@types/core/model.d.ts.map +1 -1
  7. package/dist/@types/core/payload.d.ts +15 -0
  8. package/dist/@types/core/payload.d.ts.map +1 -1
  9. package/dist/@types/core/transport.d.ts +1 -0
  10. package/dist/@types/core/transport.d.ts.map +1 -1
  11. package/dist/@types/domains/analytics.d.ts +3 -2
  12. package/dist/@types/domains/analytics.d.ts.map +1 -1
  13. package/dist/@types/domains/block.d.ts +5 -0
  14. package/dist/@types/domains/block.d.ts.map +1 -1
  15. package/dist/@types/domains/channel.d.ts +31 -0
  16. package/dist/@types/domains/channel.d.ts.map +1 -1
  17. package/dist/@types/domains/client.d.ts +31 -2
  18. package/dist/@types/domains/client.d.ts.map +1 -1
  19. package/dist/@types/domains/comment.d.ts +1 -0
  20. package/dist/@types/domains/comment.d.ts.map +1 -1
  21. package/dist/@types/domains/feed.d.ts +14 -0
  22. package/dist/@types/domains/feed.d.ts.map +1 -1
  23. package/dist/@types/domains/message.d.ts +16 -0
  24. package/dist/@types/domains/message.d.ts.map +1 -1
  25. package/dist/@types/domains/notificationSettings.d.ts +101 -0
  26. package/dist/@types/domains/notificationSettings.d.ts.map +1 -0
  27. package/dist/@types/domains/post.d.ts +2 -0
  28. package/dist/@types/domains/post.d.ts.map +1 -1
  29. package/dist/@types/domains/sharableContentType.d.ts +9 -0
  30. package/dist/@types/domains/sharableContentType.d.ts.map +1 -0
  31. package/dist/@types/index.d.ts +3 -1
  32. package/dist/@types/index.d.ts.map +1 -1
  33. package/dist/analytic/service/analytic/AnalyticsEngine.d.ts +1 -0
  34. package/dist/analytic/service/analytic/AnalyticsEngine.d.ts.map +1 -1
  35. package/dist/analytic/service/analytic/AnalyticsEventCapturer.d.ts +2 -1
  36. package/dist/analytic/service/analytic/AnalyticsEventCapturer.d.ts.map +1 -1
  37. package/dist/analytic/service/analytic/AnalyticsService.d.ts +1 -0
  38. package/dist/analytic/service/analytic/AnalyticsService.d.ts.map +1 -1
  39. package/dist/channelRepository/api/archiveChannel.d.ts +16 -0
  40. package/dist/channelRepository/api/archiveChannel.d.ts.map +1 -0
  41. package/dist/channelRepository/api/getArchivedChannelIds.d.ts +13 -0
  42. package/dist/channelRepository/api/getArchivedChannelIds.d.ts.map +1 -0
  43. package/dist/channelRepository/api/index.d.ts +3 -0
  44. package/dist/channelRepository/api/index.d.ts.map +1 -1
  45. package/dist/channelRepository/api/unarchiveChannel.d.ts +16 -0
  46. package/dist/channelRepository/api/unarchiveChannel.d.ts.map +1 -0
  47. package/dist/channelRepository/api/updateChannel.d.ts +1 -1
  48. package/dist/channelRepository/api/updateChannel.d.ts.map +1 -1
  49. package/dist/channelRepository/channelMembership/observers/getMembers/ChannelMemberQueryStreamController.d.ts.map +1 -1
  50. package/dist/channelRepository/channelModeration/api/banMembers.d.ts.map +1 -1
  51. package/dist/channelRepository/channelModeration/api/muteMembers.d.ts.map +1 -1
  52. package/dist/channelRepository/channelModeration/api/unbanMembers.d.ts.map +1 -1
  53. package/dist/channelRepository/channelModeration/api/unmuteMembers.d.ts.map +1 -1
  54. package/dist/channelRepository/events/index.d.ts +2 -0
  55. package/dist/channelRepository/events/index.d.ts.map +1 -1
  56. package/dist/channelRepository/events/onChannelArchived.d.ts +10 -0
  57. package/dist/channelRepository/events/onChannelArchived.d.ts.map +1 -0
  58. package/dist/channelRepository/events/onChannelMemberRoleRemoved.d.ts.map +1 -1
  59. package/dist/channelRepository/events/onChannelUnarchived.d.ts +11 -0
  60. package/dist/channelRepository/events/onChannelUnarchived.d.ts.map +1 -0
  61. package/dist/channelRepository/observers/getArchivedChannels/ArchivedChannelLiveCollectionController.d.ts +12 -0
  62. package/dist/channelRepository/observers/getArchivedChannels/ArchivedChannelLiveCollectionController.d.ts.map +1 -0
  63. package/dist/channelRepository/observers/getArchivedChannels/ArchivedChannelPaginationController.d.ts +11 -0
  64. package/dist/channelRepository/observers/getArchivedChannels/ArchivedChannelPaginationController.d.ts.map +1 -0
  65. package/dist/channelRepository/observers/getArchivedChannels/ArchivedChannelQueryStreamController.d.ts +13 -0
  66. package/dist/channelRepository/observers/getArchivedChannels/ArchivedChannelQueryStreamController.d.ts.map +1 -0
  67. package/dist/channelRepository/observers/getArchivedChannels/getArchivedChannels.d.ts +20 -0
  68. package/dist/channelRepository/observers/getArchivedChannels/getArchivedChannels.d.ts.map +1 -0
  69. package/dist/channelRepository/observers/getArchivedChannels/index.d.ts +2 -0
  70. package/dist/channelRepository/observers/getArchivedChannels/index.d.ts.map +1 -0
  71. package/dist/channelRepository/observers/getChannels/ChannelLiveCollectionController.d.ts.map +1 -1
  72. package/dist/channelRepository/observers/getChannels/ChannelQueryStreamController.d.ts.map +1 -1
  73. package/dist/channelRepository/observers/index.d.ts +2 -0
  74. package/dist/channelRepository/observers/index.d.ts.map +1 -1
  75. package/dist/channelRepository/observers/searchChannels/SearchChannelLiveCollectionController.d.ts +14 -0
  76. package/dist/channelRepository/observers/searchChannels/SearchChannelLiveCollectionController.d.ts.map +1 -0
  77. package/dist/channelRepository/observers/searchChannels/SearchChannelPaginationController.d.ts +10 -0
  78. package/dist/channelRepository/observers/searchChannels/SearchChannelPaginationController.d.ts.map +1 -0
  79. package/dist/channelRepository/observers/searchChannels/SearchChannelQueryStreamController.d.ts +13 -0
  80. package/dist/channelRepository/observers/searchChannels/SearchChannelQueryStreamController.d.ts.map +1 -0
  81. package/dist/channelRepository/observers/searchChannels.d.ts +21 -0
  82. package/dist/channelRepository/observers/searchChannels.d.ts.map +1 -0
  83. package/dist/channelRepository/observers/tests/integrations/searchChannels.integration.test.d.ts +2 -0
  84. package/dist/channelRepository/observers/tests/integrations/searchChannels.integration.test.d.ts.map +1 -0
  85. package/dist/channelRepository/utils/prepareChannelPayload.d.ts.map +1 -1
  86. package/dist/client/api/autoSubscription.d.ts +47 -0
  87. package/dist/client/api/autoSubscription.d.ts.map +1 -0
  88. package/dist/client/api/createClient.d.ts.map +1 -1
  89. package/dist/client/api/getCoreUserSettings.d.ts +16 -0
  90. package/dist/client/api/getCoreUserSettings.d.ts.map +1 -0
  91. package/dist/client/api/getForYouFeedSetting.d.ts +17 -0
  92. package/dist/client/api/getForYouFeedSetting.d.ts.map +1 -0
  93. package/dist/client/api/getShareableLinkConfiguration.d.ts.map +1 -1
  94. package/dist/client/api/index.d.ts +5 -0
  95. package/dist/client/api/index.d.ts.map +1 -1
  96. package/dist/client/api/notifications.d.ts +27 -0
  97. package/dist/client/api/notifications.d.ts.map +1 -0
  98. package/dist/client/api/setupLoginSubscriptions.d.ts.map +1 -1
  99. package/dist/client/api/tests/ShareableLinkConfiguration.test.d.ts +2 -0
  100. package/dist/client/api/tests/ShareableLinkConfiguration.test.d.ts.map +1 -0
  101. package/dist/client/api/tests/notifications.integration.test.d.ts +2 -0
  102. package/dist/client/api/tests/notifications.integration.test.d.ts.map +1 -0
  103. package/dist/client/services/ReadReceiptSync/readReceiptSyncEngine.d.ts.map +1 -1
  104. package/dist/client/utils/autoSubscriptionManager.d.ts +21 -0
  105. package/dist/client/utils/autoSubscriptionManager.d.ts.map +1 -0
  106. package/dist/client/utils/subscribeGlobalTopic.d.ts +6 -1
  107. package/dist/client/utils/subscribeGlobalTopic.d.ts.map +1 -1
  108. package/dist/client/utils/tests/autoSubscriptionManager.test.d.ts +2 -0
  109. package/dist/client/utils/tests/autoSubscriptionManager.test.d.ts.map +1 -0
  110. package/dist/commentRepository/observers/getComments/CommentLiveCollectionController.d.ts.map +1 -1
  111. package/dist/commentRepository/observers/tests/integrations/getCommentsExcludeBlockUser.integration.test.d.ts +2 -0
  112. package/dist/commentRepository/observers/tests/integrations/getCommentsExcludeBlockUser.integration.test.d.ts.map +1 -0
  113. package/dist/core/events.d.ts +3 -3
  114. package/dist/core/events.d.ts.map +1 -1
  115. package/dist/core/model/idResolvers.d.ts.map +1 -1
  116. package/dist/core/model/index.d.ts.map +1 -1
  117. package/dist/core/query/filtering.d.ts +32 -0
  118. package/dist/core/query/filtering.d.ts.map +1 -1
  119. package/dist/core/query/paging.d.ts +1 -0
  120. package/dist/core/query/paging.d.ts.map +1 -1
  121. package/dist/core/subscription.d.ts +3 -0
  122. package/dist/core/subscription.d.ts.map +1 -1
  123. package/dist/feedRepository/errors/AmityForYouFeedDisabledError.d.ts +13 -0
  124. package/dist/feedRepository/errors/AmityForYouFeedDisabledError.d.ts.map +1 -0
  125. package/dist/feedRepository/index.d.ts +2 -1
  126. package/dist/feedRepository/index.d.ts.map +1 -1
  127. package/dist/feedRepository/observers/getForYouFeed/CursorController.d.ts +19 -0
  128. package/dist/feedRepository/observers/getForYouFeed/CursorController.d.ts.map +1 -0
  129. package/dist/feedRepository/observers/getForYouFeed/LiveCollectionController.d.ts +13 -0
  130. package/dist/feedRepository/observers/getForYouFeed/LiveCollectionController.d.ts.map +1 -0
  131. package/dist/feedRepository/observers/getForYouFeed/PaginationController.d.ts +13 -0
  132. package/dist/feedRepository/observers/getForYouFeed/PaginationController.d.ts.map +1 -0
  133. package/dist/feedRepository/observers/getForYouFeed/QueryStreamController.d.ts +15 -0
  134. package/dist/feedRepository/observers/getForYouFeed/QueryStreamController.d.ts.map +1 -0
  135. package/dist/feedRepository/observers/getForYouFeed.d.ts +19 -0
  136. package/dist/feedRepository/observers/getForYouFeed.d.ts.map +1 -0
  137. package/dist/feedRepository/observers/index.d.ts +1 -0
  138. package/dist/feedRepository/observers/index.d.ts.map +1 -1
  139. package/dist/feedRepository/observers/tests/integration/getForYouFeed.integration.test.d.ts +2 -0
  140. package/dist/feedRepository/observers/tests/integration/getForYouFeed.integration.test.d.ts.map +1 -0
  141. package/dist/feedRepository/observers/tests/unit/CursorController.test.d.ts +2 -0
  142. package/dist/feedRepository/observers/tests/unit/CursorController.test.d.ts.map +1 -0
  143. package/dist/fileRepository/api/uploadAudio.d.ts +1 -1
  144. package/dist/fileRepository/api/uploadAudio.d.ts.map +1 -1
  145. package/dist/fileRepository/api/uploadClip.d.ts +1 -1
  146. package/dist/fileRepository/api/uploadClip.d.ts.map +1 -1
  147. package/dist/fileRepository/api/uploadFile.d.ts +1 -1
  148. package/dist/fileRepository/api/uploadFile.d.ts.map +1 -1
  149. package/dist/fileRepository/api/uploadImage.d.ts +1 -1
  150. package/dist/fileRepository/api/uploadImage.d.ts.map +1 -1
  151. package/dist/fileRepository/api/uploadVideo.d.ts +1 -1
  152. package/dist/fileRepository/api/uploadVideo.d.ts.map +1 -1
  153. package/dist/index.cjs.js +2755 -592
  154. package/dist/index.esm.js +2752 -592
  155. package/dist/index.umd.js +3 -3
  156. package/dist/messagePreview/utils/getChannelMessagePreviewWithUser.d.ts +1 -0
  157. package/dist/messagePreview/utils/getChannelMessagePreviewWithUser.d.ts.map +1 -1
  158. package/dist/messagePreview/utils/updateChannelMessagePreviewCache.d.ts.map +1 -1
  159. package/dist/messageRepository/events/onMessageCreated.d.ts.map +1 -1
  160. package/dist/messageRepository/observers/index.d.ts +1 -0
  161. package/dist/messageRepository/observers/index.d.ts.map +1 -1
  162. package/dist/messageRepository/observers/searchMessage/SearchMessageLiveCollectionController.d.ts +12 -0
  163. package/dist/messageRepository/observers/searchMessage/SearchMessageLiveCollectionController.d.ts.map +1 -0
  164. package/dist/messageRepository/observers/searchMessage/SearchMessagePaginationController.d.ts +10 -0
  165. package/dist/messageRepository/observers/searchMessage/SearchMessagePaginationController.d.ts.map +1 -0
  166. package/dist/messageRepository/observers/searchMessage/SearchMessageQueryStreamController.d.ts +8 -0
  167. package/dist/messageRepository/observers/searchMessage/SearchMessageQueryStreamController.d.ts.map +1 -0
  168. package/dist/messageRepository/observers/searchMessage/index.d.ts +2 -0
  169. package/dist/messageRepository/observers/searchMessage/index.d.ts.map +1 -0
  170. package/dist/messageRepository/observers/searchMessage/searchMessage.d.ts +24 -0
  171. package/dist/messageRepository/observers/searchMessage/searchMessage.d.ts.map +1 -0
  172. package/dist/postRepository/observers/getPosts/PostLiveCollectionController.d.ts.map +1 -1
  173. package/dist/postRepository/observers/tests/getPostsExcludeBlockUser.test.d.ts +2 -0
  174. package/dist/postRepository/observers/tests/getPostsExcludeBlockUser.test.d.ts.map +1 -0
  175. package/dist/postRepository/tests/integration/postAnalytics.integration.test.d.ts +2 -0
  176. package/dist/postRepository/tests/integration/postAnalytics.integration.test.d.ts.map +1 -0
  177. package/dist/postRepository/tests/integration/setup.d.ts +6 -0
  178. package/dist/postRepository/tests/integration/setup.d.ts.map +1 -0
  179. package/dist/reactionRepository/internalApi/addReaction.d.ts.map +1 -1
  180. package/dist/reactionRepository/internalApi/removeReaction.d.ts.map +1 -1
  181. package/dist/streamRepository/observers/getStreams/GetStreamsPageController.d.ts +1 -0
  182. package/dist/streamRepository/observers/getStreams/GetStreamsPageController.d.ts.map +1 -1
  183. package/dist/userRepository/api/getAllBlockedUsers.d.ts.map +1 -1
  184. package/dist/userRepository/api/getAllBlockingUsers.d.ts +20 -0
  185. package/dist/userRepository/api/getAllBlockingUsers.d.ts.map +1 -0
  186. package/dist/userRepository/api/index.d.ts +1 -0
  187. package/dist/userRepository/api/index.d.ts.map +1 -1
  188. package/dist/userRepository/api/tests/integration/getAllBlockingUsers.integration.test.d.ts +2 -0
  189. package/dist/userRepository/api/tests/integration/getAllBlockingUsers.integration.test.d.ts.map +1 -0
  190. package/dist/userRepository/observers/getBlockedUsers/BlockedUserLiveCollectionController.d.ts.map +1 -1
  191. package/dist/userRepository/observers/getBlockedUsers/BlockedUserQueryStreamController.d.ts +4 -3
  192. package/dist/userRepository/observers/getBlockedUsers/BlockedUserQueryStreamController.d.ts.map +1 -1
  193. package/dist/userRepository/observers/getBlockingUsers/LiveCollectionController.d.ts +13 -0
  194. package/dist/userRepository/observers/getBlockingUsers/LiveCollectionController.d.ts.map +1 -0
  195. package/dist/userRepository/observers/getBlockingUsers/PaginationController.d.ts +5 -0
  196. package/dist/userRepository/observers/getBlockingUsers/PaginationController.d.ts.map +1 -0
  197. package/dist/userRepository/observers/getBlockingUsers/QueryStreamController.d.ts +16 -0
  198. package/dist/userRepository/observers/getBlockingUsers/QueryStreamController.d.ts.map +1 -0
  199. package/dist/userRepository/observers/getBlockingUsers.d.ts +17 -0
  200. package/dist/userRepository/observers/getBlockingUsers.d.ts.map +1 -0
  201. package/dist/userRepository/observers/index.d.ts +1 -0
  202. package/dist/userRepository/observers/index.d.ts.map +1 -1
  203. package/dist/userRepository/observers/tests/integrations/getBlockingUsers.integration.test.d.ts +2 -0
  204. package/dist/userRepository/observers/tests/integrations/getBlockingUsers.integration.test.d.ts.map +1 -0
  205. package/dist/userRepository/relationship/block/enum/index.d.ts +5 -0
  206. package/dist/userRepository/relationship/block/enum/index.d.ts.map +1 -0
  207. package/dist/userRepository/relationship/block/events/index.d.ts +3 -0
  208. package/dist/userRepository/relationship/block/events/index.d.ts.map +1 -0
  209. package/dist/userRepository/relationship/block/events/onUserDidBlock.d.ts +20 -0
  210. package/dist/userRepository/relationship/block/events/onUserDidBlock.d.ts.map +1 -0
  211. package/dist/userRepository/relationship/block/events/onUserDidUnblock.d.ts +20 -0
  212. package/dist/userRepository/relationship/block/events/onUserDidUnblock.d.ts.map +1 -0
  213. package/dist/userRepository/relationship/block/index.d.ts +1 -0
  214. package/dist/userRepository/relationship/block/index.d.ts.map +1 -1
  215. package/dist/userRepository/relationship/block/utils/blockRealtimeOnLoginHandler.d.ts +12 -0
  216. package/dist/userRepository/relationship/block/utils/blockRealtimeOnLoginHandler.d.ts.map +1 -0
  217. package/dist/userRepository/relationship/block/utils/createBlockEventSubscriber.d.ts +11 -0
  218. package/dist/userRepository/relationship/block/utils/createBlockEventSubscriber.d.ts.map +1 -0
  219. package/dist/userRepository/services/BlockedUserSyncEngine/blockedUserSyncEngine.d.ts +13 -13
  220. package/dist/userRepository/services/BlockedUserSyncEngine/blockedUserSyncEngine.d.ts.map +1 -1
  221. package/dist/userRepository/services/BlockingUserSyncEngine/blockingUserSyncEngine.d.ts +56 -0
  222. package/dist/userRepository/services/BlockingUserSyncEngine/blockingUserSyncEngine.d.ts.map +1 -0
  223. package/dist/userRepository/services/BlockingUserSyncEngine/blockingUserSyncEngineOnLoginHandler.d.ts +3 -0
  224. package/dist/userRepository/services/BlockingUserSyncEngine/blockingUserSyncEngineOnLoginHandler.d.ts.map +1 -0
  225. package/dist/userRepository/utils/prepareBlockingUserPayload.d.ts +2 -0
  226. package/dist/userRepository/utils/prepareBlockingUserPayload.d.ts.map +1 -0
  227. package/dist/utils/constants.d.ts +4 -0
  228. package/dist/utils/constants.d.ts.map +1 -1
  229. package/dist/utils/linkedObject/channelLinkedObject.d.ts.map +1 -1
  230. package/dist/utils/linkedObject/postLinkedObject.d.ts.map +1 -1
  231. package/dist/utils/tests/dummy/block.d.ts +16 -0
  232. package/dist/utils/tests/dummy/block.d.ts.map +1 -1
  233. package/dist/utils/tests/dummy/community.d.ts +2 -0
  234. package/dist/utils/tests/dummy/community.d.ts.map +1 -1
  235. package/dist/utils/tests/dummy/post.d.ts.map +1 -1
  236. package/package.json +1 -1
  237. package/dist/fileRepository/utils/getUploadRequestConfig.d.ts +0 -33
  238. package/dist/fileRepository/utils/getUploadRequestConfig.d.ts.map +0 -1
  239. package/dist/fileRepository/utils/recreateUploadFormData.d.ts +0 -37
  240. package/dist/fileRepository/utils/recreateUploadFormData.d.ts.map +0 -1
package/dist/index.cjs.js CHANGED
@@ -12,7 +12,6 @@ var uuid$1 = require('react-native-uuid');
12
12
  var jwtDecode = require('jwt-decode');
13
13
  var reactNative = require('react-native');
14
14
  var hash = require('object-hash');
15
- var mime = require('mime');
16
15
  var Hls = require('hls.js');
17
16
 
18
17
  function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
@@ -43,7 +42,6 @@ var AsyncStorage__default = /*#__PURE__*/_interopDefaultLegacy(AsyncStorage);
43
42
  var uuid__default = /*#__PURE__*/_interopDefaultLegacy(uuid$1);
44
43
  var jwtDecode__default = /*#__PURE__*/_interopDefaultLegacy(jwtDecode);
45
44
  var hash__default = /*#__PURE__*/_interopDefaultLegacy(hash);
46
- var mime__default = /*#__PURE__*/_interopDefaultLegacy(mime);
47
45
  var Hls__default = /*#__PURE__*/_interopDefaultLegacy(Hls);
48
46
 
49
47
  exports.MembershipAcceptanceTypeEnum = void 0;
@@ -51,6 +49,13 @@ exports.MembershipAcceptanceTypeEnum = void 0;
51
49
  MembershipAcceptanceTypeEnum["AUTOMATIC"] = "automatic";
52
50
  MembershipAcceptanceTypeEnum["INVITATION"] = "invitation";
53
51
  })(exports.MembershipAcceptanceTypeEnum || (exports.MembershipAcceptanceTypeEnum = {}));
52
+ exports.AmityAutoSubscription = void 0;
53
+ (function (AmityAutoSubscription) {
54
+ AmityAutoSubscription["CHAT"] = "chat";
55
+ AmityAutoSubscription["NETWORK"] = "network";
56
+ AmityAutoSubscription["LIVESTREAM"] = "livestream";
57
+ AmityAutoSubscription["BLOCK"] = "block";
58
+ })(exports.AmityAutoSubscription || (exports.AmityAutoSubscription = {}));
54
59
 
55
60
  exports.UserTypeEnum = void 0;
56
61
  (function (UserTypeEnum) {
@@ -97,6 +102,13 @@ exports.FileAccessTypeEnum = void 0;
97
102
  FileAccessTypeEnum["NETWORK"] = "network";
98
103
  })(exports.FileAccessTypeEnum || (exports.FileAccessTypeEnum = {}));
99
104
 
105
+ exports.AmityChannelNotificationModeEnum = void 0;
106
+ (function (AmityChannelNotificationModeEnum) {
107
+ AmityChannelNotificationModeEnum["Default"] = "default";
108
+ AmityChannelNotificationModeEnum["Silent"] = "silent";
109
+ AmityChannelNotificationModeEnum["Subscribe"] = "subscribe";
110
+ })(exports.AmityChannelNotificationModeEnum || (exports.AmityChannelNotificationModeEnum = {}));
111
+
100
112
  const CommunityPostSettings = Object.freeze({
101
113
  ONLY_ADMIN_CAN_POST: 'ONLY_ADMIN_CAN_POST',
102
114
  ADMIN_REVIEW_POST_REQUIRED: 'ADMIN_REVIEW_POST_REQUIRED',
@@ -272,16 +284,58 @@ exports.AmityEventOrderOption = void 0;
272
284
  AmityEventOrderOption["Descending"] = "desc";
273
285
  })(exports.AmityEventOrderOption || (exports.AmityEventOrderOption = {}));
274
286
 
287
+ exports.AmitySharableContentType = void 0;
288
+ (function (AmitySharableContentType) {
289
+ AmitySharableContentType["POST"] = "post";
290
+ AmitySharableContentType["COMMUNITY"] = "community";
291
+ AmitySharableContentType["USER"] = "user";
292
+ AmitySharableContentType["LIVESTREAM"] = "livestream";
293
+ AmitySharableContentType["EVENT"] = "event";
294
+ })(exports.AmitySharableContentType || (exports.AmitySharableContentType = {}));
295
+
275
296
  exports.AnalyticsSourceTypeEnum = void 0;
276
297
  (function (AnalyticsSourceTypeEnum) {
277
298
  AnalyticsSourceTypeEnum["POST"] = "post";
278
299
  AnalyticsSourceTypeEnum["ROOM"] = "room";
279
300
  })(exports.AnalyticsSourceTypeEnum || (exports.AnalyticsSourceTypeEnum = {}));
280
301
 
302
+ exports.UserNotificationModuleNameEnum = void 0;
303
+ (function (UserNotificationModuleNameEnum) {
304
+ UserNotificationModuleNameEnum["CHAT"] = "chat";
305
+ UserNotificationModuleNameEnum["SOCIAL"] = "social";
306
+ UserNotificationModuleNameEnum["VIDEO_STREAMING"] = "video-streaming";
307
+ })(exports.UserNotificationModuleNameEnum || (exports.UserNotificationModuleNameEnum = {}));
308
+ exports.CommunityNotificationEventNameEnum = void 0;
309
+ (function (CommunityNotificationEventNameEnum) {
310
+ CommunityNotificationEventNameEnum["POST_CREATED"] = "post.created";
311
+ CommunityNotificationEventNameEnum["POST_REACTED"] = "post.reacted";
312
+ CommunityNotificationEventNameEnum["COMMENT_CREATED"] = "comment.created";
313
+ CommunityNotificationEventNameEnum["COMMENT_REPLIED"] = "comment.replied";
314
+ CommunityNotificationEventNameEnum["COMMENT_REACTED"] = "comment.reacted";
315
+ CommunityNotificationEventNameEnum["STORY_CREATED"] = "story.created";
316
+ CommunityNotificationEventNameEnum["STORY_REACTED"] = "story.reacted";
317
+ CommunityNotificationEventNameEnum["STORY_COMMENT_CREATED"] = "story-comment.created";
318
+ CommunityNotificationEventNameEnum["LIVESTREAM_START"] = "video-streaming.didStart";
319
+ })(exports.CommunityNotificationEventNameEnum || (exports.CommunityNotificationEventNameEnum = {}));
320
+ exports.NotificationSettingsLevelEnum = void 0;
321
+ (function (NotificationSettingsLevelEnum) {
322
+ NotificationSettingsLevelEnum["USER"] = "user";
323
+ NotificationSettingsLevelEnum["COMMUNITY"] = "community";
324
+ NotificationSettingsLevelEnum["CHANNEL"] = "channel";
325
+ })(exports.NotificationSettingsLevelEnum || (exports.NotificationSettingsLevelEnum = {}));
326
+ /**
327
+ * `NOT` variant is intentionally excluded from public API (internal server-side use only).
328
+ */
329
+ exports.NotificationRolesFilterTypeEnum = void 0;
330
+ (function (NotificationRolesFilterTypeEnum) {
331
+ NotificationRolesFilterTypeEnum["ALL"] = "all";
332
+ NotificationRolesFilterTypeEnum["ONLY"] = "only";
333
+ })(exports.NotificationRolesFilterTypeEnum || (exports.NotificationRolesFilterTypeEnum = {}));
334
+
281
335
  function getVersion() {
282
336
  try {
283
- // the string ''v7.22.0-cjs'' should be replaced by actual value by @rollup/plugin-replace
284
- return 'v7.22.0-cjs';
337
+ // the string ''v7.23.0-cjs'' should be replaced by actual value by @rollup/plugin-replace
338
+ return 'v7.23.0-cjs';
285
339
  }
286
340
  catch (error) {
287
341
  return '__dev__';
@@ -290,6 +344,7 @@ function getVersion() {
290
344
  const VERSION = getVersion();
291
345
 
292
346
  const COLLECTION_DEFAULT_PAGINATION_LIMIT = 5;
347
+ const COLLECTION_DEFAULT_PAGINATION_SIZE = 20;
293
348
  const COLLECTION_DEFAULT_CACHING_POLICY = 'cache_then_server';
294
349
  const ENABLE_CACHE_MESSAGE = 'For using Live Collection feature you need to enable Cache!';
295
350
  const LIVE_OBJECT_ENABLE_CACHE_MESSAGE = 'For using Live Object feature you need to enable Cache!';
@@ -302,6 +357,9 @@ const DAY = 24 * HOUR;
302
357
  const WEEK = 7 * DAY;
303
358
  const YEAR = 365 * DAY;
304
359
  const ACCESS_TOKEN_WATCHER_INTERVAL = 10 * MINUTE;
360
+ const API_ENDPOINTS = {
361
+ forYouFeed: '/api/v1/feeds/for-you',
362
+ };
305
363
 
306
364
  // cache constants
307
365
  const CACHE_KEY_GET = 'get';
@@ -682,6 +740,107 @@ function createSnapshot(data, options) {
682
740
  return Object.assign(Object.assign({}, options), { data });
683
741
  }
684
742
 
743
+ /* eslint-disable max-classes-per-file */
744
+ /**
745
+ * Generic ASC error
746
+ * @category Errors
747
+ */
748
+ class ASCError extends Error {
749
+ /**
750
+ * @param message A custom error message
751
+ * @param code A normalized error code
752
+ * @param level A normalized failure level descriptor
753
+ */
754
+ constructor(message, code, level) {
755
+ super(`Amity SDK (${code}): ${message}`);
756
+ this.code = code;
757
+ this.level = level;
758
+ this.type = 'ASC';
759
+ this.timestamp = Date.now();
760
+ if (Error.captureStackTrace)
761
+ Error.captureStackTrace(this, ASCError);
762
+ }
763
+ }
764
+ /**
765
+ * API level error
766
+ * @category Errors
767
+ */
768
+ class ASCApiError extends ASCError {
769
+ /**
770
+ * @param code A normalized error code
771
+ * @param level A normalized failure level descriptor
772
+ */
773
+ // eslint-disable-next-line no-useless-constructor
774
+ constructor(message, code, level) {
775
+ super(message, code, level);
776
+ }
777
+ }
778
+ /**
779
+ * Unexpected error
780
+ * @category Errors
781
+ */
782
+ class ASCUnknownError extends ASCError {
783
+ /**
784
+ * @param code A normalized error code
785
+ * @param level A normalized failure level descriptor
786
+ */
787
+ constructor(code = 800000 /* Amity.ClientError.UNKNOWN_ERROR */, level = "fatal" /* Amity.ErrorLevel.FATAL */) {
788
+ super('Unexpected error', code, level);
789
+ }
790
+ }
791
+ /**
792
+ * Network related error
793
+ * @category Errors
794
+ */
795
+ class ASCConnectionError extends ASCError {
796
+ /**
797
+ * @param message A custom error message
798
+ */
799
+ constructor(event, message = 'SDK client is having connection issues') {
800
+ super(`${message} (${event})`, event === 'disconnected'
801
+ ? 800211 /* Amity.ClientError.DISCONNECTED */
802
+ : 800210 /* Amity.ClientError.CONNECTION_ERROR */, "error" /* Amity.ErrorLevel.ERROR */);
803
+ this.event = event;
804
+ }
805
+ }
806
+ /**
807
+ * Input sanitization related error
808
+ * @category Errors
809
+ */
810
+ class ASCInvalidParameterError extends ASCError {
811
+ /**
812
+ * @param message A custom error message
813
+ */
814
+ constructor(message) {
815
+ super(message, 800110 /* Amity.ClientError.INVALID_PARAMETERS */, "error" /* Amity.ErrorLevel.ERROR */);
816
+ }
817
+ }
818
+
819
+ let activeClient = null;
820
+ /**
821
+ * Get the active client
822
+ *
823
+ * @returns the active client instance
824
+ *
825
+ * @hidden
826
+ */
827
+ const getActiveClient = () => {
828
+ if (!activeClient) {
829
+ throw new ASCError('There is no active client', 800000 /* Amity.ClientError.UNKNOWN_ERROR */, "fatal" /* Amity.ErrorLevel.FATAL */);
830
+ }
831
+ return activeClient;
832
+ };
833
+ /**
834
+ * Sets the active client
835
+ *
836
+ * @param client the client to assume as currently active client
837
+ *
838
+ * @hidden
839
+ */
840
+ const setActiveClient = (client) => {
841
+ activeClient = client;
842
+ };
843
+
685
844
  /** @hidden */
686
845
  const idResolvers = {
687
846
  user: ({ userId }) => userId,
@@ -690,6 +849,7 @@ const idResolvers = {
690
849
  channel: ({ channelInternalId }) => channelInternalId,
691
850
  subChannel: ({ subChannelId }) => subChannelId,
692
851
  channelUsers: ({ channelId, userId }) => `${channelId}#${userId}`,
852
+ archivedChannel: ({ channelId }) => channelId,
693
853
  message: ({ messageId, referenceId }) => referenceId !== null && referenceId !== void 0 ? referenceId : messageId,
694
854
  messagePreviewChannel: ({ channelId }) => `${channelId}`,
695
855
  messagePreviewSubChannel: ({ subChannelId }) => `${subChannelId}`,
@@ -731,6 +891,7 @@ const idResolvers = {
731
891
  event: ({ eventId }) => eventId,
732
892
  eventResponse: ({ userId }) => userId,
733
893
  product: ({ productId }) => productId,
894
+ feedMetadata: ({ postId }) => postId,
734
895
  };
735
896
  /**
736
897
  * Retrieve the id resolver matching a domain name
@@ -753,6 +914,7 @@ const PAYLOAD2MODEL = {
753
914
  channels: 'channel',
754
915
  messageFeeds: 'subChannel',
755
916
  channelUsers: 'channelUsers',
917
+ archives: 'archivedChannel',
756
918
  messages: 'message',
757
919
  messagePreviewChannel: 'messagePreviewChannel',
758
920
  messagePreviewSubChannel: 'messagePreviewSubChannel',
@@ -791,6 +953,7 @@ const PAYLOAD2MODEL = {
791
953
  viewers: 'viewer',
792
954
  eventResponses: 'eventResponse',
793
955
  products: 'product',
956
+ feedMetadata: 'feedMetadata',
794
957
  };
795
958
  /** hidden */
796
959
  const isOutdated = (prevData, nextData) => {
@@ -805,107 +968,6 @@ function getFutureDate(date = new Date().toISOString()) {
805
968
  return new Date(new Date(date).getTime() + 1).toISOString();
806
969
  }
807
970
 
808
- /* eslint-disable max-classes-per-file */
809
- /**
810
- * Generic ASC error
811
- * @category Errors
812
- */
813
- class ASCError extends Error {
814
- /**
815
- * @param message A custom error message
816
- * @param code A normalized error code
817
- * @param level A normalized failure level descriptor
818
- */
819
- constructor(message, code, level) {
820
- super(`Amity SDK (${code}): ${message}`);
821
- this.code = code;
822
- this.level = level;
823
- this.type = 'ASC';
824
- this.timestamp = Date.now();
825
- if (Error.captureStackTrace)
826
- Error.captureStackTrace(this, ASCError);
827
- }
828
- }
829
- /**
830
- * API level error
831
- * @category Errors
832
- */
833
- class ASCApiError extends ASCError {
834
- /**
835
- * @param code A normalized error code
836
- * @param level A normalized failure level descriptor
837
- */
838
- // eslint-disable-next-line no-useless-constructor
839
- constructor(message, code, level) {
840
- super(message, code, level);
841
- }
842
- }
843
- /**
844
- * Unexpected error
845
- * @category Errors
846
- */
847
- class ASCUnknownError extends ASCError {
848
- /**
849
- * @param code A normalized error code
850
- * @param level A normalized failure level descriptor
851
- */
852
- constructor(code = 800000 /* Amity.ClientError.UNKNOWN_ERROR */, level = "fatal" /* Amity.ErrorLevel.FATAL */) {
853
- super('Unexpected error', code, level);
854
- }
855
- }
856
- /**
857
- * Network related error
858
- * @category Errors
859
- */
860
- class ASCConnectionError extends ASCError {
861
- /**
862
- * @param message A custom error message
863
- */
864
- constructor(event, message = 'SDK client is having connection issues') {
865
- super(`${message} (${event})`, event === 'disconnected'
866
- ? 800211 /* Amity.ClientError.DISCONNECTED */
867
- : 800210 /* Amity.ClientError.CONNECTION_ERROR */, "error" /* Amity.ErrorLevel.ERROR */);
868
- this.event = event;
869
- }
870
- }
871
- /**
872
- * Input sanitization related error
873
- * @category Errors
874
- */
875
- class ASCInvalidParameterError extends ASCError {
876
- /**
877
- * @param message A custom error message
878
- */
879
- constructor(message) {
880
- super(message, 800110 /* Amity.ClientError.INVALID_PARAMETERS */, "error" /* Amity.ErrorLevel.ERROR */);
881
- }
882
- }
883
-
884
- let activeClient = null;
885
- /**
886
- * Get the active client
887
- *
888
- * @returns the active client instance
889
- *
890
- * @hidden
891
- */
892
- const getActiveClient = () => {
893
- if (!activeClient) {
894
- throw new ASCError('There is no active client', 800000 /* Amity.ClientError.UNKNOWN_ERROR */, "fatal" /* Amity.ErrorLevel.FATAL */);
895
- }
896
- return activeClient;
897
- };
898
- /**
899
- * Sets the active client
900
- *
901
- * @param client the client to assume as currently active client
902
- *
903
- * @hidden
904
- */
905
- const setActiveClient = (client) => {
906
- activeClient = client;
907
- };
908
-
909
971
  /**
910
972
  * ```js
911
973
  * import { enableCache } from '@amityco/ts-sdk-react-native'
@@ -1413,6 +1475,65 @@ const filterBySearchTerm = (collection, searchTerm) => {
1413
1475
  return m.user && ((_a = m.user.displayName) === null || _a === void 0 ? void 0 : _a.match(containsMatcher));
1414
1476
  });
1415
1477
  };
1478
+ /**
1479
+ * The ids of users in a block relationship with the current user — in BOTH
1480
+ * directions — derived synchronously from the local follow cache. For every
1481
+ * `status === 'blocked'` row that involves the current user, the OTHER party
1482
+ * is collected: `from === me` (users I blocked, outgoing) contributes `to`;
1483
+ * `to === me` (users who blocked me, incoming) contributes `from`.
1484
+ *
1485
+ * @returns a set of block-related user ids (both directions)
1486
+ *
1487
+ * @hidden
1488
+ */
1489
+ const getBlockUsersId = () => {
1490
+ var _a;
1491
+ const { userId } = getActiveClient();
1492
+ const ids = new Set();
1493
+ ((_a = queryCache(['follow', 'get'])) !== null && _a !== void 0 ? _a : [])
1494
+ .map(entry => entry.data)
1495
+ .filter(follow => (follow === null || follow === void 0 ? void 0 : follow.status) === 'blocked' && (follow.from === userId || follow.to === userId))
1496
+ .forEach(follow => {
1497
+ ids.add(follow.from === userId ? follow.to : follow.from);
1498
+ });
1499
+ return ids;
1500
+ };
1501
+ /**
1502
+ * Filter out posts whose author or any mentionee is in a block relationship
1503
+ * with the current user, in either direction (see {@link getBlockUsersId}).
1504
+ *
1505
+ * @param collection the post collection to filter
1506
+ * @returns a filtered collection excluding posts involving block-related users
1507
+ *
1508
+ * @hidden
1509
+ */
1510
+ const filterPostsByBlockUsers = (collection) => {
1511
+ const blockUsersId = getBlockUsersId();
1512
+ if (blockUsersId.size === 0)
1513
+ return collection;
1514
+ return collection.filter(post => {
1515
+ var _a, _b;
1516
+ if (blockUsersId.has(post.postedUserId))
1517
+ return false;
1518
+ const mentionedUserIds = (_b = (_a = post.mentionees) === null || _a === void 0 ? void 0 : _a.flatMap(mention => (mention.type === 'user' ? mention.userIds : []))) !== null && _b !== void 0 ? _b : [];
1519
+ return !mentionedUserIds.some(id => blockUsersId.has(id));
1520
+ });
1521
+ };
1522
+ /**
1523
+ * Filter out comments whose creator is in a block relationship with the
1524
+ * current user, in either direction (see {@link getBlockUsersId}).
1525
+ *
1526
+ * @param collection the comment collection to filter
1527
+ * @returns a filtered collection excluding comments from block-related users
1528
+ *
1529
+ * @hidden
1530
+ */
1531
+ const filterCommentsByBlockUsers = (collection) => {
1532
+ const blockUsersId = getBlockUsersId();
1533
+ if (blockUsersId.size === 0)
1534
+ return collection;
1535
+ return collection.filter(comment => !blockUsersId.has(comment.userId));
1536
+ };
1416
1537
 
1417
1538
  // Note:
1418
1539
  // this file should contain a suite of sorting utilities to help the
@@ -1883,13 +2004,13 @@ class NetworkActivitiesWatcher {
1883
2004
  this._listener.clear();
1884
2005
  }
1885
2006
  }
1886
- let instance$9;
2007
+ let instance$b;
1887
2008
  var NetworkActivitiesWatcher$1 = {
1888
2009
  getInstance: () => {
1889
- if (!instance$9) {
1890
- instance$9 = new NetworkActivitiesWatcher();
2010
+ if (!instance$b) {
2011
+ instance$b = new NetworkActivitiesWatcher();
1891
2012
  }
1892
- return instance$9;
2013
+ return instance$b;
1893
2014
  },
1894
2015
  };
1895
2016
 
@@ -4637,18 +4758,149 @@ walker=walker.next;}if(i===n&&walker!==null){return walker.value;}};Yallist.prot
4637
4758
  walker=walker.prev;}if(i===n&&walker!==null){return walker.value;}};Yallist.prototype.map=function(fn,thisp){thisp=thisp||this;var res=new Yallist();for(var walker=this.head;walker!==null;){res.push(fn.call(thisp,walker.value,this));walker=walker.next;}return res;};Yallist.prototype.mapReverse=function(fn,thisp){thisp=thisp||this;var res=new Yallist();for(var walker=this.tail;walker!==null;){res.push(fn.call(thisp,walker.value,this));walker=walker.prev;}return res;};Yallist.prototype.reduce=function(fn,initial){var acc;var walker=this.head;if(arguments.length>1){acc=initial;}else if(this.head){walker=this.head.next;acc=this.head.value;}else {throw new TypeError('Reduce of empty list with no initial value');}for(var i=0;walker!==null;i++){acc=fn(acc,walker.value,i);walker=walker.next;}return acc;};Yallist.prototype.reduceReverse=function(fn,initial){var acc;var walker=this.tail;if(arguments.length>1){acc=initial;}else if(this.tail){walker=this.tail.prev;acc=this.tail.value;}else {throw new TypeError('Reduce of empty list with no initial value');}for(var i=this.length-1;walker!==null;i--){acc=fn(acc,walker.value,i);walker=walker.prev;}return acc;};Yallist.prototype.toArray=function(){var arr=new Array(this.length);for(var i=0,walker=this.head;walker!==null;i++){arr[i]=walker.value;walker=walker.next;}return arr;};Yallist.prototype.toArrayReverse=function(){var arr=new Array(this.length);for(var i=0,walker=this.tail;walker!==null;i++){arr[i]=walker.value;walker=walker.prev;}return arr;};Yallist.prototype.slice=function(from,to){to=to||this.length;if(to<0){to+=this.length;}from=from||0;if(from<0){from+=this.length;}var ret=new Yallist();if(to<from||to<0){return ret;}if(from<0){from=0;}if(to>this.length){to=this.length;}for(var i=0,walker=this.head;walker!==null&&i<from;i++){walker=walker.next;}for(;walker!==null&&i<to;i++,walker=walker.next){ret.push(walker.value);}return ret;};Yallist.prototype.sliceReverse=function(from,to){to=to||this.length;if(to<0){to+=this.length;}from=from||0;if(from<0){from+=this.length;}var ret=new Yallist();if(to<from||to<0){return ret;}if(from<0){from=0;}if(to>this.length){to=this.length;}for(var i=this.length,walker=this.tail;walker!==null&&i>to;i--){walker=walker.prev;}for(;walker!==null&&i>from;i--,walker=walker.prev){ret.push(walker.value);}return ret;};Yallist.prototype.splice=function(start,deleteCount){if(start>this.length){start=this.length-1;}if(start<0){start=this.length+start;}for(var i=0,walker=this.head;walker!==null&&i<start;i++){walker=walker.next;}var ret=[];for(var i=0;walker&&i<deleteCount;i++){ret.push(walker.value);walker=this.removeNode(walker);}if(walker===null){walker=this.tail;}if(walker!==this.head&&walker!==this.tail){walker=walker.prev;}for(var i=0;i<(arguments.length<=2?0:arguments.length-2);i++){walker=insert(this,walker,i+2<2||arguments.length<=i+2?undefined:arguments[i+2]);}return ret;};Yallist.prototype.reverse=function(){var head=this.head;var tail=this.tail;for(var walker=head;walker!==null;walker=walker.prev){var p=walker.prev;walker.prev=walker.next;walker.next=p;}this.head=tail;this.tail=head;return this;};function insert(self,node,value){var inserted=node===self.head?new Node(value,null,node,self):new Node(value,node,node.next,self);if(inserted.next===null){self.tail=inserted;}if(inserted.prev===null){self.head=inserted;}self.length++;return inserted;}function push(self,item){self.tail=new Node(item,self.tail,null,self);if(!self.head){self.head=self.tail;}self.length++;}function unshift(self,item){self.head=new Node(item,null,self.head,self);if(!self.tail){self.tail=self.head;}self.length++;}function Node(value,prev,next,list){if(!(this instanceof Node)){return new Node(value,prev,next,list);}this.list=list;this.value=value;if(prev){prev.next=this;this.prev=prev;}else {this.prev=null;}if(next){next.prev=this;this.next=next;}else {this.next=null;}}try{// add if support for Symbol.iterator is present
4638
4759
  require('./iterator.js')(Yallist);}catch(er){}},{"./iterator.js":82}]},{},[12])(12);});})(mqtt$1);var mqtt = /*@__PURE__*/getDefaultExportFromCjs(mqtt$1.exports);
4639
4760
 
4761
+ class SessionWatcher {
4762
+ constructor() {
4763
+ this._sessionState = "notLoggedIn" /* Amity.SessionStates.NOT_LOGGED_IN */;
4764
+ this._listener = new Map();
4765
+ }
4766
+ onSessionStateChange(callback) {
4767
+ this._listener.set(callback, callback);
4768
+ return () => {
4769
+ this._listener.delete(callback);
4770
+ };
4771
+ }
4772
+ setSessionState(state, reason) {
4773
+ if (this._sessionState === state)
4774
+ return;
4775
+ this._sessionState = state;
4776
+ this._listener.forEach(cb => cb(state, reason));
4777
+ }
4778
+ destroy() {
4779
+ this._listener.clear();
4780
+ }
4781
+ }
4782
+ let instance$a;
4783
+ var SessionWatcher$1 = {
4784
+ getInstance: () => {
4785
+ if (!instance$a) {
4786
+ instance$a = new SessionWatcher();
4787
+ }
4788
+ return instance$a;
4789
+ },
4790
+ };
4791
+
4792
+ /**
4793
+ * ```js
4794
+ * import { onSessionStateChange } from '@amityco/ts-sdk-react-native'
4795
+ * const dispose = onSessionStateChange((state: Amity.SessionStates) => {
4796
+ * // ...
4797
+ * })
4798
+ * ```
4799
+ *
4800
+ * Fired when any {@link Amity.Client} has a session state change
4801
+ *
4802
+ * @param callback The function to call when the event was fired
4803
+ * @returns an {@link Amity.Unsubscriber} function to stop listening
4804
+ *
4805
+ * @category Client Events
4806
+ */
4807
+ const onSessionStateChange = (callback) => SessionWatcher$1.getInstance().onSessionStateChange(callback);
4808
+
4809
+ const TOPICS = {
4810
+ [exports.AmityAutoSubscription.NETWORK]: [getNetworkTopic],
4811
+ [exports.AmityAutoSubscription.CHAT]: [
4812
+ getSmartFeedChannelTopic,
4813
+ getSmartFeedSubChannelTopic,
4814
+ getSmartFeedMessageTopic,
4815
+ ],
4816
+ [exports.AmityAutoSubscription.LIVESTREAM]: [getLiveStreamTopic],
4817
+ [exports.AmityAutoSubscription.BLOCK]: [getMyFollowersTopic, getMyFollowingsTopic],
4818
+ };
4819
+ const DEFAULT_TOPICS = [
4820
+ exports.AmityAutoSubscription.CHAT,
4821
+ exports.AmityAutoSubscription.NETWORK,
4822
+ exports.AmityAutoSubscription.LIVESTREAM,
4823
+ exports.AmityAutoSubscription.BLOCK,
4824
+ ];
4825
+ const ALL_FEATURES = Object.values(exports.AmityAutoSubscription);
4826
+ /** Ref-counted, reconnect-resilient registry of the managed auto-subscriptions. */
4827
+ class AutoSubscriptionManager {
4828
+ constructor() {
4829
+ this.refCountByFeature = new Map();
4830
+ this.disposers = new Map();
4831
+ this.seed();
4832
+ }
4833
+ seed() {
4834
+ this.refCountByFeature.clear();
4835
+ DEFAULT_TOPICS.forEach(feature => this.refCountByFeature.set(feature, 1));
4836
+ }
4837
+ isActive(feature) {
4838
+ var _a;
4839
+ return ((_a = this.refCountByFeature.get(feature)) !== null && _a !== void 0 ? _a : 0) > 0;
4840
+ }
4841
+ subscribeTopics(feature) {
4842
+ this.unsubscribeTopics(feature);
4843
+ this.disposers.set(feature, TOPICS[feature].map(buildTopic => subscribeTopic(buildTopic())));
4844
+ }
4845
+ unsubscribeTopics(feature) {
4846
+ var _a;
4847
+ ((_a = this.disposers.get(feature)) !== null && _a !== void 0 ? _a : []).forEach(dispose => dispose());
4848
+ this.disposers.delete(feature);
4849
+ }
4850
+ /** Subscribe every enabled handle's topics, converging the broker to the registry. Called on each (re)connect. */
4851
+ initialize() {
4852
+ ALL_FEATURES.forEach(feature => {
4853
+ if (this.isActive(feature))
4854
+ this.subscribeTopics(feature);
4855
+ });
4856
+ }
4857
+ subscribe(feature) {
4858
+ var _a;
4859
+ const next = ((_a = this.refCountByFeature.get(feature)) !== null && _a !== void 0 ? _a : 0) + 1;
4860
+ this.refCountByFeature.set(feature, next);
4861
+ if (next === 1)
4862
+ this.subscribeTopics(feature);
4863
+ }
4864
+ unsubscribe(feature) {
4865
+ var _a;
4866
+ const next = Math.max(0, ((_a = this.refCountByFeature.get(feature)) !== null && _a !== void 0 ? _a : 0) - 1);
4867
+ this.refCountByFeature.set(feature, next);
4868
+ if (next === 0)
4869
+ this.unsubscribeTopics(feature);
4870
+ }
4871
+ subscriptions() {
4872
+ return ALL_FEATURES.map(feature => ({
4873
+ feature,
4874
+ isActive: this.isActive(feature),
4875
+ isSystem: true,
4876
+ topicCount: TOPICS[feature].length,
4877
+ }));
4878
+ }
4879
+ reset() {
4880
+ ALL_FEATURES.forEach(feature => this.unsubscribeTopics(feature));
4881
+ this.disposers.clear();
4882
+ this.seed();
4883
+ }
4884
+ }
4885
+ let instance$9 = null;
4886
+ const getAutoSubscriptionManager = () => {
4887
+ if (!instance$9)
4888
+ instance$9 = new AutoSubscriptionManager();
4889
+ return instance$9;
4890
+ };
4891
+ /** Resets the registry to its default baseline when the session ends. */
4892
+ const resetAutoSubscriptionsOnLogout = () => onSessionStateChange(state => {
4893
+ if (state !== "established" /* Amity.SessionStates.ESTABLISHED */)
4894
+ getAutoSubscriptionManager().reset();
4895
+ });
4896
+
4897
+ /**
4898
+ * (Re)subscribes the managed auto-subscription registry on every (re)connect.
4899
+ * The hardcoded topic list was promoted to the toggleable, ref-counted registry
4900
+ * in {@link getAutoSubscriptionManager} — see `client.manageAutoSubscriptions`.
4901
+ */
4640
4902
  const subscribeGlobalTopic = () => {
4641
- const disposers = [
4642
- subscribeTopic(getNetworkTopic()),
4643
- subscribeTopic(getSmartFeedChannelTopic()),
4644
- subscribeTopic(getSmartFeedSubChannelTopic()),
4645
- subscribeTopic(getSmartFeedMessageTopic()),
4646
- // subscribing to user topic is necessary to handle ban event
4647
- subscribeTopic(getUserTopic(getActiveUser())),
4648
- subscribeTopic(getMarkerUserFeedTopic()),
4649
- subscribeTopic(getLiveStreamTopic()),
4650
- ];
4651
- return () => disposers.forEach(fn => fn());
4903
+ getAutoSubscriptionManager().initialize();
4652
4904
  };
4653
4905
 
4654
4906
  class OnMemoryStorage {
@@ -5205,8 +5457,12 @@ const getChannelMessagePreviewWithUser = (channel) => {
5205
5457
  return Object.assign(Object.assign({}, channel), { messagePreview: messagePreviewWithUser });
5206
5458
  };
5207
5459
 
5460
+ const convertDateStringToTimestamp = (dateString) => {
5461
+ return new Date(dateString).getTime();
5462
+ };
5463
+
5208
5464
  const updateChannelMessagePreviewCache = (rawPayload) => {
5209
- var _a, _b;
5465
+ var _a;
5210
5466
  const withMessageFeedInfo = (messagePreview) => {
5211
5467
  var _a;
5212
5468
  const messageFeedInfo = (_a = rawPayload.messageFeedsInfo) === null || _a === void 0 ? void 0 : _a.find(messageFeed => {
@@ -5228,10 +5484,26 @@ const updateChannelMessagePreviewCache = (rawPayload) => {
5228
5484
  subChannelUpdatedAt: messageFeedInfo === null || messageFeedInfo === void 0 ? void 0 : messageFeedInfo.updatedAt,
5229
5485
  };
5230
5486
  };
5231
- const newData = {
5232
- messagePreviewChannel: (_b = (_a = rawPayload.messagePreviews) === null || _a === void 0 ? void 0 : _a.map(messagePreview => withMessageFeedInfo(messagePreview))) !== null && _b !== void 0 ? _b : [],
5233
- };
5234
- ingestInCache(newData);
5487
+ // Skip server previews older than what's cached — the cache may carry a newer
5488
+ // preview written by handleMessageCreated from an MQTT message that the server
5489
+ // payload hasn't surfaced yet. Mirrors isLastestMessageOnChannel.
5490
+ const newPreviews = ((_a = rawPayload.messagePreviews) !== null && _a !== void 0 ? _a : [])
5491
+ .map(withMessageFeedInfo)
5492
+ .filter(preview => {
5493
+ var _a;
5494
+ const cached = (_a = pullFromCache([
5495
+ 'messagePreviewChannel',
5496
+ 'get',
5497
+ preview.channelId,
5498
+ ])) === null || _a === void 0 ? void 0 : _a.data;
5499
+ if (!cached)
5500
+ return true;
5501
+ return (convertDateStringToTimestamp(cached.createdAt) <=
5502
+ convertDateStringToTimestamp(preview.createdAt));
5503
+ });
5504
+ if (newPreviews.length === 0)
5505
+ return;
5506
+ ingestInCache({ messagePreviewChannel: newPreviews });
5235
5507
  };
5236
5508
 
5237
5509
  const getSubChannelMessagePreview = (subChannelId) => {
@@ -5859,11 +6131,7 @@ getSubChannel$1.locally = (subChannelId) => {
5859
6131
  };
5860
6132
  };
5861
6133
 
5862
- const convertDateStringToTimestamp = (dateString) => {
5863
- return new Date(dateString).getTime();
5864
- };
5865
-
5866
- const getMessagePreviewSetting$1 = async () => {
6134
+ const getMessagePreviewSetting$2 = async () => {
5867
6135
  const client = getActiveClient();
5868
6136
  return client.getMessagePreviewSetting(false);
5869
6137
  };
@@ -5898,7 +6166,7 @@ const isLastestMessageOnChannel = (message) => {
5898
6166
  convertDateStringToTimestamp(cache.createdAt) <= convertDateStringToTimestamp(message.createdAt));
5899
6167
  };
5900
6168
  const handleMessageCreatedOnSubChannel = async (message) => {
5901
- const messagePreviewSetting = await getMessagePreviewSetting$1();
6169
+ const messagePreviewSetting = await getMessagePreviewSetting$2();
5902
6170
  const { channelId, messageId: messagePreviewId, creatorId, createdAt, updatedAt, data, dataType, subChannelId, channelSegment: segment, isDeleted, } = message;
5903
6171
  // 1. get subChannel from cache, if not exist fetch from server
5904
6172
  const subChannelCache = await getSubChannelCache(subChannelId);
@@ -6070,24 +6338,41 @@ const preUpdateChannelCache = (rawPayload, options = { isMessagePreviewUpdated:
6070
6338
  });
6071
6339
  };
6072
6340
  const updateChannelUnread = ({ currentUserId, channels, channelUsers, }) => {
6341
+ var _a, _b;
6073
6342
  const channelsUnread = [];
6074
6343
  for (let i = 0; i < channels.length; i += 1) {
6075
6344
  if (isUnreadCountSupport(channels[i])) {
6076
6345
  const cacheKey = ['channelUnread', 'get', channels[i].channelId];
6077
6346
  const channelUser = channelUsers.find(channelUser => channelUser.channelId === channels[i].channelId && channelUser.userId === currentUserId);
6078
- let unreadCount = 0;
6347
+ // readToSegment, lastMentionedSegment and lastSegment are monotonically non-decreasing;
6348
+ // prefer cached values when ahead of the server so a refetch returning stale data cannot
6349
+ const cached = (_a = pullFromCache(cacheKey)) === null || _a === void 0 ? void 0 : _a.data;
6350
+ const lastSegment = Math.max((_b = cached === null || cached === void 0 ? void 0 : cached.lastSegment) !== null && _b !== void 0 ? _b : 0, channels[i].messageCount);
6079
6351
  let readToSegment = null;
6080
6352
  let lastMentionedSegment = null;
6353
+ let unreadCount = 0;
6081
6354
  let isMentioned = false;
6082
6355
  if (channelUser) {
6083
- readToSegment = channelUser.readToSegment;
6084
- lastMentionedSegment = channelUser.lastMentionedSegment;
6085
- unreadCount = Math.max(channels[i].messageCount - readToSegment, 0);
6086
- isMentioned = lastMentionedSegment > readToSegment;
6356
+ const serverRead = channelUser.readToSegment;
6357
+ const serverMention = channelUser.lastMentionedSegment;
6358
+ readToSegment =
6359
+ typeof (cached === null || cached === void 0 ? void 0 : cached.readToSegment) === 'number' &&
6360
+ (typeof serverRead !== 'number' || cached.readToSegment > serverRead)
6361
+ ? cached.readToSegment
6362
+ : serverRead !== null && serverRead !== void 0 ? serverRead : null;
6363
+ lastMentionedSegment =
6364
+ typeof (cached === null || cached === void 0 ? void 0 : cached.lastMentionedSegment) === 'number' &&
6365
+ (typeof serverMention !== 'number' || cached.lastMentionedSegment > serverMention)
6366
+ ? cached.lastMentionedSegment
6367
+ : serverMention !== null && serverMention !== void 0 ? serverMention : null;
6368
+ const readForCalc = readToSegment !== null && readToSegment !== void 0 ? readToSegment : 0;
6369
+ unreadCount = Math.max(lastSegment - readForCalc, 0);
6370
+ isMentioned =
6371
+ typeof lastMentionedSegment === 'number' && readForCalc < lastMentionedSegment;
6087
6372
  }
6088
6373
  const cacheChannelUnread = {
6089
6374
  channelId: channels[i].channelId,
6090
- lastSegment: channels[i].messageCount,
6375
+ lastSegment,
6091
6376
  readToSegment,
6092
6377
  lastMentionedSegment,
6093
6378
  unreadCount,
@@ -6097,6 +6382,8 @@ const updateChannelUnread = ({ currentUserId, channels, channelUsers, }) => {
6097
6382
  pushToCache(cacheKey, cacheChannelUnread);
6098
6383
  channelsUnread.push(cacheChannelUnread);
6099
6384
  }
6385
+ }
6386
+ if (channelsUnread.length > 0) {
6100
6387
  fireEvent('local.channelUnread.updated', channelsUnread);
6101
6388
  }
6102
6389
  };
@@ -6796,7 +7083,7 @@ const onChannelMemberRoleRemoved = (callback) => {
6796
7083
  const client = getActiveClient();
6797
7084
  const filter = async (payload) => {
6798
7085
  const { channels, channelUsers } = payload;
6799
- callback(channels[0], channelUsers.find(channelUser => channelUser.membership === 'member'));
7086
+ callbacks$1.forEach(cb => cb(channels[0], channelUsers.find(channelUser => channelUser.membership === 'member')));
6800
7087
  };
6801
7088
  mainDisposer$1 = createEventSubscriber(client, 'onChannelMemberRoleRemoved', 'local.channel-moderator.role-removed', filter);
6802
7089
  }
@@ -6804,6 +7091,39 @@ const onChannelMemberRoleRemoved = (callback) => {
6804
7091
  return () => dispose$1(callback);
6805
7092
  };
6806
7093
 
7094
+ /**
7095
+ * Fired when a {@link Amity.Channel} has been archived by the active user.
7096
+ *
7097
+ * @param callback The function to call when the event was fired
7098
+ * @returns an {@link Amity.Unsubscriber} function to stop listening
7099
+ *
7100
+ * @category Channel Events
7101
+ */
7102
+ const onChannelArchived = (callback) => {
7103
+ const client = getActiveClient();
7104
+ const filter = async (payload) => {
7105
+ callback(payload);
7106
+ };
7107
+ return createEventSubscriber(client, 'onChannelArchived', 'local.channel.archived', filter);
7108
+ };
7109
+
7110
+ /**
7111
+ * Fired when a previously archived {@link Amity.Channel} has been unarchived
7112
+ * by the active user.
7113
+ *
7114
+ * @param callback The function to call when the event was fired
7115
+ * @returns an {@link Amity.Unsubscriber} function to stop listening
7116
+ *
7117
+ * @category Channel Events
7118
+ */
7119
+ const onChannelUnarchived = (callback) => {
7120
+ const client = getActiveClient();
7121
+ const filter = async (payload) => {
7122
+ callback(payload);
7123
+ };
7124
+ return createEventSubscriber(client, 'onChannelUnarchived', 'local.channel.unarchived', filter);
7125
+ };
7126
+
6807
7127
  const callbacks = [];
6808
7128
  let mainDisposer = null;
6809
7129
  const dispose = (cb) => {
@@ -6917,6 +7237,17 @@ const channelLinkedObject = (channel) => {
6917
7237
  markAsRead: () => markAsRead(channel.channelInternalId),
6918
7238
  previewMembers,
6919
7239
  myMembership: (callback) => getMyMembership(channel.channelId, callback),
7240
+ get avatar() {
7241
+ var _a;
7242
+ if (!channel.avatarFileId)
7243
+ return undefined;
7244
+ const avatar = (_a = pullFromCache([
7245
+ 'file',
7246
+ 'get',
7247
+ `${channel.avatarFileId}`,
7248
+ ])) === null || _a === void 0 ? void 0 : _a.data;
7249
+ return avatar;
7250
+ },
6920
7251
  });
6921
7252
  };
6922
7253
 
@@ -7015,54 +7346,6 @@ getChannelByIds$1.locally = (channelIds) => {
7015
7346
  };
7016
7347
  };
7017
7348
 
7018
- class SessionWatcher {
7019
- constructor() {
7020
- this._sessionState = "notLoggedIn" /* Amity.SessionStates.NOT_LOGGED_IN */;
7021
- this._listener = new Map();
7022
- }
7023
- onSessionStateChange(callback) {
7024
- this._listener.set(callback, callback);
7025
- return () => {
7026
- this._listener.delete(callback);
7027
- };
7028
- }
7029
- setSessionState(state, reason) {
7030
- if (this._sessionState === state)
7031
- return;
7032
- this._sessionState = state;
7033
- this._listener.forEach(cb => cb(state, reason));
7034
- }
7035
- destroy() {
7036
- this._listener.clear();
7037
- }
7038
- }
7039
- let instance$8;
7040
- var SessionWatcher$1 = {
7041
- getInstance: () => {
7042
- if (!instance$8) {
7043
- instance$8 = new SessionWatcher();
7044
- }
7045
- return instance$8;
7046
- },
7047
- };
7048
-
7049
- /**
7050
- * ```js
7051
- * import { onSessionStateChange } from '@amityco/ts-sdk-react-native'
7052
- * const dispose = onSessionStateChange((state: Amity.SessionStates) => {
7053
- * // ...
7054
- * })
7055
- * ```
7056
- *
7057
- * Fired when any {@link Amity.Client} has a session state change
7058
- *
7059
- * @param callback The function to call when the event was fired
7060
- * @returns an {@link Amity.Unsubscriber} function to stop listening
7061
- *
7062
- * @category Client Events
7063
- */
7064
- const onSessionStateChange = (callback) => SessionWatcher$1.getInstance().onSessionStateChange(callback);
7065
-
7066
7349
  const setIntervalTask = (handler, timeout) => {
7067
7350
  const timer = setInterval(handler, timeout);
7068
7351
  return () => clearInterval(timer);
@@ -7234,7 +7517,7 @@ const convertMessagePreviewSetting = (chatSetting) => {
7234
7517
  * @category private
7235
7518
  * @async
7236
7519
  */
7237
- const getMessagePreviewSetting = async (refresh = true) => {
7520
+ const getMessagePreviewSetting$1 = async (refresh = true) => {
7238
7521
  var _a;
7239
7522
  const messagePreviewSetting = (_a = pullFromCache([
7240
7523
  'MessagePreviewSetting',
@@ -7255,7 +7538,7 @@ const getMessagePreviewSetting = async (refresh = true) => {
7255
7538
  */
7256
7539
  const initializeMessagePreviewSetting = async () => {
7257
7540
  var _a;
7258
- const newMessagePreviewSetting = await getMessagePreviewSetting();
7541
+ const newMessagePreviewSetting = await getMessagePreviewSetting$1();
7259
7542
  const messagePreviewSetting = (_a = pullFromCache([
7260
7543
  'MessagePreviewSetting',
7261
7544
  ])) === null || _a === void 0 ? void 0 : _a.data;
@@ -7326,6 +7609,26 @@ const getSocialSettings = async () => {
7326
7609
  return data.socialNetworkSetting;
7327
7610
  };
7328
7611
 
7612
+ /**
7613
+ * ```js
7614
+ * import { createClient } from '@amityco/ts-sdk'
7615
+ * const client = createClient(apiKey, apiRegion)
7616
+ * const userSettings = await client.getCoreUserSettings()
7617
+ * ```
7618
+ *
7619
+ * Fetches a {@link Amity.CoreUserSettings} object
7620
+ *
7621
+ * @returns A Promise of {@link Amity.CoreUserSettings} object
7622
+ *
7623
+ * @category Client API
7624
+ * @async
7625
+ */
7626
+ const getCoreUserSettings = async () => {
7627
+ const client = getActiveClient();
7628
+ const { data } = await client.http.get(`/api/v3/network-settings/users`);
7629
+ return data;
7630
+ };
7631
+
7329
7632
  /* begin_public_function
7330
7633
  id: client.getProductCatalogueSetting
7331
7634
  */
@@ -7349,6 +7652,33 @@ const getProductCatalogueSetting = async () => {
7349
7652
  };
7350
7653
  /* end_public_function */
7351
7654
 
7655
+ /* begin_public_function
7656
+ id: client.getForYouFeedSetting
7657
+ */
7658
+ /**
7659
+ * ```js
7660
+ * import { Client } from '@amityco/ts-sdk'
7661
+ * const forYouFeedSetting = await Client.getForYouFeedSetting()
7662
+ * ```
7663
+ *
7664
+ * Fetches the network-level {@link Amity.ForYouFeedSetting} — whether the For You
7665
+ * feed feature is enabled for the current network. Use `forYouFeed.enabled` as a
7666
+ * feature gate before querying {@link getForYouFeed}.
7667
+ *
7668
+ * @returns A Promise of {@link Amity.ForYouFeedSetting} object
7669
+ *
7670
+ * @category Client API
7671
+ * @async
7672
+ */
7673
+ const getForYouFeedSetting = async () => {
7674
+ var _a, _b;
7675
+ const client = getActiveClient();
7676
+ const { data } = await client.http.get(`/api/v3/network-settings/for-you-feed`);
7677
+ // Surface only `enabled`; ignore server-side ranking config (scoringConfig, etc.)
7678
+ return { forYouFeed: { enabled: (_b = (_a = data.forYouFeed) === null || _a === void 0 ? void 0 : _a.enabled) !== null && _b !== void 0 ? _b : false } };
7679
+ };
7680
+ /* end_public_function */
7681
+
7352
7682
  const checkUserPermission = (userId, permission) => {
7353
7683
  var _a;
7354
7684
  const user = (_a = pullFromCache(['user', 'get', userId])) === null || _a === void 0 ? void 0 : _a.data;
@@ -7856,7 +8186,7 @@ class AnalyticsEventSyncer {
7856
8186
 
7857
8187
  class AnalyticsEventCapturer {
7858
8188
  constructor() {
7859
- this._expireTime = 5 * MINUTE;
8189
+ this._expireTime = 5 * SECOND$1;
7860
8190
  this._poolLimit = 1000;
7861
8191
  this._recentViewed = {};
7862
8192
  this._recentHighPriorityViewed = {};
@@ -7910,12 +8240,36 @@ class AnalyticsEventCapturer {
7910
8240
  }
7911
8241
  markPostAsViewed(postId) {
7912
8242
  this.markAs({
7913
- uniqueId: postId,
8243
+ uniqueId: `post.${postId}`,
7914
8244
  contentId: postId,
7915
8245
  contentType: "post" /* Amity.AnalyticEventContentType.Post */,
7916
8246
  activityType: "view" /* Amity.AnalyticEventActivityType.View */,
7917
8247
  });
7918
8248
  }
8249
+ markPostAsMeaningfullyViewed(postId, feedRenderPosition) {
8250
+ var _a;
8251
+ const cached = (_a = pullFromCache(['feedMetadata', 'get', postId])) === null || _a === void 0 ? void 0 : _a.data;
8252
+ const metadata = {};
8253
+ if (feedRenderPosition !== undefined)
8254
+ metadata.feedRenderPosition = feedRenderPosition;
8255
+ if (cached) {
8256
+ metadata.feedSnapshotPosition = cached.feedSnapshotPosition;
8257
+ metadata.feedInjectionType = cached.feedInjectionType;
8258
+ metadata.feedRelevanceScore = cached.feedRelevanceScore;
8259
+ metadata.feedPopularityScore = cached.feedPopularityScore;
8260
+ metadata.feedFreshnessScore = cached.feedFreshnessScore;
8261
+ metadata.feedAffinityScore = cached.feedAffinityScore;
8262
+ metadata.feedFinalScore = cached.feedFinalScore;
8263
+ metadata.feedMmrPenalty = cached.feedMmrPenalty;
8264
+ }
8265
+ this.markAs({
8266
+ uniqueId: `post.${postId}.meaningfulView`,
8267
+ contentId: postId,
8268
+ contentType: "post" /* Amity.AnalyticEventContentType.Post */,
8269
+ activityType: "meaningfulView" /* Amity.AnalyticEventActivityType.MeaningfulView */,
8270
+ metadata: Object.keys(metadata).length > 0 ? metadata : undefined,
8271
+ });
8272
+ }
7919
8273
  markStory(story, activityType) {
7920
8274
  if (!story.expiresAt)
7921
8275
  return;
@@ -8055,6 +8409,12 @@ class AnalyticsEngine {
8055
8409
  this._eventCapturer.markPostAsViewed(postId);
8056
8410
  }
8057
8411
  }
8412
+ markPostAsMeaningfullyViewed(postId, feedRenderPosition) {
8413
+ if (this._client.sessionState === "established" /* Amity.SessionStates.ESTABLISHED */ ||
8414
+ this._client.sessionState === "tokenExpired" /* Amity.SessionStates.TOKEN_EXPIRED */) {
8415
+ this._eventCapturer.markPostAsMeaningfullyViewed(postId, feedRenderPosition);
8416
+ }
8417
+ }
8058
8418
  markStoryAsViewed(story) {
8059
8419
  if (this._client.sessionState === "established" /* Amity.SessionStates.ESTABLISHED */ ||
8060
8420
  this._client.sessionState === "tokenExpired" /* Amity.SessionStates.TOKEN_EXPIRED */ // For case token_expired, we assume token is expired and gonna re-connect soon
@@ -8106,13 +8466,13 @@ class AnalyticsEngine {
8106
8466
  this._eventCapturer.resetAllBuckets();
8107
8467
  }
8108
8468
  }
8109
- let instance$7;
8469
+ let instance$8;
8110
8470
  var AnalyticsEngine$1 = {
8111
8471
  getInstance: () => {
8112
- if (!instance$7) {
8113
- instance$7 = new AnalyticsEngine();
8472
+ if (!instance$8) {
8473
+ instance$8 = new AnalyticsEngine();
8114
8474
  }
8115
- return instance$7;
8475
+ return instance$8;
8116
8476
  },
8117
8477
  };
8118
8478
 
@@ -8279,9 +8639,8 @@ class MessageReadReceiptSyncEngine {
8279
8639
  // Step 1: Optimistic update of channelUnread.readToSegment to message.segment and update unreadCount value
8280
8640
  const cacheKey = ['channelUnread', 'get', channelId];
8281
8641
  const channelUnread = (_a = pullFromCache(cacheKey)) === null || _a === void 0 ? void 0 : _a.data;
8282
- if (typeof (channelUnread === null || channelUnread === void 0 ? void 0 : channelUnread.readToSegment) === 'number' &&
8283
- channelUnread &&
8284
- segment > channelUnread.readToSegment) {
8642
+ if (channelUnread &&
8643
+ (typeof channelUnread.readToSegment !== 'number' || segment > channelUnread.readToSegment)) {
8285
8644
  channelUnread.readToSegment = segment;
8286
8645
  channelUnread.unreadCount = Math.max(channelUnread.lastSegment - segment, 0);
8287
8646
  pushToCache(cacheKey, channelUnread);
@@ -8340,12 +8699,12 @@ class MessageReadReceiptSyncEngine {
8340
8699
  }
8341
8700
  }
8342
8701
  }
8343
- let instance$6 = null;
8702
+ let instance$7 = null;
8344
8703
  var ReadReceiptSyncEngine = {
8345
8704
  getInstance: () => {
8346
- if (!instance$6)
8347
- instance$6 = new MessageReadReceiptSyncEngine();
8348
- return instance$6;
8705
+ if (!instance$7)
8706
+ instance$7 = new MessageReadReceiptSyncEngine();
8707
+ return instance$7;
8349
8708
  },
8350
8709
  };
8351
8710
 
@@ -8599,12 +8958,12 @@ class LegacyMessageReadReceiptSyncEngine {
8599
8958
  }
8600
8959
  }
8601
8960
  }
8602
- let instance$5 = null;
8961
+ let instance$6 = null;
8603
8962
  var LegacyReadReceiptSyncEngine = {
8604
8963
  getInstance: () => {
8605
- if (!instance$5)
8606
- instance$5 = new LegacyMessageReadReceiptSyncEngine();
8607
- return instance$5;
8964
+ if (!instance$6)
8965
+ instance$6 = new LegacyMessageReadReceiptSyncEngine();
8966
+ return instance$6;
8608
8967
  },
8609
8968
  };
8610
8969
 
@@ -8880,12 +9239,12 @@ class ObjectResolverEngine {
8880
9239
  this.stopResolver();
8881
9240
  }
8882
9241
  }
8883
- let instance$4 = null;
9242
+ let instance$5 = null;
8884
9243
  var ObjectResolverEngine$1 = {
8885
9244
  getInstance: () => {
8886
- if (!instance$4)
8887
- instance$4 = new ObjectResolverEngine();
8888
- return instance$4;
9245
+ if (!instance$5)
9246
+ instance$5 = new ObjectResolverEngine();
9247
+ return instance$5;
8889
9248
  },
8890
9249
  };
8891
9250
 
@@ -9035,13 +9394,13 @@ class LiveReactionSyncEngine {
9035
9394
  this.stopReactionsSync();
9036
9395
  }
9037
9396
  }
9038
- let instance$3;
9397
+ let instance$4;
9039
9398
  var ReactionSyncEngine = {
9040
9399
  getInstance: () => {
9041
- if (!instance$3) {
9042
- instance$3 = new LiveReactionSyncEngine();
9400
+ if (!instance$4) {
9401
+ instance$4 = new LiveReactionSyncEngine();
9043
9402
  }
9044
- return instance$3;
9403
+ return instance$4;
9045
9404
  },
9046
9405
  };
9047
9406
 
@@ -9071,19 +9430,20 @@ function prepareBlockedUserPayload(response) {
9071
9430
  }), users: users.map(convertRawUserToInternalUser) });
9072
9431
  }
9073
9432
 
9074
- const BLOCK_LIST_LIMIT = 100;
9075
- const TTL_MS = 5 * 60 * 1000; // 5 minutes
9433
+ const BLOCK_LIST_LIMIT$1 = 100;
9434
+ const TTL_MS$1 = 5 * 60 * 1000; // 5 minutes
9076
9435
  /**
9077
9436
  * Session-scoped singleton engine that manages TTL-based fetching and caching
9078
9437
  * of blocked users. Provides a lazy `ensureFetched()` gate for the
9079
9438
  * `getAllBlockedUsers()` API.
9080
9439
  *
9081
9440
  * Key behaviours:
9082
- * - `establish()` is a no-op — fetch is lazy, triggered only by consumer call
9083
- * - `destroy()` resets `lastFetchedAt` to null (ensures fresh fetch on next session)
9441
+ * - `onSessionEstablished()` is a no-op — fetch is lazy, triggered only by consumer call
9442
+ * - `onSessionDestroyed()` resets `lastFetchedAt` to null (ensures fresh fetch on next session)
9084
9443
  * - `ensureFetched()` fetches from server only when cache is expired or never fetched
9085
9444
  * - `lastFetchedAt` is only updated on successful fetch
9086
- * - `blockedUserIds` is kept in sync with each successful fetch
9445
+ * - reads query the follow cache live, so block/unblock changes are reflected
9446
+ * even within the TTL window
9087
9447
  *
9088
9448
  * @internal
9089
9449
  */
@@ -9091,12 +9451,7 @@ class BlockedUserSyncEngine {
9091
9451
  constructor() {
9092
9452
  /** Epoch ms of last successful fetch. null = never fetched in this session. */
9093
9453
  this.lastFetchedAt = null;
9094
- /** Ordered list of userId strings from the most recent successful fetch. */
9095
- this.blockedUserIds = [];
9096
9454
  }
9097
- // ---------------------------------------------------------------------------
9098
- // SessionComponent lifecycle
9099
- // ---------------------------------------------------------------------------
9100
9455
  /** No-op — fetch is lazy, triggered by consumer calling getAllBlockedUsers(). */
9101
9456
  // eslint-disable-next-line class-methods-use-this
9102
9457
  onSessionEstablished() {
@@ -9105,24 +9460,17 @@ class BlockedUserSyncEngine {
9105
9460
  /** Resets state so the next session starts with a cold cache. */
9106
9461
  onSessionDestroyed() {
9107
9462
  this.lastFetchedAt = null;
9108
- this.blockedUserIds = [];
9109
9463
  }
9110
9464
  /** No-op for this engine. */
9111
9465
  // eslint-disable-next-line class-methods-use-this
9112
9466
  onTokenExpired() {
9113
9467
  // intentionally empty
9114
9468
  }
9115
- // ---------------------------------------------------------------------------
9116
- // Cache helpers
9117
- // ---------------------------------------------------------------------------
9118
9469
  isCacheExpired() {
9119
9470
  if (this.lastFetchedAt === null)
9120
9471
  return true;
9121
- return Date.now() - this.lastFetchedAt > TTL_MS;
9472
+ return Date.now() - this.lastFetchedAt > TTL_MS$1;
9122
9473
  }
9123
- // ---------------------------------------------------------------------------
9124
- // Core fetch gate
9125
- // ---------------------------------------------------------------------------
9126
9474
  /**
9127
9475
  * Ensures the local store is populated with fresh blocked-user data.
9128
9476
  *
@@ -9138,52 +9486,50 @@ class BlockedUserSyncEngine {
9138
9486
  if (!this.isCacheExpired())
9139
9487
  return;
9140
9488
  const client = getActiveClient();
9141
- const { data } = await client.http.get('/api/v4/me/user-blocks', { params: { options: { limit: BLOCK_LIST_LIMIT }, isDeleted: false } });
9489
+ const { data } = await client.http.get('/api/v4/me/user-blocks', { params: { options: { limit: BLOCK_LIST_LIMIT$1 }, isDeleted: false } });
9142
9490
  const cachedAt = client.cache && Date.now();
9143
9491
  const payload = prepareBlockedUserPayload(data);
9144
9492
  if (client.cache) {
9145
9493
  ingestInCache(payload, { cachedAt });
9146
9494
  }
9147
- // Keep the ordered list of blocked user IDs for getCachedUsers()
9148
- this.blockedUserIds = payload.users.map(u => u.userId);
9149
9495
  // Only update timestamp on success — failure leaves it unchanged so the
9150
9496
  // next call retries.
9151
9497
  this.lastFetchedAt = Date.now();
9152
9498
  }
9153
- // ---------------------------------------------------------------------------
9154
- // Local store read
9155
- // ---------------------------------------------------------------------------
9156
9499
  /**
9157
- * Returns blocked {@link Amity.InternalUser} objects from the in-memory cache.
9158
- *
9159
- * Applies the spec-mandated filter:
9160
- * - Only users whose `isDeleted` is false or null
9161
- * - Hard limit of 100 results
9500
+ * Returns the blocked users by querying the follow cache live — the outgoing
9501
+ * direction (`from === me`, `status === 'blocked'`). Reading the cache (not a
9502
+ * fetched snapshot) means `blockUser()` / `unblockUser()` changes are reflected
9503
+ * even within the TTL window.
9162
9504
  *
9163
- * This always reads the latest local state, so changes made by `blockUser()`
9164
- * and `unblockUser()` are reflected even within the TTL window.
9505
+ * Applies the spec-mandated query:
9506
+ * - filter `from === currentUserId`, `status === 'blocked'`, blocked user not deleted
9507
+ * - sort by `updatedAt` DESC
9508
+ * - hard limit of 100 results
9165
9509
  */
9510
+ // eslint-disable-next-line class-methods-use-this
9166
9511
  getCachedUsers() {
9512
+ var _a;
9167
9513
  const client = getActiveClient();
9168
- if (!client.cache) {
9169
- // No cache available — fall back to the in-memory list from the last fetch
9514
+ if (!client.cache)
9170
9515
  return [];
9171
- }
9172
- return this.blockedUserIds
9173
- .map(id => { var _a; return (_a = pullFromCache(['user', 'get', id])) === null || _a === void 0 ? void 0 : _a.data; })
9516
+ const { userId } = client;
9517
+ return ((_a = queryCache(['follow', 'get'])) !== null && _a !== void 0 ? _a : [])
9518
+ .map(entry => entry.data)
9519
+ .filter(follow => (follow === null || follow === void 0 ? void 0 : follow.status) === 'blocked' && follow.from === userId)
9520
+ .sort((a, b) => { var _a, _b; return (((_a = a.updatedAt) !== null && _a !== void 0 ? _a : '') < ((_b = b.updatedAt) !== null && _b !== void 0 ? _b : '') ? 1 : -1); })
9521
+ .map(follow => { var _a; return (_a = pullFromCache(['user', 'get', follow.to])) === null || _a === void 0 ? void 0 : _a.data; })
9174
9522
  .filter((user) => user != null && user.isDeleted !== true)
9175
- .slice(0, BLOCK_LIST_LIMIT);
9523
+ .slice(0, BLOCK_LIST_LIMIT$1)
9524
+ .map(userLinkedObject);
9176
9525
  }
9177
9526
  }
9178
- // ---------------------------------------------------------------------------
9179
- // Module-level singleton
9180
- // ---------------------------------------------------------------------------
9181
- let instance$2 = null;
9527
+ let instance$3 = null;
9182
9528
  var BlockedUserSyncEngine$1 = {
9183
9529
  getInstance: () => {
9184
- if (!instance$2)
9185
- instance$2 = new BlockedUserSyncEngine();
9186
- return instance$2;
9530
+ if (!instance$3)
9531
+ instance$3 = new BlockedUserSyncEngine();
9532
+ return instance$3;
9187
9533
  },
9188
9534
  };
9189
9535
 
@@ -9205,6 +9551,290 @@ var blockedUserSyncEngineOnLoginHandler = () => {
9205
9551
  };
9206
9552
  };
9207
9553
 
9554
+ function prepareBlockingUserPayload(response) {
9555
+ const { users, follows } = response, rest = __rest(response, ["users", "follows"]);
9556
+ return Object.assign(Object.assign({}, rest), { follows: follows.map(follow => {
9557
+ const followUser = users.find(user => user.userId === follow.from);
9558
+ return Object.assign(Object.assign({}, follow), { user: convertRawUserToInternalUser(followUser) });
9559
+ }), users: users.map(convertRawUserToInternalUser) });
9560
+ }
9561
+
9562
+ const BLOCK_LIST_LIMIT = 100;
9563
+ const TTL_MS = 5 * 60 * 1000; // 5 minutes
9564
+ /**
9565
+ * Session-scoped singleton engine that manages TTL-based fetching and caching
9566
+ * of blocking users (the "blocked-by" list — users who blocked the current
9567
+ * user). Provides a lazy `ensureFetched()` gate for the `getAllBlockingUsers()`
9568
+ * API. Directional inverse of {@link BlockedUserSyncEngine}.
9569
+ *
9570
+ * Key behaviours:
9571
+ * - `onSessionEstablished()` is a no-op — fetch is lazy, triggered only by consumer call
9572
+ * - `onSessionDestroyed()` resets `lastFetchedAt` to null (ensures fresh fetch on next session)
9573
+ * - `ensureFetched()` fetches from server only when cache is expired or never fetched
9574
+ * - `lastFetchedAt` is only updated on successful fetch
9575
+ * - reads query the follow cache live, so block/unblock changes are reflected
9576
+ * even within the TTL window
9577
+ *
9578
+ * @internal
9579
+ */
9580
+ class BlockingUserSyncEngine {
9581
+ constructor() {
9582
+ /** Epoch ms of last successful fetch. null = never fetched in this session. */
9583
+ this.lastFetchedAt = null;
9584
+ }
9585
+ /** No-op — fetch is lazy, triggered by consumer calling getAllBlockingUsers(). */
9586
+ // eslint-disable-next-line class-methods-use-this
9587
+ onSessionEstablished() {
9588
+ // intentionally empty
9589
+ }
9590
+ /** Resets state so the next session starts with a cold cache. */
9591
+ onSessionDestroyed() {
9592
+ this.lastFetchedAt = null;
9593
+ }
9594
+ /** No-op for this engine. */
9595
+ // eslint-disable-next-line class-methods-use-this
9596
+ onTokenExpired() {
9597
+ // intentionally empty
9598
+ }
9599
+ isCacheExpired() {
9600
+ if (this.lastFetchedAt === null)
9601
+ return true;
9602
+ return Date.now() - this.lastFetchedAt > TTL_MS;
9603
+ }
9604
+ /**
9605
+ * Ensures the local store is populated with fresh blocking-user data.
9606
+ *
9607
+ * - If the cache is still within the 5-minute TTL window: resolves immediately
9608
+ * (no server call).
9609
+ * - If the cache is expired (or never fetched): fetches from the server,
9610
+ * persists the payload to the cache, and updates `lastFetchedAt`.
9611
+ *
9612
+ * On failure the error propagates to the caller and `lastFetchedAt` is NOT
9613
+ * updated, so the next call will retry.
9614
+ */
9615
+ async ensureFetched() {
9616
+ if (!this.isCacheExpired())
9617
+ return;
9618
+ const client = getActiveClient();
9619
+ const { data } = await client.http.get('/api/v4/me/blockers', { params: { options: { limit: BLOCK_LIST_LIMIT }, isDeleted: false } });
9620
+ const cachedAt = client.cache && Date.now();
9621
+ const payload = prepareBlockingUserPayload(data);
9622
+ if (client.cache) {
9623
+ ingestInCache(payload, { cachedAt });
9624
+ }
9625
+ // Only update timestamp on success — failure leaves it unchanged so the
9626
+ // next call retries.
9627
+ this.lastFetchedAt = Date.now();
9628
+ }
9629
+ /**
9630
+ * Returns the "blocked-by" users by querying the follow cache live — the
9631
+ * incoming direction (`to === me`, `status === 'blocked'`). Reading the cache
9632
+ * (not a fetched snapshot) means RTE `user.didBlock` / `user.didUnblock`
9633
+ * changes are reflected even within the TTL window.
9634
+ *
9635
+ * Applies the spec-mandated query (REQ-012/013/014):
9636
+ * - filter `to === currentUserId`, `status === 'blocked'`, blocker not deleted
9637
+ * - sort by `updatedAt` DESC
9638
+ * - hard limit of 100 results
9639
+ */
9640
+ // eslint-disable-next-line class-methods-use-this
9641
+ getCachedUsers() {
9642
+ var _a;
9643
+ const client = getActiveClient();
9644
+ if (!client.cache)
9645
+ return [];
9646
+ const { userId } = client;
9647
+ return ((_a = queryCache(['follow', 'get'])) !== null && _a !== void 0 ? _a : [])
9648
+ .map(entry => entry.data)
9649
+ .filter(follow => (follow === null || follow === void 0 ? void 0 : follow.status) === 'blocked' && follow.to === userId)
9650
+ .sort((a, b) => { var _a, _b; return (((_a = a.updatedAt) !== null && _a !== void 0 ? _a : '') < ((_b = b.updatedAt) !== null && _b !== void 0 ? _b : '') ? 1 : -1); })
9651
+ .map(follow => { var _a; return (_a = pullFromCache(['user', 'get', follow.from])) === null || _a === void 0 ? void 0 : _a.data; })
9652
+ .filter((user) => user != null && user.isDeleted !== true)
9653
+ .slice(0, BLOCK_LIST_LIMIT)
9654
+ .map(userLinkedObject);
9655
+ }
9656
+ }
9657
+ let instance$2 = null;
9658
+ var BlockingUserSyncEngine$1 = {
9659
+ getInstance: () => {
9660
+ if (!instance$2)
9661
+ instance$2 = new BlockingUserSyncEngine();
9662
+ return instance$2;
9663
+ },
9664
+ };
9665
+
9666
+ var blockingUserSyncEngineOnLoginHandler = () => {
9667
+ const blockingUserSyncEngine = BlockingUserSyncEngine$1.getInstance();
9668
+ onSessionStateChange(state => {
9669
+ if (state === "established" /* Amity.SessionStates.ESTABLISHED */) {
9670
+ blockingUserSyncEngine.onSessionEstablished();
9671
+ }
9672
+ else if (state === "tokenExpired" /* Amity.SessionStates.TOKEN_EXPIRED */) {
9673
+ blockingUserSyncEngine.onTokenExpired();
9674
+ }
9675
+ else {
9676
+ blockingUserSyncEngine.onSessionDestroyed();
9677
+ }
9678
+ });
9679
+ return () => {
9680
+ blockingUserSyncEngine.onSessionDestroyed();
9681
+ };
9682
+ };
9683
+
9684
+ function prepareFollowersPayload(response) {
9685
+ const { users, follows } = response, rest = __rest(response, ["users", "follows"]);
9686
+ return Object.assign(Object.assign({}, rest), { follows, users: users.map(convertRawUserToInternalUser) });
9687
+ }
9688
+ function prepareFollowingsPayload(response) {
9689
+ const { users, follows } = response, rest = __rest(response, ["users", "follows"]);
9690
+ return Object.assign(Object.assign({}, rest), { follows, users: users.map(convertRawUserToInternalUser) });
9691
+ }
9692
+ function prepareFollowStatusPayload(response) {
9693
+ const { follows } = response, rest = __rest(response, ["follows"]);
9694
+ return Object.assign(Object.assign({}, rest), { follows });
9695
+ }
9696
+
9697
+ /**
9698
+ * Subscribes to a block MQTT event (`user.didBlock` / `user.didUnblock`),
9699
+ * ingests the carried `FollowersPayload` (follows + users) into the cache so
9700
+ * the block-relationship rows (`['follow', 'get', from#to]`) and user rows are
9701
+ * kept current, then forwards the affected {@link Amity.FollowStatus} to the
9702
+ * caller.
9703
+ *
9704
+ * @hidden
9705
+ */
9706
+ const createBlockEventSubscriber = (event, callback) => {
9707
+ const client = getActiveClient();
9708
+ const filter = (data) => {
9709
+ const payload = prepareFollowersPayload(data);
9710
+ if (client.cache) {
9711
+ ingestInCache(payload);
9712
+ }
9713
+ callback(payload.follows[0]);
9714
+ };
9715
+ return createEventSubscriber(client, event, event, filter);
9716
+ };
9717
+
9718
+ /**
9719
+ * ```js
9720
+ * import { onUserDidBlock } from '@amityco/ts-sdk'
9721
+ * const dispose = onUserDidBlock(status => {
9722
+ * // ...
9723
+ * })
9724
+ * ```
9725
+ *
9726
+ * Fired when a block relationship is created in real time — either a user
9727
+ * blocks the current user (incoming) or the current user blocks someone on
9728
+ * another device (outgoing). The local block-relationship store is updated
9729
+ * before the callback runs.
9730
+ *
9731
+ * @param callback The function to call when the event was fired
9732
+ * @returns an {@link Amity.Unsubscriber} function to stop listening
9733
+ *
9734
+ * @category Block Events
9735
+ */
9736
+ const onUserDidBlock = (callback) => createBlockEventSubscriber('user.didBlock', callback);
9737
+
9738
+ /**
9739
+ * ```js
9740
+ * import { onUserDidUnblock } from '@amityco/ts-sdk'
9741
+ * const dispose = onUserDidUnblock(status => {
9742
+ * // ...
9743
+ * })
9744
+ * ```
9745
+ *
9746
+ * Fired when a block relationship is removed in real time — either a user
9747
+ * unblocks the current user (incoming) or the current user unblocks someone on
9748
+ * another device (outgoing). The local block-relationship store is updated
9749
+ * before the callback runs.
9750
+ *
9751
+ * @param callback The function to call when the event was fired
9752
+ * @returns an {@link Amity.Unsubscriber} function to stop listening
9753
+ *
9754
+ * @category Block Events
9755
+ */
9756
+ const onUserDidUnblock = (callback) => createBlockEventSubscriber('user.didUnblock', callback);
9757
+
9758
+ /**
9759
+ * Keeps the follow cache current for incoming/outgoing block changes for the
9760
+ * whole session — the ingest happens as a side effect inside
9761
+ * createBlockEventSubscriber, so the one-shot `getAllBlockedUsers()` /
9762
+ * `getAllBlockingUsers()` reflect RTE block/unblock within the TTL window.
9763
+ *
9764
+ * Registered via `setupLoginSubscriptions`; the returned unsubscriber is torn
9765
+ * down on logout.
9766
+ */
9767
+ var blockRealtimeOnLoginHandler = () => {
9768
+ const disposers = [onUserDidBlock(() => { }), onUserDidUnblock(() => { })];
9769
+ return () => disposers.forEach(dispose => dispose());
9770
+ };
9771
+
9772
+ class CursorController {
9773
+ constructor(networkId, userId) {
9774
+ this.networkId = networkId;
9775
+ this.userId = userId;
9776
+ }
9777
+ static current() {
9778
+ try {
9779
+ const user = getCurrentUser();
9780
+ if (!user)
9781
+ return null;
9782
+ const networkId = getNetworkId(user);
9783
+ const { userId } = user;
9784
+ return networkId && userId ? new CursorController(networkId, userId) : null;
9785
+ }
9786
+ catch (_a) {
9787
+ return null;
9788
+ }
9789
+ }
9790
+ static isExpired(expiredAt) {
9791
+ return Date.now() >= expiredAt;
9792
+ }
9793
+ static clearOnLogout() {
9794
+ return onSessionStateChange(state => {
9795
+ var _a;
9796
+ if (state === "terminated" /* Amity.SessionStates.TERMINATED */)
9797
+ (_a = CursorController.current()) === null || _a === void 0 ? void 0 : _a.clear();
9798
+ });
9799
+ }
9800
+ get key() {
9801
+ return `amity:forYouFeed:cursor:${this.networkId}:${this.userId}`;
9802
+ }
9803
+ async get() {
9804
+ const raw = await getItem(this.key);
9805
+ if (!raw)
9806
+ return null;
9807
+ try {
9808
+ const parsed = JSON.parse(raw);
9809
+ if (typeof (parsed === null || parsed === void 0 ? void 0 : parsed.cursor) !== 'string' || typeof (parsed === null || parsed === void 0 ? void 0 : parsed.expiredAt) !== 'number')
9810
+ return null;
9811
+ return {
9812
+ cursor: parsed.cursor,
9813
+ expiredAt: parsed.expiredAt,
9814
+ reachedEndOfFeed: parsed.reachedEndOfFeed === true,
9815
+ };
9816
+ }
9817
+ catch (_a) {
9818
+ return null;
9819
+ }
9820
+ }
9821
+ async set(value) {
9822
+ await setItem(this.key, JSON.stringify(value));
9823
+ }
9824
+ async markReachedEndOfFeed(expiredAt) {
9825
+ var _a;
9826
+ const stored = await this.get();
9827
+ await this.set({
9828
+ cursor: (_a = stored === null || stored === void 0 ? void 0 : stored.cursor) !== null && _a !== void 0 ? _a : '',
9829
+ expiredAt,
9830
+ reachedEndOfFeed: true,
9831
+ });
9832
+ }
9833
+ async clear() {
9834
+ await setItem(this.key, '');
9835
+ }
9836
+ }
9837
+
9208
9838
  const EVENTS = [
9209
9839
  'disconnected',
9210
9840
  'error',
@@ -9394,7 +10024,7 @@ const setupLoginSubscriptions = (unsubWatcher) => {
9394
10024
  // NOTE: This is a temporary solution to handle the channel marker when the user is forced to leave
9395
10025
  // the channel because currently backend can't handle this, so every time a user is banned from
9396
10026
  // a channel or the channel is deleted the channel's unread count will not be reset to zero
9397
- onChannelDeleted(removeChannelMarkerCache), onChannelMemberBanned(removeChannelMarkerCache), markReadEngineOnLoginHandler(), analyticsEngineOnLoginHandler(), objectResolverEngineOnLoginHandler(), reactionSyncEngineOnLoginHandler(), blockedUserSyncEngineOnLoginHandler());
10027
+ onChannelDeleted(removeChannelMarkerCache), onChannelMemberBanned(removeChannelMarkerCache), markReadEngineOnLoginHandler(), analyticsEngineOnLoginHandler(), objectResolverEngineOnLoginHandler(), reactionSyncEngineOnLoginHandler(), blockedUserSyncEngineOnLoginHandler(), blockingUserSyncEngineOnLoginHandler(), blockRealtimeOnLoginHandler(), resetAutoSubscriptionsOnLogout(), CursorController.clearOnLogout());
9398
10028
  if (client.useLegacyUnreadCount) {
9399
10029
  subscriptions.push(readReceiptSyncEngineOnLoginHandler());
9400
10030
  }
@@ -10093,16 +10723,13 @@ const onMessageCreatedMqtt = (callback) => {
10093
10723
  }
10094
10724
  if (client.useLegacyUnreadCount) {
10095
10725
  rawPayload.messages.forEach(message => {
10096
- var _a, _b;
10726
+ var _a, _b, _c;
10097
10727
  const channelUnread = (_a = pullFromCache([
10098
10728
  'channelUnread',
10099
10729
  'get',
10100
10730
  message.channelId,
10101
10731
  ])) === null || _a === void 0 ? void 0 : _a.data;
10102
- if (!channelUnread ||
10103
- channelUnread.lastSegment >= message.segment ||
10104
- typeof channelUnread.readToSegment !== 'number' ||
10105
- typeof channelUnread.lastMentionedSegment !== 'number')
10732
+ if (!channelUnread || channelUnread.lastSegment >= message.segment)
10106
10733
  return;
10107
10734
  const lastSegment = message.segment;
10108
10735
  const isMentionedInMessage = (_b = message.mentionedUsers) === null || _b === void 0 ? void 0 : _b.some(mention => {
@@ -10114,7 +10741,8 @@ const onMessageCreatedMqtt = (callback) => {
10114
10741
  const lastMentionedSegment = isMentionedInMessage
10115
10742
  ? message.segment
10116
10743
  : channelUnread.lastMentionedSegment;
10117
- const updatedChannelUnread = Object.assign(Object.assign({}, channelUnread), { lastSegment, unreadCount: Math.max(lastSegment - channelUnread.readToSegment, 0), lastMentionedSegment, isMentioned: !(channelUnread.readToSegment >= lastMentionedSegment) });
10744
+ const readToSegment = (_c = channelUnread.readToSegment) !== null && _c !== void 0 ? _c : 0;
10745
+ const updatedChannelUnread = Object.assign(Object.assign({}, channelUnread), { lastSegment, unreadCount: Math.max(lastSegment - readToSegment, 0), lastMentionedSegment, isMentioned: typeof lastMentionedSegment === 'number' && readToSegment < lastMentionedSegment });
10118
10746
  pushToCache(['channelUnread', 'get', message.channelId], updatedChannelUnread);
10119
10747
  fireEvent('local.channelUnread.updated', [updatedChannelUnread]);
10120
10748
  });
@@ -10497,15 +11125,18 @@ const createClient = (apiKey, apiRegion = API_REGIONS.SG, { debugSession = DEFAU
10497
11125
  validateUrls,
10498
11126
  validateTexts,
10499
11127
  getFeedSettings,
11128
+ getCoreUserSettings,
10500
11129
  getSocialSettings,
11130
+ getChatSettings,
10501
11131
  getVisitorDeviceId: getDeviceId,
10502
- getMessagePreviewSetting,
11132
+ getMessagePreviewSetting: getMessagePreviewSetting$1,
10503
11133
  onRTEConnectionStateChange,
10504
11134
  use: () => setActiveClient(client),
10505
11135
  isUnreadCountEnabled,
10506
11136
  useLegacyUnreadCount,
10507
11137
  getMarkerSyncConsistentMode,
10508
11138
  getProductCatalogueSetting,
11139
+ getForYouFeedSetting,
10509
11140
  /**
10510
11141
  * Prefix for the deviceId key in the local storage or async storage.
10511
11142
  * This is allow user to have multiple SDK client and Mqtt client within the same app.
@@ -10817,6 +11448,13 @@ const getLinkPreviewMetadata = async (url) => {
10817
11448
  return data;
10818
11449
  };
10819
11450
 
11451
+ const CONTENT_TYPE_CONFIG = {
11452
+ [exports.AmitySharableContentType.POST]: { key: 'posts', placeholder: 'postId' },
11453
+ [exports.AmitySharableContentType.COMMUNITY]: { key: 'communities', placeholder: 'communityId' },
11454
+ [exports.AmitySharableContentType.USER]: { key: 'users', placeholder: 'userId' },
11455
+ [exports.AmitySharableContentType.LIVESTREAM]: { key: 'livestream', placeholder: 'livestream' },
11456
+ [exports.AmitySharableContentType.EVENT]: { key: 'events', placeholder: 'eventId' },
11457
+ };
10820
11458
  /**
10821
11459
  * ```js
10822
11460
  * import Client from '@amityco/ts-sdk-react-native'
@@ -10832,9 +11470,29 @@ const getLinkPreviewMetadata = async (url) => {
10832
11470
  * @async
10833
11471
  */
10834
11472
  const getShareableLinkConfiguration = async () => {
11473
+ var _a, _b;
10835
11474
  const client = getActiveClient();
10836
11475
  const { data } = await client.http.get(`/api/v3/network-settings/shareable-deep-links`);
10837
- return data;
11476
+ const domain = (_a = data.domain) !== null && _a !== void 0 ? _a : '';
11477
+ const patterns = (_b = data.patterns) !== null && _b !== void 0 ? _b : {};
11478
+ return {
11479
+ domain,
11480
+ patterns,
11481
+ isEnabled(contentType) {
11482
+ const { key } = CONTENT_TYPE_CONFIG[contentType];
11483
+ return !!domain && !!patterns[key];
11484
+ },
11485
+ getPattern(contentType) {
11486
+ const { key } = CONTENT_TYPE_CONFIG[contentType];
11487
+ return patterns[key] || null;
11488
+ },
11489
+ generateLink(contentType, referenceId) {
11490
+ const { key, placeholder } = CONTENT_TYPE_CONFIG[contentType];
11491
+ if (!domain || !patterns[key])
11492
+ return null;
11493
+ return domain + patterns[key].replace(`{${placeholder}}`, referenceId);
11494
+ },
11495
+ };
10838
11496
  };
10839
11497
 
10840
11498
  /**
@@ -11025,6 +11683,205 @@ const setAccessTokenHandler = (accessTokenHandler) => {
11025
11683
  client.accessTokenHandler = accessTokenHandler;
11026
11684
  };
11027
11685
 
11686
+ function parseRolesFilter(listenFromRoleIds, ignoreFromRoleIds) {
11687
+ if (ignoreFromRoleIds && ignoreFromRoleIds.length > 0) {
11688
+ return { type: 'not', roleIds: ignoreFromRoleIds };
11689
+ }
11690
+ if (listenFromRoleIds && listenFromRoleIds.length > 0) {
11691
+ return { type: exports.NotificationRolesFilterTypeEnum.ONLY, roleIds: listenFromRoleIds };
11692
+ }
11693
+ return { type: exports.NotificationRolesFilterTypeEnum.ALL };
11694
+ }
11695
+ function serializeRolesFilter(rolesFilter) {
11696
+ if ((rolesFilter === null || rolesFilter === void 0 ? void 0 : rolesFilter.type) === exports.NotificationRolesFilterTypeEnum.ONLY) {
11697
+ return { listenFromRoleIds: rolesFilter.roleIds };
11698
+ }
11699
+ return { listenFromRoleIds: [] };
11700
+ }
11701
+ class ChannelNotifications {
11702
+ constructor(channelId) {
11703
+ this.channelId = channelId;
11704
+ }
11705
+ async enable() {
11706
+ const client = getActiveClient();
11707
+ const body = {
11708
+ level: exports.NotificationSettingsLevelEnum.CHANNEL,
11709
+ channelId: this.channelId,
11710
+ isPushNotifiable: true,
11711
+ };
11712
+ await client.http.post('/api/v3/notification/setting', body);
11713
+ }
11714
+ async disable() {
11715
+ const client = getActiveClient();
11716
+ const body = {
11717
+ level: exports.NotificationSettingsLevelEnum.CHANNEL,
11718
+ channelId: this.channelId,
11719
+ isPushNotifiable: false,
11720
+ };
11721
+ await client.http.post('/api/v3/notification/setting', body);
11722
+ }
11723
+ async getSettings() {
11724
+ const client = getActiveClient();
11725
+ const { data } = await client.http.get(`/api/v3/notification/setting?level=${exports.NotificationSettingsLevelEnum.CHANNEL}&channelId=${encodeURIComponent(this.channelId)}`);
11726
+ return { isEnabled: data.isPushNotifiable };
11727
+ }
11728
+ }
11729
+ class UserNotifications {
11730
+ async enable(modules) {
11731
+ var _a;
11732
+ const client = getActiveClient();
11733
+ const notifiableEvents = (_a = modules === null || modules === void 0 ? void 0 : modules.map(module => (Object.assign({ moduleName: module.moduleName, isPushNotifiable: module.isEnabled }, serializeRolesFilter(module.rolesFilter))))) !== null && _a !== void 0 ? _a : [];
11734
+ const body = {
11735
+ level: exports.NotificationSettingsLevelEnum.USER,
11736
+ isPushNotifiable: true,
11737
+ notifiableEvents,
11738
+ };
11739
+ await client.http.post('/api/v3/notification/setting', body);
11740
+ }
11741
+ async disableAllNotifications() {
11742
+ const client = getActiveClient();
11743
+ const body = {
11744
+ level: exports.NotificationSettingsLevelEnum.USER,
11745
+ isPushNotifiable: false,
11746
+ notifiableEvents: [],
11747
+ };
11748
+ await client.http.post('/api/v3/notification/setting', body);
11749
+ }
11750
+ async getSettings() {
11751
+ var _a;
11752
+ const client = getActiveClient();
11753
+ const { data } = await client.http.get(`/api/v3/notification/setting?level=${exports.NotificationSettingsLevelEnum.USER}`);
11754
+ const validModuleNames = Object.values(exports.UserNotificationModuleNameEnum);
11755
+ const modules = ((_a = data.notifiableEvents) !== null && _a !== void 0 ? _a : [])
11756
+ .filter(e => e.moduleName != null && validModuleNames.includes(e.moduleName))
11757
+ .map(e => ({
11758
+ moduleName: e.moduleName,
11759
+ isEnabled: e.isPushNotifiable,
11760
+ rolesFilter: parseRolesFilter(e.listenFromRoleIds, e.ignoreFromRoleIds),
11761
+ }));
11762
+ return { isEnabled: data.isPushNotifiable, modules };
11763
+ }
11764
+ }
11765
+ class CommunityNotifications {
11766
+ constructor(communityId) {
11767
+ this.communityId = communityId;
11768
+ }
11769
+ async enable(events) {
11770
+ var _a;
11771
+ const client = getActiveClient();
11772
+ const notifiableEvents = (_a = events === null || events === void 0 ? void 0 : events.map(event => (Object.assign({ moduleName: exports.UserNotificationModuleNameEnum.SOCIAL, name: event.eventName, isPushNotifiable: event.isEnabled }, serializeRolesFilter(event.rolesFilter))))) !== null && _a !== void 0 ? _a : [];
11773
+ const body = {
11774
+ level: exports.NotificationSettingsLevelEnum.COMMUNITY,
11775
+ communityId: this.communityId,
11776
+ isPushNotifiable: true,
11777
+ notifiableEvents,
11778
+ };
11779
+ await client.http.post('/api/v3/notification/setting', body);
11780
+ }
11781
+ async disable() {
11782
+ const client = getActiveClient();
11783
+ const body = {
11784
+ level: exports.NotificationSettingsLevelEnum.COMMUNITY,
11785
+ communityId: this.communityId,
11786
+ isPushNotifiable: false,
11787
+ notifiableEvents: [],
11788
+ };
11789
+ await client.http.post('/api/v3/notification/setting', body);
11790
+ }
11791
+ async getSettings() {
11792
+ var _a;
11793
+ const client = getActiveClient();
11794
+ const { data } = await client.http.get(`/api/v3/notification/setting?level=${exports.NotificationSettingsLevelEnum.COMMUNITY}&communityId=${encodeURIComponent(this.communityId)}`);
11795
+ const validEventNames = Object.values(exports.CommunityNotificationEventNameEnum);
11796
+ const events = ((_a = data.notifiableEvents) !== null && _a !== void 0 ? _a : [])
11797
+ .filter(e => e.name != null && validEventNames.includes(e.name))
11798
+ .map(e => ({
11799
+ eventName: e.name,
11800
+ isEnabled: e.isPushNotifiable,
11801
+ isNetworkEnabled: e.isNetworkEnabled,
11802
+ rolesFilter: parseRolesFilter(e.listenFromRoleIds, e.ignoreFromRoleIds),
11803
+ }));
11804
+ return { isEnabled: data.isPushNotifiable, events };
11805
+ }
11806
+ }
11807
+ class Notifications {
11808
+ user() {
11809
+ return new UserNotifications();
11810
+ }
11811
+ community(communityId) {
11812
+ return new CommunityNotifications(communityId);
11813
+ }
11814
+ channel(channelId) {
11815
+ return new ChannelNotifications(channelId);
11816
+ }
11817
+ }
11818
+ const notifications = () => new Notifications();
11819
+
11820
+ /* begin_public_function
11821
+ id: client.enable_auto_subscriptions
11822
+ */
11823
+ /**
11824
+ * ```js
11825
+ * import { Client, AmityAutoSubscription } from '@amityco/ts-sdk'
11826
+ * Client.enableAutoSubscriptions([AmityAutoSubscription.BLOCK])
11827
+ * ```
11828
+ *
11829
+ * Enables one or more managed auto-subscription handles. Managed handles are
11830
+ * re-applied on every (re)connect and ref-counted. All handles are on by
11831
+ * default; use this to re-enable handles previously turned off via
11832
+ * {@link disableAutoSubscriptions}. Synchronous fire-and-forget — the registry
11833
+ * updates immediately and the broker subscribe is retried on reconnect.
11834
+ *
11835
+ * @param features the {@link AmityAutoSubscription} handles to enable
11836
+ *
11837
+ * @category Client API
11838
+ */
11839
+ const enableAutoSubscriptions = (features) => {
11840
+ const manager = getAutoSubscriptionManager();
11841
+ features.forEach(feature => manager.subscribe(feature));
11842
+ };
11843
+ /* end_public_function */
11844
+ /* begin_public_function
11845
+ id: client.disable_auto_subscriptions
11846
+ */
11847
+ /**
11848
+ * ```js
11849
+ * import { Client, AmityAutoSubscription } from '@amityco/ts-sdk'
11850
+ * Client.disableAutoSubscriptions([AmityAutoSubscription.LIVESTREAM])
11851
+ * ```
11852
+ *
11853
+ * Disables one or more managed auto-subscription handles. The change persists
11854
+ * across reconnect (it is not silently re-enabled) until
11855
+ * {@link enableAutoSubscriptions} is called again. Synchronous fire-and-forget.
11856
+ *
11857
+ * @param features the {@link AmityAutoSubscription} handles to disable
11858
+ *
11859
+ * @category Client API
11860
+ */
11861
+ const disableAutoSubscriptions = (features) => {
11862
+ const manager = getAutoSubscriptionManager();
11863
+ features.forEach(feature => manager.unsubscribe(feature));
11864
+ };
11865
+ /* end_public_function */
11866
+ /* begin_public_function
11867
+ id: client.auto_subscriptions
11868
+ */
11869
+ /**
11870
+ * ```js
11871
+ * import { Client } from '@amityco/ts-sdk'
11872
+ * Client.autoSubscriptions().forEach(s => console.log(s.feature, s.isActive, s.topicCount))
11873
+ * ```
11874
+ *
11875
+ * Inspects the managed auto-subscription registry — each handle's `isActive`,
11876
+ * `isSystem`, and `topicCount`.
11877
+ *
11878
+ * @returns a snapshot of the managed subscription registry
11879
+ *
11880
+ * @category Client API
11881
+ */
11882
+ const autoSubscriptions = () => getAutoSubscriptionManager().subscriptions();
11883
+ /* end_public_function */
11884
+
11028
11885
  /**
11029
11886
  * ```js
11030
11887
  * import { onChannelMarkerFetched } from '@amityco/ts-sdk-react-native'
@@ -11402,12 +12259,19 @@ var index$s = /*#__PURE__*/Object.freeze({
11402
12259
  getSocialSettings: getSocialSettings,
11403
12260
  getShareableLinkConfiguration: getShareableLinkConfiguration,
11404
12261
  getProductCatalogueSetting: getProductCatalogueSetting,
12262
+ getForYouFeedSetting: getForYouFeedSetting,
11405
12263
  loginAsVisitor: loginAsVisitor,
11406
12264
  loginAsBot: loginAsBot,
11407
12265
  getCurrentUser: getCurrentUser,
11408
12266
  getCurrentUserType: getCurrentUserType,
11409
12267
  setCurrentUserType: setCurrentUserType,
11410
12268
  setAccessTokenHandler: setAccessTokenHandler,
12269
+ getChatSettings: getChatSettings,
12270
+ getCoreUserSettings: getCoreUserSettings,
12271
+ notifications: notifications,
12272
+ enableAutoSubscriptions: enableAutoSubscriptions,
12273
+ disableAutoSubscriptions: disableAutoSubscriptions,
12274
+ autoSubscriptions: autoSubscriptions,
11411
12275
  onConnectionError: onConnectionError,
11412
12276
  onClientDisconnected: onClientDisconnected,
11413
12277
  onClientBanned: onClientBanned,
@@ -11425,19 +12289,6 @@ var index$s = /*#__PURE__*/Object.freeze({
11425
12289
  getMarkerSyncConsistentMode: getMarkerSyncConsistentMode
11426
12290
  });
11427
12291
 
11428
- function prepareFollowersPayload(response) {
11429
- const { users, follows } = response, rest = __rest(response, ["users", "follows"]);
11430
- return Object.assign(Object.assign({}, rest), { follows, users: users.map(convertRawUserToInternalUser) });
11431
- }
11432
- function prepareFollowingsPayload(response) {
11433
- const { users, follows } = response, rest = __rest(response, ["users", "follows"]);
11434
- return Object.assign(Object.assign({}, rest), { follows, users: users.map(convertRawUserToInternalUser) });
11435
- }
11436
- function prepareFollowStatusPayload(response) {
11437
- const { follows } = response, rest = __rest(response, ["follows"]);
11438
- return Object.assign(Object.assign({}, rest), { follows });
11439
- }
11440
-
11441
12292
  /* begin_public_function
11442
12293
  id: user.relationship.block
11443
12294
  */
@@ -12615,6 +13466,8 @@ var index$r = /*#__PURE__*/Object.freeze({
12615
13466
  __proto__: null,
12616
13467
  blockUser: blockUser,
12617
13468
  unBlockUser: unBlockUser,
13469
+ onUserDidBlock: onUserDidBlock,
13470
+ onUserDidUnblock: onUserDidUnblock,
12618
13471
  follow: follow,
12619
13472
  unfollow: unfollow,
12620
13473
  acceptMyFollower: acceptMyFollower,
@@ -13444,7 +14297,7 @@ const getWatchSessionStorage = () => {
13444
14297
  return storageInstance;
13445
14298
  };
13446
14299
 
13447
- const privateKey = "-----BEGIN PRIVATE KEY-----\nMIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQDAARz+hmBgi8pJ\nQb8LeY41gtHhk+ACMwRfhsn7GqpqRQNG2qU0755mzZuVDUqjQMGSo8THJB7O+OJs\nflbZRkFXlFoFOVNw1UpNOgwEQZ6wB9oRwzepTJAfF1sVhm/o/ixvXh1zDFNDy6yZ\npXyiiJHUVxqyjllZhxnwdvjoVtDs6hW6awG09bB9nh/TTejlUKXoAgzqVwu/1QMu\nUVViET495elEe19aUarEy+oL2iKeXCEvqda/pWNBdbieFyJvvZ08HN8dPuT88wq2\njZLEAth1vrwQ2IAa4ktaLcBQdLJgIkrbDvAiVZ8lQAjS/bq5vXQikTGvoPlC5bbn\nvuOM/3eLAgMBAAECggEAVZ+peHAghq2QVj71nX5lxsNCKaCyYwixSJBpfouTt7Rz\nE6PpzMOXFi1W1o+I22jDakuSM2SOQKqI/u0QefB0r0O/KVk5NrZHXk0mkrdYtxOp\nUgaGyf8UvmjB+8VqHrNKyZdk9qtmbnNj01kTTcAtmE4H39zPR7eR/8Rul94vaZbs\nwCnKJS3mLT3JxyGug6lxanveKkjG+CKC1nJQYWaxCJxaFSzbwXQPvDhB+TvrIbee\npd5v4EAyEJohpr+T9oDGGJkb/KARBZCtwLyB976PKJwwBA8MRVL1i5QwawuMiMq5\nUtnOnbGKtCeFzaLbNU0Qi8bqyims84EQxC6DOu1fkQKBgQDdvsoBsEhsOXV7hlIJ\naEd0eSJZVkdqimxH8uGoMM2FeNaOrcB6yBXqTSP0R3OIyf8eaY6yjRvP30ZNXcll\n/gD3O1Mu6YmWQdt1W2WA6pKOsUuPXasf0pdOF7IiFZKlSabz5YHXFqwVuqm8loaj\nsXel3YWqPVdHiankE7tz+3ssnQKBgQDdqi4TNdD1MdEpihx19jr0QjUiXW3939FK\nqp30HESPEGDGQzXdmJgif9HhZb+cJSuWaHEbjgBrYahvgCF+y6LbEpOD+D/dmT+s\nDEAQaR84sah6dokwPjV8fjBSrcVFjCS+doxv0d3p/9OUEeyUhFrY03nxtIEYkLIE\n/Zvn37b4RwKBgQCLENVFe9XfsaVhQ5r9dV2iyTlmh7qgMZG5CbTFs12hQGhm8McO\n+Z7s41YSJCFr/yq1WwP4LJDtrBw99vyQr1zRsG35tNLp3gGRNzGQSQyC2uQFVHw2\np+7mNewsfhUK/gbrXNsyFnDz6635rPlhfbII3sWuP2wWXFqkxE9CbMwR7QKBgQC6\nawDMzxmo2/iYArrkyevSuEuPVxvFwpF1RgAI6C0QVCnPE38dmdN4UB7mfHekje4W\nVEercMURidPp0cxZolCYBQtilUjAyL0vqC3In1/Ogjq6oy3FEMxSop1pKxMY5j+Q\nnoqFD+6deLUrddeNH7J3X4LSr4dSbX4JjG+tlgt+yQKBgQCuwTL4hA6KqeInQ0Ta\n9VQX5Qr8hFlqJz1gpymi/k63tW/Ob8yedbg3WWNWyShwRMFYyY9S81ITFWM95uL6\nvF3x9rmRjwElJw9PMwVu6dmf/CO0Z1wzXSp2VVD12gbrUD/0/d7MUoJ9LgC8X8f/\nn0txLHYGHbx+nf95+JUg6lV3hg==\n-----END PRIVATE KEY-----";
14300
+ const privateKey = "-----BEGIN PRIVATE KEY-----\nMIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDHo80SecH7FuF2\nhFYnb+l26/VN8UMLXAQFLnxciNTEwkGVFMpdezlH8rU2HtUJL4RETogbAOLVY0XM\njs6sPn8G1nALmh9qeDpUtVqFOVtBHxEZ910TLOtQiunjqJKO5nWdqZ71EC3OFluR\niGQkO84BiIFbv37ub7xl3S8XarbtKoLcyVpkDHi+1wx1pgCAn6gtBUgckPL5NR8j\nLseabl3HAXQfhTCKo4tmOFM2Dxwl1IUMmIJrJg/aIU/U0tj/1Eoo7mG0JcNWX19l\nW3EecCbi0ncCJOrkUdwlBrcjaMayaX/ubEwyUeTGiLdyc4L3GRLHjyK8xgVNXRMH\nbZWJ2a5NAgMBAAECggEASxuE+35zTFO/XydKgmvIGcWL9FbgMlXb7Vcf0nBoG945\nbiz0NVc2paraIhJXc608xbYF3qLmtAE1MVBI0ORyRdBHNxY024l/6H6SH60Ed+uI\nM4ysp5ourY6Vj+DLwpdRiI9YDjqYAQDIUmhNxJP7XPhOMoZI6st+xZQBM34ic/bv\nAMSJm9OZphSp3+qXVkFZztr2mxD2EZSJJLYxi8BCdgM2qhazalbcJ6zDKHCZWVWm\n8RRxDGldyMb/237JxETzP40tAlzOZDmBAbUgEnurDJ93RVDIE3rbZUshwgeQd18a\nem096mWgvB1AIKYgsTAR3pw+V19YWAjq/glP6fz8wQKBgQD/oQq+ukKF0PRgBeM5\ngeTjSwsdGppQLmf5ndujvoiz/TpdjDEPu6R8kigQr1rG2t4K/yfdZoI8RdmJD1al\n3Q7N9hofooSy4rj6E3txzWZCHJjHad2cnCp/O26HiReGAl7wTcfTmNdiFHhZQzm5\nJBkvWAiwuvQMNfEbnXxw6/vIDwKBgQDH7fX8gsc77JLvAWgp1MaQN/sbqVb6JeT1\nFQfR8E/WFCSmzQBtNzd5KgYuCeelwr/8DyYytvN2BzCYZXp73gI1jF3YlW5jVn74\nOY6TwQ095digwo6Z0yuxopdIOApKgAkL9PRKgNrqAf3NAyMua6lOGifzjDojC3KU\nfylQmxMn4wKBgHp2B9O/H0dEBw5JQ8W0+JX6yWQz7mEjGiR2/1W+XXb8hQ1zr709\nw1r6Gb+EghRpnZ3fBpYGGbYOMFx8wKHM+N6qW3F0ReX8v2juFGE8aRSa5oYBrWzt\nU16Idjbv8hj84cZ1PJmdyvDtpYn9rpWHOZl4rxEbPvbqkIsOMyNVqdT5AoGAOSge\nmwIIU2le2FVeohbibXiToWTYKMuMmURZ5/r72AgKMmWJKbAPe+Q3wBG01/7FRBpQ\noU8Ma0HC8s6QJbliiEyIx9JwrJWd1vkdecBHONrtA4ibm/5zD2WcOllLF+FitLhi\n3qnX6+6F0IaFGFBPJrTzlv0P4dTz/OAdv52V7GECgYEA2TttOKBAqWllgOaZOkql\nLVMJVmgR7s6tLi1+cEP8ZcapV9aRbRzTAKXm4f8AEhtlG9F9kCOvHYCYGi6JaiWJ\nZkHjeex3T+eE6Di6y5Bm/Ift5jtVhJ4jCVwHOKTMej79NPUFTJfv8hCo29haBDv6\nRXFrv+T21KCcw8k3sJeJWWQ=\n-----END PRIVATE KEY-----";
13448
14301
  /*
13449
14302
  * The crypto algorithm used for importing key and signing string
13450
14303
  */
@@ -14766,6 +15619,10 @@ const postLinkedObject = (post) => {
14766
15619
  const analyticsEngineInstance = AnalyticsEngine$1.getInstance();
14767
15620
  analyticsEngineInstance.markPostAsViewed(post.postId);
14768
15621
  },
15622
+ markAsMeaningfullyViewed: (feedRenderPosition) => {
15623
+ const analyticsEngineInstance = AnalyticsEngine$1.getInstance();
15624
+ analyticsEngineInstance.markPostAsMeaningfullyViewed(post.postId, feedRenderPosition);
15625
+ },
14769
15626
  },
14770
15627
  get productTags() {
14771
15628
  var _a, _b;
@@ -14955,6 +15812,11 @@ const addReaction$1 = async (referenceType, referenceId, reactionName, reference
14955
15812
  });
14956
15813
  return true;
14957
15814
  }
15815
+ if (referenceType === 'message') {
15816
+ upsertInCache(['message', 'get', referenceId], updatedModel);
15817
+ fireEvent('local.message.updated', { messages: [updatedModel] });
15818
+ return true;
15819
+ }
14958
15820
  }
14959
15821
  return true;
14960
15822
  };
@@ -15033,7 +15895,7 @@ const removeReaction$1 = async (referenceType, referenceId, reactionName, refere
15033
15895
  return true;
15034
15896
  }
15035
15897
  if (referenceType === 'story') {
15036
- fireEvent('local.story.reactionAdded', {
15898
+ fireEvent('local.story.reactionRemoved', {
15037
15899
  story: updatedModel,
15038
15900
  reactor: {
15039
15901
  userId: client.userId,
@@ -15043,6 +15905,11 @@ const removeReaction$1 = async (referenceType, referenceId, reactionName, refere
15043
15905
  });
15044
15906
  return true;
15045
15907
  }
15908
+ if (referenceType === 'message') {
15909
+ upsertInCache(['message', 'get', referenceId], updatedModel);
15910
+ fireEvent('local.message.updated', { messages: [updatedModel] });
15911
+ return true;
15912
+ }
15046
15913
  }
15047
15914
  return true;
15048
15915
  };
@@ -15315,7 +16182,7 @@ const createEventResponseSubscriber = (event, callback) => {
15315
16182
  const eventResponse = pullFromCache([
15316
16183
  'eventResponse',
15317
16184
  'get',
15318
- payload.eventResponses[0].eventId,
16185
+ unpackedPayload.eventResponses[0].userId,
15319
16186
  ]);
15320
16187
  callback(eventResponse.data);
15321
16188
  }
@@ -15979,7 +16846,38 @@ const getAllBlockedUsers = async () => {
15979
16846
  const engine = BlockedUserSyncEngine$1.getInstance();
15980
16847
  // Ensure data is fetched (no-op if cache is fresh)
15981
16848
  await engine.ensureFetched();
15982
- // Read from the engine's bounded ID list — O(blocked users) not O(cache size)
16849
+ return engine.getCachedUsers();
16850
+ };
16851
+ /* end_public_function */
16852
+
16853
+ /* begin_public_function
16854
+ id: user.get_all_blocking_users
16855
+ */
16856
+ /**
16857
+ * ```js
16858
+ * import { UserRepository } from '@amityco/ts-sdk'
16859
+ * const blockingUsers = await UserRepository.getAllBlockingUsers()
16860
+ * ```
16861
+ *
16862
+ * Returns all users who have blocked the current user
16863
+ * non-paginated list (limit 100) with TTL-based caching (5-minute window). Within the
16864
+ * TTL window, subsequent calls resolve instantly from the local store without any
16865
+ * server call. After the TTL expires, the next call triggers a fresh server fetch.
16866
+ *
16867
+ * The directional inverse of {@link getAllBlockedUsers}.
16868
+ *
16869
+ * @returns A promise that resolves to an array of blocking {@link Amity.User} objects
16870
+ *
16871
+ * @category Block API
16872
+ * @async
16873
+ */
16874
+ const getAllBlockingUsers = async () => {
16875
+ const client = getActiveClient();
16876
+ client.log('user/getAllBlockingUsers');
16877
+ const engine = BlockingUserSyncEngine$1.getInstance();
16878
+ // Ensure data is fetched (no-op if cache is fresh)
16879
+ await engine.ensureFetched();
16880
+ // Read from the engine's bounded ID list — O(blocking users) not O(cache size)
15983
16881
  return engine.getCachedUsers();
15984
16882
  };
15985
16883
  /* end_public_function */
@@ -16362,6 +17260,12 @@ class BlockedUserPaginationController extends PaginationController {
16362
17260
  }
16363
17261
  }
16364
17262
 
17263
+ var EnumBlockActions;
17264
+ (function (EnumBlockActions) {
17265
+ EnumBlockActions["OnBlocked"] = "onBlocked";
17266
+ EnumBlockActions["OnUnblocked"] = "onUnblocked";
17267
+ })(EnumBlockActions || (EnumBlockActions = {}));
17268
+
16365
17269
  class BlockedUserQueryStreamController extends QueryStreamController {
16366
17270
  constructor(query, cacheKey, notifyChange, preparePayload) {
16367
17271
  super(query, cacheKey);
@@ -16391,11 +17295,16 @@ class BlockedUserQueryStreamController extends QueryStreamController {
16391
17295
  }
16392
17296
  reactor(action) {
16393
17297
  return (targetUser) => {
16394
- var _a;
16395
- if (action === EnumFollowActions.OnFollowed) {
17298
+ var _a, _b;
17299
+ const isRemoval = action === EnumFollowActions.OnFollowed || action === EnumBlockActions.OnUnblocked;
17300
+ const isAddition = action === EnumBlockActions.OnBlocked;
17301
+ if (isRemoval || isAddition) {
16396
17302
  const collection = (_a = pullFromCache(this.cacheKey)) === null || _a === void 0 ? void 0 : _a.data;
16397
- const updatedCollection = collection === null || collection === void 0 ? void 0 : collection.data.filter(id => id !== targetUser.userId);
16398
- pushToCache(this.cacheKey, Object.assign(Object.assign({}, collection), { data: updatedCollection }));
17303
+ const ids = (_b = collection === null || collection === void 0 ? void 0 : collection.data) !== null && _b !== void 0 ? _b : [];
17304
+ const data = isAddition
17305
+ ? [...new Set([...ids, targetUser.userId])]
17306
+ : ids.filter(id => id !== targetUser.userId);
17307
+ pushToCache(this.cacheKey, Object.assign(Object.assign({}, collection), { data }));
16399
17308
  }
16400
17309
  this.notifyChange({ origin: "event" /* Amity.LiveDataOrigin.EVENT */, loading: false });
16401
17310
  };
@@ -16450,7 +17359,6 @@ class BlockedUserLiveCollectionController extends LiveCollectionController {
16450
17359
  fn: onUserDeleted$2,
16451
17360
  action: EnumUserActions.OnUserDeleted,
16452
17361
  },
16453
- // In the case of unblocking a user, we need to subscribe to the follow events
16454
17362
  {
16455
17363
  fn: convertEventPayload(onLocalUserFollowed, 'to', 'user'),
16456
17364
  action: EnumFollowActions.OnFollowed,
@@ -16459,6 +17367,28 @@ class BlockedUserLiveCollectionController extends LiveCollectionController {
16459
17367
  fn: convertEventPayload(onUserFollowed, 'to', 'user'),
16460
17368
  action: EnumFollowActions.OnFollowed,
16461
17369
  },
17370
+ {
17371
+ fn: (reactor) => onUserDidBlock(status => {
17372
+ var _a;
17373
+ if (status.from !== getActiveClient().userId)
17374
+ return;
17375
+ const blocked = (_a = pullFromCache(['user', 'get', status.to])) === null || _a === void 0 ? void 0 : _a.data;
17376
+ if (blocked)
17377
+ reactor(blocked);
17378
+ }),
17379
+ action: EnumBlockActions.OnBlocked,
17380
+ },
17381
+ {
17382
+ fn: (reactor) => onUserDidUnblock(status => {
17383
+ var _a;
17384
+ if (status.from !== getActiveClient().userId)
17385
+ return;
17386
+ const blocked = (_a = pullFromCache(['user', 'get', status.to])) === null || _a === void 0 ? void 0 : _a.data;
17387
+ if (blocked)
17388
+ reactor(blocked);
17389
+ }),
17390
+ action: EnumBlockActions.OnUnblocked,
17391
+ },
16462
17392
  ]);
16463
17393
  }
16464
17394
  notifyChange({ origin, loading, error }) {
@@ -16526,6 +17456,184 @@ const getBlockedUsers = (params, callback, config) => {
16526
17456
  };
16527
17457
  /* end_public_function */
16528
17458
 
17459
+ class BlockingUserQueryStreamController extends QueryStreamController {
17460
+ constructor(query, cacheKey, notifyChange, preparePayload) {
17461
+ super(query, cacheKey);
17462
+ this.notifyChange = notifyChange;
17463
+ this.preparePayload = preparePayload;
17464
+ }
17465
+ async saveToMainDB(response) {
17466
+ const processedPayload = await this.preparePayload(response);
17467
+ const client = getActiveClient();
17468
+ const cachedAt = client.cache && Date.now();
17469
+ if (client.cache) {
17470
+ ingestInCache(processedPayload, { cachedAt });
17471
+ }
17472
+ }
17473
+ appendToQueryStream(response, direction, refresh = false) {
17474
+ var _a, _b;
17475
+ if (refresh) {
17476
+ pushToCache(this.cacheKey, {
17477
+ data: response.users.map(getResolver('user')),
17478
+ });
17479
+ }
17480
+ else {
17481
+ const collection = (_a = pullFromCache(this.cacheKey)) === null || _a === void 0 ? void 0 : _a.data;
17482
+ const users = (_b = collection === null || collection === void 0 ? void 0 : collection.data) !== null && _b !== void 0 ? _b : [];
17483
+ pushToCache(this.cacheKey, Object.assign(Object.assign({}, collection), { data: [...new Set([...users, ...response.users.map(getResolver('user'))])] }));
17484
+ }
17485
+ }
17486
+ reactor(action) {
17487
+ return (user) => {
17488
+ var _a, _b;
17489
+ if (user &&
17490
+ (action === EnumBlockActions.OnBlocked || action === EnumBlockActions.OnUnblocked)) {
17491
+ const collection = (_a = pullFromCache(this.cacheKey)) === null || _a === void 0 ? void 0 : _a.data;
17492
+ const ids = (_b = collection === null || collection === void 0 ? void 0 : collection.data) !== null && _b !== void 0 ? _b : [];
17493
+ const data = action === EnumBlockActions.OnBlocked
17494
+ ? [...new Set([...ids, user.userId])]
17495
+ : ids.filter(id => id !== user.userId);
17496
+ pushToCache(this.cacheKey, Object.assign(Object.assign({}, collection), { data }));
17497
+ }
17498
+ this.notifyChange({ origin: "event" /* Amity.LiveDataOrigin.EVENT */, loading: false });
17499
+ };
17500
+ }
17501
+ subscribeRTE(createSubscriber) {
17502
+ return createSubscriber.map(subscriber => subscriber.fn(this.reactor(subscriber.action)));
17503
+ }
17504
+ }
17505
+
17506
+ class BlockingUserPaginationController extends PaginationController {
17507
+ async getRequest(queryParams, token) {
17508
+ const { limit = COLLECTION_DEFAULT_PAGINATION_SIZE } = queryParams, params = __rest(queryParams, ["limit"]);
17509
+ const options = token ? { token } : { limit };
17510
+ const { data: queryResponse } = await this.http.get('/api/v4/me/blockers', {
17511
+ params: Object.assign(Object.assign({}, params), { options, isDeleted: false }),
17512
+ });
17513
+ return queryResponse;
17514
+ }
17515
+ }
17516
+
17517
+ class BlockingUserLiveCollectionController extends LiveCollectionController {
17518
+ constructor(callback) {
17519
+ const queryStreamId = `blocking-users-${getActiveClient().userId}`;
17520
+ const query = {};
17521
+ const cacheKey = ['blockingUsers', 'collection', queryStreamId];
17522
+ const paginationController = new BlockingUserPaginationController(query);
17523
+ super(paginationController, queryStreamId, cacheKey, callback);
17524
+ this.queryStreamController = new BlockingUserQueryStreamController(query, this.cacheKey, this.notifyChange.bind(this), prepareBlockingUserPayload);
17525
+ this.callback = callback.bind(this);
17526
+ this.loadPage({ initial: true });
17527
+ }
17528
+ setup() {
17529
+ var _a;
17530
+ const collection = (_a = pullFromCache(this.cacheKey)) === null || _a === void 0 ? void 0 : _a.data;
17531
+ if (!collection) {
17532
+ pushToCache(this.cacheKey, {
17533
+ data: [],
17534
+ params: {},
17535
+ });
17536
+ }
17537
+ }
17538
+ async persistModel(queryPayload) {
17539
+ await this.queryStreamController.saveToMainDB(queryPayload);
17540
+ }
17541
+ persistQueryStream({ response, direction, refresh, }) {
17542
+ this.queryStreamController.appendToQueryStream(response, direction, refresh);
17543
+ }
17544
+ startSubscription() {
17545
+ return this.queryStreamController.subscribeRTE([
17546
+ {
17547
+ fn: onUserDeleted$2,
17548
+ action: EnumUserActions.OnUserDeleted,
17549
+ },
17550
+ {
17551
+ fn: (reactor) => onUserDidBlock(status => {
17552
+ var _a;
17553
+ if (status.to !== getActiveClient().userId)
17554
+ return;
17555
+ const blocker = (_a = pullFromCache(['user', 'get', status.from])) === null || _a === void 0 ? void 0 : _a.data;
17556
+ if (blocker)
17557
+ reactor(blocker);
17558
+ }),
17559
+ action: EnumBlockActions.OnBlocked,
17560
+ },
17561
+ {
17562
+ fn: (reactor) => onUserDidUnblock(status => {
17563
+ var _a;
17564
+ if (status.to !== getActiveClient().userId)
17565
+ return;
17566
+ const blocker = (_a = pullFromCache(['user', 'get', status.from])) === null || _a === void 0 ? void 0 : _a.data;
17567
+ if (blocker)
17568
+ reactor(blocker);
17569
+ }),
17570
+ action: EnumBlockActions.OnUnblocked,
17571
+ },
17572
+ ]);
17573
+ }
17574
+ notifyChange({ origin, loading, error }) {
17575
+ var _a, _b;
17576
+ const collection = (_a = pullFromCache(this.cacheKey)) === null || _a === void 0 ? void 0 : _a.data;
17577
+ if (!collection)
17578
+ return;
17579
+ const data = this.applyFilter((_b = collection.data
17580
+ .map(id => pullFromCache(['user', 'get', id]))
17581
+ .filter(isNonNullable)
17582
+ .map(({ data }) => data)
17583
+ .map(LinkedObject.user)) !== null && _b !== void 0 ? _b : []);
17584
+ if (!this.shouldNotify(data) && origin === 'event')
17585
+ return;
17586
+ this.callback({
17587
+ onNextPage: () => this.loadPage({ direction: "next" /* Amity.LiveCollectionPageDirection.NEXT */ }),
17588
+ data,
17589
+ hasNextPage: !!this.paginationController.getNextToken(),
17590
+ loading,
17591
+ error,
17592
+ });
17593
+ }
17594
+ applyFilter(data) {
17595
+ let users = data;
17596
+ users = users.filter(user => user.isDeleted == null || user.isDeleted === false);
17597
+ return users;
17598
+ }
17599
+ }
17600
+
17601
+ /* begin_public_function
17602
+ id: user.get_blocking_users
17603
+ */
17604
+ /**
17605
+ * ```js
17606
+ * import { UserRepository } from '@amityco/ts-sdk'
17607
+ * const unsubscribe = UserRepository.getBlockingUsers(({ data: users }) => {
17608
+ * console.log(users)
17609
+ * })
17610
+ * ```
17611
+ *
17612
+ * Observe the {@link Amity.User}s who have blocked the current user
17613
+ *
17614
+ * @param callback to receive updates on the blocking {@link Amity.User}s
17615
+ * @returns {@link Amity.Unsubscriber} to unsubscribe from collection
17616
+ *
17617
+ * @category User API
17618
+ */
17619
+ const getBlockingUsers = (callback) => {
17620
+ const { log, cache } = getActiveClient();
17621
+ if (!cache)
17622
+ console.log(ENABLE_CACHE_MESSAGE);
17623
+ const timestamp = Date.now();
17624
+ log(`getBlockingUsers(tmpid: ${timestamp}) > listen`);
17625
+ const blockingUserLiveCollection = new BlockingUserLiveCollectionController(callback);
17626
+ const disposers = blockingUserLiveCollection.startSubscription();
17627
+ const cacheKey = blockingUserLiveCollection.getCacheKey();
17628
+ disposers.push(() => dropFromCache(cacheKey));
17629
+ return () => {
17630
+ log(`getBlockingUsers(tmpid: ${timestamp}) > dispose`);
17631
+ disposers.forEach(fn => fn());
17632
+ dropFromCache(cacheKey);
17633
+ };
17634
+ };
17635
+ /* end_public_function */
17636
+
16529
17637
  class SearchUserPaginationController extends PaginationController {
16530
17638
  async getRequest(queryParams, token) {
16531
17639
  const { limit = COLLECTION_DEFAULT_PAGINATION_LIMIT, displayName } = queryParams, params = __rest(queryParams, ["limit", "displayName"]);
@@ -16792,6 +17900,7 @@ var index$q = /*#__PURE__*/Object.freeze({
16792
17900
  unflagUser: unflagUser,
16793
17901
  isUserFlaggedByMe: isUserFlaggedByMe,
16794
17902
  getAllBlockedUsers: getAllBlockedUsers,
17903
+ getAllBlockingUsers: getAllBlockingUsers,
16795
17904
  onUserUpdated: onUserUpdated,
16796
17905
  onUserDeleted: onUserDeleted$2,
16797
17906
  onUserFlagged: onUserFlagged,
@@ -16800,6 +17909,7 @@ var index$q = /*#__PURE__*/Object.freeze({
16800
17909
  getUser: getUser,
16801
17910
  getUsers: getUsers,
16802
17911
  getBlockedUsers: getBlockedUsers,
17912
+ getBlockingUsers: getBlockingUsers,
16803
17913
  searchUserByDisplayName: searchUserByDisplayName,
16804
17914
  getReachedUsers: getReachedUsers,
16805
17915
  get AmityUserSearchMatchType () { return AmityUserSearchMatchType; }
@@ -16864,129 +17974,6 @@ getFile.locally = (fileId) => {
16864
17974
  };
16865
17975
  };
16866
17976
 
16867
- /**
16868
- * Builds the axios request config for multipart file uploads.
16869
- *
16870
- * ## Why this exists (React Native 0.83 New Architecture)
16871
- *
16872
- * Previously every upload hardcoded `{ 'content-type': 'multipart/form-data' }`.
16873
- * That header has **no `boundary`**, which breaks multipart uploads on React
16874
- * Native's New Architecture (Bridgeless): the request body is sent without the
16875
- * file bytes (it surfaces as `[object Object]` / `Stream Closed` /
16876
- * `AxiosError: Network Error`, or the server replies `400 "No files uploaded."`).
16877
- *
16878
- * The correct behaviour for the React Native / browser environment is to let
16879
- * the platform networking layer (XMLHttpRequest) serialize the `FormData` and
16880
- * generate the `multipart/form-data; boundary=…` header itself. So we must NOT
16881
- * set the content-type at all in that environment.
16882
- *
16883
- * We also pin `adapter: 'xhr'` so axios always routes the request through React
16884
- * Native's `XMLHttpRequest` (which understands RN file parts), rather than
16885
- * auto-selecting the `fetch` adapter that the New Architecture now also exposes.
16886
- *
16887
- * On Node (the `form-data` package exposes `getHeaders()`), we keep using its
16888
- * generated headers — which already include the correct boundary — and leave
16889
- * the adapter selection to axios (its http adapter, via the configured agents).
16890
- *
16891
- * @param formData The multipart payload about to be uploaded.
16892
- * @returns A partial axios config to spread into the upload request.
16893
- *
16894
- * @category File Util
16895
- * @hidden
16896
- */
16897
- const getUploadRequestConfig = (formData) => {
16898
- // Node `form-data` instances expose getHeaders() (with a valid boundary).
16899
- if ('getHeaders' in formData) {
16900
- return { headers: formData.getHeaders() };
16901
- }
16902
- // React Native / browser.
16903
- //
16904
- // Set `multipart/form-data` explicitly. We must NOT omit it: when omitted,
16905
- // axios applies its default POST content-type (`application/x-www-form-urlencoded`)
16906
- // and the server rejects the upload (`multipart != application/x-www-form-urlencoded`).
16907
- // React Native's native networking layer appends the real `boundary=…` to this
16908
- // header when it serializes a (recognized) FormData body.
16909
- //
16910
- // `adapter: 'xhr'` pins axios to React Native's XMLHttpRequest (which
16911
- // understands RN file parts) instead of the `fetch` adapter the New
16912
- // Architecture also exposes.
16913
- //
16914
- // NOTE: this only works if the FormData instance is recognized as multipart.
16915
- // See `recreateUploadFormData` — the upload APIs rebuild the FormData in the
16916
- // SDK's own module realm first, otherwise axios/XHR treat it as a plain object
16917
- // and send `[object Object]`.
16918
- return {
16919
- headers: { 'content-type': 'multipart/form-data' },
16920
- adapter: 'xhr',
16921
- };
16922
- };
16923
-
16924
- /**
16925
- * Rebuilds a multipart `FormData` inside the SDK's own module realm.
16926
- *
16927
- * ## Why this is required (React Native 0.83 New Architecture)
16928
- *
16929
- * When the app/UIKit constructs `new FormData()` from a *different* module realm
16930
- * than the SDK (which happens with `.tgz`/duplicate-`react-native` setups, and
16931
- * is common under the New Architecture), the resulting instance is NOT an
16932
- * `instanceof` the `FormData` that the SDK's axios — and React Native's native
16933
- * `XMLHttpRequest` — reference.
16934
- *
16935
- * As a result `axios.isFormData()` returns `false`, so axios:
16936
- * - serializes the body as a plain object → it goes out as `"[object Object]"`, and
16937
- * - applies its default POST content-type (`application/x-www-form-urlencoded`),
16938
- * which the upload server rejects with
16939
- * `"multipart != application/x-www-form-urlencoded"`.
16940
- *
16941
- * Re-creating the FormData here, with the SDK's own `new FormData()`, produces an
16942
- * instance both axios and RN's XHR recognize, so the file is sent as a real
16943
- * multipart body.
16944
- *
16945
- * We also backfill the file part's MIME `type` (via the file name/URI) because
16946
- * React Native on Android does not set it by default, and the backend rejects
16947
- * file parts without a content type.
16948
- *
16949
- * Only React Native's `FormData` exposes `getParts()`. For Node's `form-data`
16950
- * package or a spec-compliant `FormData`, there is nothing to normalize and the
16951
- * original instance is returned unchanged.
16952
- *
16953
- * @param formData The FormData passed in by the caller.
16954
- * @returns A FormData safe to hand to the upload transport.
16955
- *
16956
- * @category File Util
16957
- * @hidden
16958
- */
16959
- const recreateUploadFormData = (formData) => {
16960
- const source = formData;
16961
- if (typeof source.getParts !== 'function') {
16962
- return formData;
16963
- }
16964
- const rebuilt = new FormData();
16965
- source.getParts().forEach(part => {
16966
- var _a;
16967
- const { fieldName } = part;
16968
- // String fields (accessType, preferredFilename, feedType, altText, …).
16969
- if (typeof part.string === 'string') {
16970
- rebuilt.append(fieldName, part.string);
16971
- return;
16972
- }
16973
- // File parts are represented as `{ uri, name?, type? }` in React Native.
16974
- if (part.uri) {
16975
- const type = part.type ||
16976
- ((_a = part.headers) === null || _a === void 0 ? void 0 : _a['content-type']) ||
16977
- (part.name && mime__default["default"].getType(part.name)) ||
16978
- mime__default["default"].getType(part.uri) ||
16979
- undefined;
16980
- rebuilt.append(fieldName, {
16981
- uri: part.uri,
16982
- name: part.name,
16983
- type,
16984
- });
16985
- }
16986
- });
16987
- return rebuilt;
16988
- };
16989
-
16990
17977
  /* begin_public_function
16991
17978
  id: file.upload.file
16992
17979
  */
@@ -17005,10 +17992,8 @@ const recreateUploadFormData = (formData) => {
17005
17992
  * @category File API
17006
17993
  * @async
17007
17994
  */
17008
- const uploadFile = async (inputFormData, onProgress) => {
17995
+ const uploadFile = async (formData, onProgress) => {
17009
17996
  const client = getActiveClient();
17010
- // Rebuild in the SDK's realm so axios/XHR serialize it as real multipart.
17011
- const formData = recreateUploadFormData(inputFormData);
17012
17997
  client.log('file/uploadFile', formData);
17013
17998
  const files = formData.getAll('files');
17014
17999
  if (!files.length)
@@ -17016,9 +18001,15 @@ const uploadFile = async (inputFormData, onProgress) => {
17016
18001
  const accessType = GlobalFileAccessType$1.getInstance().getFileAccessType();
17017
18002
  formData.append('accessType', accessType);
17018
18003
  formData.append('preferredFilename', files[0].name);
17019
- const { data } = await client.upload.post('/api/v4/files', formData, Object.assign(Object.assign({}, getUploadRequestConfig(formData)), { onUploadProgress({ loaded, total = 100 }) {
18004
+ const headers = 'getHeaders' in formData
18005
+ ? formData.getHeaders()
18006
+ : { 'content-type': 'multipart/form-data' };
18007
+ const { data } = await client.upload.post('/api/v4/files', formData, {
18008
+ headers,
18009
+ onUploadProgress({ loaded, total = 100 }) {
17020
18010
  onProgress && onProgress(Math.round((loaded * 100) / total));
17021
- } }));
18011
+ },
18012
+ });
17022
18013
  // API-FIX: payload should be serialized properly
17023
18014
  // const { files } = data
17024
18015
  const cachedAt = client.cache && Date.now();
@@ -17088,10 +18079,8 @@ const fileUrlWithSize = (fileUrl, size) => {
17088
18079
  * @category File API
17089
18080
  * @async
17090
18081
  */
17091
- const uploadVideo = async (inputFormData, feedType, onProgress) => {
18082
+ const uploadVideo = async (formData, feedType, onProgress) => {
17092
18083
  const client = getActiveClient();
17093
- // Rebuild in the SDK's realm so axios/XHR serialize it as real multipart.
17094
- const formData = recreateUploadFormData(inputFormData);
17095
18084
  client.log('file/uploadVideo', formData);
17096
18085
  const files = formData.getAll('files');
17097
18086
  if (!files.length)
@@ -17102,9 +18091,15 @@ const uploadVideo = async (inputFormData, feedType, onProgress) => {
17102
18091
  if (feedType) {
17103
18092
  formData.append('feedType', feedType);
17104
18093
  }
17105
- const { data } = await client.upload.post('/api/v4/videos', formData, Object.assign(Object.assign({}, getUploadRequestConfig(formData)), { onUploadProgress({ loaded, total = 100 }) {
18094
+ const headers = 'getHeaders' in formData
18095
+ ? formData.getHeaders()
18096
+ : { 'content-type': 'multipart/form-data' };
18097
+ const { data } = await client.upload.post('/api/v4/videos', formData, {
18098
+ headers,
18099
+ onUploadProgress({ loaded, total = 100 }) {
17106
18100
  onProgress && onProgress(Math.round((loaded * 100) / total));
17107
- } }));
18101
+ },
18102
+ });
17108
18103
  // API-FIX: payload should be serialized properly
17109
18104
  // const { files } = data
17110
18105
  const cachedAt = client.cache && Date.now();
@@ -17136,11 +18131,8 @@ const uploadVideo = async (inputFormData, feedType, onProgress) => {
17136
18131
  * @category File API
17137
18132
  * @async
17138
18133
  */
17139
- const uploadImage = async (inputFormData, onProgress, altText) => {
18134
+ const uploadImage = async (formData, onProgress, altText) => {
17140
18135
  const client = getActiveClient();
17141
- // Rebuild the FormData in the SDK's realm so axios/XHR serialize it as real
17142
- // multipart (otherwise it is sent as "[object Object]"). See helper for details.
17143
- const formData = recreateUploadFormData(inputFormData);
17144
18136
  client.log('file/uploadImage', formData);
17145
18137
  const files = formData.getAll('files');
17146
18138
  if (files === null || files === void 0 ? void 0 : files.length) {
@@ -17160,9 +18152,15 @@ const uploadImage = async (inputFormData, onProgress, altText) => {
17160
18152
  }
17161
18153
  const accessType = GlobalFileAccessType$1.getInstance().getFileAccessType();
17162
18154
  formData.append('accessType', accessType);
17163
- const { data } = await client.upload.post('/api/v4/images', formData, Object.assign(Object.assign({}, getUploadRequestConfig(formData)), { onUploadProgress({ loaded, total = 100 }) {
18155
+ const headers = 'getHeaders' in formData
18156
+ ? formData.getHeaders()
18157
+ : { 'content-type': 'multipart/form-data' };
18158
+ const { data } = await client.upload.post('/api/v4/images', formData, {
18159
+ headers,
18160
+ onUploadProgress({ loaded, total = 100 }) {
17164
18161
  onProgress && onProgress(Math.round((loaded * 100) / total));
17165
- } }));
18162
+ },
18163
+ });
17166
18164
  // API-FIX: payload should be serialized properly
17167
18165
  // const { files } = data
17168
18166
  const cachedAt = client.cache && Date.now();
@@ -17224,10 +18222,8 @@ const updateAltText = async (fileId, altText) => {
17224
18222
  * @category File API
17225
18223
  * @async
17226
18224
  */
17227
- const uploadClip = async (inputFormData, feedType, onProgress) => {
18225
+ const uploadClip = async (formData, feedType, onProgress) => {
17228
18226
  const client = getActiveClient();
17229
- // Rebuild in the SDK's realm so axios/XHR serialize it as real multipart.
17230
- const formData = recreateUploadFormData(inputFormData);
17231
18227
  client.log('file/uploadClip', formData);
17232
18228
  const file = formData.get('files');
17233
18229
  if (!file)
@@ -17238,9 +18234,15 @@ const uploadClip = async (inputFormData, feedType, onProgress) => {
17238
18234
  if (feedType) {
17239
18235
  formData.append('feedType', feedType);
17240
18236
  }
17241
- const { data } = await client.upload.post('/api/v4/clips', formData, Object.assign(Object.assign({}, getUploadRequestConfig(formData)), { onUploadProgress({ loaded, total = 100 }) {
18237
+ const headers = 'getHeaders' in formData
18238
+ ? formData.getHeaders()
18239
+ : { 'content-type': 'multipart/form-data' };
18240
+ const { data } = await client.upload.post('/api/v4/clips', formData, {
18241
+ headers,
18242
+ onUploadProgress({ loaded, total = 100 }) {
17242
18243
  onProgress && onProgress(Math.round((loaded * 100) / total));
17243
- } }));
18244
+ },
18245
+ });
17244
18246
  // API-FIX: payload should be serialized properly
17245
18247
  // const { files } = data
17246
18248
  const cachedAt = client.cache && Date.now();
@@ -17271,10 +18273,8 @@ const uploadClip = async (inputFormData, feedType, onProgress) => {
17271
18273
  * @category File API
17272
18274
  * @async
17273
18275
  */
17274
- const uploadAudio = async (inputFormData, onProgress) => {
18276
+ const uploadAudio = async (formData, onProgress) => {
17275
18277
  const client = getActiveClient();
17276
- // Rebuild in the SDK's realm so axios/XHR serialize it as real multipart.
17277
- const formData = recreateUploadFormData(inputFormData);
17278
18278
  client.log('file/uploadAudio', formData);
17279
18279
  const files = formData.getAll('file');
17280
18280
  if (files.length === 0)
@@ -17283,9 +18283,13 @@ const uploadAudio = async (inputFormData, onProgress) => {
17283
18283
  const accessType = GlobalFileAccessType$1.getInstance().getFileAccessType();
17284
18284
  formData.append('accessType', accessType);
17285
18285
  formData.append('preferredFilename', file.name);
17286
- const { data } = await client.upload.post('/api/v4/audios', formData, Object.assign(Object.assign({}, getUploadRequestConfig(formData)), { onUploadProgress({ loaded, total = 100 }) {
18286
+ const headers = { 'content-type': 'multipart/form-data' };
18287
+ const { data } = await client.upload.post('/api/v4/audios', formData, {
18288
+ headers,
18289
+ onUploadProgress({ loaded, total = 100 }) {
17287
18290
  onProgress === null || onProgress === void 0 ? void 0 : onProgress(Math.round((loaded * 100) / total));
17288
- } }));
18291
+ },
18292
+ });
17289
18293
  const cachedAt = client.cache && Date.now();
17290
18294
  if (client.cache)
17291
18295
  ingestInCache({ files: data }, { cachedAt });
@@ -18072,7 +19076,7 @@ const removeReaction = async (referenceType, referenceId, reactionName) => {
18072
19076
  return true;
18073
19077
  }
18074
19078
  if (referenceType === 'story') {
18075
- fireEvent('local.story.reactionAdded', {
19079
+ fireEvent('local.story.reactionRemoved', {
18076
19080
  story: updatedModel,
18077
19081
  reactor: {
18078
19082
  userId: client.userId,
@@ -19656,6 +20660,104 @@ const unmuteChannel = async (channelId) => {
19656
20660
  };
19657
20661
  /* end_public_function */
19658
20662
 
20663
+ /* begin_public_function
20664
+ id: channel.archive
20665
+ */
20666
+ /**
20667
+ * ```js
20668
+ * import { ChannelRepository } from '@amityco/ts-sdk'
20669
+ * const success = await ChannelRepository.archiveChannel('foobar')
20670
+ * ```
20671
+ *
20672
+ * Archive a {@link Amity.Channel}.
20673
+ *
20674
+ * @param channelId The id of the {@link Amity.Channel} to archive
20675
+ * @returns A success boolean
20676
+ *
20677
+ * @category Channel API
20678
+ * @async
20679
+ */
20680
+ const archiveChannel = async (channelId) => {
20681
+ const client = getActiveClient();
20682
+ client.log('channel/archiveChannel', channelId);
20683
+ await client.http.post(`/api/v1/archives/channels/${encodeURIComponent(channelId)}`);
20684
+ const archive = {
20685
+ channelId,
20686
+ archivedAt: new Date().toISOString(),
20687
+ };
20688
+ if (client.cache) {
20689
+ pushToCache(['archivedChannel', 'get', getResolver('archivedChannel')(archive)], archive);
20690
+ }
20691
+ fireEvent('local.channel.archived', { archives: [archive] });
20692
+ };
20693
+ /* end_public_function */
20694
+
20695
+ /* begin_public_function
20696
+ id: channel.unarchive
20697
+ */
20698
+ /**
20699
+ * ```js
20700
+ * import { ChannelRepository } from '@amityco/ts-sdk'
20701
+ * const success = await ChannelRepository.unarchiveChannel('foobar')
20702
+ * ```
20703
+ *
20704
+ * Unarchive a previously archived {@link Amity.Channel}.
20705
+ *
20706
+ * @param channelId The id of the {@link Amity.Channel} to unarchive
20707
+ * @returns A success boolean
20708
+ *
20709
+ * @category Channel API
20710
+ * @async
20711
+ */
20712
+ const unarchiveChannel = async (channelId) => {
20713
+ var _a;
20714
+ const client = getActiveClient();
20715
+ client.log('channel/unarchiveChannel', channelId);
20716
+ await client.http.delete(`/api/v1/archives/channels/${encodeURIComponent(channelId)}`);
20717
+ const cached = (_a = pullFromCache(['archivedChannel', 'get', channelId])) === null || _a === void 0 ? void 0 : _a.data;
20718
+ const archive = cached !== null && cached !== void 0 ? cached : {
20719
+ channelId,
20720
+ archivedAt: new Date().toISOString(),
20721
+ };
20722
+ if (client.cache) {
20723
+ dropFromCache(['archivedChannel', 'get', channelId], true);
20724
+ }
20725
+ fireEvent('local.channel.unarchived', { archives: [archive] });
20726
+ };
20727
+ /* end_public_function */
20728
+
20729
+ /* begin_public_function
20730
+ id: channel.archive.ids
20731
+ */
20732
+ /**
20733
+ * ```js
20734
+ * import { ChannelRepository } from '@amityco/ts-sdk'
20735
+ * const ids = await ChannelRepository.getArchivedChannelIds()
20736
+ * ```
20737
+ *
20738
+ * @returns A list of archived channel ids sorted by `archivedAt` descending.
20739
+ *
20740
+ * @category Channel API
20741
+ * @async
20742
+ */
20743
+ const getArchivedChannelIds = async () => {
20744
+ var _a;
20745
+ const client = getActiveClient();
20746
+ client.log('channel/getArchivedChannelIds');
20747
+ const { data: payload } = await client.http.get(`/api/v1/archives/channels`);
20748
+ const archives = (_a = payload.archives) !== null && _a !== void 0 ? _a : [];
20749
+ if (client.cache) {
20750
+ dropFromCache(['archivedChannel', 'get']);
20751
+ archives.forEach(archive => {
20752
+ if (!archive.channelId)
20753
+ return;
20754
+ pushToCache(['archivedChannel', 'get', archive.channelId], archive);
20755
+ });
20756
+ }
20757
+ return archives.map(entry => entry.channelId).filter(channelId => !!channelId);
20758
+ };
20759
+ /* end_public_function */
20760
+
19659
20761
  /**
19660
20762
  * ```js
19661
20763
  * import { onMessageUpdated } from '@amityco/ts-sdk-react-native'
@@ -21034,6 +22136,160 @@ const getMessages = (params, callback, config) => {
21034
22136
  };
21035
22137
  /* end_public_function */
21036
22138
 
22139
+ class SearchMessagePaginationController extends PaginationController {
22140
+ async getRequest(queryParams, token) {
22141
+ const { query, exactMatch, channelId, messageFeedId, userIds, tags, types, sortBy, orderBy, limit = COLLECTION_DEFAULT_PAGINATION_LIMIT, } = queryParams;
22142
+ const options = token ? { token } : { limit, sortBy, orderBy };
22143
+ const { data: queryResponse } = await this.http.get(`/api/v2/search/messages`, {
22144
+ params: {
22145
+ query,
22146
+ exactMatch,
22147
+ channelId,
22148
+ messageFeedId,
22149
+ userIds,
22150
+ tags,
22151
+ types,
22152
+ options,
22153
+ },
22154
+ });
22155
+ return queryResponse;
22156
+ }
22157
+ }
22158
+
22159
+ class SearchMessageQueryStreamController extends QueryStreamController {
22160
+ constructor(query, cacheKey, notifyChange) {
22161
+ super(query, cacheKey);
22162
+ this.notifyChange = notifyChange;
22163
+ }
22164
+ async saveToMainDB(response) {
22165
+ var _a;
22166
+ const processedPayload = await prepareMessagePayload(response);
22167
+ const client = getActiveClient();
22168
+ const cachedAt = client.cache && Date.now();
22169
+ if (client.cache) {
22170
+ ingestInCache(processedPayload, { cachedAt });
22171
+ if ((_a = response.channels) === null || _a === void 0 ? void 0 : _a.length) {
22172
+ response.channels.forEach(channel => {
22173
+ pushToCache(['channel', 'get', channel.channelId], channel, { cachedAt });
22174
+ });
22175
+ }
22176
+ }
22177
+ }
22178
+ appendToQueryStream(response, direction, refresh = false) {
22179
+ var _a, _b;
22180
+ if (refresh) {
22181
+ pushToCache(this.cacheKey, {
22182
+ data: response.messages.map(getResolver('message')),
22183
+ });
22184
+ return;
22185
+ }
22186
+ const collection = (_a = pullFromCache(this.cacheKey)) === null || _a === void 0 ? void 0 : _a.data;
22187
+ const existing = (_b = collection === null || collection === void 0 ? void 0 : collection.data) !== null && _b !== void 0 ? _b : [];
22188
+ const incoming = response.messages.map(getResolver('message'));
22189
+ pushToCache(this.cacheKey, Object.assign(Object.assign({}, collection), { data: direction === "prev" /* Amity.LiveCollectionPageDirection.PREV */
22190
+ ? [...new Set([...incoming, ...existing])]
22191
+ : [...new Set([...existing, ...incoming])] }));
22192
+ }
22193
+ }
22194
+
22195
+ class SearchMessageLiveCollectionController extends LiveCollectionController {
22196
+ constructor(query, callback) {
22197
+ const queryStreamId = hash__default["default"](query);
22198
+ const cacheKey = ['message', 'search', queryStreamId];
22199
+ const paginationController = new SearchMessagePaginationController(query);
22200
+ super(paginationController, queryStreamId, cacheKey, callback);
22201
+ this.queryStreamController = new SearchMessageQueryStreamController(query, this.cacheKey, this.notifyChange.bind(this));
22202
+ this.callback = callback.bind(this);
22203
+ this.loadPage({ initial: true });
22204
+ }
22205
+ startSubscription() {
22206
+ return [];
22207
+ }
22208
+ notifyChange({ origin, loading, error }) {
22209
+ var _a, _b;
22210
+ const collection = (_a = pullFromCache(this.cacheKey)) === null || _a === void 0 ? void 0 : _a.data;
22211
+ if (!collection)
22212
+ return;
22213
+ const data = (_b = collection.data
22214
+ .map(messageId => getMessageFromMainDB(messageId))
22215
+ .filter(isNonNullable)
22216
+ .map(message => LinkedObject.message(message))) !== null && _b !== void 0 ? _b : [];
22217
+ if (!this.shouldNotify(data) && origin === 'event')
22218
+ return;
22219
+ this.callback({
22220
+ onNextPage: () => this.loadPage({ direction: "next" /* Amity.LiveCollectionPageDirection.NEXT */ }),
22221
+ data,
22222
+ hasNextPage: !!this.paginationController.getNextToken(),
22223
+ loading,
22224
+ error,
22225
+ });
22226
+ }
22227
+ setup() {
22228
+ var _a;
22229
+ const collection = (_a = pullFromCache(this.cacheKey)) === null || _a === void 0 ? void 0 : _a.data;
22230
+ if (!collection) {
22231
+ pushToCache(this.cacheKey, {
22232
+ data: [],
22233
+ params: {},
22234
+ });
22235
+ }
22236
+ }
22237
+ async persistModel(response) {
22238
+ await this.queryStreamController.saveToMainDB(response);
22239
+ }
22240
+ persistQueryStream({ response, direction, refresh, }) {
22241
+ this.queryStreamController.appendToQueryStream(response, direction, refresh);
22242
+ }
22243
+ }
22244
+
22245
+ /* begin_public_function
22246
+ id: message.search
22247
+ */
22248
+ /**
22249
+ * ```js
22250
+ * import { MessageRepository } from '@amityco/ts-sdk';
22251
+ *
22252
+ * let messages = [];
22253
+ *
22254
+ * const unsubscribe = MessageRepository.searchMessage(
22255
+ * { query: 'hello' },
22256
+ * response => merge(messages, response.data),
22257
+ * );
22258
+ * ```
22259
+ *
22260
+ * Live collection of {@link Amity.Message}s matching the search query. Backed
22261
+ * by `GET /api/v2/search/messages`. The first emission delivers the first
22262
+ * page; pagination is driven by `response.onNextPage()`.
22263
+ *
22264
+ * @param params Search parameters. `query` is required.
22265
+ * @param callback Called whenever new data are available.
22266
+ * @returns An {@link Amity.Unsubscriber} function to stop observing.
22267
+ *
22268
+ * @category Message Live Collection
22269
+ */
22270
+ const searchMessage = (params, callback) => {
22271
+ if (!params.query || params.query.trim().length === 0) {
22272
+ throw new Error('Query is required for message search');
22273
+ }
22274
+ const { log, cache } = getActiveClient();
22275
+ if (!cache) {
22276
+ console.log(ENABLE_CACHE_MESSAGE);
22277
+ }
22278
+ const timestamp = Date.now();
22279
+ log(`searchMessage(tmpid: ${timestamp}) > listen`);
22280
+ const controller = new SearchMessageLiveCollectionController(params, callback);
22281
+ const disposers = controller.startSubscription();
22282
+ const cacheKey = controller.getCacheKey();
22283
+ disposers.push(() => {
22284
+ dropFromCache(cacheKey);
22285
+ });
22286
+ return () => {
22287
+ log(`searchMessage(tmpid: ${timestamp}) > dispose`);
22288
+ disposers.forEach(fn => fn());
22289
+ };
22290
+ };
22291
+ /* end_public_function */
22292
+
21037
22293
  var index$n = /*#__PURE__*/Object.freeze({
21038
22294
  __proto__: null,
21039
22295
  createMessage: createMessage,
@@ -21059,6 +22315,7 @@ var index$n = /*#__PURE__*/Object.freeze({
21059
22315
  onMessageFetched: onMessageFetched,
21060
22316
  getMessage: getMessage,
21061
22317
  getMessages: getMessages,
22318
+ searchMessage: searchMessage,
21062
22319
  convertFromRaw: convertFromRaw$1,
21063
22320
  prepareMessagePayload: prepareMessagePayload,
21064
22321
  convertParams: convertParams,
@@ -21906,6 +23163,7 @@ class ChannelQueryStreamController extends QueryStreamController {
21906
23163
  "onCreate" /* Amity.ChannelActionType.OnCreate */,
21907
23164
  "onJoin" /* Amity.ChannelActionType.OnJoin */,
21908
23165
  "onResolveChannel" /* Amity.ChannelActionType.OnResolveChannel */,
23166
+ "onUnarchived" /* Amity.ChannelActionType.OnUnarchived */,
21909
23167
  ].includes(action)) {
21910
23168
  if (Array.isArray(payload)) {
21911
23169
  collection.data = [
@@ -21915,6 +23173,12 @@ class ChannelQueryStreamController extends QueryStreamController {
21915
23173
  else
21916
23174
  collection.data = [...new Set([payload.channelInternalId, ...collection.data])];
21917
23175
  }
23176
+ if (action === "onArchived" /* Amity.ChannelActionType.OnArchived */) {
23177
+ const ids = Array.isArray(payload)
23178
+ ? payload.map(getResolver('channel'))
23179
+ : [getResolver('channel')(payload)];
23180
+ collection.data = collection.data.filter(channelInternalId => !ids.includes(channelInternalId));
23181
+ }
21918
23182
  pushToCache(this.cacheKey, collection);
21919
23183
  this.notifyChange({ origin: "event" /* Amity.LiveDataOrigin.EVENT */, loading: false });
21920
23184
  };
@@ -22181,6 +23445,32 @@ class ChannelLiveCollectionController extends LiveCollectionController {
22181
23445
  },
22182
23446
  { fn: onChannelMemberAdded, action: "onMemberAdded" /* Amity.ChannelActionType.OnMemberAdded */ },
22183
23447
  { fn: onChannelMemberRemoved, action: "onMemberRemoved" /* Amity.ChannelActionType.OnMemberRemoved */ },
23448
+ {
23449
+ fn: (reactor) => onChannelArchived(payload => {
23450
+ const channels = payload.archives
23451
+ .map(archive => {
23452
+ var _a;
23453
+ return (_a = pullFromCache(['channel', 'get', archive.channelId])) === null || _a === void 0 ? void 0 : _a.data;
23454
+ })
23455
+ .filter((c) => Boolean(c));
23456
+ if (channels.length > 0)
23457
+ reactor(channels);
23458
+ }),
23459
+ action: "onArchived" /* Amity.ChannelActionType.OnArchived */,
23460
+ },
23461
+ {
23462
+ fn: (reactor) => onChannelUnarchived(payload => {
23463
+ const channels = payload.archives
23464
+ .map(archive => {
23465
+ var _a;
23466
+ return (_a = pullFromCache(['channel', 'get', archive.channelId])) === null || _a === void 0 ? void 0 : _a.data;
23467
+ })
23468
+ .filter((c) => Boolean(c));
23469
+ if (channels.length > 0)
23470
+ reactor(channels);
23471
+ }),
23472
+ action: "onUnarchived" /* Amity.ChannelActionType.OnUnarchived */,
23473
+ },
22184
23474
  {
22185
23475
  fn: convertEventPayload(onChannelMarkerFetched, 'entityId', 'channel'),
22186
23476
  action: "onUpdate" /* Amity.ChannelActionType.OnUpdate */,
@@ -22359,181 +23649,766 @@ class ChannelLiveCollectionController extends LiveCollectionController {
22359
23649
  action: "onUpdate" /* Amity.ChannelActionType.OnUpdate */,
22360
23650
  },
22361
23651
  ];
22362
- if (this.paginationController instanceof PaginationController) {
22363
- return [
22364
- ...subscriptions,
22365
- {
22366
- fn: (callback) => {
22367
- return onChannelCreated(channel => {
22368
- resolveUnreadInfoOnChannelEvent(channel);
22369
- callback(channel);
22370
- });
22371
- },
22372
- action: "onCreate" /* Amity.ChannelActionType.OnCreate */,
22373
- },
22374
- ];
22375
- }
22376
- return subscriptions;
23652
+ if (this.paginationController instanceof PaginationController) {
23653
+ return [
23654
+ ...subscriptions,
23655
+ {
23656
+ fn: (callback) => {
23657
+ return onChannelCreated(channel => {
23658
+ resolveUnreadInfoOnChannelEvent(channel);
23659
+ callback(channel);
23660
+ });
23661
+ },
23662
+ action: "onCreate" /* Amity.ChannelActionType.OnCreate */,
23663
+ },
23664
+ ];
23665
+ }
23666
+ return subscriptions;
23667
+ }
23668
+ }
23669
+
23670
+ /* eslint-disable no-use-before-define */
23671
+ /* begin_public_function
23672
+ id: channel.query
23673
+ */
23674
+ /**
23675
+ * ```js
23676
+ * import { getChannels } from '@amityco/ts-sdk-react-native'
23677
+ *
23678
+ * let channels = []
23679
+ * const unsub = getChannels({
23680
+ * displayName: Amity.Channel['displayName'],
23681
+ * }, response => merge(channels, response.data))
23682
+ * ```
23683
+ *
23684
+ * Observe all mutations on a list of {@link Amity.Channel}s
23685
+ *
23686
+ * @param params for querying channels
23687
+ * @param callback the function to call when new data are available
23688
+ * @returns An {@link Amity.Unsubscriber} function to run when willing to stop observing the channels
23689
+ *
23690
+ * @category Channel Live Collection
23691
+ */
23692
+ const getChannels = (params, callback, config) => {
23693
+ const { log, cache, userId } = getActiveClient();
23694
+ if (!cache) {
23695
+ console.log(ENABLE_CACHE_MESSAGE);
23696
+ }
23697
+ const timestamp = Date.now();
23698
+ log(`getChannels(tmpid: ${timestamp}) > listen`);
23699
+ const channelLiveCollection = new ChannelLiveCollectionController(params, callback);
23700
+ const disposers = channelLiveCollection.startSubscription();
23701
+ const cacheKey = channelLiveCollection.getCacheKey();
23702
+ disposers.push(() => {
23703
+ dropFromCache(cacheKey);
23704
+ });
23705
+ return () => {
23706
+ log(`getChannels(tmpid: ${timestamp}) > dispose`);
23707
+ disposers.forEach(fn => fn());
23708
+ };
23709
+ };
23710
+ /* end_public_function */
23711
+
23712
+ /**
23713
+ *
23714
+ * Calculate user unread from {@link Amity.ChannelUnread} objects
23715
+ *
23716
+ * @returns the {@link Amity.UserUnread} objects
23717
+ *
23718
+ * @category Channel API
23719
+ * @async
23720
+ */
23721
+ const getTotalChannelsUnread$1 = () => {
23722
+ var _a;
23723
+ const client = getActiveClient();
23724
+ client.log('channel/getTotalChannelsUnread.locally');
23725
+ const cachedChannelsUnread = ((_a = queryCache(['channelUnread', 'get'])) === null || _a === void 0 ? void 0 : _a.filter(({ data }) => {
23726
+ return !data.isDeleted;
23727
+ })) || [];
23728
+ const totalChannelsUnread = (cachedChannelsUnread === null || cachedChannelsUnread === void 0 ? void 0 : cachedChannelsUnread.reduce((acc, { data }) => {
23729
+ acc.unreadCount += data.unreadCount;
23730
+ acc.isMentioned = acc.isMentioned || data.isMentioned;
23731
+ return acc;
23732
+ }, { unreadCount: 0, isMentioned: false })) || { unreadCount: 0, isMentioned: false };
23733
+ const cachedAt = client.cache && Date.now();
23734
+ return {
23735
+ data: totalChannelsUnread,
23736
+ cachedAt,
23737
+ };
23738
+ };
23739
+
23740
+ /* begin_public_function
23741
+ id: totalChannelsUnread.get
23742
+ */
23743
+ /**
23744
+ * ```js
23745
+ * import { ChannelRepository } from '@amityco/ts-sdk-react-native';
23746
+ *
23747
+ * let totalChannelsUnread;
23748
+ *
23749
+ * const unsubscribe = ChannelRepository.getTotalChannelsUnread(response => {
23750
+ * unread = response.data;
23751
+ * });
23752
+ * ```
23753
+ *
23754
+ * Observe all mutation on a given {@link Amity.UserUnread}
23755
+ *
23756
+ * @returns An {@link Amity.UserUnread} function to run when willing to stop observing the message
23757
+ *
23758
+ * @category User Unread Live Object
23759
+ *
23760
+ */
23761
+ const getTotalChannelsUnread = (callback) => {
23762
+ const { _id: userId } = getActiveUser();
23763
+ if (!userId)
23764
+ throw new ASCError('The _id has not been defined in ActiveUser', 800000 /* Amity.ClientError.UNKNOWN_ERROR */, "error" /* Amity.ErrorLevel.ERROR */);
23765
+ const { log, cache } = getActiveClient();
23766
+ if (!cache) {
23767
+ console.log('For using Live Object feature you need to enable Cache!');
23768
+ }
23769
+ const timestamp = Date.now();
23770
+ log(`liveTotalChannelsUnread(tmpid: ${timestamp}) > listen`);
23771
+ const disposers = [];
23772
+ let isUnsyncedModel = false; // for messages
23773
+ let model;
23774
+ const dispatcher = (data) => {
23775
+ const { data: userUnread } = data;
23776
+ const callbackModel = userUnread
23777
+ ? {
23778
+ unreadCount: userUnread.unreadCount,
23779
+ isMentioned: userUnread.isMentioned,
23780
+ }
23781
+ : undefined;
23782
+ model = callbackModel ? convertGetterPropsToStatic(callbackModel) : callbackModel;
23783
+ callback({
23784
+ data: callbackModel
23785
+ ? Object.assign(Object.assign({}, callbackModel), { isMentioned: callbackModel.isMentioned }) : callbackModel,
23786
+ loading: data.loading,
23787
+ error: data.error,
23788
+ });
23789
+ };
23790
+ const realtimeRouter = (_) => {
23791
+ const { data: userUnread } = getTotalChannelsUnread$1();
23792
+ if (isEqual(model, userUnread))
23793
+ return;
23794
+ dispatcher({
23795
+ loading: false,
23796
+ data: userUnread,
23797
+ });
23798
+ };
23799
+ const onFetch = () => {
23800
+ const query = createQuery(async () => getTotalChannelsUnread$1());
23801
+ runQuery(query, ({ error, data, loading, origin, cachedAt }) => {
23802
+ if (cachedAt === UNSYNCED_OBJECT_CACHED_AT_VALUE) {
23803
+ dispatcher({
23804
+ data,
23805
+ origin,
23806
+ loading: false,
23807
+ error: new ASCApiError(UNSYNCED_OBJECT_CACHED_AT_MESSAGE, 800800 /* Amity.ClientError.DISALOOW_UNSYNCED_OBJECT */, "error" /* Amity.ErrorLevel.ERROR */),
23808
+ });
23809
+ isUnsyncedModel = true;
23810
+ disposers.forEach(fn => fn());
23811
+ }
23812
+ else if (!isUnsyncedModel) {
23813
+ dispatcher({ loading, data, origin, error });
23814
+ }
23815
+ if (error) {
23816
+ disposers.forEach(fn => fn());
23817
+ }
23818
+ });
23819
+ };
23820
+ disposers.push(onChannelUnreadUpdatedLocal(realtimeRouter));
23821
+ onFetch();
23822
+ return () => {
23823
+ disposers.forEach(fn => fn());
23824
+ };
23825
+ };
23826
+
23827
+ class ArchivedChannelPaginationController extends PaginationController {
23828
+ async getRequest(queryParams, token) {
23829
+ var _a, _b;
23830
+ const limit = (_a = queryParams.limit) !== null && _a !== void 0 ? _a : COLLECTION_DEFAULT_PAGINATION_LIMIT;
23831
+ const pageIndex = token ? Number.parseInt(token, 10) : 0;
23832
+ if (pageIndex === 0) {
23833
+ await getArchivedChannelIds();
23834
+ }
23835
+ const cached = (_b = queryCache(['archivedChannel', 'get'])) !== null && _b !== void 0 ? _b : [];
23836
+ const archives = cached
23837
+ .map(entry => entry.data)
23838
+ .slice()
23839
+ .sort((a, b) => Number(new Date(b.archivedAt)) - Number(new Date(a.archivedAt)));
23840
+ const start = pageIndex * limit;
23841
+ const end = start + limit;
23842
+ const slice = archives.slice(start, end);
23843
+ const hasMore = end < archives.length;
23844
+ if (slice.length > 0) {
23845
+ await getChannelByIds$1(slice.map(archive => archive.channelId));
23846
+ }
23847
+ return {
23848
+ archives: slice,
23849
+ paging: {
23850
+ next: hasMore ? String(pageIndex + 1) : undefined,
23851
+ previous: undefined,
23852
+ },
23853
+ };
23854
+ }
23855
+ }
23856
+
23857
+ class ArchivedChannelQueryStreamController extends QueryStreamController {
23858
+ constructor(query, cacheKey, notifyChange) {
23859
+ super(query, cacheKey);
23860
+ this.notifyChange = notifyChange;
23861
+ }
23862
+ async saveToMainDB(_response) {
23863
+ //
23864
+ }
23865
+ appendToQueryStream(response, direction, refresh = false) {
23866
+ var _a, _b;
23867
+ const channelIds = response.archives.map(archive => archive.channelId);
23868
+ if (refresh) {
23869
+ pushToCache(this.cacheKey, {
23870
+ data: channelIds,
23871
+ params: {},
23872
+ });
23873
+ return;
23874
+ }
23875
+ const collection = (_a = pullFromCache(this.cacheKey)) === null || _a === void 0 ? void 0 : _a.data;
23876
+ const existing = (_b = collection === null || collection === void 0 ? void 0 : collection.data) !== null && _b !== void 0 ? _b : [];
23877
+ pushToCache(this.cacheKey, Object.assign(Object.assign({}, collection), { data: direction === "prev" /* Amity.LiveCollectionPageDirection.PREV */
23878
+ ? [...new Set([...channelIds, ...existing])]
23879
+ : [...new Set([...existing, ...channelIds])] }));
23880
+ }
23881
+ reactor(action) {
23882
+ return (channelIds) => {
23883
+ var _a;
23884
+ const collection = (_a = pullFromCache(this.cacheKey)) === null || _a === void 0 ? void 0 : _a.data;
23885
+ if (!collection)
23886
+ return;
23887
+ if (action === "onArchived" /* Amity.ChannelActionType.OnArchived */) {
23888
+ const filtered = collection.data.filter(id => !channelIds.includes(id));
23889
+ collection.data = [...channelIds, ...filtered];
23890
+ }
23891
+ if (action === "onUnarchived" /* Amity.ChannelActionType.OnUnarchived */ ||
23892
+ action === "onDelete" /* Amity.ChannelActionType.OnDelete */) {
23893
+ collection.data = collection.data.filter(id => !channelIds.includes(id));
23894
+ }
23895
+ pushToCache(this.cacheKey, collection);
23896
+ this.notifyChange({ origin: "event" /* Amity.LiveDataOrigin.EVENT */, loading: false });
23897
+ };
23898
+ }
23899
+ subscribeRTE(createSubscriber) {
23900
+ return createSubscriber.map(subscriber => subscriber.fn(this.reactor(subscriber.action)));
23901
+ }
23902
+ }
23903
+
23904
+ class ArchivedChannelLiveCollectionController extends LiveCollectionController {
23905
+ constructor(query, callback) {
23906
+ const queryStreamId = hash__default["default"](query);
23907
+ const cacheKey = ['archivedChannel', 'collection', queryStreamId];
23908
+ const paginationController = new ArchivedChannelPaginationController(query);
23909
+ super(paginationController, queryStreamId, cacheKey, callback);
23910
+ this.queryStreamController = new ArchivedChannelQueryStreamController(query, this.cacheKey, this.notifyChange.bind(this));
23911
+ this.callback = callback.bind(this);
23912
+ this.loadPage({ initial: true });
23913
+ }
23914
+ setup() {
23915
+ var _a;
23916
+ const collection = (_a = pullFromCache(this.cacheKey)) === null || _a === void 0 ? void 0 : _a.data;
23917
+ if (!collection) {
23918
+ pushToCache(this.cacheKey, {
23919
+ data: [],
23920
+ params: {},
23921
+ });
23922
+ }
23923
+ }
23924
+ async persistModel(response) {
23925
+ await this.queryStreamController.saveToMainDB(response);
23926
+ }
23927
+ persistQueryStream({ response, direction, refresh, }) {
23928
+ this.queryStreamController.appendToQueryStream(response, direction, refresh);
23929
+ }
23930
+ startSubscription() {
23931
+ return this.queryStreamController.subscribeRTE([
23932
+ {
23933
+ fn: reactor => onChannelArchived(payload => reactor(payload.archives.map(archive => archive.channelId))),
23934
+ action: "onArchived" /* Amity.ChannelActionType.OnArchived */,
23935
+ },
23936
+ {
23937
+ fn: reactor => onChannelUnarchived(payload => reactor(payload.archives.map(archive => archive.channelId))),
23938
+ action: "onUnarchived" /* Amity.ChannelActionType.OnUnarchived */,
23939
+ },
23940
+ {
23941
+ fn: reactor => onChannelUpdated(channel => reactor([channel.channelId])),
23942
+ action: "onUpdate" /* Amity.ChannelActionType.OnUpdate */,
23943
+ },
23944
+ {
23945
+ fn: reactor => onChannelDeleted(channel => reactor([channel.channelId])),
23946
+ action: "onDelete" /* Amity.ChannelActionType.OnDelete */,
23947
+ },
23948
+ ]);
23949
+ }
23950
+ notifyChange({ origin, loading, error }) {
23951
+ var _a, _b;
23952
+ const collection = (_a = pullFromCache(this.cacheKey)) === null || _a === void 0 ? void 0 : _a.data;
23953
+ if (!collection)
23954
+ return;
23955
+ const data = (_b = collection.data
23956
+ .map(channelId => pullFromCache(['channel', 'get', channelId]))
23957
+ .filter((entry) => Boolean(entry))
23958
+ .map(({ data: channel }) => channel)
23959
+ .map(constructChannelObject)) !== null && _b !== void 0 ? _b : [];
23960
+ if (!this.shouldNotify(data) && origin === 'event')
23961
+ return;
23962
+ this.callback({
23963
+ onNextPage: () => this.loadPage({ direction: "next" /* Amity.LiveCollectionPageDirection.NEXT */ }),
23964
+ data,
23965
+ hasNextPage: !!this.paginationController.getNextToken(),
23966
+ loading,
23967
+ error,
23968
+ });
23969
+ }
23970
+ }
23971
+
23972
+ /* begin_public_function
23973
+ id: channel.archive.collection
23974
+ */
23975
+ /**
23976
+ * ```js
23977
+ * import { ChannelRepository } from '@amityco/ts-sdk'
23978
+ *
23979
+ * let channels = []
23980
+ * const unsub = ChannelRepository.getArchivedChannels(params, response => merge(channels, response.data))
23981
+ * ```
23982
+ *
23983
+ * Live collection of {@link Amity.Channel}s archived by the active user.
23984
+ *
23985
+ * @param params Live collection parameters (only `limit` is honored; the
23986
+ * archive list takes no other filters).
23987
+ * @param callback the function to call when new data are available
23988
+ * @returns An {@link Amity.Unsubscriber} function to run when willing to
23989
+ * stop observing.
23990
+ *
23991
+ * @category Channel Live Collection
23992
+ */
23993
+ const getArchivedChannels = (params, callback) => {
23994
+ const { log, cache } = getActiveClient();
23995
+ if (!cache) {
23996
+ console.log(ENABLE_CACHE_MESSAGE);
23997
+ }
23998
+ const timestamp = Date.now();
23999
+ log(`getArchivedChannels(tmpid: ${timestamp}) > listen`);
24000
+ const controller = new ArchivedChannelLiveCollectionController(params, callback);
24001
+ const disposers = controller.startSubscription();
24002
+ const cacheKey = controller.getCacheKey();
24003
+ disposers.push(() => {
24004
+ dropFromCache(cacheKey);
24005
+ });
24006
+ return () => {
24007
+ log(`getArchivedChannels(tmpid: ${timestamp}) > dispose`);
24008
+ disposers.forEach(fn => fn());
24009
+ };
24010
+ };
24011
+ /* end_public_function */
24012
+
24013
+ class SearchChannelPaginationController extends PaginationController {
24014
+ async getRequest(queryParams, token) {
24015
+ const { query, exactMatch, isMemberOnly, types, tags, sortBy, orderBy, limit = COLLECTION_DEFAULT_PAGINATION_SIZE, } = queryParams;
24016
+ const options = token ? { token } : { limit: Math.min(100, Math.max(1, limit)) };
24017
+ const { data: queryResponse } = await this.http.get(`/api/v2/search/channels`, {
24018
+ params: {
24019
+ query,
24020
+ exactMatch,
24021
+ isMemberOnly,
24022
+ types,
24023
+ tags,
24024
+ sortBy,
24025
+ orderBy,
24026
+ options,
24027
+ },
24028
+ });
24029
+ return queryResponse;
24030
+ }
24031
+ }
24032
+
24033
+ class SearchChannelQueryStreamController extends QueryStreamController {
24034
+ constructor(query, cacheKey, notifyChange) {
24035
+ super(query, cacheKey);
24036
+ this.notifyChange = notifyChange;
24037
+ }
24038
+ async saveToMainDB(response) {
24039
+ const processedPayload = await prepareChannelPayload(response);
24040
+ const client = getActiveClient();
24041
+ const cachedAt = client.cache && Date.now();
24042
+ if (client.cache) {
24043
+ ingestInCache(processedPayload, { cachedAt });
24044
+ }
24045
+ }
24046
+ appendToQueryStream(response, direction, refresh = false) {
24047
+ var _a, _b;
24048
+ if (refresh) {
24049
+ pushToCache(this.cacheKey, {
24050
+ data: response.channels.map(getResolver('channel')),
24051
+ });
24052
+ return;
24053
+ }
24054
+ const collection = (_a = pullFromCache(this.cacheKey)) === null || _a === void 0 ? void 0 : _a.data;
24055
+ const existing = (_b = collection === null || collection === void 0 ? void 0 : collection.data) !== null && _b !== void 0 ? _b : [];
24056
+ const incoming = response.channels.map(getResolver('channel'));
24057
+ pushToCache(this.cacheKey, Object.assign(Object.assign({}, collection), { data: direction === "prev" /* Amity.LiveCollectionPageDirection.PREV */
24058
+ ? [...new Set([...incoming, ...existing])]
24059
+ : [...new Set([...existing, ...incoming])] }));
24060
+ }
24061
+ reactor() {
24062
+ return () => this.notifyChange({ origin: "event" /* Amity.LiveDataOrigin.EVENT */, loading: false });
24063
+ }
24064
+ subscribeRTE(createSubscriber) {
24065
+ return createSubscriber.map(subscriber => subscriber.fn(this.reactor()));
24066
+ }
24067
+ }
24068
+
24069
+ /* eslint-disable no-use-before-define */
24070
+ const getMessagePreviewSetting = () => {
24071
+ const client = getActiveClient();
24072
+ return client.getMessagePreviewSetting(false);
24073
+ };
24074
+ class SearchChannelLiveCollectionController extends LiveCollectionController {
24075
+ constructor(query, callback) {
24076
+ const queryStreamId = hash__default["default"](query);
24077
+ const cacheKey = ['channel', 'search', queryStreamId];
24078
+ const paginationController = new SearchChannelPaginationController(query);
24079
+ super(paginationController, queryStreamId, cacheKey, callback);
24080
+ this.queryStreamController = new SearchChannelQueryStreamController(query, this.cacheKey, this.notifyChange.bind(this));
24081
+ this.callback = callback.bind(this);
24082
+ this.loadPage({ initial: true });
24083
+ }
24084
+ startSubscription() {
24085
+ return this.queryStreamController.subscribeRTE(this.getSubscriptions());
24086
+ }
24087
+ notifyChange({ origin, loading, error }) {
24088
+ var _a, _b;
24089
+ const collection = (_a = pullFromCache(this.cacheKey)) === null || _a === void 0 ? void 0 : _a.data;
24090
+ if (!collection)
24091
+ return;
24092
+ const data = (_b = collection.data
24093
+ .map(channelId => pullFromCache(['channel', 'get', channelId]))
24094
+ .filter(Boolean)
24095
+ .map(cached => constructChannelObject(cached.data))) !== null && _b !== void 0 ? _b : [];
24096
+ if (!this.shouldNotify(data) && origin === 'event')
24097
+ return;
24098
+ this.callback({
24099
+ onNextPage: () => this.loadPage({ direction: "next" /* Amity.LiveCollectionPageDirection.NEXT */ }),
24100
+ data,
24101
+ hasNextPage: !!this.paginationController.getNextToken(),
24102
+ loading,
24103
+ error,
24104
+ });
24105
+ }
24106
+ setup() {
24107
+ var _a;
24108
+ const collection = (_a = pullFromCache(this.cacheKey)) === null || _a === void 0 ? void 0 : _a.data;
24109
+ if (!collection) {
24110
+ pushToCache(this.cacheKey, {
24111
+ data: [],
24112
+ params: {},
24113
+ });
24114
+ }
24115
+ }
24116
+ async persistModel(response) {
24117
+ await this.queryStreamController.saveToMainDB(response);
24118
+ }
24119
+ persistQueryStream({ response, direction, refresh, }) {
24120
+ this.queryStreamController.appendToQueryStream(response, direction, refresh);
24121
+ }
24122
+ shouldAbort(targetChannelId) {
24123
+ var _a;
24124
+ const collection = (_a = pullFromCache(this.cacheKey)) === null || _a === void 0 ? void 0 : _a.data;
24125
+ if (!collection)
24126
+ return true;
24127
+ return !collection.data.find(channelId => channelId === targetChannelId);
24128
+ }
24129
+ getSubscriptions() {
24130
+ return [
24131
+ {
24132
+ fn: convertEventPayload((callback) => {
24133
+ return onMessageCreatedMqtt(message => {
24134
+ var _a;
24135
+ const cacheData = (_a = pullFromCache([
24136
+ 'channel',
24137
+ 'get',
24138
+ message.channelId,
24139
+ ])) === null || _a === void 0 ? void 0 : _a.data;
24140
+ if (!cacheData)
24141
+ return;
24142
+ updateChannelCache(cacheData, {
24143
+ lastActivity: message.createdAt,
24144
+ });
24145
+ callback(message);
24146
+ });
24147
+ }, 'channelId', 'channel'),
24148
+ action: "onUpdate" /* Amity.ChannelActionType.OnUpdate */,
24149
+ },
24150
+ {
24151
+ fn: convertEventPayload((callback) => {
24152
+ return onMessageCreatedLocal(message => {
24153
+ var _a;
24154
+ const cacheData = (_a = pullFromCache([
24155
+ 'channel',
24156
+ 'get',
24157
+ message.channelId,
24158
+ ])) === null || _a === void 0 ? void 0 : _a.data;
24159
+ if (!cacheData)
24160
+ return;
24161
+ updateChannelCache(cacheData, {
24162
+ lastActivity: message.createdAt,
24163
+ });
24164
+ callback(message);
24165
+ });
24166
+ }, 'channelId', 'channel'),
24167
+ action: "onUpdate" /* Amity.ChannelActionType.OnUpdate */,
24168
+ },
24169
+ { fn: onChannelDeleted, action: "onDelete" /* Amity.ChannelActionType.OnDelete */ },
24170
+ { fn: onChannelUpdated, action: "onUpdate" /* Amity.ChannelActionType.OnUpdate */ },
24171
+ { fn: onChannelSetMuted, action: "onMute" /* Amity.ChannelActionType.OnMute */ },
24172
+ {
24173
+ fn: (reactor) => onChannelArchived(payload => {
24174
+ const channels = payload.archives
24175
+ .map(archive => {
24176
+ var _a;
24177
+ return (_a = pullFromCache(['channel', 'get', archive.channelId])) === null || _a === void 0 ? void 0 : _a.data;
24178
+ })
24179
+ .filter((c) => Boolean(c));
24180
+ if (channels.length > 0)
24181
+ reactor(channels);
24182
+ }),
24183
+ action: "onArchived" /* Amity.ChannelActionType.OnArchived */,
24184
+ },
24185
+ {
24186
+ fn: (reactor) => onChannelUnarchived(payload => {
24187
+ const channels = payload.archives
24188
+ .map(archive => {
24189
+ var _a;
24190
+ return (_a = pullFromCache(['channel', 'get', archive.channelId])) === null || _a === void 0 ? void 0 : _a.data;
24191
+ })
24192
+ .filter((c) => Boolean(c));
24193
+ if (channels.length > 0)
24194
+ reactor(channels);
24195
+ }),
24196
+ action: "onUnarchived" /* Amity.ChannelActionType.OnUnarchived */,
24197
+ },
24198
+ {
24199
+ fn: convertEventPayload(onChannelMarkerFetched, 'entityId', 'channel'),
24200
+ action: "onUpdate" /* Amity.ChannelActionType.OnUpdate */,
24201
+ },
24202
+ {
24203
+ fn: convertEventPayload(onChannelMarkerUpdated, 'entityId', 'channel'),
24204
+ action: "onUpdate" /* Amity.ChannelActionType.OnUpdate */,
24205
+ },
24206
+ {
24207
+ fn: convertEventPayload((callback) => {
24208
+ const updateMessagePreview = async (message) => {
24209
+ var _a;
24210
+ const messagePreviewSetting = await getMessagePreviewSetting();
24211
+ if (messagePreviewSetting === "no-message-preview" /* Amity.MessagePreviewSetting.NO_MESSAGE_PREVIEW */)
24212
+ return;
24213
+ handleMessageCreated(message);
24214
+ if (this.shouldAbort(message.channelId))
24215
+ return;
24216
+ const channel = (_a = pullFromCache([
24217
+ 'channel',
24218
+ 'get',
24219
+ message.channelId,
24220
+ ])) === null || _a === void 0 ? void 0 : _a.data;
24221
+ if (!channel)
24222
+ return;
24223
+ updateChannelCache(channel, {
24224
+ messagePreviewId: message.messageId,
24225
+ });
24226
+ callback(message);
24227
+ };
24228
+ return onMessageCreatedMqtt(updateMessagePreview);
24229
+ }, 'channelId', 'channel'),
24230
+ action: "onUpdate" /* Amity.ChannelActionType.OnUpdate */,
24231
+ },
24232
+ {
24233
+ fn: convertEventPayload((callback) => {
24234
+ const updateMessagePreview = async (message) => {
24235
+ var _a;
24236
+ const messagePreviewSetting = await getMessagePreviewSetting();
24237
+ if (messagePreviewSetting === "no-message-preview" /* Amity.MessagePreviewSetting.NO_MESSAGE_PREVIEW */)
24238
+ return;
24239
+ handleMessageCreated(message);
24240
+ if (this.shouldAbort(message.channelId))
24241
+ return;
24242
+ const channel = (_a = pullFromCache([
24243
+ 'channel',
24244
+ 'get',
24245
+ message.channelId,
24246
+ ])) === null || _a === void 0 ? void 0 : _a.data;
24247
+ if (!channel)
24248
+ return;
24249
+ updateChannelCache(channel, {
24250
+ messagePreviewId: message.messageId,
24251
+ });
24252
+ callback(message);
24253
+ };
24254
+ return onMessageCreatedLocal(updateMessagePreview);
24255
+ }, 'channelId', 'channel'),
24256
+ action: "onUpdate" /* Amity.ChannelActionType.OnUpdate */,
24257
+ },
24258
+ {
24259
+ fn: convertEventPayload((callback) => {
24260
+ const updateMessagePreview = async (message) => {
24261
+ const messagePreviewSetting = await getMessagePreviewSetting();
24262
+ if (messagePreviewSetting === "no-message-preview" /* Amity.MessagePreviewSetting.NO_MESSAGE_PREVIEW */)
24263
+ return;
24264
+ handleMessageUpdated(message);
24265
+ if (this.shouldAbort(message.channelId))
24266
+ return;
24267
+ callback(message);
24268
+ };
24269
+ return onMessageUpdated(updateMessagePreview);
24270
+ }, 'channelId', 'channel'),
24271
+ action: "onUpdate" /* Amity.ChannelActionType.OnUpdate */,
24272
+ },
24273
+ {
24274
+ fn: convertEventPayload((callback) => {
24275
+ const updateMessagePreview = async (message) => {
24276
+ const messagePreviewSetting = await getMessagePreviewSetting();
24277
+ if (messagePreviewSetting === "no-message-preview" /* Amity.MessagePreviewSetting.NO_MESSAGE_PREVIEW */)
24278
+ return;
24279
+ if (messagePreviewSetting ===
24280
+ "message-preview-include-deleted" /* Amity.MessagePreviewSetting.MESSAGE_PREVIEW_INCLUDE_DELETED */)
24281
+ await handleMessageUpdated(message);
24282
+ if (this.shouldAbort(message.channelId))
24283
+ return;
24284
+ if (messagePreviewSetting ===
24285
+ "message-preview-not-include-deleted" /* Amity.MessagePreviewSetting.MESSAGE_PREVIEW_NOT_INCLUDE_DELETED */) {
24286
+ await getChannel$1(message.channelId);
24287
+ }
24288
+ callback(message);
24289
+ };
24290
+ return onMessageDeleted(updateMessagePreview);
24291
+ }, 'channelId', 'channel'),
24292
+ action: "onUpdate" /* Amity.ChannelActionType.OnUpdate */,
24293
+ },
24294
+ {
24295
+ fn: convertEventPayload((callback) => {
24296
+ const updateMessagePreview = async (subChannel) => {
24297
+ var _a;
24298
+ const collections = (_a = pullFromCache(this.cacheKey)) === null || _a === void 0 ? void 0 : _a.data;
24299
+ if (!collections)
24300
+ return;
24301
+ const channelId = collections.data.find(channel => {
24302
+ const messagePreviewCache = getChannelMessagePreview(channel);
24303
+ return (messagePreviewCache === null || messagePreviewCache === void 0 ? void 0 : messagePreviewCache.subChannelId) === subChannel.subChannelId;
24304
+ });
24305
+ if (!channelId)
24306
+ return;
24307
+ await getChannel$1(subChannel.channelId);
24308
+ callback(subChannel);
24309
+ };
24310
+ return onSubChannelDeleted(updateMessagePreview);
24311
+ }, 'channelId', 'channel'),
24312
+ action: "onUpdate" /* Amity.ChannelActionType.OnUpdate */,
24313
+ },
24314
+ {
24315
+ fn: convertEventPayload((callback) => {
24316
+ const updateMessagePreview = async (subChannel) => {
24317
+ var _a;
24318
+ const messagePreviewSetting = await getMessagePreviewSetting();
24319
+ if (messagePreviewSetting === "no-message-preview" /* Amity.MessagePreviewSetting.NO_MESSAGE_PREVIEW */)
24320
+ return;
24321
+ const collections = (_a = pullFromCache(this.cacheKey)) === null || _a === void 0 ? void 0 : _a.data;
24322
+ if (!collections)
24323
+ return;
24324
+ await handleSubChannelUpdated(subChannel);
24325
+ if (this.shouldAbort(subChannel.channelId))
24326
+ return;
24327
+ callback(subChannel);
24328
+ };
24329
+ return onSubChannelUpdated(updateMessagePreview);
24330
+ }, 'channelId', 'channel'),
24331
+ action: "onUpdate" /* Amity.ChannelActionType.OnUpdate */,
24332
+ },
24333
+ {
24334
+ fn: (callback) => {
24335
+ const handleUserFeedMarkerResolved = async (marker) => {
24336
+ if (marker.feedMarkers) {
24337
+ const channels = marker.feedMarkers
24338
+ .map(feedMarker => {
24339
+ var _a;
24340
+ return (_a = pullFromCache([
24341
+ 'channel',
24342
+ 'get',
24343
+ feedMarker.entityId,
24344
+ ])) === null || _a === void 0 ? void 0 : _a.data;
24345
+ })
24346
+ .filter(Boolean);
24347
+ callback(channels);
24348
+ }
24349
+ };
24350
+ return onUserMessageFeedMarkerResolved(handleUserFeedMarkerResolved);
24351
+ },
24352
+ action: "OnResolveUnread" /* Amity.ChannelActionType.OnResolveUnread */,
24353
+ },
24354
+ {
24355
+ fn: convertEventPayload(onChannelUnreadInfoUpdatedLocal, 'channelId', 'channel'),
24356
+ action: "onUpdate" /* Amity.ChannelActionType.OnUpdate */,
24357
+ },
24358
+ {
24359
+ fn: convertEventPayload((callback) => {
24360
+ const processPayload = (payloads) => {
24361
+ payloads.forEach(callback);
24362
+ };
24363
+ return onChannelUnreadUpdatedLocal(processPayload);
24364
+ }, 'channelId', 'channel'),
24365
+ action: "onUpdate" /* Amity.ChannelActionType.OnUpdate */,
24366
+ },
24367
+ ];
22377
24368
  }
22378
24369
  }
22379
24370
 
22380
- /* eslint-disable no-use-before-define */
22381
24371
  /* begin_public_function
22382
- id: channel.query
24372
+ id: channel.search
22383
24373
  */
22384
24374
  /**
22385
24375
  * ```js
22386
- * import { getChannels } from '@amityco/ts-sdk-react-native'
24376
+ * import { ChannelRepository } from '@amityco/ts-sdk';
22387
24377
  *
22388
- * let channels = []
22389
- * const unsub = getChannels({
22390
- * displayName: Amity.Channel['displayName'],
22391
- * }, response => merge(channels, response.data))
24378
+ * const unsubscribe = ChannelRepository.searchChannels(
24379
+ * { query: 'hello' },
24380
+ * response => response.data,
24381
+ * );
22392
24382
  * ```
22393
24383
  *
22394
- * Observe all mutations on a list of {@link Amity.Channel}s
24384
+ * Live collection of {@link Amity.Channel}s matching the search query. Backed by
24385
+ * `GET /api/v2/search/channels`.
22395
24386
  *
22396
- * @param params for querying channels
22397
- * @param callback the function to call when new data are available
22398
- * @returns An {@link Amity.Unsubscriber} function to run when willing to stop observing the channels
24387
+ * @param params Search parameters.
24388
+ * @param callback Called whenever new data are available.
24389
+ * @returns An {@link Amity.Unsubscriber} function to stop observing.
22399
24390
  *
22400
24391
  * @category Channel Live Collection
22401
24392
  */
22402
- const getChannels = (params, callback, config) => {
22403
- const { log, cache, userId } = getActiveClient();
22404
- if (!cache) {
24393
+ const searchChannels = (params, callback) => {
24394
+ const { log, cache } = getActiveClient();
24395
+ if (!cache)
22405
24396
  console.log(ENABLE_CACHE_MESSAGE);
22406
- }
22407
24397
  const timestamp = Date.now();
22408
- log(`getChannels(tmpid: ${timestamp}) > listen`);
22409
- const channelLiveCollection = new ChannelLiveCollectionController(params, callback);
22410
- const disposers = channelLiveCollection.startSubscription();
22411
- const cacheKey = channelLiveCollection.getCacheKey();
24398
+ log(`searchChannels(tmpid: ${timestamp}) > listen`);
24399
+ const searchChannelLiveCollection = new SearchChannelLiveCollectionController(params, callback);
24400
+ const disposers = searchChannelLiveCollection.startSubscription();
24401
+ const cacheKey = searchChannelLiveCollection.getCacheKey();
22412
24402
  disposers.push(() => {
22413
24403
  dropFromCache(cacheKey);
22414
24404
  });
22415
24405
  return () => {
22416
- log(`getChannels(tmpid: ${timestamp}) > dispose`);
24406
+ log(`searchChannels(tmpid: ${timestamp}) > dispose`);
22417
24407
  disposers.forEach(fn => fn());
22418
24408
  };
22419
24409
  };
22420
24410
  /* end_public_function */
22421
24411
 
22422
- /**
22423
- *
22424
- * Calculate user unread from {@link Amity.ChannelUnread} objects
22425
- *
22426
- * @returns the {@link Amity.UserUnread} objects
22427
- *
22428
- * @category Channel API
22429
- * @async
22430
- */
22431
- const getTotalChannelsUnread$1 = () => {
22432
- var _a;
22433
- const client = getActiveClient();
22434
- client.log('channel/getTotalChannelsUnread.locally');
22435
- const cachedChannelsUnread = ((_a = queryCache(['channelUnread', 'get'])) === null || _a === void 0 ? void 0 : _a.filter(({ data }) => {
22436
- return !data.isDeleted;
22437
- })) || [];
22438
- const totalChannelsUnread = (cachedChannelsUnread === null || cachedChannelsUnread === void 0 ? void 0 : cachedChannelsUnread.reduce((acc, { data }) => {
22439
- acc.unreadCount += data.unreadCount;
22440
- acc.isMentioned = acc.isMentioned || data.isMentioned;
22441
- return acc;
22442
- }, { unreadCount: 0, isMentioned: false })) || { unreadCount: 0, isMentioned: false };
22443
- const cachedAt = client.cache && Date.now();
22444
- return {
22445
- data: totalChannelsUnread,
22446
- cachedAt,
22447
- };
22448
- };
22449
-
22450
- /* begin_public_function
22451
- id: totalChannelsUnread.get
22452
- */
22453
- /**
22454
- * ```js
22455
- * import { ChannelRepository } from '@amityco/ts-sdk-react-native';
22456
- *
22457
- * let totalChannelsUnread;
22458
- *
22459
- * const unsubscribe = ChannelRepository.getTotalChannelsUnread(response => {
22460
- * unread = response.data;
22461
- * });
22462
- * ```
22463
- *
22464
- * Observe all mutation on a given {@link Amity.UserUnread}
22465
- *
22466
- * @returns An {@link Amity.UserUnread} function to run when willing to stop observing the message
22467
- *
22468
- * @category User Unread Live Object
22469
- *
22470
- */
22471
- const getTotalChannelsUnread = (callback) => {
22472
- const { _id: userId } = getActiveUser();
22473
- if (!userId)
22474
- throw new ASCError('The _id has not been defined in ActiveUser', 800000 /* Amity.ClientError.UNKNOWN_ERROR */, "error" /* Amity.ErrorLevel.ERROR */);
22475
- const { log, cache } = getActiveClient();
22476
- if (!cache) {
22477
- console.log('For using Live Object feature you need to enable Cache!');
22478
- }
22479
- const timestamp = Date.now();
22480
- log(`liveTotalChannelsUnread(tmpid: ${timestamp}) > listen`);
22481
- const disposers = [];
22482
- let isUnsyncedModel = false; // for messages
22483
- let model;
22484
- const dispatcher = (data) => {
22485
- const { data: userUnread } = data;
22486
- const callbackModel = userUnread
22487
- ? {
22488
- unreadCount: userUnread.unreadCount,
22489
- isMentioned: userUnread.isMentioned,
22490
- }
22491
- : undefined;
22492
- model = callbackModel ? convertGetterPropsToStatic(callbackModel) : callbackModel;
22493
- callback({
22494
- data: callbackModel
22495
- ? Object.assign(Object.assign({}, callbackModel), { isMentioned: callbackModel.isMentioned }) : callbackModel,
22496
- loading: data.loading,
22497
- error: data.error,
22498
- });
22499
- };
22500
- const realtimeRouter = (_) => {
22501
- const { data: userUnread } = getTotalChannelsUnread$1();
22502
- if (isEqual(model, userUnread))
22503
- return;
22504
- dispatcher({
22505
- loading: false,
22506
- data: userUnread,
22507
- });
22508
- };
22509
- const onFetch = () => {
22510
- const query = createQuery(async () => getTotalChannelsUnread$1());
22511
- runQuery(query, ({ error, data, loading, origin, cachedAt }) => {
22512
- if (cachedAt === UNSYNCED_OBJECT_CACHED_AT_VALUE) {
22513
- dispatcher({
22514
- data,
22515
- origin,
22516
- loading: false,
22517
- error: new ASCApiError(UNSYNCED_OBJECT_CACHED_AT_MESSAGE, 800800 /* Amity.ClientError.DISALOOW_UNSYNCED_OBJECT */, "error" /* Amity.ErrorLevel.ERROR */),
22518
- });
22519
- isUnsyncedModel = true;
22520
- disposers.forEach(fn => fn());
22521
- }
22522
- else if (!isUnsyncedModel) {
22523
- dispatcher({ loading, data, origin, error });
22524
- }
22525
- if (error) {
22526
- disposers.forEach(fn => fn());
22527
- }
22528
- });
22529
- };
22530
- disposers.push(onChannelUnreadUpdatedLocal(realtimeRouter));
22531
- onFetch();
22532
- return () => {
22533
- disposers.forEach(fn => fn());
22534
- };
22535
- };
22536
-
22537
24412
  /* begin_public_function
22538
24413
  id: channel.member.add
22539
24414
  */
@@ -22665,7 +24540,9 @@ class ChannelMemberQueryStreamController extends QueryStreamController {
22665
24540
  channelId: this.query.channelId,
22666
24541
  userId: channelMember.userId,
22667
24542
  });
22668
- if (channelMember.membership === 'none') {
24543
+ const membershipFilter = this.query.memberships;
24544
+ const isInFilter = !membershipFilter || membershipFilter.includes(channelMember.membership);
24545
+ if (channelMember.membership === 'none' || !isInFilter) {
22669
24546
  collection.data = collection.data.filter(m => m !== channelMemberCacheId);
22670
24547
  }
22671
24548
  else if (!collection.data.includes(channelMemberCacheId)) {
@@ -23001,6 +24878,7 @@ const banMembers$1 = async (channelId, userIds) => {
23001
24878
  const cachedAt = client.cache && Date.now();
23002
24879
  if (client.cache)
23003
24880
  ingestInCache(preparedPayload, { cachedAt });
24881
+ fireEvent('channel.banned', payload);
23004
24882
  return {
23005
24883
  data: channelUsers === null || channelUsers === void 0 ? void 0 : channelUsers.filter(user => user.membership === 'banned'),
23006
24884
  cachedAt,
@@ -23035,6 +24913,7 @@ const unbanMembers$1 = async (channelId, userIds) => {
23035
24913
  const cachedAt = client.cache && Date.now();
23036
24914
  if (client.cache)
23037
24915
  ingestInCache(preparedPayload, { cachedAt });
24916
+ fireEvent('channel.unbanned', payload);
23038
24917
  const { channelUsers } = preparedPayload;
23039
24918
  return {
23040
24919
  data: channelUsers === null || channelUsers === void 0 ? void 0 : channelUsers.filter(user => user.membership === 'member'),
@@ -23063,6 +24942,7 @@ const MUTE_FOREVER = -1;
23063
24942
  * @async
23064
24943
  * */
23065
24944
  const muteMembers = async (channelId, userIds, mutePeriod = MUTE_FOREVER) => {
24945
+ var _a;
23066
24946
  const client = getActiveClient();
23067
24947
  client.log('channel/muteMembers', { userIds, channelId, mutePeriod });
23068
24948
  const { data } = await client.http.put(`/api/v2/channel/${channelId}/users/mute`, {
@@ -23070,6 +24950,15 @@ const muteMembers = async (channelId, userIds, mutePeriod = MUTE_FOREVER) => {
23070
24950
  mutePeriod: mutePeriod === MUTE_FOREVER ? mutePeriod : mutePeriod * 1000,
23071
24951
  });
23072
24952
  const { success } = data;
24953
+ const muteTimeout = mutePeriod === MUTE_FOREVER
24954
+ ? new Date('9999-12-31T23:59:59.999Z').toISOString()
24955
+ : new Date(Date.now() + mutePeriod * 1000).toISOString();
24956
+ fireEvent('channel.setMutedUsers', {
24957
+ channelId,
24958
+ userIds,
24959
+ muteTimeout,
24960
+ actor: (_a = client.userId) !== null && _a !== void 0 ? _a : '',
24961
+ });
23073
24962
  return success;
23074
24963
  };
23075
24964
  /* end_public_function */
@@ -23092,6 +24981,7 @@ const muteMembers = async (channelId, userIds, mutePeriod = MUTE_FOREVER) => {
23092
24981
  * @async
23093
24982
  * */
23094
24983
  const unmuteMembers = async (channelId, userIds) => {
24984
+ var _a;
23095
24985
  const client = getActiveClient();
23096
24986
  client.log('channel/unmuteMembers', { userIds, channelId });
23097
24987
  const { data } = await client.http.put(`/api/v2/channel/${encodeURIComponent(channelId)}/users/mute`, {
@@ -23099,6 +24989,12 @@ const unmuteMembers = async (channelId, userIds) => {
23099
24989
  mutePeriod: 0,
23100
24990
  });
23101
24991
  const { success } = data;
24992
+ fireEvent('channel.setMutedUsers', {
24993
+ channelId,
24994
+ userIds,
24995
+ muteTimeout: new Date(0).toISOString(),
24996
+ actor: (_a = client.userId) !== null && _a !== void 0 ? _a : '',
24997
+ });
23102
24998
  return success;
23103
24999
  };
23104
25000
  /* end_public_function */
@@ -23125,6 +25021,9 @@ var index$j = /*#__PURE__*/Object.freeze({
23125
25021
  leaveChannel: leaveChannel,
23126
25022
  muteChannel: muteChannel,
23127
25023
  unmuteChannel: unmuteChannel,
25024
+ archiveChannel: archiveChannel,
25025
+ unarchiveChannel: unarchiveChannel,
25026
+ getArchivedChannelIds: getArchivedChannelIds,
23128
25027
  onChannelCreated: onChannelCreated,
23129
25028
  onChannelUpdated: onChannelUpdated,
23130
25029
  onChannelDeleted: onChannelDeleted,
@@ -23137,9 +25036,13 @@ var index$j = /*#__PURE__*/Object.freeze({
23137
25036
  onChannelMemberUnbanned: onChannelMemberUnbanned,
23138
25037
  onChannelMemberRoleAdded: onChannelMemberRoleAdded,
23139
25038
  onChannelMemberRoleRemoved: onChannelMemberRoleRemoved,
25039
+ onChannelArchived: onChannelArchived,
25040
+ onChannelUnarchived: onChannelUnarchived,
23140
25041
  getChannel: getChannel,
23141
25042
  getChannels: getChannels,
23142
25043
  getTotalChannelsUnread: getTotalChannelsUnread,
25044
+ getArchivedChannels: getArchivedChannels,
25045
+ searchChannels: searchChannels,
23143
25046
  MARKER_INCLUDED_CHANNEL_TYPE: MARKER_INCLUDED_CHANNEL_TYPE,
23144
25047
  isUnreadCountSupport: isUnreadCountSupport,
23145
25048
  convertFromRaw: convertFromRaw,
@@ -27036,7 +28939,7 @@ class CommentLiveCollectionController extends LiveCollectionController {
27036
28939
  this.queryStreamController.appendToQueryStream(response, direction, refresh);
27037
28940
  }
27038
28941
  startSubscription() {
27039
- return this.queryStreamController.subscribeRTE([
28942
+ const disposers = this.queryStreamController.subscribeRTE([
27040
28943
  { fn: onCommentCreatedLocal, action: EnumCommentActions.OnCommentCreated },
27041
28944
  { fn: onCommentDeleteLocal, action: EnumCommentActions.OnCommentDeleted },
27042
28945
  { fn: onCommentCreated, action: EnumCommentActions.OnCommentCreated },
@@ -27049,6 +28952,11 @@ class CommentLiveCollectionController extends LiveCollectionController {
27049
28952
  { fn: onLocalCommentReactionAdded, action: EnumCommentActions.OnCommentReactionAdded },
27050
28953
  { fn: onLocalCommentReactionRemoved, action: EnumCommentActions.OnCommentReactionRemoved },
27051
28954
  ]);
28955
+ if (this.query.excludeBlockUserComments) {
28956
+ const refresh = () => this.notifyChange({ origin: "event" /* Amity.LiveDataOrigin.EVENT */, loading: false });
28957
+ disposers.push(onUserDidBlock(refresh), onUserDidUnblock(refresh));
28958
+ }
28959
+ return disposers;
27052
28960
  }
27053
28961
  notifyChange({ origin, loading, error }) {
27054
28962
  var _a, _b;
@@ -27101,6 +29009,9 @@ class CommentLiveCollectionController extends LiveCollectionController {
27101
29009
  comments = comments.filter(comment => { var _a; return (_a = this.query.dataTypes) === null || _a === void 0 ? void 0 : _a.values.some(value => { var _a; return (_a = comment.dataTypes) === null || _a === void 0 ? void 0 : _a.includes(value); }); });
27102
29010
  }
27103
29011
  }
29012
+ if (this.query.excludeBlockUserComments) {
29013
+ comments = filterCommentsByBlockUsers(comments);
29014
+ }
27104
29015
  switch (this.query.sortBy) {
27105
29016
  case 'firstCreated':
27106
29017
  comments = comments.sort(sortByFirstCreated);
@@ -28186,13 +30097,253 @@ const getCommunityFeed = (params, callback, config) => {
28186
30097
  };
28187
30098
  /* end_public_function */
28188
30099
 
30100
+ /**
30101
+ * Thrown by `getForYouFeed` when the network has the For You feature
30102
+ * disabled. Mapped from HTTP 404 NOT_FOUND. Distinct from a generic
30103
+ * not-found so consumers can hide the For You tab without retrying.
30104
+ *
30105
+ * @category Errors
30106
+ */
30107
+ class AmityForYouFeedDisabledError extends ASCApiError {
30108
+ constructor(message = 'For You feed is not enabled for this network') {
30109
+ super(message, 400400 /* Amity.ServerError.ITEM_NOT_FOUND */, "error" /* Amity.ErrorLevel.ERROR */);
30110
+ this.type = 'AmityForYouFeedDisabledError';
30111
+ }
30112
+ }
30113
+
30114
+ class ForYouFeedPaginationController extends PaginationController {
30115
+ constructor(query) {
30116
+ super(query);
30117
+ this.checkedDisk = false;
30118
+ this.hasDeliveredPost = false;
30119
+ this.cursor = CursorController.current();
30120
+ }
30121
+ async getRequest(_queryParams, token) {
30122
+ var _a, _b, _c, _d, _e;
30123
+ const isFirstPage = token === undefined;
30124
+ let stored = null;
30125
+ // On the first page of a fresh collection, load the saved cursor from disk once.
30126
+ // Drop it if the snapshot has already expired so we start fresh.
30127
+ if (isFirstPage && !this.checkedDisk && this.cursor) {
30128
+ this.checkedDisk = true;
30129
+ stored = await this.cursor.get();
30130
+ if (stored && CursorController.isExpired(stored.expiredAt)) {
30131
+ await this.cursor.clear();
30132
+ stored = null;
30133
+ }
30134
+ }
30135
+ // Already paged to the end before. Ask the BE fresh (no cursor) and check if it's
30136
+ // still the same snapshot the user finished.
30137
+ if (isFirstPage && (stored === null || stored === void 0 ? void 0 : stored.reachedEndOfFeed)) {
30138
+ const fresh = await this.fetch();
30139
+ const freshExpiredAt = Date.parse((_b = (_a = fresh.paging) === null || _a === void 0 ? void 0 : _a.expiredAt) !== null && _b !== void 0 ? _b : '');
30140
+ const rolledOver = !Number.isNaN(freshExpiredAt) && freshExpiredAt !== stored.expiredAt;
30141
+ // New snapshot → serve it. Same snapshot → user has seen it all, show empty.
30142
+ if (rolledOver) {
30143
+ await this.persistCursor(fresh);
30144
+ if (fresh.posts.length > 0)
30145
+ this.hasDeliveredPost = true;
30146
+ return fresh;
30147
+ }
30148
+ return Object.assign(Object.assign({}, fresh), { posts: [], paging: {} });
30149
+ }
30150
+ // Resume from the saved cursor on re-entry; otherwise use the live-collection token.
30151
+ const effectiveToken = isFirstPage && stored ? stored.cursor : token;
30152
+ const response = await this.fetch(effectiveToken);
30153
+ if (response.posts.length > 0)
30154
+ this.hasDeliveredPost = true;
30155
+ if ((_c = response.paging) === null || _c === void 0 ? void 0 : _c.next) {
30156
+ // More pages left → advance the saved cursor.
30157
+ await this.persistCursor(response);
30158
+ }
30159
+ else if (this.hasDeliveredPost && this.cursor) {
30160
+ // Reached the end and mark end of feed
30161
+ const expiredAt = Date.parse((_e = (_d = response.paging) === null || _d === void 0 ? void 0 : _d.expiredAt) !== null && _e !== void 0 ? _e : '');
30162
+ if (!Number.isNaN(expiredAt))
30163
+ await this.cursor.markReachedEndOfFeed(expiredAt);
30164
+ }
30165
+ return response;
30166
+ }
30167
+ async fetch(token) {
30168
+ const options = { limit: COLLECTION_DEFAULT_PAGINATION_SIZE };
30169
+ if (token)
30170
+ options.token = token;
30171
+ try {
30172
+ const { data } = await this.http.get(API_ENDPOINTS.forYouFeed, {
30173
+ params: { options },
30174
+ });
30175
+ return data;
30176
+ }
30177
+ catch (error) {
30178
+ if (error instanceof ASCApiError && error.code === 400300 /* Amity.ServerError.FORBIDDEN */) {
30179
+ throw new AmityForYouFeedDisabledError();
30180
+ }
30181
+ const recoverable = error instanceof ASCApiError && error.code === 400322 /* Amity.ServerError.FEED_SNAPSHOT_EXPIRED */;
30182
+ if (recoverable && token !== undefined) {
30183
+ if (this.cursor)
30184
+ await this.cursor.clear();
30185
+ const { data } = await this.http.get(API_ENDPOINTS.forYouFeed, {
30186
+ params: { options: { limit: COLLECTION_DEFAULT_PAGINATION_SIZE } },
30187
+ });
30188
+ return data;
30189
+ }
30190
+ throw error;
30191
+ }
30192
+ }
30193
+ async persistCursor(response) {
30194
+ var _a, _b;
30195
+ if (!this.cursor)
30196
+ return;
30197
+ const cursor = (_a = response.paging) === null || _a === void 0 ? void 0 : _a.next;
30198
+ const expiredAtIso = (_b = response.paging) === null || _b === void 0 ? void 0 : _b.expiredAt;
30199
+ if (!cursor || !expiredAtIso)
30200
+ return;
30201
+ const expiredAt = Date.parse(expiredAtIso);
30202
+ if (Number.isNaN(expiredAt))
30203
+ return;
30204
+ await this.cursor.set({ cursor, expiredAt });
30205
+ }
30206
+ }
30207
+
30208
+ class ForYouFeedQueryStreamController extends QueryStreamController {
30209
+ constructor(query, cacheKey, notifyChange, preparePayload) {
30210
+ super(query, cacheKey);
30211
+ this.notifyChange = notifyChange;
30212
+ this.preparePayload = preparePayload;
30213
+ }
30214
+ async saveToMainDB(response) {
30215
+ const processedPayload = await this.preparePayload(response);
30216
+ const client = getActiveClient();
30217
+ const cachedAt = client.cache && Date.now();
30218
+ if (client.cache)
30219
+ ingestInCache(processedPayload, { cachedAt });
30220
+ }
30221
+ appendToQueryStream(response, _direction, refresh = false) {
30222
+ var _a, _b;
30223
+ if (refresh) {
30224
+ pushToCache(this.cacheKey, {
30225
+ data: response.posts.map(getResolver('post')),
30226
+ });
30227
+ }
30228
+ else {
30229
+ const collection = (_a = pullFromCache(this.cacheKey)) === null || _a === void 0 ? void 0 : _a.data;
30230
+ const posts = (_b = collection === null || collection === void 0 ? void 0 : collection.data) !== null && _b !== void 0 ? _b : [];
30231
+ pushToCache(this.cacheKey, Object.assign(Object.assign({}, collection), { data: [...new Set([...posts, ...response.posts.map(getResolver('post'))])] }));
30232
+ }
30233
+ }
30234
+ reactor(action) {
30235
+ return (post) => {
30236
+ var _a;
30237
+ const collection = (_a = pullFromCache(this.cacheKey)) === null || _a === void 0 ? void 0 : _a.data;
30238
+ if (!collection)
30239
+ return;
30240
+ if (post.parentPostId && !collection.data.includes(post.parentPostId))
30241
+ return;
30242
+ if (action === EnumPostActions.OnPostDeleted || action === EnumPostActions.OnPostDeclined) {
30243
+ collection.data = collection.data.filter(postId => postId !== post.postId);
30244
+ }
30245
+ pushToCache(this.cacheKey, collection);
30246
+ this.notifyChange({ origin: "event" /* Amity.LiveDataOrigin.EVENT */, loading: false });
30247
+ };
30248
+ }
30249
+ subscribeRTE(createSubscriber) {
30250
+ return createSubscriber.map(subscriber => subscriber.fn(this.reactor(subscriber.action)));
30251
+ }
30252
+ }
30253
+
30254
+ const FOR_YOU_FEED_CACHE_KEY = ['forYouFeed', 'collection'];
30255
+ class ForYouFeedLiveCollectionController extends LiveCollectionController {
30256
+ constructor(callback) {
30257
+ const queryStreamId = `for-you-feed-${getActiveClient().userId}`;
30258
+ const query = {};
30259
+ const paginationController = new ForYouFeedPaginationController(query);
30260
+ super(paginationController, queryStreamId, FOR_YOU_FEED_CACHE_KEY, callback);
30261
+ this.queryStreamController = new ForYouFeedQueryStreamController(query, this.cacheKey, this.notifyChange.bind(this), preparePostPayload);
30262
+ this.callback = callback.bind(this);
30263
+ this.loadPage({ initial: true });
30264
+ }
30265
+ setup() {
30266
+ var _a;
30267
+ const collection = (_a = pullFromCache(this.cacheKey)) === null || _a === void 0 ? void 0 : _a.data;
30268
+ if (!collection)
30269
+ pushToCache(this.cacheKey, { data: [], params: {} });
30270
+ }
30271
+ async persistModel(payload) {
30272
+ await this.queryStreamController.saveToMainDB(payload);
30273
+ }
30274
+ persistQueryStream({ response, direction, refresh, }) {
30275
+ this.queryStreamController.appendToQueryStream(response, direction, refresh);
30276
+ }
30277
+ startSubscription() {
30278
+ return this.queryStreamController.subscribeRTE(getGlobalFeedSubscriptions(this.cacheKey));
30279
+ }
30280
+ notifyChange({ origin, loading, error }) {
30281
+ var _a, _b;
30282
+ const collection = (_a = pullFromCache(this.cacheKey)) === null || _a === void 0 ? void 0 : _a.data;
30283
+ if (!collection)
30284
+ return;
30285
+ const data = ((_b = collection.data
30286
+ .map(id => pullFromCache(['post', 'get', id]))
30287
+ .filter(isNonNullable)
30288
+ .map(({ data }) => data)) !== null && _b !== void 0 ? _b : []).map(LinkedObject.post);
30289
+ if (!this.shouldNotify(data) && origin === 'event')
30290
+ return;
30291
+ this.callback({
30292
+ onNextPage: () => this.loadPage({ direction: "next" /* Amity.LiveCollectionPageDirection.NEXT */ }),
30293
+ data,
30294
+ hasNextPage: !!this.paginationController.getNextToken(),
30295
+ loading,
30296
+ error,
30297
+ });
30298
+ }
30299
+ }
30300
+
30301
+ /* begin_public_function
30302
+ id: feed.query.for_you_feed
30303
+ */
30304
+ /**
30305
+ * ```js
30306
+ * import { FeedRepository } from '@amityco/ts-sdk'
30307
+ *
30308
+ * const unsub = FeedRepository.getForYouFeed(({ data, loading, error, hasNextPage, onNextPage }) => {
30309
+ * // render posts; call onNextPage() to load the next page (20 posts)
30310
+ * })
30311
+ * ```
30312
+ *
30313
+ * Observe the For You feed — a personalized, server-ranked
30314
+ * {@link Amity.LiveCollection} of {@link Amity.Post}.
30315
+ *
30316
+ * @param callback the function to call when new data is available
30317
+ * @returns an {@link Amity.Unsubscriber} function to stop observing
30318
+ *
30319
+ * @category Posts Live Collection
30320
+ */
30321
+ const getForYouFeed = (callback) => {
30322
+ const { log, cache } = getActiveClient();
30323
+ if (!cache)
30324
+ console.log(ENABLE_CACHE_MESSAGE);
30325
+ const timestamp = Date.now();
30326
+ log(`getForYouFeed(tmpid: ${timestamp}) > listen`);
30327
+ const forYouFeedLiveCollection = new ForYouFeedLiveCollectionController(callback);
30328
+ const disposers = forYouFeedLiveCollection.startSubscription();
30329
+ const cacheKey = forYouFeedLiveCollection.getCacheKey();
30330
+ disposers.push(() => dropFromCache(cacheKey));
30331
+ return () => {
30332
+ log(`getForYouFeed(tmpid: ${timestamp}) > dispose`);
30333
+ disposers.forEach(fn => fn());
30334
+ };
30335
+ };
30336
+ /* end_public_function */
30337
+
28189
30338
  var index$d = /*#__PURE__*/Object.freeze({
28190
30339
  __proto__: null,
28191
30340
  queryGlobalFeed: queryGlobalFeed,
28192
30341
  getCustomRankingGlobalFeed: getCustomRankingGlobalFeed,
28193
30342
  getGlobalFeed: getGlobalFeed,
28194
30343
  getUserFeed: getUserFeed,
28195
- getCommunityFeed: getCommunityFeed
30344
+ getCommunityFeed: getCommunityFeed,
30345
+ getForYouFeed: getForYouFeed,
30346
+ AmityForYouFeedDisabledError: AmityForYouFeedDisabledError
28196
30347
  });
28197
30348
 
28198
30349
  /* begin_public_function
@@ -29205,7 +31356,12 @@ class PostLiveCollectionController extends LiveCollectionController {
29205
31356
  this.queryStreamController.appendToQueryStream(response, direction, refresh);
29206
31357
  }
29207
31358
  startSubscription() {
29208
- return this.queryStreamController.subscribeRTE(getPostSubscription(this.cacheKey));
31359
+ const disposers = this.queryStreamController.subscribeRTE(getPostSubscription(this.cacheKey));
31360
+ if (this.query.excludeBlockUserPosts) {
31361
+ const refresh = () => this.notifyChange({ origin: "event" /* Amity.LiveDataOrigin.EVENT */, loading: false });
31362
+ disposers.push(onUserDidBlock(refresh), onUserDidUnblock(refresh));
31363
+ }
31364
+ return disposers;
29209
31365
  }
29210
31366
  notifyChange({ origin, loading, error }) {
29211
31367
  var _a, _b;
@@ -29251,6 +31407,9 @@ class PostLiveCollectionController extends LiveCollectionController {
29251
31407
  const sortBy = this.query.sortBy || 'lastCreated';
29252
31408
  posts = posts.filter(post => !exceedsUntilAtBoundary(post.createdAt, validatedUntilAt, sortBy));
29253
31409
  }
31410
+ if (this.query.excludeBlockUserPosts) {
31411
+ posts = filterPostsByBlockUsers(posts);
31412
+ }
29254
31413
  switch (this.query.sortBy) {
29255
31414
  case 'firstCreated':
29256
31415
  posts = posts.sort(sortByFirstCreated);
@@ -35965,6 +38124,9 @@ exports.filterByPropIntersection = filterByPropIntersection;
35965
38124
  exports.filterBySearchTerm = filterBySearchTerm;
35966
38125
  exports.filterByStringComparePartially = filterByStringComparePartially;
35967
38126
  exports.filterByUntilAt = filterByUntilAt;
38127
+ exports.filterCommentsByBlockUsers = filterCommentsByBlockUsers;
38128
+ exports.filterPostsByBlockUsers = filterPostsByBlockUsers;
38129
+ exports.getBlockUsersId = getBlockUsersId;
35968
38130
  exports.getChannelTopic = getChannelTopic;
35969
38131
  exports.getCommentTopic = getCommentTopic;
35970
38132
  exports.getCommunityStoriesTopic = getCommunityStoriesTopic;
@@ -35976,6 +38138,7 @@ exports.getMarkerUserFeedTopic = getMarkerUserFeedTopic;
35976
38138
  exports.getMessageTopic = getMessageTopic;
35977
38139
  exports.getMyFollowersTopic = getMyFollowersTopic;
35978
38140
  exports.getMyFollowingsTopic = getMyFollowingsTopic;
38141
+ exports.getNetworkId = getNetworkId;
35979
38142
  exports.getNetworkTopic = getNetworkTopic;
35980
38143
  exports.getPostTopic = getPostTopic;
35981
38144
  exports.getRole = getRole;