@amityco/ts-sdk 7.4.1-d23fab2f.0 → 7.4.1-e8631ca7.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 (104) hide show
  1. package/dist/@types/core/events.d.ts +3 -3
  2. package/dist/@types/core/events.d.ts.map +1 -1
  3. package/dist/@types/core/payload.d.ts +14 -0
  4. package/dist/@types/core/payload.d.ts.map +1 -1
  5. package/dist/@types/domains/community.d.ts +4 -0
  6. package/dist/@types/domains/community.d.ts.map +1 -1
  7. package/dist/@types/domains/invitation.d.ts +48 -3
  8. package/dist/@types/domains/invitation.d.ts.map +1 -1
  9. package/dist/communityRepository/api/getCommunities.d.ts +1 -1
  10. package/dist/communityRepository/api/getCommunities.d.ts.map +1 -1
  11. package/dist/communityRepository/api/getRecommendedCommunities.d.ts +3 -1
  12. package/dist/communityRepository/api/getRecommendedCommunities.d.ts.map +1 -1
  13. package/dist/communityRepository/api/getTrendingCommunities.d.ts +3 -1
  14. package/dist/communityRepository/api/getTrendingCommunities.d.ts.map +1 -1
  15. package/dist/communityRepository/api/updateCommunity.d.ts +2 -2
  16. package/dist/communityRepository/api/updateCommunity.d.ts.map +1 -1
  17. package/dist/index.cjs.js +1849 -1325
  18. package/dist/index.esm.js +2067 -1543
  19. package/dist/index.umd.js +4 -4
  20. package/dist/invitationRepository/events/index.d.ts +2 -0
  21. package/dist/invitationRepository/events/index.d.ts.map +1 -1
  22. package/dist/invitationRepository/events/onLocalInvitationCreated.d.ts +1 -1
  23. package/dist/invitationRepository/events/onLocalInvitationCreated.d.ts.map +1 -1
  24. package/dist/invitationRepository/events/onLocalInvitationDeleted.d.ts +1 -1
  25. package/dist/invitationRepository/events/onLocalInvitationDeleted.d.ts.map +1 -1
  26. package/dist/invitationRepository/events/onLocalInvitationUpdated.d.ts +1 -1
  27. package/dist/invitationRepository/events/onLocalInvitationUpdated.d.ts.map +1 -1
  28. package/dist/invitationRepository/index.d.ts +1 -0
  29. package/dist/invitationRepository/index.d.ts.map +1 -1
  30. package/dist/invitationRepository/internalApi/createInvitations.d.ts.map +1 -1
  31. package/dist/invitationRepository/internalApi/getInvitation.d.ts +17 -0
  32. package/dist/invitationRepository/internalApi/getInvitation.d.ts.map +1 -0
  33. package/dist/invitationRepository/observers/getInvitations/InvitationsLiveCollectionController.d.ts +14 -0
  34. package/dist/invitationRepository/observers/getInvitations/InvitationsLiveCollectionController.d.ts.map +1 -0
  35. package/dist/invitationRepository/observers/getInvitations/InvitationsPaginationController.d.ts +5 -0
  36. package/dist/invitationRepository/observers/getInvitations/InvitationsPaginationController.d.ts.map +1 -0
  37. package/dist/invitationRepository/observers/getInvitations/InvitationsQueryStreamController.d.ts +15 -0
  38. package/dist/invitationRepository/observers/getInvitations/InvitationsQueryStreamController.d.ts.map +1 -0
  39. package/dist/invitationRepository/observers/getInvitations/enums.d.ts +6 -0
  40. package/dist/invitationRepository/observers/getInvitations/enums.d.ts.map +1 -0
  41. package/dist/invitationRepository/observers/getInvitations.d.ts +12 -0
  42. package/dist/invitationRepository/observers/getInvitations.d.ts.map +1 -0
  43. package/dist/invitationRepository/observers/getMyCommunityInvitations.d.ts +12 -0
  44. package/dist/invitationRepository/observers/getMyCommunityInvitations.d.ts.map +1 -0
  45. package/dist/invitationRepository/observers/getMyInvitations/MyInvitationsLiveCollectionController.d.ts +14 -0
  46. package/dist/invitationRepository/observers/getMyInvitations/MyInvitationsLiveCollectionController.d.ts.map +1 -0
  47. package/dist/invitationRepository/observers/getMyInvitations/MyInvitationsPaginationController.d.ts +5 -0
  48. package/dist/invitationRepository/observers/getMyInvitations/MyInvitationsPaginationController.d.ts.map +1 -0
  49. package/dist/invitationRepository/observers/getMyInvitations/MyInvitationsQueryStreamController.d.ts +15 -0
  50. package/dist/invitationRepository/observers/getMyInvitations/MyInvitationsQueryStreamController.d.ts.map +1 -0
  51. package/dist/invitationRepository/observers/index.d.ts +2 -0
  52. package/dist/invitationRepository/observers/index.d.ts.map +1 -0
  53. package/dist/invitationRepository/utils/convertRawInvitationToInternalInvitation.d.ts +2 -0
  54. package/dist/invitationRepository/utils/convertRawInvitationToInternalInvitation.d.ts.map +1 -0
  55. package/dist/invitationRepository/utils/index.d.ts +2 -0
  56. package/dist/invitationRepository/utils/index.d.ts.map +1 -0
  57. package/dist/invitationRepository/utils/prepareInvitationPayload.d.ts +2 -0
  58. package/dist/invitationRepository/utils/prepareInvitationPayload.d.ts.map +1 -0
  59. package/dist/invitationRepository/utils/prepareMyInvitationsPayload.d.ts +2 -0
  60. package/dist/invitationRepository/utils/prepareMyInvitationsPayload.d.ts.map +1 -0
  61. package/dist/utils/linkedObject/communityLinkedObject.d.ts +1 -1
  62. package/dist/utils/linkedObject/communityLinkedObject.d.ts.map +1 -1
  63. package/dist/utils/linkedObject/index.d.ts +2 -2
  64. package/dist/utils/linkedObject/invitationLinkedObject.d.ts +1 -1
  65. package/dist/utils/linkedObject/invitationLinkedObject.d.ts.map +1 -1
  66. package/package.json +1 -1
  67. package/src/@types/core/events.ts +3 -3
  68. package/src/@types/core/payload.ts +17 -0
  69. package/src/@types/domains/community.ts +7 -0
  70. package/src/@types/domains/invitation.ts +67 -3
  71. package/src/communityRepository/api/getCommunities.ts +5 -1
  72. package/src/communityRepository/api/getCommunity.ts +1 -1
  73. package/src/communityRepository/api/getRecommendedCommunities.ts +9 -3
  74. package/src/communityRepository/api/getTrendingCommunities.ts +9 -3
  75. package/src/communityRepository/api/updateCommunity.ts +9 -2
  76. package/src/core/liveCollection/PaginationController.ts +1 -1
  77. package/src/core/liveCollection/PaginationNoPageController.ts +1 -1
  78. package/src/invitationRepository/events/index.ts +2 -0
  79. package/src/invitationRepository/events/onLocalInvitationCreated.ts +1 -1
  80. package/src/invitationRepository/events/onLocalInvitationDeleted.ts +1 -1
  81. package/src/invitationRepository/events/onLocalInvitationUpdated.ts +1 -1
  82. package/src/invitationRepository/index.ts +1 -0
  83. package/src/invitationRepository/internalApi/acceptInvitation.ts +1 -1
  84. package/src/invitationRepository/internalApi/cancelInvitation.ts +1 -1
  85. package/src/invitationRepository/internalApi/createInvitations.ts +8 -2
  86. package/src/invitationRepository/internalApi/getInvitation.ts +47 -0
  87. package/src/invitationRepository/internalApi/rejectInvitation.ts +1 -1
  88. package/src/invitationRepository/observers/getInvitations/InvitationsLiveCollectionController.ts +148 -0
  89. package/src/invitationRepository/observers/getInvitations/InvitationsPaginationController.ts +19 -0
  90. package/src/invitationRepository/observers/getInvitations/InvitationsQueryStreamController.ts +97 -0
  91. package/src/invitationRepository/observers/getInvitations/enums.ts +5 -0
  92. package/src/invitationRepository/observers/getInvitations.ts +44 -0
  93. package/src/invitationRepository/observers/getMyCommunityInvitations.ts +48 -0
  94. package/src/invitationRepository/observers/getMyInvitations/MyInvitationsLiveCollectionController.ts +148 -0
  95. package/src/invitationRepository/observers/getMyInvitations/MyInvitationsPaginationController.ts +22 -0
  96. package/src/invitationRepository/observers/getMyInvitations/MyInvitationsQueryStreamController.ts +105 -0
  97. package/src/invitationRepository/observers/index.ts +1 -0
  98. package/src/invitationRepository/utils/convertRawInvitationToInternalInvitation.ts +8 -0
  99. package/src/invitationRepository/utils/index.ts +1 -0
  100. package/src/invitationRepository/utils/prepareInvitationPayload.ts +12 -0
  101. package/src/invitationRepository/utils/prepareMyInvitationsPayload.ts +12 -0
  102. package/src/messagePreview/utils/getChannelMessagePreviewWithUser.ts +3 -3
  103. package/src/utils/linkedObject/communityLinkedObject.ts +21 -1
  104. package/src/utils/linkedObject/invitationLinkedObject.ts +25 -1
package/dist/index.cjs.js CHANGED
@@ -129,7 +129,12 @@ exports.InvitationStatusEnum = void 0;
129
129
  InvitationStatusEnum["Approved"] = "approved";
130
130
  InvitationStatusEnum["Rejected"] = "rejected";
131
131
  InvitationStatusEnum["Cancelled"] = "cancelled";
132
- })(exports.InvitationStatusEnum || (exports.InvitationStatusEnum = {}));
132
+ })(exports.InvitationStatusEnum || (exports.InvitationStatusEnum = {}));
133
+ exports.InvitationSortByEnum = void 0;
134
+ (function (InvitationSortByEnum) {
135
+ InvitationSortByEnum["FirstCreated"] = "firstCreated";
136
+ InvitationSortByEnum["LastCreated"] = "lastCreated";
137
+ })(exports.InvitationSortByEnum || (exports.InvitationSortByEnum = {}));
133
138
 
134
139
  function getVersion() {
135
140
  try {
@@ -4898,6 +4903,1102 @@ const getChannelMessagePreview = (channelId) => {
4898
4903
  return ((_b = (_a = pullFromCache(['messagePreviewChannel', 'get', channelId])) === null || _a === void 0 ? void 0 : _a.data) !== null && _b !== void 0 ? _b : null);
4899
4904
  };
4900
4905
 
4906
+ const userLinkedObject = (user) => {
4907
+ return Object.assign(Object.assign({}, user), { get avatar() {
4908
+ var _a;
4909
+ if (!user.avatarFileId)
4910
+ return undefined;
4911
+ const avatar = (_a = pullFromCache([
4912
+ 'file',
4913
+ 'get',
4914
+ `${user.avatarFileId}`,
4915
+ ])) === null || _a === void 0 ? void 0 : _a.data;
4916
+ return avatar;
4917
+ } });
4918
+ };
4919
+
4920
+ const getChannelMessagePreviewWithUser = (channel) => {
4921
+ var _a;
4922
+ const messagePreview = channel.messagePreviewId
4923
+ ? getChannelMessagePreview(channel.channelId)
4924
+ : null;
4925
+ const internalUser = (_a = pullFromCache([
4926
+ 'user',
4927
+ 'get',
4928
+ messagePreview === null || messagePreview === void 0 ? void 0 : messagePreview.creatorId,
4929
+ ])) === null || _a === void 0 ? void 0 : _a.data;
4930
+ const messagePreviewWithUser = messagePreview
4931
+ ? Object.assign(Object.assign({}, messagePreview), { user: internalUser ? userLinkedObject(internalUser) : undefined }) : null;
4932
+ return Object.assign(Object.assign({}, channel), { messagePreview: messagePreviewWithUser });
4933
+ };
4934
+
4935
+ const updateChannelMessagePreviewCache = (rawPayload) => {
4936
+ var _a, _b;
4937
+ const withMessageFeedInfo = (messagePreview) => {
4938
+ var _a;
4939
+ const messageFeedInfo = (_a = rawPayload.messageFeedsInfo) === null || _a === void 0 ? void 0 : _a.find(messageFeed => {
4940
+ return messageFeed.messageFeedId === messagePreview.messageFeedId;
4941
+ });
4942
+ const { channelPublicId: channelId, messageFeedId: subChannelId, data, dataType, isDeleted, segment, creatorPublicId: creatorId, createdAt, updatedAt, } = messagePreview;
4943
+ return {
4944
+ channelId,
4945
+ subChannelId,
4946
+ data,
4947
+ dataType,
4948
+ isDeleted,
4949
+ segment,
4950
+ creatorId,
4951
+ createdAt,
4952
+ updatedAt,
4953
+ subChannelName: messageFeedInfo === null || messageFeedInfo === void 0 ? void 0 : messageFeedInfo.name,
4954
+ messagePreviewId: messageFeedInfo === null || messageFeedInfo === void 0 ? void 0 : messageFeedInfo.messagePreviewId,
4955
+ subChannelUpdatedAt: messageFeedInfo === null || messageFeedInfo === void 0 ? void 0 : messageFeedInfo.updatedAt,
4956
+ };
4957
+ };
4958
+ const newData = {
4959
+ messagePreviewChannel: (_b = (_a = rawPayload.messagePreviews) === null || _a === void 0 ? void 0 : _a.map(messagePreview => withMessageFeedInfo(messagePreview))) !== null && _b !== void 0 ? _b : [],
4960
+ };
4961
+ ingestInCache(newData);
4962
+ };
4963
+
4964
+ const getSubChannelMessagePreview = (subChannelId) => {
4965
+ var _a, _b;
4966
+ return ((_b = (_a = pullFromCache(['messagePreviewSubChannel', 'get', subChannelId])) === null || _a === void 0 ? void 0 : _a.data) !== null && _b !== void 0 ? _b : null);
4967
+ };
4968
+
4969
+ const getSubChannelMessagePreviewWithUser = (subChannel) => {
4970
+ var _a;
4971
+ const messagePreview = subChannel.messagePreviewId
4972
+ ? getSubChannelMessagePreview(subChannel.subChannelId)
4973
+ : null;
4974
+ const messagePreviewWithUser = messagePreview
4975
+ ? Object.assign(Object.assign({}, messagePreview), { user: (_a = pullFromCache(['user', 'get', messagePreview === null || messagePreview === void 0 ? void 0 : messagePreview.creatorId])) === null || _a === void 0 ? void 0 : _a.data }) : null;
4976
+ return Object.assign(Object.assign({}, subChannel), { messagePreview: messagePreviewWithUser });
4977
+ };
4978
+
4979
+ const updateSubChannelMessagePreviewCache = (rawPayload) => {
4980
+ var _a, _b;
4981
+ const withMessageFeedInfo = (messagePreview) => {
4982
+ var _a;
4983
+ const messageFeedInfo = (_a = rawPayload.messageFeeds) === null || _a === void 0 ? void 0 : _a.find(messageFeed => {
4984
+ return messageFeed.messageFeedId === messagePreview.messageFeedId;
4985
+ });
4986
+ const { channelPublicId: channelId, messageFeedId: subChannelId, messageId: messagePreviewId, creatorPublicId: creatorId, data, dataType, isDeleted, segment, createdAt, updatedAt, } = messagePreview;
4987
+ return {
4988
+ messagePreviewId,
4989
+ channelId,
4990
+ subChannelId,
4991
+ data,
4992
+ dataType,
4993
+ isDeleted,
4994
+ segment,
4995
+ creatorId,
4996
+ createdAt,
4997
+ updatedAt,
4998
+ subChannelName: messageFeedInfo === null || messageFeedInfo === void 0 ? void 0 : messageFeedInfo.name,
4999
+ subChannelUpdatedAt: messageFeedInfo === null || messageFeedInfo === void 0 ? void 0 : messageFeedInfo.updatedAt,
5000
+ };
5001
+ };
5002
+ const newData = {
5003
+ messagePreviewSubChannel: (_b = (_a = rawPayload.messages) === null || _a === void 0 ? void 0 : _a.map(messagePreview => withMessageFeedInfo(messagePreview))) !== null && _b !== void 0 ? _b : [],
5004
+ };
5005
+ ingestInCache(newData);
5006
+ };
5007
+
5008
+ /**
5009
+ * ```js
5010
+ * import { shallowClone } from '~/utils/shallowClone'
5011
+ * const newObj = shallowClone(obj)
5012
+ * ```
5013
+ *
5014
+ * Clone an object with same prototype and properties
5015
+ *
5016
+ * @param obj the object to clone
5017
+ * @returns new object with same prototype and properties
5018
+ *
5019
+ * @category utility
5020
+ * @private
5021
+ */
5022
+ function shallowClone(source, target) {
5023
+ return Object.create(Object.getPrototypeOf(source), Object.assign(Object.assign({}, Object.getOwnPropertyDescriptors(source)), Object.getOwnPropertyDescriptors(target)));
5024
+ }
5025
+
5026
+ function updateSubChannelCache(subChannelId, subChannel, params) {
5027
+ pushToCache(['subChannel', 'get', subChannelId],
5028
+ // eslint-disable-next-line prefer-object-spread
5029
+ shallowClone(subChannel, params));
5030
+ }
5031
+
5032
+ /**
5033
+ * ```js
5034
+ * import { isInTombstone } from '@amityco/ts-sdk'
5035
+ * const user = isInTombstone(["message", "messageId"])
5036
+ * ```
5037
+ *
5038
+ * Checks if the {@link Amity.TombstoneCacheOptions} exists
5039
+ * in cache and it's not expired means it's in tombstone
5040
+ * and we throw an Error
5041
+ *
5042
+ * @param model the model to check
5043
+ * @param modelId the object id to check
5044
+ * @returns the matching cache entry, or undefined.
5045
+ *
5046
+ * @category Cache API
5047
+ */
5048
+ const isInTombstone = (model, modelId) => {
5049
+ const { log, cache } = getActiveClient();
5050
+ const key = [model, CACHE_KEY_TOMBSTONE, modelId];
5051
+ if (!cache)
5052
+ return;
5053
+ log('cache/api/isInTombstone', key);
5054
+ const isInTombstone = pullFromCache(key);
5055
+ const { lifeSpan } = queryOptions('cache_then_server', CACHE_LIFESPAN_TOMBSTONE);
5056
+ if (isInTombstone && isFresh(isInTombstone.data, lifeSpan)) {
5057
+ throw new ASCApiError('Item not found!', 400400 /* Amity.ServerError.ITEM_NOT_FOUND */, "error" /* Amity.ErrorLevel.ERROR */);
5058
+ }
5059
+ };
5060
+
5061
+ /**
5062
+ * ```js
5063
+ * import { getMessageMarkers } from '@amityco/ts-sdk'
5064
+ * const messageMarkers = await getMessageMarkers(['sch1', 'sch2'])
5065
+ * ```
5066
+ *
5067
+ * Fetches a list of {@link Amity.MessageMarker} by messageIds
5068
+ *
5069
+ * @param messageIds the feed IDs of the {@link Amity.RawMessage} marker to fetch
5070
+ * @returns A list of {@link Amity.MessageMarker} by messageIds
5071
+ *
5072
+ * @category Channel API
5073
+ * @async
5074
+ * @private
5075
+ */
5076
+ const getMessageMarkers = async (messageIds) => {
5077
+ const client = getActiveClient();
5078
+ client.log('channel/getMessageMarkers', messageIds);
5079
+ const { data: queryPayload } = await client.http.get(`/api/v1/markers/messages`, {
5080
+ params: {
5081
+ messageIds,
5082
+ },
5083
+ });
5084
+ const { contentMarkers, feedMarkers, userMarkers } = queryPayload;
5085
+ const cachedAt = client.cache && Date.now();
5086
+ if (client.cache)
5087
+ ingestInCache({ contentMarkers, feedMarkers, userMarkers }, { cachedAt });
5088
+ fireEvent('local.feedMarker.fetched', { feedMarkers });
5089
+ fireEvent('local.messageMarker.fetched', { contentMarkers });
5090
+ fireEvent('local.userMarker.fetched', { userMarkers });
5091
+ return { data: contentMarkers, cachedAt };
5092
+ };
5093
+
5094
+ const reCalculateChannelUnreadInfo = (channelId) => {
5095
+ var _a;
5096
+ const cacheKeyChannelUnread = ['channelUnreadInfo', 'get', channelId];
5097
+ const cacheChannelUnreadInfo = (_a = pullFromCache(cacheKeyChannelUnread)) === null || _a === void 0 ? void 0 : _a.data;
5098
+ const cacheKeySubChannelUnread = ['subChannelUnreadInfo', 'get'];
5099
+ const cachedSubChannelUnreadInfo = queryCache(cacheKeySubChannelUnread);
5100
+ let channelUnreads = 0;
5101
+ let isMentioned = false;
5102
+ if (cachedSubChannelUnreadInfo && (cachedSubChannelUnreadInfo === null || cachedSubChannelUnreadInfo === void 0 ? void 0 : cachedSubChannelUnreadInfo.length) > 0) {
5103
+ const subChannelUnreadsInfo = cachedSubChannelUnreadInfo === null || cachedSubChannelUnreadInfo === void 0 ? void 0 : cachedSubChannelUnreadInfo.filter(({ data }) => {
5104
+ return data.channelId === channelId && !data.isDeleted;
5105
+ });
5106
+ channelUnreads = subChannelUnreadsInfo
5107
+ .map(({ data }) => data.unreadCount)
5108
+ .reduce((acc, cur) => acc + cur, 0);
5109
+ isMentioned = subChannelUnreadsInfo.some(({ data }) => data.isMentioned);
5110
+ }
5111
+ const channelUnreadInfo = Object.assign(Object.assign({}, (cacheChannelUnreadInfo !== null && cacheChannelUnreadInfo !== void 0 ? cacheChannelUnreadInfo : {
5112
+ channelId,
5113
+ createdAt: new Date().toISOString(),
5114
+ })), { updatedAt: new Date().toISOString(), unreadCount: channelUnreads, isMentioned });
5115
+ pushToCache(cacheKeyChannelUnread, channelUnreadInfo);
5116
+ return channelUnreadInfo;
5117
+ };
5118
+
5119
+ const persistUnreadCountInfo = (payload) => {
5120
+ const { feedMarkers, userFeedMarkers } = payload;
5121
+ // calculate sub channel unread info and channel unread info
5122
+ if (feedMarkers.length > 0 && userFeedMarkers.length > 0) {
5123
+ const channelIds = [];
5124
+ const feedMarkerMap = new Map(feedMarkers.map(fm => [fm.feedId, fm]));
5125
+ userFeedMarkers.forEach(userFeedMarker => {
5126
+ const feedMarker = feedMarkerMap.get(userFeedMarker.feedId);
5127
+ if (!feedMarker)
5128
+ return;
5129
+ if (feedMarker.feedId === userFeedMarker.feedId) {
5130
+ const unreadCount = feedMarker.lastSegment - userFeedMarker.readToSegment;
5131
+ const subChannelUnreadInfo = {
5132
+ subChannelId: feedMarker.feedId,
5133
+ channelId: feedMarker.entityId,
5134
+ readToSegment: userFeedMarker.readToSegment,
5135
+ lastSegment: feedMarker.lastSegment,
5136
+ lastMentionSegment: userFeedMarker.lastMentionSegment,
5137
+ unreadCount: Math.max(0, unreadCount),
5138
+ isMentioned: userFeedMarker.isMentioned,
5139
+ isDeleted: feedMarker.isDeleted,
5140
+ createdAt: userFeedMarker.createdAt,
5141
+ updatedAt: userFeedMarker.updatedAt,
5142
+ };
5143
+ // update sub channel unread info in cache
5144
+ ingestInCache({ subChannelUnreadInfo: [subChannelUnreadInfo] });
5145
+ if (!channelIds.includes(feedMarker.entityId)) {
5146
+ channelIds.push(feedMarker.entityId);
5147
+ }
5148
+ }
5149
+ });
5150
+ // re-calculate channel unread info in cache
5151
+ channelIds.forEach(channelId => {
5152
+ reCalculateChannelUnreadInfo(channelId);
5153
+ });
5154
+ }
5155
+ };
5156
+
5157
+ /**
5158
+ * ```js
5159
+ * import { getSubChannelMarkers } from '@amityco/ts-sdk'
5160
+ * const subChannelMarkers = await getSubChannelMarkers(['sch1', 'sch2'])
5161
+ * ```
5162
+ *
5163
+ * Fetches a paginable list of {@link Amity.SubChannelMarker} objects
5164
+ *
5165
+ * @param messageFeedIds the feed IDs of the {@link Amity.RawSubChannel} marker to fetch
5166
+ * @param page
5167
+ * @returns A page of {@link Amity.SubChannelMarker} objects
5168
+ *
5169
+ * @category Channel API
5170
+ * @async
5171
+ * @private
5172
+ */
5173
+ const getSubChannelMarkers = async (messageFeedIds, page = { limit: 100 }) => {
5174
+ const client = getActiveClient();
5175
+ client.log('channel/getSubChannelMarkers', messageFeedIds, page);
5176
+ const { data: queryPayload } = await client.http.get(`/api/v1/markers/message-feeds`, {
5177
+ params: {
5178
+ messageFeedIds,
5179
+ options: {
5180
+ token: toToken(page, 'skiplimit'),
5181
+ },
5182
+ },
5183
+ });
5184
+ const { paging } = queryPayload, payload = __rest(queryPayload, ["paging"]);
5185
+ const { userEntityMarkers: userEntityMarkersPayload, userFeedMarkers: userFeedMarkersPayload, userMarkers, feedMarkers: feedMarkersPayload, } = payload;
5186
+ // if consistent mode is enabled, persist the unread count info to the cache
5187
+ if (client.isUnreadCountEnabled && client.getMarkerSyncConsistentMode()) {
5188
+ persistUnreadCountInfo({
5189
+ feedMarkers: feedMarkersPayload,
5190
+ userFeedMarkers: userFeedMarkersPayload,
5191
+ });
5192
+ }
5193
+ const userEntityMarkers = convertChannelMarkerResponse(userEntityMarkersPayload);
5194
+ const userFeedMarkers = convertSubChannelMarkerResponse(userFeedMarkersPayload);
5195
+ const cachedAt = client.cache && Date.now();
5196
+ if (client.cache)
5197
+ ingestInCache({ userEntityMarkers, userFeedMarkers, userMarkers }, { cachedAt });
5198
+ fireEvent('local.channelMarker.fetched', { userEntityMarkers });
5199
+ fireEvent('local.subChannelMarker.fetched', { userFeedMarkers });
5200
+ fireEvent('local.userMarker.fetched', { userMarkers });
5201
+ const nextPage = toPage(paging.next);
5202
+ const prevPage = toPage(paging.previous);
5203
+ return { data: userFeedMarkers, cachedAt, prevPage, nextPage };
5204
+ };
5205
+
5206
+ const getUserMarker = async () => {
5207
+ const client = getActiveClient();
5208
+ client.log('channel/getUserMarker');
5209
+ const { data: payload } = await client.http.get(`/api/v1/markers/userMarker`);
5210
+ const { userMarkers } = payload;
5211
+ const cachedAt = client.cache && Date.now();
5212
+ if (client.cache)
5213
+ ingestInCache({ userMarkers }, { cachedAt });
5214
+ fireEvent('local.userMarker.fetched', { userMarkers });
5215
+ const latestUserMarker = userMarkers.reduce((maxUserMarker, userMarker) => {
5216
+ if (maxUserMarker == null ||
5217
+ new Date(maxUserMarker.lastSyncAt).getTime() < new Date(userMarker.lastSyncAt).getTime()) {
5218
+ return userMarker;
5219
+ }
5220
+ return maxUserMarker;
5221
+ }, undefined);
5222
+ return { data: latestUserMarker, cachedAt };
5223
+ };
5224
+
5225
+ /** @hidden */
5226
+ /*
5227
+ * @param message payload from http request without myReactions
5228
+ * add myReactions to http response if the event was a reaction event
5229
+ */
5230
+ const prepareMessagePayloadForCache = (payload, reactors, event) => {
5231
+ const client = getActiveClient();
5232
+ const cached = pullFromCache(['message', 'get', payload.messageId]);
5233
+ // '[]' in cases where the new reaction is the first one
5234
+ const myReactions = (cached === null || cached === void 0 ? void 0 : cached.data.myReactions) || [];
5235
+ // add myReactions to the payload
5236
+ Object.assign(payload, { myReactions });
5237
+ // check if there are any updates to the reactions
5238
+ const latestReaction = reactors[0];
5239
+ const isLatestReactionMine = latestReaction && latestReaction.userId === client.userId;
5240
+ if (!isLatestReactionMine) {
5241
+ return;
5242
+ }
5243
+ // new reaction added
5244
+ if (event === 'message.reactionAdded' && !myReactions.includes(latestReaction.reactionName)) {
5245
+ Object.assign(payload, {
5246
+ myReactions: [...myReactions, latestReaction.reactionName],
5247
+ });
5248
+ }
5249
+ // existing reaction removed
5250
+ if (event === 'message.reactionRemoved' && myReactions.includes(latestReaction.reactionName)) {
5251
+ Object.assign(payload, {
5252
+ myReactions: myReactions.filter(x => x !== latestReaction.reactionName),
5253
+ });
5254
+ }
5255
+ };
5256
+
5257
+ /*
5258
+ * This is a simple utility that infers the value of isDeleted based on the
5259
+ * value of includeDeleted
5260
+ *
5261
+ * There are two important things to note here:
5262
+ * 1. `includeDeleted` is purely client side query param and not recognized by
5263
+ * the server
5264
+ * 2. The only values we wish to expose with regards to `isDeleted` (the server
5265
+ * param for queries) is false | undefined and want to disallow users to query
5266
+ * for deleted entities
5267
+ *
5268
+ * Although this is a very simple utility, it's only purpose is to keep things
5269
+ * DRY
5270
+ */
5271
+ const inferIsDeleted = (includeDeleted) => includeDeleted === true ? undefined : false;
5272
+
5273
+ function getSubChannelIsMentioned(channelId, subChannelId, marker) {
5274
+ var _a, _b;
5275
+ // Look for `unreadCount` in the marker param first
5276
+ if (marker) {
5277
+ return marker.hasMentioned;
5278
+ }
5279
+ const client = getActiveClient();
5280
+ // If consistent mode is enabled, look in the SubChannelUnreadCountInfo cache
5281
+ if (client.isUnreadCountEnabled && client.getMarkerSyncConsistentMode()) {
5282
+ const cachedUnreadCount = (_a = pullFromCache([
5283
+ 'subChannelUnreadInfo',
5284
+ 'get',
5285
+ subChannelId,
5286
+ ])) === null || _a === void 0 ? void 0 : _a.data;
5287
+ if (cachedUnreadCount) {
5288
+ return cachedUnreadCount.isMentioned;
5289
+ }
5290
+ return false;
5291
+ }
5292
+ const key = {
5293
+ entityId: channelId,
5294
+ feedId: subChannelId,
5295
+ userId: getActiveUser()._id,
5296
+ };
5297
+ // If the marker param is not set, look in the cache
5298
+ const cachedMarker = (_b = pullFromCache([
5299
+ 'subChannelMarker',
5300
+ 'get',
5301
+ getResolver('subChannelMarker')(key),
5302
+ ])) === null || _b === void 0 ? void 0 : _b.data;
5303
+ if (cachedMarker) {
5304
+ return cachedMarker.hasMentioned;
5305
+ }
5306
+ // and if not found in cache use default value `false`
5307
+ return false;
5308
+ }
5309
+
5310
+ function getSubChannelUnreadCount(channelId, subChannelId, marker) {
5311
+ var _a, _b;
5312
+ // Look for `unreadCount` in the marker param first
5313
+ if (marker) {
5314
+ return marker.unreadCount;
5315
+ }
5316
+ const client = getActiveClient();
5317
+ // If consistent mode is enabled, look in the SubChannelUnreadCountInfo cache
5318
+ if (client.isUnreadCountEnabled && client.getMarkerSyncConsistentMode()) {
5319
+ const cachedUnreadCount = (_a = pullFromCache([
5320
+ 'subChannelUnreadInfo',
5321
+ 'get',
5322
+ subChannelId,
5323
+ ])) === null || _a === void 0 ? void 0 : _a.data;
5324
+ if (cachedUnreadCount) {
5325
+ return cachedUnreadCount.isDeleted ? 0 : cachedUnreadCount.unreadCount;
5326
+ }
5327
+ return 0;
5328
+ }
5329
+ const key = {
5330
+ entityId: channelId,
5331
+ feedId: subChannelId,
5332
+ userId: getActiveUser()._id,
5333
+ };
5334
+ // If the marker param is not set, look in the cache
5335
+ const cachedMarker = (_b = pullFromCache([
5336
+ 'subChannelMarker',
5337
+ 'get',
5338
+ getResolver('subChannelMarker')(key),
5339
+ ])) === null || _b === void 0 ? void 0 : _b.data;
5340
+ if (cachedMarker) {
5341
+ return cachedMarker.unreadCount;
5342
+ }
5343
+ // and if not found in cache use default value `0`
5344
+ return 0;
5345
+ }
5346
+
5347
+ const MARKER_INCLUDED_SUB_CHANNEL_TYPE$1 = ['broadcast', 'conversation', 'community'];
5348
+ const isUnreadCountSupport$2 = ({ channelType }) => MARKER_INCLUDED_SUB_CHANNEL_TYPE$1.includes(channelType);
5349
+ function convertFromRaw$2(_a) {
5350
+ var { channelId, channelPublicId, channelType, childCount, creatorId, creatorPublicId, lastMessageId, lastMessageTimestamp, messageFeedId, name } = _a, rest = __rest(_a, ["channelId", "channelPublicId", "channelType", "childCount", "creatorId", "creatorPublicId", "lastMessageId", "lastMessageTimestamp", "messageFeedId", "name"]);
5351
+ return Object.assign(Object.assign({ get unreadCount() {
5352
+ return getSubChannelUnreadCount(channelId, messageFeedId);
5353
+ },
5354
+ get hasMentioned() {
5355
+ return getSubChannelIsMentioned(channelId, messageFeedId);
5356
+ },
5357
+ get isMentioned() {
5358
+ return getSubChannelIsMentioned(channelId, messageFeedId);
5359
+ } }, rest), { channelId: channelPublicId, creatorId: creatorPublicId, displayName: name, lastActivity: lastMessageTimestamp, latestMessageId: lastMessageId, messageCount: childCount, subChannelId: messageFeedId, isUnreadCountSupport: isUnreadCountSupport$2({ channelType }) });
5360
+ }
5361
+
5362
+ const mergePayloadWithLocal = (payload) => {
5363
+ var _a, _b, _c;
5364
+ const localMessage = (_b = (_a = queryCache(['message', 'get'])) === null || _a === void 0 ? void 0 : _a.find(({ data }) => data.messageId === payload.messageId)) === null || _b === void 0 ? void 0 : _b.data;
5365
+ if (localMessage) {
5366
+ return Object.assign(Object.assign(Object.assign({}, localMessage), payload), {
5367
+ // NOTE: referenceId is missing in the some payload event. If we have local message data with referenceId, use it instead.
5368
+ referenceId: (_c = localMessage.referenceId) !== null && _c !== void 0 ? _c : payload.referenceId });
5369
+ }
5370
+ return payload;
5371
+ };
5372
+ function convertFromRaw$1(message, reactors, event) {
5373
+ var _a;
5374
+ const mergeMessage = mergePayloadWithLocal(message);
5375
+ const { channelPublicId, childCount, creatorPublicId, mentionedUsers, messageFeedId, myReactions, reactionCount, reactions, referenceId, segment, messageId, creatorId } = mergeMessage, rest = __rest(mergeMessage, ["channelPublicId", "childCount", "creatorPublicId", "mentionedUsers", "messageFeedId", "myReactions", "reactionCount", "reactions", "referenceId", "segment", "messageId", "creatorId"]);
5376
+ let cache;
5377
+ if (referenceId) {
5378
+ cache = pullFromCache(['message', 'get', referenceId]);
5379
+ }
5380
+ if (!cache) {
5381
+ cache = pullFromCache(['message', 'get', messageId]);
5382
+ }
5383
+ const out = Object.assign(Object.assign({}, rest), { messageId, channelId: channelPublicId, channelSegment: segment, childrenNumber: childCount, creatorId: creatorPublicId, creatorPrivateId: message.creatorId, reactions: reactions !== null && reactions !== void 0 ? reactions : {},
5384
+ /*
5385
+ * Previously, myReactions were added only if it was part of the payload.
5386
+ * So empty myReactions were not present. So I've edited the payload to add
5387
+ * a default for those cases.
5388
+ *
5389
+ * Check git blame for previous iteration
5390
+ */
5391
+ myReactions: myReactions || ((_a = cache === null || cache === void 0 ? void 0 : cache.data.myReactions) !== null && _a !== void 0 ? _a : []), reactionsCount: reactionCount, subChannelId: messageFeedId, uniqueId: cache ? cache.data.uniqueId : messageId, referenceId, syncState: "synced" /* Amity.SyncState.Synced */ });
5392
+ if (mentionedUsers) {
5393
+ out.mentionees = mentionedUsers.map(mention => {
5394
+ if (mention.type === 'channel') {
5395
+ return mention;
5396
+ }
5397
+ return { type: 'user', userIds: mention.userPublicIds };
5398
+ });
5399
+ }
5400
+ if (reactors && reactors.length && event) {
5401
+ // mqtt event
5402
+ prepareMessagePayloadForCache(out, reactors, event);
5403
+ }
5404
+ return out;
5405
+ }
5406
+ const preUpdateMessageCache = (rawPayload) => {
5407
+ ingestInCache({
5408
+ messages: rawPayload.messages.map(message => convertFromRaw$1(message, rawPayload.reactions)),
5409
+ });
5410
+ };
5411
+ const DEBOUNCE_TIME = 2000;
5412
+ const currentDebounceMap = {};
5413
+ const prepareMessagePayload = async (payload, event) => {
5414
+ const markerIds = payload.messages.map(({ messageId }) => messageId);
5415
+ if (markerIds.length > 0) {
5416
+ // since the get markers method requires a channel cache to function with the reducer.
5417
+ preUpdateMessageCache(payload);
5418
+ const markerIdsKey = markerIds.join('');
5419
+ if (currentDebounceMap[markerIdsKey]) {
5420
+ clearTimeout(currentDebounceMap[markerIdsKey]);
5421
+ }
5422
+ currentDebounceMap[markerIdsKey] = setTimeout(() => {
5423
+ try {
5424
+ getMessageMarkers(markerIds);
5425
+ }
5426
+ catch (_error) {
5427
+ // do nothing
5428
+ }
5429
+ }, DEBOUNCE_TIME);
5430
+ }
5431
+ const { messageFeeds } = payload, restPayload = __rest(payload, ["messageFeeds"]);
5432
+ // upsert messageFeeds to subchannel cache because messageFeeds from event payload not include messagePreviewId
5433
+ if (messageFeeds && messageFeeds.length > 0) {
5434
+ messageFeeds === null || messageFeeds === void 0 ? void 0 : messageFeeds.forEach(messageFeed => {
5435
+ var _a, _b;
5436
+ const subChannelCache = (_b = (_a = pullFromCache(['subChannel', 'get', messageFeed.messageFeedId])) === null || _a === void 0 ? void 0 : _a.data) !== null && _b !== void 0 ? _b : {};
5437
+ // exclude getter properties from existing subChannel cache, update only other properties to existing subChannel cache
5438
+ const _c = convertFromRaw$2(messageFeed), restSubChannel = __rest(_c, ["unreadCount", "isMentioned"]);
5439
+ updateSubChannelCache(messageFeed.messageFeedId, subChannelCache, restSubChannel);
5440
+ });
5441
+ }
5442
+ return Object.assign(Object.assign({}, restPayload), { messages: payload.messages.map(m => convertFromRaw$1(m, payload.reactions, event)) });
5443
+ };
5444
+ function convertParams(_a) {
5445
+ var { subChannelId, mentionees, dataType, data } = _a, rest = __rest(_a, ["subChannelId", "mentionees", "dataType", "data"]);
5446
+ if (dataType === MessageContentType.IMAGE || dataType === MessageContentType.FILE) {
5447
+ return Object.assign({ messageFeedId: subChannelId, mentionedUsers: mentionees, dataType, data: Object.assign({ caption: '' }, data) }, rest);
5448
+ }
5449
+ return Object.assign({ messageFeedId: subChannelId, mentionedUsers: mentionees, dataType, data }, rest);
5450
+ }
5451
+ function convertQueryParams$1(_a) {
5452
+ var { sortBy, subChannelId, includingTags, excludingTags, includeDeleted, aroundMessageId, limit, type } = _a, rest = __rest(_a, ["sortBy", "subChannelId", "includingTags", "excludingTags", "includeDeleted", "aroundMessageId", "limit", "type"]);
5453
+ const out = Object.assign(Object.assign({}, rest), { messageFeedId: subChannelId, isDeleted: inferIsDeleted(includeDeleted), options: {
5454
+ sortBy,
5455
+ limit: limit || COLLECTION_DEFAULT_PAGINATION_LIMIT,
5456
+ around: aroundMessageId,
5457
+ } });
5458
+ if (includingTags) {
5459
+ out.includeTags = includingTags;
5460
+ }
5461
+ if (type) {
5462
+ out.dataType = type;
5463
+ }
5464
+ if (excludingTags) {
5465
+ out.excludeTags = excludingTags;
5466
+ }
5467
+ return out;
5468
+ }
5469
+
5470
+ const MARKER_INCLUDED_SUB_CHANNEL_TYPE = ['broadcast', 'conversation', 'community'];
5471
+ /**
5472
+ * Filter sub channel by type. Only conversation, community and broadcast type are included.
5473
+ */
5474
+ const isUnreadCountSupport$1 = ({ channelType }) => MARKER_INCLUDED_SUB_CHANNEL_TYPE.includes(channelType);
5475
+ const preUpdateSubChannelCache = (rawPayload) => {
5476
+ ingestInCache({
5477
+ messageFeeds: rawPayload.messageFeeds.map(messageFeed => convertFromRaw$2(messageFeed)),
5478
+ });
5479
+ };
5480
+ const prepareSubChannelPayload = async (rawPayload) => {
5481
+ const markerIds = rawPayload.messageFeeds
5482
+ .filter(isUnreadCountSupport$1)
5483
+ .map(({ messageFeedId }) => messageFeedId);
5484
+ if (markerIds.length > 0) {
5485
+ // since the get markers method requires a channel cache to function with the reducer.
5486
+ preUpdateSubChannelCache(rawPayload);
5487
+ try {
5488
+ await getSubChannelMarkers(markerIds);
5489
+ }
5490
+ catch (e) {
5491
+ // empty block (from the spec, allow marker fetch to fail without having to do anything)
5492
+ }
5493
+ }
5494
+ updateSubChannelMessagePreviewCache(rawPayload);
5495
+ // attach marker to sub channel
5496
+ const messageFeeds = rawPayload.messageFeeds.map(convertFromRaw$2);
5497
+ const messages = rawPayload.messages.map(m => convertFromRaw$1(m));
5498
+ return Object.assign(Object.assign({}, rawPayload), { messageFeeds,
5499
+ messages });
5500
+ };
5501
+ function convertQueryParams(_a) {
5502
+ var { excludeDefaultSubChannel } = _a, rest = __rest(_a, ["excludeDefaultSubChannel"]);
5503
+ const out = Object.assign({}, rest);
5504
+ if (excludeDefaultSubChannel !== undefined) {
5505
+ out.excludeDefaultMessageFeed = excludeDefaultSubChannel;
5506
+ }
5507
+ return out;
5508
+ }
5509
+
5510
+ /**
5511
+ * ```js
5512
+ * import { getSubChannel } from '@amityco/ts-sdk'
5513
+ * const subChannel = await getSubChannel('foobar')
5514
+ * ```
5515
+ *
5516
+ * Fetches a {@link Amity.SubChannel} object
5517
+ *
5518
+ * @param subChannelId the ID of the {@link Amity.SubChannel} to fetch
5519
+ * @returns the associated {@link Amity.SubChannel} object
5520
+ *
5521
+ * @category Channel API
5522
+ * @async
5523
+ */
5524
+ const getSubChannel$1 = async (subChannelId) => {
5525
+ const client = getActiveClient();
5526
+ client.log('channel/getSubChannel', subChannelId);
5527
+ isInTombstone('subChannel', subChannelId);
5528
+ try {
5529
+ const response = await client.http.get(`/api/v5/message-feeds/${encodeURIComponent(subChannelId)}`);
5530
+ const data = await prepareSubChannelPayload(response.data);
5531
+ const cachedAt = client.cache && Date.now();
5532
+ if (client.cache)
5533
+ ingestInCache(data, { cachedAt });
5534
+ fireEvent('local.message-feed.fetched', data);
5535
+ return {
5536
+ data: data.messageFeeds[0],
5537
+ cachedAt,
5538
+ };
5539
+ }
5540
+ catch (error) {
5541
+ if (checkIfShouldGoesToTombstone(error === null || error === void 0 ? void 0 : error.code)) {
5542
+ pushToTombstone('subChannel', subChannelId);
5543
+ }
5544
+ throw error;
5545
+ }
5546
+ };
5547
+ /**
5548
+ * ```js
5549
+ * import { getSubChannel } from '@amityco/ts-sdk'
5550
+ * const subChannel = getSubChannel.locally('foobar')
5551
+ * ```
5552
+ *
5553
+ * Fetches a {@link Amity.SubChannel} object from cache
5554
+ *
5555
+ * @param subChannelId the ID of the {@link Amity.SubChannel} to fetch
5556
+ * @returns the associated {@link Amity.SubChannel} object
5557
+ *
5558
+ * @category Channel API
5559
+ */
5560
+ getSubChannel$1.locally = (subChannelId) => {
5561
+ const client = getActiveClient();
5562
+ client.log('channel/getSubChannel.locally', subChannelId);
5563
+ if (!client.cache)
5564
+ return;
5565
+ const cached = pullFromCache(['subChannel', 'get', subChannelId]);
5566
+ if (!cached)
5567
+ return;
5568
+ return {
5569
+ data: cached.data,
5570
+ cachedAt: cached.cachedAt,
5571
+ };
5572
+ };
5573
+
5574
+ const convertDateStringToTimestamp = (dateString) => {
5575
+ return new Date(dateString).getTime();
5576
+ };
5577
+
5578
+ const getMessagePreviewSetting$1 = async () => {
5579
+ const client = getActiveClient();
5580
+ return client.getMessagePreviewSetting(false);
5581
+ };
5582
+ const getSubChannelCache = async (subChannelId) => {
5583
+ var _a;
5584
+ let subChannelCache = (_a = pullFromCache(['subChannel', 'get', subChannelId])) === null || _a === void 0 ? void 0 : _a.data;
5585
+ if (!subChannelCache) {
5586
+ subChannelCache = (await getSubChannel$1(subChannelId)).data;
5587
+ }
5588
+ return subChannelCache;
5589
+ };
5590
+ const isLastestMessageOnSubchannel = (message) => {
5591
+ var _a;
5592
+ const cache = (_a = pullFromCache([
5593
+ 'messagePreviewSubChannel',
5594
+ 'get',
5595
+ message.subChannelId,
5596
+ ])) === null || _a === void 0 ? void 0 : _a.data;
5597
+ // The message payload from optimistic created event has no segment, so we check createdAt instead.
5598
+ return (!cache ||
5599
+ cache.segment <= message.channelSegment ||
5600
+ convertDateStringToTimestamp(cache.createdAt) <= convertDateStringToTimestamp(message.createdAt));
5601
+ };
5602
+ const isLastestMessageOnChannel = (message) => {
5603
+ var _a;
5604
+ const cache = (_a = pullFromCache([
5605
+ 'messagePreviewChannel',
5606
+ 'get',
5607
+ message.channelId,
5608
+ ])) === null || _a === void 0 ? void 0 : _a.data;
5609
+ return (!cache ||
5610
+ convertDateStringToTimestamp(cache.createdAt) <= convertDateStringToTimestamp(message.createdAt));
5611
+ };
5612
+ const handleMessageCreatedOnSubChannel = async (message) => {
5613
+ const messagePreviewSetting = await getMessagePreviewSetting$1();
5614
+ const { channelId, messageId: messagePreviewId, creatorId, createdAt, updatedAt, data, dataType, subChannelId, channelSegment: segment, isDeleted, } = message;
5615
+ // 1. get subChannel from cache, if not exist fetch from server
5616
+ const subChannelCache = await getSubChannelCache(subChannelId);
5617
+ // 2. if messagePreviewSetting is NO_MESSAGE_PREVEIW, update only lastActiviy in subChannel cache
5618
+ if (messagePreviewSetting === "no-message-preview" /* Amity.MessagePreviewSetting.NO_MESSAGE_PREVIEW */) {
5619
+ // 2.1 if the message is the latest message, update lastActivity to be createdAt in subChannel cache
5620
+ if (convertDateStringToTimestamp(subChannelCache.lastActivity) <
5621
+ convertDateStringToTimestamp(createdAt))
5622
+ updateSubChannelCache(message.subChannelId, subChannelCache, {
5623
+ lastActivity: createdAt,
5624
+ });
5625
+ return;
5626
+ }
5627
+ // 3. if messagePreviewSetting is `NOT` NO_MESSAGE_PREVEIW, update messagePreviewSubChannel and subChannel cache
5628
+ // 3.1 check if the message is the latest message, if not ignore the message.
5629
+ if (!isLastestMessageOnSubchannel(message))
5630
+ return;
5631
+ // 3.2 if the message is the latest message, update messagePreviewSubChannel and subChannel cache
5632
+ pushToCache(['messagePreviewSubChannel', 'get', message.subChannelId], {
5633
+ channelId,
5634
+ creatorId,
5635
+ messagePreviewId,
5636
+ createdAt,
5637
+ updatedAt,
5638
+ subChannelId,
5639
+ data,
5640
+ dataType,
5641
+ segment,
5642
+ isDeleted,
5643
+ subChannelUpdatedAt: subChannelCache === null || subChannelCache === void 0 ? void 0 : subChannelCache.updatedAt,
5644
+ subChannelName: subChannelCache === null || subChannelCache === void 0 ? void 0 : subChannelCache.displayName,
5645
+ });
5646
+ updateSubChannelCache(message.subChannelId, subChannelCache, {
5647
+ lastActivity: createdAt,
5648
+ messagePreviewId,
5649
+ });
5650
+ };
5651
+ const handleMessageUpdatedOnSubChannel = async (message) => {
5652
+ var _a;
5653
+ const { channelId, messageId: messagePreviewId, creatorId, createdAt, updatedAt, data, dataType, subChannelId, channelSegment: segment, isDeleted, } = message;
5654
+ const messagePreviewSubChannelCache = (_a = pullFromCache([
5655
+ 'messagePreviewSubChannel',
5656
+ 'get',
5657
+ message.subChannelId,
5658
+ ])) === null || _a === void 0 ? void 0 : _a.data;
5659
+ // if messagePreviewSubChannel is not exist, ignore the message.
5660
+ if (messagePreviewSubChannelCache &&
5661
+ messagePreviewSubChannelCache.messagePreviewId === message.messageId) {
5662
+ const subChannelCache = await getSubChannelCache(subChannelId);
5663
+ pushToCache(['messagePreviewSubChannel', 'get', message.subChannelId], {
5664
+ channelId,
5665
+ creatorId,
5666
+ messagePreviewId,
5667
+ createdAt,
5668
+ updatedAt,
5669
+ subChannelId,
5670
+ data,
5671
+ dataType,
5672
+ segment,
5673
+ isDeleted,
5674
+ subChannelUpdatedAt: subChannelCache.updatedAt,
5675
+ subChannelName: messagePreviewSubChannelCache.subChannelName,
5676
+ });
5677
+ }
5678
+ };
5679
+ const handleMessageCreated = async (message) => {
5680
+ const { channelId, messageId: messagePreviewId, creatorId, createdAt, updatedAt, data, dataType, subChannelId, channelSegment: segment, isDeleted, } = message;
5681
+ if (isLastestMessageOnChannel(message)) {
5682
+ const subChannelCache = await getSubChannelCache(subChannelId);
5683
+ pushToCache(['messagePreviewChannel', 'get', message.channelId], {
5684
+ channelId,
5685
+ creatorId,
5686
+ messagePreviewId,
5687
+ createdAt,
5688
+ updatedAt,
5689
+ subChannelId,
5690
+ data,
5691
+ dataType,
5692
+ segment,
5693
+ isDeleted,
5694
+ subChannelUpdatedAt: subChannelCache === null || subChannelCache === void 0 ? void 0 : subChannelCache.updatedAt,
5695
+ subChannelName: subChannelCache === null || subChannelCache === void 0 ? void 0 : subChannelCache.displayName,
5696
+ });
5697
+ }
5698
+ };
5699
+ const handleMessageUpdated = async (message) => {
5700
+ /**
5701
+ * Channel Case
5702
+ */
5703
+ var _a;
5704
+ const { channelId, messageId: messagePreviewId, creatorId, createdAt, updatedAt, data, dataType, subChannelId, channelSegment: segment, isDeleted, } = message;
5705
+ const messagePreviewChannelCache = (_a = pullFromCache([
5706
+ 'messagePreviewChannel',
5707
+ 'get',
5708
+ message.channelId,
5709
+ ])) === null || _a === void 0 ? void 0 : _a.data;
5710
+ if (messagePreviewChannelCache &&
5711
+ messagePreviewChannelCache.messagePreviewId === message.messageId) {
5712
+ const subChannelCache = await getSubChannelCache(subChannelId);
5713
+ pushToCache(['messagePreviewChannel', 'get', message.channelId], {
5714
+ channelId,
5715
+ creatorId,
5716
+ messagePreviewId,
5717
+ createdAt,
5718
+ updatedAt,
5719
+ subChannelId,
5720
+ data,
5721
+ dataType,
5722
+ segment,
5723
+ isDeleted,
5724
+ subChannelUpdatedAt: subChannelCache.updatedAt,
5725
+ subChannelName: messagePreviewChannelCache.subChannelName,
5726
+ });
5727
+ }
5728
+ };
5729
+ const handleSubChannelUpdated = async (subChannel) => {
5730
+ var _a, _b, _c, _d;
5731
+ const { channelId, subChannelId } = subChannel;
5732
+ /** Channel Case */
5733
+ const messagePreviewChannelCache = (_a = pullFromCache([
5734
+ 'messagePreviewChannel',
5735
+ 'get',
5736
+ channelId,
5737
+ ])) === null || _a === void 0 ? void 0 : _a.data;
5738
+ if ((messagePreviewChannelCache === null || messagePreviewChannelCache === void 0 ? void 0 : messagePreviewChannelCache.subChannelId) === subChannelId) {
5739
+ const subChannelCache = (_b = pullFromCache([
5740
+ 'subChannel',
5741
+ 'get',
5742
+ subChannelId,
5743
+ ])) === null || _b === void 0 ? void 0 : _b.data;
5744
+ pushToCache(['messagePreviewChannel', 'get', channelId], Object.assign(Object.assign({}, messagePreviewChannelCache), { subChannelName: subChannelCache === null || subChannelCache === void 0 ? void 0 : subChannelCache.displayName, subChannelUpdatedAt: subChannelCache === null || subChannelCache === void 0 ? void 0 : subChannelCache.updatedAt }));
5745
+ }
5746
+ /** SubChannel Case */
5747
+ const messagePreviewSubChannelCache = (_c = pullFromCache([
5748
+ 'messagePreviewSubChannel',
5749
+ 'get',
5750
+ subChannelId,
5751
+ ])) === null || _c === void 0 ? void 0 : _c.data;
5752
+ if (messagePreviewSubChannelCache &&
5753
+ new Date(messagePreviewSubChannelCache.updatedAt).valueOf() >
5754
+ new Date(subChannel.updatedAt).valueOf()) {
5755
+ const subChannelCache = (_d = pullFromCache([
5756
+ 'subChannel',
5757
+ 'get',
5758
+ subChannelId,
5759
+ ])) === null || _d === void 0 ? void 0 : _d.data;
5760
+ pushToCache(['messagePreviewSubChannel', 'get', subChannelId], Object.assign(Object.assign({}, messagePreviewSubChannelCache), { subChannelName: subChannelCache === null || subChannelCache === void 0 ? void 0 : subChannelCache.displayName, subChannelUpdatedAt: subChannelCache === null || subChannelCache === void 0 ? void 0 : subChannelCache.updatedAt }));
5761
+ }
5762
+ };
5763
+
5764
+ function convertRawUserToInternalUser(rawUser) {
5765
+ return Object.assign(Object.assign({}, rawUser), { isGlobalBanned: (rawUser === null || rawUser === void 0 ? void 0 : rawUser.isGlobalBan) || false });
5766
+ }
5767
+
5768
+ const MARKER_INCLUDED_CHANNEL_TYPE = ['broadcast', 'conversation', 'community'];
5769
+ const isUnreadCountSupport = ({ type }) => MARKER_INCLUDED_CHANNEL_TYPE.includes(type);
5770
+ function convertFromRaw(channel, options = { isMessagePreviewUpdated: true }) {
5771
+ var _a;
5772
+ let { messagePreviewId } = channel;
5773
+ const messagePreviewChannelCache = (_a = pullFromCache([
5774
+ 'messagePreviewChannel',
5775
+ 'get',
5776
+ channel.channelId,
5777
+ ])) === null || _a === void 0 ? void 0 : _a.data;
5778
+ if ((messagePreviewChannelCache === null || messagePreviewChannelCache === void 0 ? void 0 : messagePreviewChannelCache.messagePreviewId) && !options.isMessagePreviewUpdated) {
5779
+ messagePreviewId = messagePreviewChannelCache.messagePreviewId;
5780
+ }
5781
+ return Object.assign(Object.assign({}, channel), { defaultSubChannelId: channel.channelInternalId, isUnreadCountSupport: isUnreadCountSupport(channel), messagePreviewId });
5782
+ }
5783
+ const preUpdateChannelCache = (rawPayload, options = { isMessagePreviewUpdated: true }) => {
5784
+ ingestInCache({
5785
+ channels: rawPayload.channels.map(channel => convertFromRaw(channel, { isMessagePreviewUpdated: options.isMessagePreviewUpdated })),
5786
+ });
5787
+ };
5788
+ const updateChannelUnread = ({ currentUserId, channels, channelUsers, }) => {
5789
+ for (let i = 0; i < channels.length; i += 1) {
5790
+ const cacheKey = ['channelUnread', 'get', channels[i].channelId];
5791
+ const channelUser = channelUsers.find(channelUser => channelUser.channelId === channels[i].channelId && channelUser.userId === currentUserId);
5792
+ let unreadCount = 0;
5793
+ let readToSegment = null;
5794
+ let lastMentionedSegment = null;
5795
+ let isMentioned = false;
5796
+ if (channelUser) {
5797
+ readToSegment = channelUser.readToSegment;
5798
+ lastMentionedSegment = channelUser.lastMentionedSegment;
5799
+ unreadCount = Math.max(channels[i].messageCount - readToSegment, 0);
5800
+ isMentioned = lastMentionedSegment > readToSegment;
5801
+ }
5802
+ const cacheChannelUnread = {
5803
+ channelId: channels[i].channelId,
5804
+ lastSegment: channels[i].messageCount,
5805
+ readToSegment,
5806
+ lastMentionedSegment,
5807
+ unreadCount,
5808
+ isMentioned,
5809
+ isDeleted: channels[i].isDeleted || false,
5810
+ };
5811
+ pushToCache(cacheKey, cacheChannelUnread);
5812
+ }
5813
+ };
5814
+ const prepareChannelPayload = async (rawPayload, options = { isMessagePreviewUpdated: true }) => {
5815
+ const client = getActiveClient();
5816
+ const networkPreviewSetting = await client.getMessagePreviewSetting(false);
5817
+ if (options.isMessagePreviewUpdated &&
5818
+ networkPreviewSetting !== "no-message-preview" /* Amity.MessagePreviewSetting.NO_MESSAGE_PREVIEW */ &&
5819
+ rawPayload.messagePreviews &&
5820
+ rawPayload.messagePreviews.length > 0) {
5821
+ updateChannelMessagePreviewCache(rawPayload);
5822
+ }
5823
+ if (client.useLegacyUnreadCount) {
5824
+ updateChannelUnread({
5825
+ channels: rawPayload.channels,
5826
+ channelUsers: rawPayload.channelUsers,
5827
+ currentUserId: client.userId,
5828
+ });
5829
+ }
5830
+ else {
5831
+ const markerIds = rawPayload.channels
5832
+ // filter channel by type. Only conversation, community and broadcast type are included.
5833
+ .filter(isUnreadCountSupport)
5834
+ .map(({ channelInternalId }) => channelInternalId);
5835
+ if (markerIds.length > 0) {
5836
+ // since the get markers method requires a channel cache to function with the reducer.
5837
+ preUpdateChannelCache(rawPayload, {
5838
+ isMessagePreviewUpdated: options.isMessagePreviewUpdated,
5839
+ });
5840
+ try {
5841
+ await getChannelMarkers(markerIds);
5842
+ }
5843
+ catch (e) {
5844
+ // empty block (from the spec, allow marker fetch to fail without having to do anything)
5845
+ }
5846
+ }
5847
+ }
5848
+ // convert raw channel to internal channel
5849
+ const channels = rawPayload.channels.map(payload => convertFromRaw(payload, { isMessagePreviewUpdated: options.isMessagePreviewUpdated }));
5850
+ // convert raw channel user to membership (add user object)
5851
+ const channelUsers = rawPayload.channelUsers.map(channelUser => {
5852
+ return convertRawMembershipToMembership(channelUser);
5853
+ });
5854
+ const users = rawPayload.users.map(convertRawUserToInternalUser);
5855
+ const restRawPayload = __rest(rawPayload, ["messageFeedsInfo", "messagePreviews"]);
5856
+ return Object.assign(Object.assign({}, restRawPayload), { users,
5857
+ channels,
5858
+ channelUsers });
5859
+ };
5860
+
5861
+ /**
5862
+ * ```js
5863
+ * import { getSubChannelMarkers } from '@amityco/ts-sdk'
5864
+ * const subChannelMarkers = await getSubChannelMarkers(['sch1', 'sch2'])
5865
+ * ```
5866
+ *
5867
+ * Fetches a paginable list of {@link Amity.SubChannelMarker} objects
5868
+ *
5869
+ * @param messageFeedIds the feed IDs of the {@link Amity.RawSubChannel} marker to fetch
5870
+ * @param page
5871
+ * @returns A page of {@link Amity.SubChannelMarker} objects
5872
+ *
5873
+ * @category Channel API
5874
+ * @async
5875
+ * @private
5876
+ */
5877
+ const getUserMessageFeedMakers = async (channelIds) => {
5878
+ const client = getActiveClient();
5879
+ client.log('channel/getUserMessageFeedMakers', channelIds);
5880
+ const { data } = await client.http.get(`/api/v1/markers/user-message-feed`, {
5881
+ params: {
5882
+ channelIds,
5883
+ },
5884
+ });
5885
+ fireEvent('local.userMessageFeedMarker.fetched', { userMessageFeedMarker: data });
5886
+ return data;
5887
+ };
5888
+
5889
+ const prepareUnreadCountInfo = async (rawPayload) => {
5890
+ const client = getActiveClient();
5891
+ // if consistent mode is enabled, persist the unread count info to the cache
5892
+ // Marker service API uses channelInternalId as channelId
5893
+ const queryPayload = await getUserMessageFeedMakers(rawPayload.channels.map(({ channelInternalId }) => channelInternalId));
5894
+ const { feedMarkers, userFeedMarkers } = queryPayload;
5895
+ persistUnreadCountInfo({
5896
+ feedMarkers,
5897
+ userFeedMarkers,
5898
+ });
5899
+ client.log('channel/prepareUnreadCountInfo', rawPayload.channels);
5900
+ };
5901
+
5902
+ const getCachedMarker$2 = (entityId) => {
5903
+ var _a;
5904
+ const key = {
5905
+ entityId,
5906
+ userId: getActiveUser()._id,
5907
+ };
5908
+ return (_a = pullFromCache([
5909
+ 'channelMarker',
5910
+ 'get',
5911
+ getResolver('channelMarker')(key),
5912
+ ])) === null || _a === void 0 ? void 0 : _a.data;
5913
+ };
5914
+ const getUnreadInfoCached$1 = (channelId) => {
5915
+ var _a;
5916
+ return (_a = pullFromCache(['channelUnreadInfo', 'get', channelId])) === null || _a === void 0 ? void 0 : _a.data;
5917
+ };
5918
+ /**
5919
+ * The function use to get value of hasMentioned or isMentioned field.
5920
+ * function will get the value from marker params first, if there is no hasMentioned field, will look in to the cache.
5921
+ *
5922
+ * If consistent mode is enabled, the function will return the value from the channelUnreadCountInfo cache.
5923
+ * If not, the function will return the value from the channelMarker cache.
5924
+ * If not found in the both cache, use `false` as defaul value.
5925
+ */
5926
+ const getChannelIsMentioned = (channel, marker) => {
5927
+ var _a, _b, _c, _d;
5928
+ const client = getActiveClient();
5929
+ if (client.isUnreadCountEnabled && client.getMarkerSyncConsistentMode()) {
5930
+ return (_b = (_a = getUnreadInfoCached$1(channel.channelPublicId)) === null || _a === void 0 ? void 0 : _a.isMentioned) !== null && _b !== void 0 ? _b : false;
5931
+ }
5932
+ return (marker === null || marker === void 0 ? void 0 : marker.hasMentioned) !== undefined
5933
+ ? marker === null || marker === void 0 ? void 0 : marker.hasMentioned
5934
+ : (_d = (_c = getCachedMarker$2(channel.channelPublicId)) === null || _c === void 0 ? void 0 : _c.hasMentioned) !== null && _d !== void 0 ? _d : false;
5935
+ };
5936
+
5937
+ const getCachedMarker$1 = (entityId) => {
5938
+ var _a;
5939
+ const key = {
5940
+ entityId,
5941
+ userId: getActiveUser()._id,
5942
+ };
5943
+ return (_a = pullFromCache([
5944
+ 'channelMarker',
5945
+ 'get',
5946
+ getResolver('channelMarker')(key),
5947
+ ])) === null || _a === void 0 ? void 0 : _a.data;
5948
+ };
5949
+ const getUnreadInfoCached = (channelId) => {
5950
+ var _a;
5951
+ return (_a = pullFromCache(['channelUnreadInfo', 'get', channelId])) === null || _a === void 0 ? void 0 : _a.data;
5952
+ };
5953
+ /**
5954
+ * The function use to get value of unreadCount field.
5955
+ * function will get the value from marker params first, if there is no hasMentioned field, will look in to the cache.
5956
+ *
5957
+ * If consistent mode is enabled, the function will return the value from the channelUnreadCountInfo cache.
5958
+ * If not, the function will return the value from the channelMarker cache.
5959
+ * If not found in the both cache, use `0` as defaul value.
5960
+ */
5961
+ const getSubChannelsUnreadCount = (channel, marker) => {
5962
+ var _a, _b, _c, _d, _e;
5963
+ const client = getActiveClient();
5964
+ if (client.isUnreadCountEnabled && client.getMarkerSyncConsistentMode()) {
5965
+ // Marker service API uses channelInternalId as channelId
5966
+ return (_b = (_a = getUnreadInfoCached(channel.channelInternalId)) === null || _a === void 0 ? void 0 : _a.unreadCount) !== null && _b !== void 0 ? _b : 0;
5967
+ }
5968
+ if (marker === null || marker === void 0 ? void 0 : marker.isDeleted) {
5969
+ // NOTE: This is a temporary solution to handle the channel marker when the user is forced to
5970
+ // leave the channel because currently backend can't handle this, so every time a user is banned
5971
+ // from a channel or the channel is deleted the channel's unread count will reset to zero
5972
+ return 0;
5973
+ }
5974
+ return (_e = (_c = marker === null || marker === void 0 ? void 0 : marker.unreadCount) !== null && _c !== void 0 ? _c : (_d = getCachedMarker$1(channel.channelInternalId)) === null || _d === void 0 ? void 0 : _d.unreadCount) !== null && _e !== void 0 ? _e : 0;
5975
+ };
5976
+
5977
+ const getLegacyChannelUnread = (channelId) => {
5978
+ var _a;
5979
+ return (_a = pullFromCache(['channelUnread', 'get', channelId])) === null || _a === void 0 ? void 0 : _a.data;
5980
+ };
5981
+
5982
+ const constructChannelDynamicValue = (channel) => {
5983
+ const client = getActiveClient();
5984
+ const rest = __rest(channel, ["messageCount"]);
5985
+ return shallowClone(rest, {
5986
+ get unreadCount() {
5987
+ var _a, _b;
5988
+ return (_b = (_a = getLegacyChannelUnread(rest.channelId)) === null || _a === void 0 ? void 0 : _a.unreadCount) !== null && _b !== void 0 ? _b : 0;
5989
+ },
5990
+ get subChannelsUnreadCount() {
5991
+ return getSubChannelsUnreadCount(rest);
5992
+ },
5993
+ get isMentioned() {
5994
+ var _a, _b;
5995
+ if (client.useLegacyUnreadCount)
5996
+ return (_b = (_a = getLegacyChannelUnread(rest.channelId)) === null || _a === void 0 ? void 0 : _a.isMentioned) !== null && _b !== void 0 ? _b : false;
5997
+ return getChannelIsMentioned(rest);
5998
+ },
5999
+ });
6000
+ };
6001
+
4901
6002
  const ANALYTIC_CACHE_KEY = ['analytic', 'normal-priority'];
4902
6003
  const HIGH_PRIORITY_ANALYTIC_CACHE_KEY = ['analytic', 'high-priority'];
4903
6004
 
@@ -5197,20 +6298,6 @@ var AnalyticsEngine$1 = {
5197
6298
  },
5198
6299
  };
5199
6300
 
5200
- const userLinkedObject = (user) => {
5201
- return Object.assign(Object.assign({}, user), { get avatar() {
5202
- var _a;
5203
- if (!user.avatarFileId)
5204
- return undefined;
5205
- const avatar = (_a = pullFromCache([
5206
- 'file',
5207
- 'get',
5208
- `${user.avatarFileId}`,
5209
- ])) === null || _a === void 0 ? void 0 : _a.data;
5210
- return avatar;
5211
- } });
5212
- };
5213
-
5214
6301
  class StoryComputedValue {
5215
6302
  constructor(targetId, lastStoryExpiresAt, lastStorySeenExpiresAt) {
5216
6303
  this._syncingStoriesCount = 0;
@@ -5642,7 +6729,7 @@ const postLinkedObject = (post) => {
5642
6729
  } });
5643
6730
  };
5644
6731
 
5645
- const getCachedMarker$2 = (message) => {
6732
+ const getCachedMarker = (message) => {
5646
6733
  var _a, _b;
5647
6734
  const key = {
5648
6735
  creatorId: 'creatorPrivateId' in message ? message.creatorPrivateId : message.creatorId,
@@ -5660,7 +6747,7 @@ const getMessageReadCount = (message, marker) => {
5660
6747
  // Look in the marker param first
5661
6748
  return (_a = marker !== null && marker !== void 0 ? marker :
5662
6749
  // If the marker param is not set, look in the cache
5663
- getCachedMarker$2(message)) !== null && _a !== void 0 ? _a : { readCount: 0, deliveredCount: 0 };
6750
+ getCachedMarker(message)) !== null && _a !== void 0 ? _a : { readCount: 0, deliveredCount: 0 };
5664
6751
  }; // and if not found in cache use default value `0`
5665
6752
 
5666
6753
  /**
@@ -5903,31 +6990,6 @@ const markAsReadBySegment = async ({ subChannelId, readToSegment, }) => {
5903
6990
  }
5904
6991
  };
5905
6992
 
5906
- const reCalculateChannelUnreadInfo = (channelId) => {
5907
- var _a;
5908
- const cacheKeyChannelUnread = ['channelUnreadInfo', 'get', channelId];
5909
- const cacheChannelUnreadInfo = (_a = pullFromCache(cacheKeyChannelUnread)) === null || _a === void 0 ? void 0 : _a.data;
5910
- const cacheKeySubChannelUnread = ['subChannelUnreadInfo', 'get'];
5911
- const cachedSubChannelUnreadInfo = queryCache(cacheKeySubChannelUnread);
5912
- let channelUnreads = 0;
5913
- let isMentioned = false;
5914
- if (cachedSubChannelUnreadInfo && (cachedSubChannelUnreadInfo === null || cachedSubChannelUnreadInfo === void 0 ? void 0 : cachedSubChannelUnreadInfo.length) > 0) {
5915
- const subChannelUnreadsInfo = cachedSubChannelUnreadInfo === null || cachedSubChannelUnreadInfo === void 0 ? void 0 : cachedSubChannelUnreadInfo.filter(({ data }) => {
5916
- return data.channelId === channelId && !data.isDeleted;
5917
- });
5918
- channelUnreads = subChannelUnreadsInfo
5919
- .map(({ data }) => data.unreadCount)
5920
- .reduce((acc, cur) => acc + cur, 0);
5921
- isMentioned = subChannelUnreadsInfo.some(({ data }) => data.isMentioned);
5922
- }
5923
- const channelUnreadInfo = Object.assign(Object.assign({}, (cacheChannelUnreadInfo !== null && cacheChannelUnreadInfo !== void 0 ? cacheChannelUnreadInfo : {
5924
- channelId,
5925
- createdAt: new Date().toISOString(),
5926
- })), { updatedAt: new Date().toISOString(), unreadCount: channelUnreads, isMentioned });
5927
- pushToCache(cacheKeyChannelUnread, channelUnreadInfo);
5928
- return channelUnreadInfo;
5929
- };
5930
-
5931
6993
  class LegacyMessageReadReceiptSyncEngine {
5932
6994
  constructor() {
5933
6995
  this.isActive = true;
@@ -6213,24 +7275,6 @@ const markAsRead = async (channelId) => {
6213
7275
  return true;
6214
7276
  };
6215
7277
 
6216
- /**
6217
- * ```js
6218
- * import { shallowClone } from '~/utils/shallowClone'
6219
- * const newObj = shallowClone(obj)
6220
- * ```
6221
- *
6222
- * Clone an object with same prototype and properties
6223
- *
6224
- * @param obj the object to clone
6225
- * @returns new object with same prototype and properties
6226
- *
6227
- * @category utility
6228
- * @private
6229
- */
6230
- function shallowClone(source, target) {
6231
- return Object.create(Object.getPrototypeOf(source), Object.assign(Object.assign({}, Object.getOwnPropertyDescriptors(source)), Object.getOwnPropertyDescriptors(target)));
6232
- }
6233
-
6234
7278
  const channelLinkedObject = (channel) => {
6235
7279
  return shallowClone(channel, {
6236
7280
  markAsRead: () => markAsRead(channel.channelInternalId),
@@ -6310,6 +7354,14 @@ const notificationTrayLinkedObject = (noti) => {
6310
7354
  .map(user => userLinkedObject(user)) });
6311
7355
  };
6312
7356
 
7357
+ const convertRawInvitationToInternalInvitation = (rawInvitation) => {
7358
+ return Object.assign(Object.assign({}, rawInvitation), { createdById: rawInvitation.createdBy });
7359
+ };
7360
+
7361
+ const prepareInvitationPayload = (rawPayload) => {
7362
+ return Object.assign(Object.assign({}, rawPayload), { invitations: rawPayload.invitations.map(convertRawInvitationToInternalInvitation), users: rawPayload.users.map(convertRawUserToInternalUser) });
7363
+ };
7364
+
6313
7365
  /* begin_public_function
6314
7366
  id: invitation.createInvitations
6315
7367
  */
@@ -6335,11 +7387,12 @@ const notificationTrayLinkedObject = (noti) => {
6335
7387
  const createInvitations = async (bundle) => {
6336
7388
  const client = getActiveClient();
6337
7389
  client.log('invitation/createInvitations', bundle);
6338
- const { data } = await client.http.post('/api/v1/invitations', bundle);
7390
+ const { data: payload } = await client.http.post('/api/v1/invitations', bundle);
7391
+ const data = prepareInvitationPayload(payload);
6339
7392
  const cachedAt = client.cache && Date.now();
6340
7393
  if (client.cache)
6341
7394
  ingestInCache(data, { cachedAt });
6342
- fireEvent('local.invitation.created', data);
7395
+ fireEvent('local.invitation.created', data.invitations);
6343
7396
  return {
6344
7397
  data: data.invitations,
6345
7398
  cachedAt,
@@ -6367,1167 +7420,652 @@ const createInvitations = async (bundle) => {
6367
7420
  const acceptInvitation = async (invitationId) => {
6368
7421
  var _a;
6369
7422
  const client = getActiveClient();
6370
- client.log('invitation/acceptInvitation', invitationId);
6371
- const { data } = await client.http.post(`/api/v1/invitations/${invitationId}/accept`);
6372
- const invitation = (_a = pullFromCache([
6373
- 'invitation',
6374
- 'get',
6375
- invitationId,
6376
- ])) === null || _a === void 0 ? void 0 : _a.data;
6377
- if (invitation) {
6378
- upsertInCache(['invitation', 'get', invitationId], { status: "approved" /* InvitationStatusEnum.Approved */ });
6379
- fireEvent('local.invitation.updated', { invitations: [invitation] });
6380
- }
6381
- return data.success;
6382
- };
6383
- /* end_public_function */
6384
-
6385
- /* begin_public_function
6386
- id: invitation.reject
6387
- */
6388
- /**
6389
- * ```js
6390
- * import { rejectInvitation } from '@amityco/ts-sdk'
6391
- * const isRejected = await rejectInvitation(invitationId)
6392
- * ```
6393
- *
6394
- * Rejects a {@link Amity.Invitation} object
6395
- *
6396
- * @param invitationId the {@link Amity.Invitation} to reject
6397
- * @returns A success boolean if the {@link Amity.Invitation} was rejected
6398
- *
6399
- * @category Invitation API
6400
- * @async
6401
- */
6402
- const rejectInvitation = async (invitationId) => {
6403
- var _a;
6404
- const client = getActiveClient();
6405
- client.log('invitation/rejectInvitation', invitationId);
6406
- const { data } = await client.http.post(`/api/v1/invitations/${invitationId}/reject`);
7423
+ client.log('invitation/acceptInvitation', invitationId);
7424
+ const { data } = await client.http.post(`/api/v1/invitations/${invitationId}/accept`);
6407
7425
  const invitation = (_a = pullFromCache([
6408
7426
  'invitation',
6409
7427
  'get',
6410
7428
  invitationId,
6411
7429
  ])) === null || _a === void 0 ? void 0 : _a.data;
6412
7430
  if (invitation) {
6413
- upsertInCache(['invitation', 'get', invitationId], { status: "rejected" /* InvitationStatusEnum.Rejected */ });
6414
- fireEvent('local.invitation.updated', { invitations: [invitation] });
7431
+ upsertInCache(['invitation', 'get', invitationId], { status: "approved" /* InvitationStatusEnum.Approved */ });
7432
+ fireEvent('local.invitation.updated', [invitation]);
6415
7433
  }
6416
7434
  return data.success;
6417
7435
  };
6418
7436
  /* end_public_function */
6419
7437
 
6420
7438
  /* begin_public_function
6421
- id: invitation.cancel
7439
+ id: invitation.reject
6422
7440
  */
6423
7441
  /**
6424
7442
  * ```js
6425
- * import { cancelInvitation } from '@amityco/ts-sdk'
6426
- * const isCanceled = await cancelInvitation(invitationId)
7443
+ * import { rejectInvitation } from '@amityco/ts-sdk'
7444
+ * const isRejected = await rejectInvitation(invitationId)
6427
7445
  * ```
6428
7446
  *
6429
- * Cancels a {@link Amity.Invitation} object
7447
+ * Rejects a {@link Amity.Invitation} object
6430
7448
  *
6431
- * @param invitationId the {@link Amity.Invitation} to cancel
6432
- * @returns A success boolean if the {@link Amity.Invitation} was canceled
7449
+ * @param invitationId the {@link Amity.Invitation} to reject
7450
+ * @returns A success boolean if the {@link Amity.Invitation} was rejected
6433
7451
  *
6434
7452
  * @category Invitation API
6435
7453
  * @async
6436
7454
  */
6437
- const cancelInvitation = async (invitationId) => {
7455
+ const rejectInvitation = async (invitationId) => {
6438
7456
  var _a;
6439
7457
  const client = getActiveClient();
6440
- client.log('invitation/cancelInvitation', invitationId);
6441
- const { data } = await client.http.delete(`/api/v1/invitations/${invitationId}`);
7458
+ client.log('invitation/rejectInvitation', invitationId);
7459
+ const { data } = await client.http.post(`/api/v1/invitations/${invitationId}/reject`);
6442
7460
  const invitation = (_a = pullFromCache([
6443
7461
  'invitation',
6444
7462
  'get',
6445
7463
  invitationId,
6446
7464
  ])) === null || _a === void 0 ? void 0 : _a.data;
6447
7465
  if (invitation) {
6448
- dropFromCache(['invitation', 'get', invitationId]);
6449
- fireEvent('local.invitation.deleted', { invitations: [invitation] });
7466
+ upsertInCache(['invitation', 'get', invitationId], { status: "rejected" /* InvitationStatusEnum.Rejected */ });
7467
+ fireEvent('local.invitation.updated', [invitation]);
6450
7468
  }
6451
7469
  return data.success;
6452
7470
  };
6453
7471
  /* end_public_function */
6454
7472
 
6455
- const communityLinkedObject = (community) => {
6456
- return Object.assign(Object.assign({}, community), { createInvitations: async (userIds) => {
6457
- await createInvitations({
6458
- type: "communityMemberInvite" /* InvitationTypeEnum.CommunityMemberInvite */,
6459
- targetType: 'community',
6460
- targetId: community.communityId,
6461
- userIds,
6462
- });
6463
- } });
6464
- };
6465
-
6466
- const invitationLinkedObject = (invitation) => {
6467
- return Object.assign(Object.assign({}, invitation), { accept: async () => {
6468
- await acceptInvitation(invitation._id);
6469
- }, reject: async () => {
6470
- await rejectInvitation(invitation._id);
6471
- }, cancel: async () => {
6472
- await cancelInvitation(invitation._id);
6473
- } });
6474
- };
6475
-
6476
- const LinkedObject = {
6477
- ad: adLinkedObject,
6478
- comment: commentLinkedObject,
6479
- post: postLinkedObject,
6480
- user: userLinkedObject,
6481
- category: categoryLinkedObject,
6482
- stream: streamLinkedObject,
6483
- story: storyLinkedObject,
6484
- storyTarget: storyTargetLinkedObject,
6485
- message: messageLinkedObject,
6486
- reactor: reactorLinkedObject,
6487
- channel: channelLinkedObject,
6488
- pinnedPost: pinnedPostLinkedObject,
6489
- notificationTray: notificationTrayLinkedObject,
6490
- community: communityLinkedObject,
6491
- invitation: invitationLinkedObject,
6492
- };
6493
-
6494
- const getChannelMessagePreviewWithUser = (channel) => {
6495
- var _a;
6496
- const messagePreview = channel.messagePreviewId
6497
- ? getChannelMessagePreview(channel.channelId)
6498
- : null;
6499
- const internalUser = (_a = pullFromCache([
6500
- 'user',
6501
- 'get',
6502
- messagePreview === null || messagePreview === void 0 ? void 0 : messagePreview.creatorId,
6503
- ])) === null || _a === void 0 ? void 0 : _a.data;
6504
- const messagePreviewWithUser = messagePreview
6505
- ? Object.assign(Object.assign({}, messagePreview), { user: internalUser ? LinkedObject.user(internalUser) : undefined }) : null;
6506
- return Object.assign(Object.assign({}, channel), { messagePreview: messagePreviewWithUser });
6507
- };
6508
-
6509
- const updateChannelMessagePreviewCache = (rawPayload) => {
6510
- var _a, _b;
6511
- const withMessageFeedInfo = (messagePreview) => {
6512
- var _a;
6513
- const messageFeedInfo = (_a = rawPayload.messageFeedsInfo) === null || _a === void 0 ? void 0 : _a.find(messageFeed => {
6514
- return messageFeed.messageFeedId === messagePreview.messageFeedId;
6515
- });
6516
- const { channelPublicId: channelId, messageFeedId: subChannelId, data, dataType, isDeleted, segment, creatorPublicId: creatorId, createdAt, updatedAt, } = messagePreview;
6517
- return {
6518
- channelId,
6519
- subChannelId,
6520
- data,
6521
- dataType,
6522
- isDeleted,
6523
- segment,
6524
- creatorId,
6525
- createdAt,
6526
- updatedAt,
6527
- subChannelName: messageFeedInfo === null || messageFeedInfo === void 0 ? void 0 : messageFeedInfo.name,
6528
- messagePreviewId: messageFeedInfo === null || messageFeedInfo === void 0 ? void 0 : messageFeedInfo.messagePreviewId,
6529
- subChannelUpdatedAt: messageFeedInfo === null || messageFeedInfo === void 0 ? void 0 : messageFeedInfo.updatedAt,
6530
- };
6531
- };
6532
- const newData = {
6533
- messagePreviewChannel: (_b = (_a = rawPayload.messagePreviews) === null || _a === void 0 ? void 0 : _a.map(messagePreview => withMessageFeedInfo(messagePreview))) !== null && _b !== void 0 ? _b : [],
6534
- };
6535
- ingestInCache(newData);
6536
- };
6537
-
6538
- const getSubChannelMessagePreview = (subChannelId) => {
6539
- var _a, _b;
6540
- return ((_b = (_a = pullFromCache(['messagePreviewSubChannel', 'get', subChannelId])) === null || _a === void 0 ? void 0 : _a.data) !== null && _b !== void 0 ? _b : null);
6541
- };
6542
-
6543
- const getSubChannelMessagePreviewWithUser = (subChannel) => {
6544
- var _a;
6545
- const messagePreview = subChannel.messagePreviewId
6546
- ? getSubChannelMessagePreview(subChannel.subChannelId)
6547
- : null;
6548
- const messagePreviewWithUser = messagePreview
6549
- ? Object.assign(Object.assign({}, messagePreview), { user: (_a = pullFromCache(['user', 'get', messagePreview === null || messagePreview === void 0 ? void 0 : messagePreview.creatorId])) === null || _a === void 0 ? void 0 : _a.data }) : null;
6550
- return Object.assign(Object.assign({}, subChannel), { messagePreview: messagePreviewWithUser });
6551
- };
6552
-
6553
- const updateSubChannelMessagePreviewCache = (rawPayload) => {
6554
- var _a, _b;
6555
- const withMessageFeedInfo = (messagePreview) => {
6556
- var _a;
6557
- const messageFeedInfo = (_a = rawPayload.messageFeeds) === null || _a === void 0 ? void 0 : _a.find(messageFeed => {
6558
- return messageFeed.messageFeedId === messagePreview.messageFeedId;
6559
- });
6560
- const { channelPublicId: channelId, messageFeedId: subChannelId, messageId: messagePreviewId, creatorPublicId: creatorId, data, dataType, isDeleted, segment, createdAt, updatedAt, } = messagePreview;
6561
- return {
6562
- messagePreviewId,
6563
- channelId,
6564
- subChannelId,
6565
- data,
6566
- dataType,
6567
- isDeleted,
6568
- segment,
6569
- creatorId,
6570
- createdAt,
6571
- updatedAt,
6572
- subChannelName: messageFeedInfo === null || messageFeedInfo === void 0 ? void 0 : messageFeedInfo.name,
6573
- subChannelUpdatedAt: messageFeedInfo === null || messageFeedInfo === void 0 ? void 0 : messageFeedInfo.updatedAt,
6574
- };
6575
- };
6576
- const newData = {
6577
- messagePreviewSubChannel: (_b = (_a = rawPayload.messages) === null || _a === void 0 ? void 0 : _a.map(messagePreview => withMessageFeedInfo(messagePreview))) !== null && _b !== void 0 ? _b : [],
6578
- };
6579
- ingestInCache(newData);
6580
- };
6581
-
6582
- function updateSubChannelCache(subChannelId, subChannel, params) {
6583
- pushToCache(['subChannel', 'get', subChannelId],
6584
- // eslint-disable-next-line prefer-object-spread
6585
- shallowClone(subChannel, params));
6586
- }
6587
-
6588
- /**
6589
- * ```js
6590
- * import { isInTombstone } from '@amityco/ts-sdk'
6591
- * const user = isInTombstone(["message", "messageId"])
6592
- * ```
6593
- *
6594
- * Checks if the {@link Amity.TombstoneCacheOptions} exists
6595
- * in cache and it's not expired means it's in tombstone
6596
- * and we throw an Error
6597
- *
6598
- * @param model the model to check
6599
- * @param modelId the object id to check
6600
- * @returns the matching cache entry, or undefined.
6601
- *
6602
- * @category Cache API
6603
- */
6604
- const isInTombstone = (model, modelId) => {
6605
- const { log, cache } = getActiveClient();
6606
- const key = [model, CACHE_KEY_TOMBSTONE, modelId];
6607
- if (!cache)
6608
- return;
6609
- log('cache/api/isInTombstone', key);
6610
- const isInTombstone = pullFromCache(key);
6611
- const { lifeSpan } = queryOptions('cache_then_server', CACHE_LIFESPAN_TOMBSTONE);
6612
- if (isInTombstone && isFresh(isInTombstone.data, lifeSpan)) {
6613
- throw new ASCApiError('Item not found!', 400400 /* Amity.ServerError.ITEM_NOT_FOUND */, "error" /* Amity.ErrorLevel.ERROR */);
6614
- }
6615
- };
6616
-
6617
- /**
6618
- * ```js
6619
- * import { getMessageMarkers } from '@amityco/ts-sdk'
6620
- * const messageMarkers = await getMessageMarkers(['sch1', 'sch2'])
6621
- * ```
6622
- *
6623
- * Fetches a list of {@link Amity.MessageMarker} by messageIds
6624
- *
6625
- * @param messageIds the feed IDs of the {@link Amity.RawMessage} marker to fetch
6626
- * @returns A list of {@link Amity.MessageMarker} by messageIds
6627
- *
6628
- * @category Channel API
6629
- * @async
6630
- * @private
6631
- */
6632
- const getMessageMarkers = async (messageIds) => {
6633
- const client = getActiveClient();
6634
- client.log('channel/getMessageMarkers', messageIds);
6635
- const { data: queryPayload } = await client.http.get(`/api/v1/markers/messages`, {
6636
- params: {
6637
- messageIds,
6638
- },
6639
- });
6640
- const { contentMarkers, feedMarkers, userMarkers } = queryPayload;
6641
- const cachedAt = client.cache && Date.now();
6642
- if (client.cache)
6643
- ingestInCache({ contentMarkers, feedMarkers, userMarkers }, { cachedAt });
6644
- fireEvent('local.feedMarker.fetched', { feedMarkers });
6645
- fireEvent('local.messageMarker.fetched', { contentMarkers });
6646
- fireEvent('local.userMarker.fetched', { userMarkers });
6647
- return { data: contentMarkers, cachedAt };
6648
- };
6649
-
6650
- const persistUnreadCountInfo = (payload) => {
6651
- const { feedMarkers, userFeedMarkers } = payload;
6652
- // calculate sub channel unread info and channel unread info
6653
- if (feedMarkers.length > 0 && userFeedMarkers.length > 0) {
6654
- const channelIds = [];
6655
- const feedMarkerMap = new Map(feedMarkers.map(fm => [fm.feedId, fm]));
6656
- userFeedMarkers.forEach(userFeedMarker => {
6657
- const feedMarker = feedMarkerMap.get(userFeedMarker.feedId);
6658
- if (!feedMarker)
6659
- return;
6660
- if (feedMarker.feedId === userFeedMarker.feedId) {
6661
- const unreadCount = feedMarker.lastSegment - userFeedMarker.readToSegment;
6662
- const subChannelUnreadInfo = {
6663
- subChannelId: feedMarker.feedId,
6664
- channelId: feedMarker.entityId,
6665
- readToSegment: userFeedMarker.readToSegment,
6666
- lastSegment: feedMarker.lastSegment,
6667
- lastMentionSegment: userFeedMarker.lastMentionSegment,
6668
- unreadCount: Math.max(0, unreadCount),
6669
- isMentioned: userFeedMarker.isMentioned,
6670
- isDeleted: feedMarker.isDeleted,
6671
- createdAt: userFeedMarker.createdAt,
6672
- updatedAt: userFeedMarker.updatedAt,
6673
- };
6674
- // update sub channel unread info in cache
6675
- ingestInCache({ subChannelUnreadInfo: [subChannelUnreadInfo] });
6676
- if (!channelIds.includes(feedMarker.entityId)) {
6677
- channelIds.push(feedMarker.entityId);
6678
- }
6679
- }
6680
- });
6681
- // re-calculate channel unread info in cache
6682
- channelIds.forEach(channelId => {
6683
- reCalculateChannelUnreadInfo(channelId);
6684
- });
6685
- }
6686
- };
6687
-
7473
+ /* begin_public_function
7474
+ id: invitation.cancel
7475
+ */
6688
7476
  /**
6689
7477
  * ```js
6690
- * import { getSubChannelMarkers } from '@amityco/ts-sdk'
6691
- * const subChannelMarkers = await getSubChannelMarkers(['sch1', 'sch2'])
7478
+ * import { cancelInvitation } from '@amityco/ts-sdk'
7479
+ * const isCanceled = await cancelInvitation(invitationId)
6692
7480
  * ```
6693
7481
  *
6694
- * Fetches a paginable list of {@link Amity.SubChannelMarker} objects
7482
+ * Cancels a {@link Amity.Invitation} object
6695
7483
  *
6696
- * @param messageFeedIds the feed IDs of the {@link Amity.RawSubChannel} marker to fetch
6697
- * @param page
6698
- * @returns A page of {@link Amity.SubChannelMarker} objects
7484
+ * @param invitationId the {@link Amity.Invitation} to cancel
7485
+ * @returns A success boolean if the {@link Amity.Invitation} was canceled
6699
7486
  *
6700
- * @category Channel API
7487
+ * @category Invitation API
6701
7488
  * @async
6702
- * @private
6703
7489
  */
6704
- const getSubChannelMarkers = async (messageFeedIds, page = { limit: 100 }) => {
7490
+ const cancelInvitation = async (invitationId) => {
7491
+ var _a;
6705
7492
  const client = getActiveClient();
6706
- client.log('channel/getSubChannelMarkers', messageFeedIds, page);
6707
- const { data: queryPayload } = await client.http.get(`/api/v1/markers/message-feeds`, {
6708
- params: {
6709
- messageFeedIds,
6710
- options: {
6711
- token: toToken(page, 'skiplimit'),
6712
- },
6713
- },
6714
- });
6715
- const { paging } = queryPayload, payload = __rest(queryPayload, ["paging"]);
6716
- const { userEntityMarkers: userEntityMarkersPayload, userFeedMarkers: userFeedMarkersPayload, userMarkers, feedMarkers: feedMarkersPayload, } = payload;
6717
- // if consistent mode is enabled, persist the unread count info to the cache
6718
- if (client.isUnreadCountEnabled && client.getMarkerSyncConsistentMode()) {
6719
- persistUnreadCountInfo({
6720
- feedMarkers: feedMarkersPayload,
6721
- userFeedMarkers: userFeedMarkersPayload,
6722
- });
7493
+ client.log('invitation/cancelInvitation', invitationId);
7494
+ const { data } = await client.http.delete(`/api/v1/invitations/${invitationId}`);
7495
+ const invitation = (_a = pullFromCache([
7496
+ 'invitation',
7497
+ 'get',
7498
+ invitationId,
7499
+ ])) === null || _a === void 0 ? void 0 : _a.data;
7500
+ if (invitation) {
7501
+ dropFromCache(['invitation', 'get', invitationId]);
7502
+ fireEvent('local.invitation.deleted', [invitation]);
6723
7503
  }
6724
- const userEntityMarkers = convertChannelMarkerResponse(userEntityMarkersPayload);
6725
- const userFeedMarkers = convertSubChannelMarkerResponse(userFeedMarkersPayload);
6726
- const cachedAt = client.cache && Date.now();
6727
- if (client.cache)
6728
- ingestInCache({ userEntityMarkers, userFeedMarkers, userMarkers }, { cachedAt });
6729
- fireEvent('local.channelMarker.fetched', { userEntityMarkers });
6730
- fireEvent('local.subChannelMarker.fetched', { userFeedMarkers });
6731
- fireEvent('local.userMarker.fetched', { userMarkers });
6732
- const nextPage = toPage(paging.next);
6733
- const prevPage = toPage(paging.previous);
6734
- return { data: userFeedMarkers, cachedAt, prevPage, nextPage };
6735
- };
7504
+ return data.success;
7505
+ };
7506
+ /* end_public_function */
6736
7507
 
6737
- const getUserMarker = async () => {
6738
- const client = getActiveClient();
6739
- client.log('channel/getUserMarker');
6740
- const { data: payload } = await client.http.get(`/api/v1/markers/userMarker`);
6741
- const { userMarkers } = payload;
6742
- const cachedAt = client.cache && Date.now();
6743
- if (client.cache)
6744
- ingestInCache({ userMarkers }, { cachedAt });
6745
- fireEvent('local.userMarker.fetched', { userMarkers });
6746
- const latestUserMarker = userMarkers.reduce((maxUserMarker, userMarker) => {
6747
- if (maxUserMarker == null ||
6748
- new Date(maxUserMarker.lastSyncAt).getTime() < new Date(userMarker.lastSyncAt).getTime()) {
6749
- return userMarker;
6750
- }
6751
- return maxUserMarker;
6752
- }, undefined);
6753
- return { data: latestUserMarker, cachedAt };
7508
+ const prepareMyInvitationsPayload = (rawPayload) => {
7509
+ return Object.assign(Object.assign({}, rawPayload), { users: rawPayload.users.map(convertRawUserToInternalUser), invitations: rawPayload.invitations.map(convertRawInvitationToInternalInvitation) });
6754
7510
  };
6755
7511
 
6756
- /** @hidden */
6757
- /*
6758
- * @param message payload from http request without myReactions
6759
- * add myReactions to http response if the event was a reaction event
6760
- */
6761
- const prepareMessagePayloadForCache = (payload, reactors, event) => {
6762
- const client = getActiveClient();
6763
- const cached = pullFromCache(['message', 'get', payload.messageId]);
6764
- // '[]' in cases where the new reaction is the first one
6765
- const myReactions = (cached === null || cached === void 0 ? void 0 : cached.data.myReactions) || [];
6766
- // add myReactions to the payload
6767
- Object.assign(payload, { myReactions });
6768
- // check if there are any updates to the reactions
6769
- const latestReaction = reactors[0];
6770
- const isLatestReactionMine = latestReaction && latestReaction.userId === client.userId;
6771
- if (!isLatestReactionMine) {
6772
- return;
6773
- }
6774
- // new reaction added
6775
- if (event === 'message.reactionAdded' && !myReactions.includes(latestReaction.reactionName)) {
6776
- Object.assign(payload, {
6777
- myReactions: [...myReactions, latestReaction.reactionName],
6778
- });
6779
- }
6780
- // existing reaction removed
6781
- if (event === 'message.reactionRemoved' && myReactions.includes(latestReaction.reactionName)) {
6782
- Object.assign(payload, {
6783
- myReactions: myReactions.filter(x => x !== latestReaction.reactionName),
6784
- });
6785
- }
7512
+ const invitationLinkedObject = (invitation) => {
7513
+ return Object.assign(Object.assign({}, invitation), { get user() {
7514
+ const cacheData = pullFromCache(['user', 'get', invitation.invitedUserPublicId]);
7515
+ if (cacheData === null || cacheData === void 0 ? void 0 : cacheData.data)
7516
+ return userLinkedObject(cacheData.data);
7517
+ return undefined;
7518
+ },
7519
+ get createdBy() {
7520
+ const cacheData = pullFromCache(['user', 'get', invitation.inviterUserPublicId]);
7521
+ if (cacheData === null || cacheData === void 0 ? void 0 : cacheData.data)
7522
+ return userLinkedObject(cacheData.data);
7523
+ return undefined;
7524
+ },
7525
+ get target() {
7526
+ if (invitation.targetType === 'community') {
7527
+ const cacheData = pullFromCache([
7528
+ 'community',
7529
+ 'get',
7530
+ invitation.targetId,
7531
+ ]);
7532
+ if (cacheData === null || cacheData === void 0 ? void 0 : cacheData.data)
7533
+ return cacheData.data;
7534
+ return undefined;
7535
+ }
7536
+ return undefined;
7537
+ }, accept: async () => {
7538
+ await acceptInvitation(invitation._id);
7539
+ }, reject: async () => {
7540
+ await rejectInvitation(invitation._id);
7541
+ }, cancel: async () => {
7542
+ await cancelInvitation(invitation._id);
7543
+ } });
6786
7544
  };
6787
7545
 
6788
- /*
6789
- * This is a simple utility that infers the value of isDeleted based on the
6790
- * value of includeDeleted
7546
+ /* begin_public_function
7547
+ id: invitation.get
7548
+ */
7549
+ /**
7550
+ * ```js
7551
+ * import { getInvitation } from '@amityco/ts-sdk'
7552
+ * const { invitation } = await getInvitation(targetType, targetId)
7553
+ * ```
6791
7554
  *
6792
- * There are two important things to note here:
6793
- * 1. `includeDeleted` is purely client side query param and not recognized by
6794
- * the server
6795
- * 2. The only values we wish to expose with regards to `isDeleted` (the server
6796
- * param for queries) is false | undefined and want to disallow users to query
6797
- * for deleted entities
7555
+ * Get a {@link Amity.Invitation} object
6798
7556
  *
6799
- * Although this is a very simple utility, it's only purpose is to keep things
6800
- * DRY
7557
+ * @param targetType The type of the target of the {@link Amity.Invitation}
7558
+ * @param targetId The ID of the target of the {@link Amity.Invitation}
7559
+ * @returns A {@link Amity.Invitation} object
7560
+ *
7561
+ * @category Invitation API
7562
+ * @async
6801
7563
  */
6802
- const inferIsDeleted = (includeDeleted) => includeDeleted === true ? undefined : false;
6803
-
6804
- function getSubChannelIsMentioned(channelId, subChannelId, marker) {
6805
- var _a, _b;
6806
- // Look for `unreadCount` in the marker param first
6807
- if (marker) {
6808
- return marker.hasMentioned;
6809
- }
6810
- const client = getActiveClient();
6811
- // If consistent mode is enabled, look in the SubChannelUnreadCountInfo cache
6812
- if (client.isUnreadCountEnabled && client.getMarkerSyncConsistentMode()) {
6813
- const cachedUnreadCount = (_a = pullFromCache([
6814
- 'subChannelUnreadInfo',
6815
- 'get',
6816
- subChannelId,
6817
- ])) === null || _a === void 0 ? void 0 : _a.data;
6818
- if (cachedUnreadCount) {
6819
- return cachedUnreadCount.isMentioned;
6820
- }
6821
- return false;
6822
- }
6823
- const key = {
6824
- entityId: channelId,
6825
- feedId: subChannelId,
6826
- userId: getActiveUser()._id,
6827
- };
6828
- // If the marker param is not set, look in the cache
6829
- const cachedMarker = (_b = pullFromCache([
6830
- 'subChannelMarker',
6831
- 'get',
6832
- getResolver('subChannelMarker')(key),
6833
- ])) === null || _b === void 0 ? void 0 : _b.data;
6834
- if (cachedMarker) {
6835
- return cachedMarker.hasMentioned;
6836
- }
6837
- // and if not found in cache use default value `false`
6838
- return false;
6839
- }
6840
-
6841
- function getSubChannelUnreadCount(channelId, subChannelId, marker) {
6842
- var _a, _b;
6843
- // Look for `unreadCount` in the marker param first
6844
- if (marker) {
6845
- return marker.unreadCount;
6846
- }
7564
+ const getInvitation = async (targetType, targetId) => {
6847
7565
  const client = getActiveClient();
6848
- // If consistent mode is enabled, look in the SubChannelUnreadCountInfo cache
6849
- if (client.isUnreadCountEnabled && client.getMarkerSyncConsistentMode()) {
6850
- const cachedUnreadCount = (_a = pullFromCache([
6851
- 'subChannelUnreadInfo',
6852
- 'get',
6853
- subChannelId,
6854
- ])) === null || _a === void 0 ? void 0 : _a.data;
6855
- if (cachedUnreadCount) {
6856
- return cachedUnreadCount.isDeleted ? 0 : cachedUnreadCount.unreadCount;
6857
- }
6858
- return 0;
6859
- }
6860
- const key = {
6861
- entityId: channelId,
6862
- feedId: subChannelId,
6863
- userId: getActiveUser()._id,
6864
- };
6865
- // If the marker param is not set, look in the cache
6866
- const cachedMarker = (_b = pullFromCache([
6867
- 'subChannelMarker',
6868
- 'get',
6869
- getResolver('subChannelMarker')(key),
6870
- ])) === null || _b === void 0 ? void 0 : _b.data;
6871
- if (cachedMarker) {
6872
- return cachedMarker.unreadCount;
6873
- }
6874
- // and if not found in cache use default value `0`
6875
- return 0;
6876
- }
6877
-
6878
- const MARKER_INCLUDED_SUB_CHANNEL_TYPE$1 = ['broadcast', 'conversation', 'community'];
6879
- const isUnreadCountSupport$2 = ({ channelType }) => MARKER_INCLUDED_SUB_CHANNEL_TYPE$1.includes(channelType);
6880
- function convertFromRaw$2(_a) {
6881
- var { channelId, channelPublicId, channelType, childCount, creatorId, creatorPublicId, lastMessageId, lastMessageTimestamp, messageFeedId, name } = _a, rest = __rest(_a, ["channelId", "channelPublicId", "channelType", "childCount", "creatorId", "creatorPublicId", "lastMessageId", "lastMessageTimestamp", "messageFeedId", "name"]);
6882
- return Object.assign(Object.assign({ get unreadCount() {
6883
- return getSubChannelUnreadCount(channelId, messageFeedId);
6884
- },
6885
- get hasMentioned() {
6886
- return getSubChannelIsMentioned(channelId, messageFeedId);
6887
- },
6888
- get isMentioned() {
6889
- return getSubChannelIsMentioned(channelId, messageFeedId);
6890
- } }, rest), { channelId: channelPublicId, creatorId: creatorPublicId, displayName: name, lastActivity: lastMessageTimestamp, latestMessageId: lastMessageId, messageCount: childCount, subChannelId: messageFeedId, isUnreadCountSupport: isUnreadCountSupport$2({ channelType }) });
6891
- }
6892
-
6893
- const mergePayloadWithLocal = (payload) => {
6894
- var _a, _b, _c;
6895
- const localMessage = (_b = (_a = queryCache(['message', 'get'])) === null || _a === void 0 ? void 0 : _a.find(({ data }) => data.messageId === payload.messageId)) === null || _b === void 0 ? void 0 : _b.data;
6896
- if (localMessage) {
6897
- return Object.assign(Object.assign(Object.assign({}, localMessage), payload), {
6898
- // NOTE: referenceId is missing in the some payload event. If we have local message data with referenceId, use it instead.
6899
- referenceId: (_c = localMessage.referenceId) !== null && _c !== void 0 ? _c : payload.referenceId });
6900
- }
6901
- return payload;
6902
- };
6903
- function convertFromRaw$1(message, reactors, event) {
6904
- var _a;
6905
- const mergeMessage = mergePayloadWithLocal(message);
6906
- const { channelPublicId, childCount, creatorPublicId, mentionedUsers, messageFeedId, myReactions, reactionCount, reactions, referenceId, segment, messageId, creatorId } = mergeMessage, rest = __rest(mergeMessage, ["channelPublicId", "childCount", "creatorPublicId", "mentionedUsers", "messageFeedId", "myReactions", "reactionCount", "reactions", "referenceId", "segment", "messageId", "creatorId"]);
6907
- let cache;
6908
- if (referenceId) {
6909
- cache = pullFromCache(['message', 'get', referenceId]);
7566
+ client.log('invitation/getInvitation', targetType, targetId);
7567
+ const { data: payload } = await client.http.get(`/api/v1/invitations/me`, { params: { targetType, targetId } });
7568
+ const data = prepareMyInvitationsPayload(payload);
7569
+ const cachedAt = client.cache && Date.now();
7570
+ if (client.cache)
7571
+ ingestInCache(data, { cachedAt });
7572
+ return {
7573
+ data: data.invitations[0] ? invitationLinkedObject(data.invitations[0]) : undefined,
7574
+ cachedAt,
7575
+ };
7576
+ };
7577
+ /* end_public_function */
7578
+
7579
+ var InvitationActionsEnum;
7580
+ (function (InvitationActionsEnum) {
7581
+ InvitationActionsEnum["OnLocalInvitationCreated"] = "onLocalInvitationCreated";
7582
+ InvitationActionsEnum["OnLocalInvitationUpdated"] = "onLocalInvitationUpdated";
7583
+ InvitationActionsEnum["OnLocalInvitationDeleted"] = "onLocalInvitationDeleted";
7584
+ })(InvitationActionsEnum || (InvitationActionsEnum = {}));
7585
+
7586
+ class PaginationController {
7587
+ constructor(queryParams) {
7588
+ const { http } = getActiveClient();
7589
+ this.queryParams = queryParams;
7590
+ this.http = http;
6910
7591
  }
6911
- if (!cache) {
6912
- cache = pullFromCache(['message', 'get', messageId]);
7592
+ loadFirstPage() {
7593
+ return this.onFetch("first" /* Amity.LiveCollectionPageDirection.FIRST */);
6913
7594
  }
6914
- const out = Object.assign(Object.assign({}, rest), { messageId, channelId: channelPublicId, channelSegment: segment, childrenNumber: childCount, creatorId: creatorPublicId, creatorPrivateId: message.creatorId, reactions: reactions !== null && reactions !== void 0 ? reactions : {},
6915
- /*
6916
- * Previously, myReactions were added only if it was part of the payload.
6917
- * So empty myReactions were not present. So I've edited the payload to add
6918
- * a default for those cases.
6919
- *
6920
- * Check git blame for previous iteration
6921
- */
6922
- myReactions: myReactions || ((_a = cache === null || cache === void 0 ? void 0 : cache.data.myReactions) !== null && _a !== void 0 ? _a : []), reactionsCount: reactionCount, subChannelId: messageFeedId, uniqueId: cache ? cache.data.uniqueId : messageId, referenceId, syncState: "synced" /* Amity.SyncState.Synced */ });
6923
- if (mentionedUsers) {
6924
- out.mentionees = mentionedUsers.map(mention => {
6925
- if (mention.type === 'channel') {
6926
- return mention;
6927
- }
6928
- return { type: 'user', userIds: mention.userPublicIds };
6929
- });
7595
+ loadNextPage() {
7596
+ return this.onFetch("next" /* Amity.LiveCollectionPageDirection.NEXT */);
6930
7597
  }
6931
- if (reactors && reactors.length && event) {
6932
- // mqtt event
6933
- prepareMessagePayloadForCache(out, reactors, event);
7598
+ loadPreviousPage() {
7599
+ return this.onFetch("prev" /* Amity.LiveCollectionPageDirection.PREV */);
6934
7600
  }
6935
- return out;
6936
- }
6937
- const preUpdateMessageCache = (rawPayload) => {
6938
- ingestInCache({
6939
- messages: rawPayload.messages.map(message => convertFromRaw$1(message, rawPayload.reactions)),
6940
- });
6941
- };
6942
- const DEBOUNCE_TIME = 2000;
6943
- const currentDebounceMap = {};
6944
- const prepareMessagePayload = async (payload, event) => {
6945
- const markerIds = payload.messages.map(({ messageId }) => messageId);
6946
- if (markerIds.length > 0) {
6947
- // since the get markers method requires a channel cache to function with the reducer.
6948
- preUpdateMessageCache(payload);
6949
- const markerIdsKey = markerIds.join('');
6950
- if (currentDebounceMap[markerIdsKey]) {
6951
- clearTimeout(currentDebounceMap[markerIdsKey]);
7601
+ async onFetch(direction = "first" /* Amity.LiveCollectionPageDirection.FIRST */) {
7602
+ var _a, _b, _c, _d;
7603
+ if (direction === 'prev' && !this.previousToken)
7604
+ return;
7605
+ if (direction === 'next' && !this.nextToken)
7606
+ return;
7607
+ let token;
7608
+ if (direction === 'prev')
7609
+ token = this.previousToken;
7610
+ if (direction === 'next')
7611
+ token = this.nextToken;
7612
+ const queryResponse = await this.getRequest(this.queryParams, token);
7613
+ if (direction === 'first') {
7614
+ this.nextToken = (_a = queryResponse.paging) === null || _a === void 0 ? void 0 : _a.next;
7615
+ this.previousToken = (_b = queryResponse.paging) === null || _b === void 0 ? void 0 : _b.previous;
6952
7616
  }
6953
- currentDebounceMap[markerIdsKey] = setTimeout(() => {
6954
- try {
6955
- getMessageMarkers(markerIds);
6956
- }
6957
- catch (_error) {
6958
- // do nothing
6959
- }
6960
- }, DEBOUNCE_TIME);
6961
- }
6962
- const { messageFeeds } = payload, restPayload = __rest(payload, ["messageFeeds"]);
6963
- // upsert messageFeeds to subchannel cache because messageFeeds from event payload not include messagePreviewId
6964
- if (messageFeeds && messageFeeds.length > 0) {
6965
- messageFeeds === null || messageFeeds === void 0 ? void 0 : messageFeeds.forEach(messageFeed => {
6966
- var _a, _b;
6967
- const subChannelCache = (_b = (_a = pullFromCache(['subChannel', 'get', messageFeed.messageFeedId])) === null || _a === void 0 ? void 0 : _a.data) !== null && _b !== void 0 ? _b : {};
6968
- // exclude getter properties from existing subChannel cache, update only other properties to existing subChannel cache
6969
- const _c = convertFromRaw$2(messageFeed), restSubChannel = __rest(_c, ["unreadCount", "isMentioned"]);
6970
- updateSubChannelCache(messageFeed.messageFeedId, subChannelCache, restSubChannel);
6971
- });
7617
+ if (direction === 'prev')
7618
+ this.previousToken = (_c = queryResponse.paging) === null || _c === void 0 ? void 0 : _c.previous;
7619
+ if (direction === 'next')
7620
+ this.nextToken = (_d = queryResponse.paging) === null || _d === void 0 ? void 0 : _d.next;
7621
+ return queryResponse;
6972
7622
  }
6973
- return Object.assign(Object.assign({}, restPayload), { messages: payload.messages.map(m => convertFromRaw$1(m, payload.reactions, event)) });
6974
- };
6975
- function convertParams(_a) {
6976
- var { subChannelId, mentionees, dataType, data } = _a, rest = __rest(_a, ["subChannelId", "mentionees", "dataType", "data"]);
6977
- if (dataType === MessageContentType.IMAGE || dataType === MessageContentType.FILE) {
6978
- return Object.assign({ messageFeedId: subChannelId, mentionedUsers: mentionees, dataType, data: Object.assign({ caption: '' }, data) }, rest);
7623
+ getNextToken() {
7624
+ return this.nextToken;
6979
7625
  }
6980
- return Object.assign({ messageFeedId: subChannelId, mentionedUsers: mentionees, dataType, data }, rest);
6981
- }
6982
- function convertQueryParams$1(_a) {
6983
- var { sortBy, subChannelId, includingTags, excludingTags, includeDeleted, aroundMessageId, limit, type } = _a, rest = __rest(_a, ["sortBy", "subChannelId", "includingTags", "excludingTags", "includeDeleted", "aroundMessageId", "limit", "type"]);
6984
- const out = Object.assign(Object.assign({}, rest), { messageFeedId: subChannelId, isDeleted: inferIsDeleted(includeDeleted), options: {
6985
- sortBy,
6986
- limit: limit || COLLECTION_DEFAULT_PAGINATION_LIMIT,
6987
- around: aroundMessageId,
6988
- } });
6989
- if (includingTags) {
6990
- out.includeTags = includingTags;
7626
+ getPrevToken() {
7627
+ return this.previousToken;
6991
7628
  }
6992
- if (type) {
6993
- out.dataType = type;
7629
+ }
7630
+
7631
+ class InvitationsPaginationController extends PaginationController {
7632
+ async getRequest(queryParams, token) {
7633
+ const { limit = COLLECTION_DEFAULT_PAGINATION_LIMIT } = queryParams, params = __rest(queryParams, ["limit"]);
7634
+ const options = token ? { token } : { limit };
7635
+ const { data } = await this.http.get('/api/v1/invitations', { params: Object.assign(Object.assign({}, params), { options }) });
7636
+ return data;
6994
7637
  }
6995
- if (excludingTags) {
6996
- out.excludeTags = excludingTags;
7638
+ }
7639
+
7640
+ class QueryStreamController {
7641
+ constructor(query, cacheKey) {
7642
+ this.query = query;
7643
+ this.cacheKey = cacheKey;
6997
7644
  }
6998
- return out;
6999
7645
  }
7000
7646
 
7001
- const MARKER_INCLUDED_SUB_CHANNEL_TYPE = ['broadcast', 'conversation', 'community'];
7002
- /**
7003
- * Filter sub channel by type. Only conversation, community and broadcast type are included.
7004
- */
7005
- const isUnreadCountSupport$1 = ({ channelType }) => MARKER_INCLUDED_SUB_CHANNEL_TYPE.includes(channelType);
7006
- const preUpdateSubChannelCache = (rawPayload) => {
7007
- ingestInCache({
7008
- messageFeeds: rawPayload.messageFeeds.map(messageFeed => convertFromRaw$2(messageFeed)),
7009
- });
7010
- };
7011
- const prepareSubChannelPayload = async (rawPayload) => {
7012
- const markerIds = rawPayload.messageFeeds
7013
- .filter(isUnreadCountSupport$1)
7014
- .map(({ messageFeedId }) => messageFeedId);
7015
- if (markerIds.length > 0) {
7016
- // since the get markers method requires a channel cache to function with the reducer.
7017
- preUpdateSubChannelCache(rawPayload);
7018
- try {
7019
- await getSubChannelMarkers(markerIds);
7647
+ class InvitationsQueryStreamController extends QueryStreamController {
7648
+ constructor(query, cacheKey, notifyChange, preparePayload) {
7649
+ super(query, cacheKey);
7650
+ this.notifyChange = notifyChange;
7651
+ this.preparePayload = preparePayload;
7652
+ }
7653
+ async saveToMainDB(response) {
7654
+ const processedPayload = await this.preparePayload(response);
7655
+ const client = getActiveClient();
7656
+ const cachedAt = client.cache && Date.now();
7657
+ if (client.cache) {
7658
+ ingestInCache(processedPayload, { cachedAt });
7020
7659
  }
7021
- catch (e) {
7022
- // empty block (from the spec, allow marker fetch to fail without having to do anything)
7660
+ }
7661
+ appendToQueryStream(response, direction, refresh = false) {
7662
+ var _a, _b;
7663
+ if (refresh) {
7664
+ pushToCache(this.cacheKey, {
7665
+ data: response.invitations.map(getResolver('invitation')),
7666
+ });
7667
+ }
7668
+ else {
7669
+ const collection = (_a = pullFromCache(this.cacheKey)) === null || _a === void 0 ? void 0 : _a.data;
7670
+ const invitations = (_b = collection === null || collection === void 0 ? void 0 : collection.data) !== null && _b !== void 0 ? _b : [];
7671
+ pushToCache(this.cacheKey, Object.assign(Object.assign({}, collection), { data: [
7672
+ ...new Set([...invitations, ...response.invitations.map(getResolver('invitation'))]),
7673
+ ] }));
7023
7674
  }
7024
7675
  }
7025
- updateSubChannelMessagePreviewCache(rawPayload);
7026
- // attach marker to sub channel
7027
- const messageFeeds = rawPayload.messageFeeds.map(convertFromRaw$2);
7028
- const messages = rawPayload.messages.map(m => convertFromRaw$1(m));
7029
- return Object.assign(Object.assign({}, rawPayload), { messageFeeds,
7030
- messages });
7031
- };
7032
- function convertQueryParams(_a) {
7033
- var { excludeDefaultSubChannel } = _a, rest = __rest(_a, ["excludeDefaultSubChannel"]);
7034
- const out = Object.assign({}, rest);
7035
- if (excludeDefaultSubChannel !== undefined) {
7036
- out.excludeDefaultMessageFeed = excludeDefaultSubChannel;
7676
+ reactor(action) {
7677
+ return (invitations) => {
7678
+ var _a;
7679
+ const collection = (_a = pullFromCache(this.cacheKey)) === null || _a === void 0 ? void 0 : _a.data;
7680
+ if (!collection)
7681
+ return;
7682
+ if (action === InvitationActionsEnum.OnLocalInvitationUpdated) {
7683
+ const isExist = collection.data.find(id => id === invitations[0].invitationId);
7684
+ if (!isExist)
7685
+ return;
7686
+ }
7687
+ if (action === InvitationActionsEnum.OnLocalInvitationCreated) {
7688
+ collection.data = [
7689
+ ...new Set([
7690
+ ...invitations.map(invitation => invitation.invitationId),
7691
+ ...collection.data,
7692
+ ]),
7693
+ ];
7694
+ }
7695
+ if (action === InvitationActionsEnum.OnLocalInvitationDeleted) {
7696
+ collection.data = collection.data.filter(id => id !== invitations[0].invitationId);
7697
+ }
7698
+ pushToCache(this.cacheKey, collection);
7699
+ this.notifyChange({ origin: "event" /* Amity.LiveDataOrigin.EVENT */, loading: false });
7700
+ };
7701
+ }
7702
+ subscribeRTE(createSubscriber) {
7703
+ return createSubscriber.map(subscriber => subscriber.fn(this.reactor(subscriber.action)));
7037
7704
  }
7038
- return out;
7039
7705
  }
7040
7706
 
7707
+ function isObject(value) {
7708
+ return typeof value === 'object' && value !== null;
7709
+ }
7041
7710
  /**
7042
- * ```js
7043
- * import { getSubChannel } from '@amityco/ts-sdk'
7044
- * const subChannel = await getSubChannel('foobar')
7045
- * ```
7046
- *
7047
- * Fetches a {@link Amity.SubChannel} object
7048
- *
7049
- * @param subChannelId the ID of the {@link Amity.SubChannel} to fetch
7050
- * @returns the associated {@link Amity.SubChannel} object
7051
- *
7052
- * @category Channel API
7053
- * @async
7711
+ * convert all object getter property to static value
7054
7712
  */
7055
- const getSubChannel$1 = async (subChannelId) => {
7056
- const client = getActiveClient();
7057
- client.log('channel/getSubChannel', subChannelId);
7058
- isInTombstone('subChannel', subChannelId);
7059
- try {
7060
- const response = await client.http.get(`/api/v5/message-feeds/${encodeURIComponent(subChannelId)}`);
7061
- const data = await prepareSubChannelPayload(response.data);
7062
- const cachedAt = client.cache && Date.now();
7063
- if (client.cache)
7064
- ingestInCache(data, { cachedAt });
7065
- fireEvent('local.message-feed.fetched', data);
7066
- return {
7067
- data: data.messageFeeds[0],
7068
- cachedAt,
7069
- };
7713
+ const convertGetterPropsToStatic = (obj) => {
7714
+ if (!isObject(obj)) {
7715
+ return obj;
7716
+ }
7717
+ const entries = Object.entries(obj).map(([key, value]) => {
7718
+ const descriptor = Object.getOwnPropertyDescriptor(obj, key);
7719
+ if (typeof (descriptor === null || descriptor === void 0 ? void 0 : descriptor.get) === 'function') {
7720
+ return [key, descriptor.get.call(obj)];
7721
+ }
7722
+ return [key, value];
7723
+ });
7724
+ return Object.fromEntries(entries);
7725
+ };
7726
+ const removeFunctionProperties = (obj) => {
7727
+ if (!isObject(obj)) {
7728
+ return obj;
7070
7729
  }
7071
- catch (error) {
7072
- if (checkIfShouldGoesToTombstone(error === null || error === void 0 ? void 0 : error.code)) {
7073
- pushToTombstone('subChannel', subChannelId);
7730
+ const entries = Object.entries(obj).map(([key, value]) => {
7731
+ if (typeof value === 'function') {
7732
+ return [key, undefined];
7074
7733
  }
7075
- throw error;
7076
- }
7077
- };
7078
- /**
7079
- * ```js
7080
- * import { getSubChannel } from '@amityco/ts-sdk'
7081
- * const subChannel = getSubChannel.locally('foobar')
7082
- * ```
7083
- *
7084
- * Fetches a {@link Amity.SubChannel} object from cache
7085
- *
7086
- * @param subChannelId the ID of the {@link Amity.SubChannel} to fetch
7087
- * @returns the associated {@link Amity.SubChannel} object
7088
- *
7089
- * @category Channel API
7090
- */
7091
- getSubChannel$1.locally = (subChannelId) => {
7092
- const client = getActiveClient();
7093
- client.log('channel/getSubChannel.locally', subChannelId);
7094
- if (!client.cache)
7095
- return;
7096
- const cached = pullFromCache(['subChannel', 'get', subChannelId]);
7097
- if (!cached)
7098
- return;
7099
- return {
7100
- data: cached.data,
7101
- cachedAt: cached.cachedAt,
7102
- };
7734
+ return [key, value];
7735
+ });
7736
+ return Object.fromEntries(entries);
7103
7737
  };
7104
7738
 
7105
- const convertDateStringToTimestamp = (dateString) => {
7106
- return new Date(dateString).getTime();
7107
- };
7739
+ class PaginationNoPageController {
7740
+ constructor(queryParams) {
7741
+ const { http } = getActiveClient();
7742
+ this.queryParams = queryParams;
7743
+ this.http = http;
7744
+ }
7745
+ async onFetch() {
7746
+ const queryResponse = await this.getRequest(this.queryParams);
7747
+ return queryResponse;
7748
+ }
7749
+ }
7108
7750
 
7109
- const getMessagePreviewSetting$1 = async () => {
7110
- const client = getActiveClient();
7111
- return client.getMessagePreviewSetting(false);
7112
- };
7113
- const getSubChannelCache = async (subChannelId) => {
7114
- var _a;
7115
- let subChannelCache = (_a = pullFromCache(['subChannel', 'get', subChannelId])) === null || _a === void 0 ? void 0 : _a.data;
7116
- if (!subChannelCache) {
7117
- subChannelCache = (await getSubChannel$1(subChannelId)).data;
7751
+ class LiveCollectionController {
7752
+ constructor(paginationController, queryStreamId, cacheKey, callback) {
7753
+ this.paginationController = paginationController;
7754
+ this.queryStreamId = queryStreamId;
7755
+ this.cacheKey = cacheKey;
7756
+ this.callback = callback;
7118
7757
  }
7119
- return subChannelCache;
7120
- };
7121
- const isLastestMessageOnSubchannel = (message) => {
7122
- var _a;
7123
- const cache = (_a = pullFromCache([
7124
- 'messagePreviewSubChannel',
7125
- 'get',
7126
- message.subChannelId,
7127
- ])) === null || _a === void 0 ? void 0 : _a.data;
7128
- // The message payload from optimistic created event has no segment, so we check createdAt instead.
7129
- return (!cache ||
7130
- cache.segment <= message.channelSegment ||
7131
- convertDateStringToTimestamp(cache.createdAt) <= convertDateStringToTimestamp(message.createdAt));
7132
- };
7133
- const isLastestMessageOnChannel = (message) => {
7134
- var _a;
7135
- const cache = (_a = pullFromCache([
7136
- 'messagePreviewChannel',
7137
- 'get',
7138
- message.channelId,
7139
- ])) === null || _a === void 0 ? void 0 : _a.data;
7140
- return (!cache ||
7141
- convertDateStringToTimestamp(cache.createdAt) <= convertDateStringToTimestamp(message.createdAt));
7142
- };
7143
- const handleMessageCreatedOnSubChannel = async (message) => {
7144
- const messagePreviewSetting = await getMessagePreviewSetting$1();
7145
- const { channelId, messageId: messagePreviewId, creatorId, createdAt, updatedAt, data, dataType, subChannelId, channelSegment: segment, isDeleted, } = message;
7146
- // 1. get subChannel from cache, if not exist fetch from server
7147
- const subChannelCache = await getSubChannelCache(subChannelId);
7148
- // 2. if messagePreviewSetting is NO_MESSAGE_PREVEIW, update only lastActiviy in subChannel cache
7149
- if (messagePreviewSetting === "no-message-preview" /* Amity.MessagePreviewSetting.NO_MESSAGE_PREVIEW */) {
7150
- // 2.1 if the message is the latest message, update lastActivity to be createdAt in subChannel cache
7151
- if (convertDateStringToTimestamp(subChannelCache.lastActivity) <
7152
- convertDateStringToTimestamp(createdAt))
7153
- updateSubChannelCache(message.subChannelId, subChannelCache, {
7154
- lastActivity: createdAt,
7758
+ async refresh() {
7759
+ try {
7760
+ let result;
7761
+ if (this.paginationController instanceof PaginationNoPageController) {
7762
+ result = await this.paginationController.onFetch();
7763
+ }
7764
+ else {
7765
+ result = await this.paginationController.loadFirstPage();
7766
+ }
7767
+ if (!result)
7768
+ return;
7769
+ await this.persistModel(result);
7770
+ this.persistQueryStream({
7771
+ response: result,
7772
+ direction: "next" /* Amity.LiveCollectionPageDirection.NEXT */,
7773
+ refresh: true,
7155
7774
  });
7156
- return;
7775
+ this.notifyChange({ origin: "server" /* Amity.LiveDataOrigin.SERVER */, loading: false });
7776
+ }
7777
+ catch (e) {
7778
+ this.notifyChange({ origin: "server" /* Amity.LiveDataOrigin.SERVER */, loading: false, error: e });
7779
+ }
7157
7780
  }
7158
- // 3. if messagePreviewSetting is `NOT` NO_MESSAGE_PREVEIW, update messagePreviewSubChannel and subChannel cache
7159
- // 3.1 check if the message is the latest message, if not ignore the message.
7160
- if (!isLastestMessageOnSubchannel(message))
7161
- return;
7162
- // 3.2 if the message is the latest message, update messagePreviewSubChannel and subChannel cache
7163
- pushToCache(['messagePreviewSubChannel', 'get', message.subChannelId], {
7164
- channelId,
7165
- creatorId,
7166
- messagePreviewId,
7167
- createdAt,
7168
- updatedAt,
7169
- subChannelId,
7170
- data,
7171
- dataType,
7172
- segment,
7173
- isDeleted,
7174
- subChannelUpdatedAt: subChannelCache === null || subChannelCache === void 0 ? void 0 : subChannelCache.updatedAt,
7175
- subChannelName: subChannelCache === null || subChannelCache === void 0 ? void 0 : subChannelCache.displayName,
7176
- });
7177
- updateSubChannelCache(message.subChannelId, subChannelCache, {
7178
- lastActivity: createdAt,
7179
- messagePreviewId,
7180
- });
7181
- };
7182
- const handleMessageUpdatedOnSubChannel = async (message) => {
7183
- var _a;
7184
- const { channelId, messageId: messagePreviewId, creatorId, createdAt, updatedAt, data, dataType, subChannelId, channelSegment: segment, isDeleted, } = message;
7185
- const messagePreviewSubChannelCache = (_a = pullFromCache([
7186
- 'messagePreviewSubChannel',
7187
- 'get',
7188
- message.subChannelId,
7189
- ])) === null || _a === void 0 ? void 0 : _a.data;
7190
- // if messagePreviewSubChannel is not exist, ignore the message.
7191
- if (messagePreviewSubChannelCache &&
7192
- messagePreviewSubChannelCache.messagePreviewId === message.messageId) {
7193
- const subChannelCache = await getSubChannelCache(subChannelId);
7194
- pushToCache(['messagePreviewSubChannel', 'get', message.subChannelId], {
7195
- channelId,
7196
- creatorId,
7197
- messagePreviewId,
7198
- createdAt,
7199
- updatedAt,
7200
- subChannelId,
7201
- data,
7202
- dataType,
7203
- segment,
7204
- isDeleted,
7205
- subChannelUpdatedAt: subChannelCache.updatedAt,
7206
- subChannelName: messagePreviewSubChannelCache.subChannelName,
7207
- });
7781
+ loadPage({ initial = false, direction = "next" /* Amity.LiveCollectionPageDirection.NEXT */, }) {
7782
+ this.setup();
7783
+ this.notifyChange({ origin: "local" /* Amity.LiveDataOrigin.LOCAL */, loading: true });
7784
+ if (initial) {
7785
+ this.refresh();
7786
+ }
7787
+ else if (direction === "prev" /* Amity.LiveCollectionPageDirection.PREV */) {
7788
+ this.loadPrevPage();
7789
+ }
7790
+ else if (direction === "next" /* Amity.LiveCollectionPageDirection.NEXT */) {
7791
+ this.loadNextPage();
7792
+ }
7208
7793
  }
7209
- };
7210
- const handleMessageCreated = async (message) => {
7211
- const { channelId, messageId: messagePreviewId, creatorId, createdAt, updatedAt, data, dataType, subChannelId, channelSegment: segment, isDeleted, } = message;
7212
- if (isLastestMessageOnChannel(message)) {
7213
- const subChannelCache = await getSubChannelCache(subChannelId);
7214
- pushToCache(['messagePreviewChannel', 'get', message.channelId], {
7215
- channelId,
7216
- creatorId,
7217
- messagePreviewId,
7218
- createdAt,
7219
- updatedAt,
7220
- subChannelId,
7221
- data,
7222
- dataType,
7223
- segment,
7224
- isDeleted,
7225
- subChannelUpdatedAt: subChannelCache === null || subChannelCache === void 0 ? void 0 : subChannelCache.updatedAt,
7226
- subChannelName: subChannelCache === null || subChannelCache === void 0 ? void 0 : subChannelCache.displayName,
7227
- });
7794
+ async loadNextPage() {
7795
+ try {
7796
+ if (this.paginationController instanceof PaginationNoPageController)
7797
+ return;
7798
+ const result = await this.paginationController.loadNextPage();
7799
+ if (!result)
7800
+ return;
7801
+ await this.persistModel(result);
7802
+ this.persistQueryStream({
7803
+ response: result,
7804
+ direction: "next" /* Amity.LiveCollectionPageDirection.NEXT */,
7805
+ });
7806
+ this.notifyChange({ origin: "server" /* Amity.LiveDataOrigin.SERVER */, loading: false });
7807
+ }
7808
+ catch (e) {
7809
+ this.notifyChange({ origin: "server" /* Amity.LiveDataOrigin.SERVER */, loading: false, error: e });
7810
+ }
7228
7811
  }
7229
- };
7230
- const handleMessageUpdated = async (message) => {
7231
- /**
7232
- * Channel Case
7233
- */
7234
- var _a;
7235
- const { channelId, messageId: messagePreviewId, creatorId, createdAt, updatedAt, data, dataType, subChannelId, channelSegment: segment, isDeleted, } = message;
7236
- const messagePreviewChannelCache = (_a = pullFromCache([
7237
- 'messagePreviewChannel',
7238
- 'get',
7239
- message.channelId,
7240
- ])) === null || _a === void 0 ? void 0 : _a.data;
7241
- if (messagePreviewChannelCache &&
7242
- messagePreviewChannelCache.messagePreviewId === message.messageId) {
7243
- const subChannelCache = await getSubChannelCache(subChannelId);
7244
- pushToCache(['messagePreviewChannel', 'get', message.channelId], {
7245
- channelId,
7246
- creatorId,
7247
- messagePreviewId,
7248
- createdAt,
7249
- updatedAt,
7250
- subChannelId,
7251
- data,
7252
- dataType,
7253
- segment,
7254
- isDeleted,
7255
- subChannelUpdatedAt: subChannelCache.updatedAt,
7256
- subChannelName: messagePreviewChannelCache.subChannelName,
7257
- });
7812
+ async loadPrevPage() {
7813
+ try {
7814
+ if (this.paginationController instanceof PaginationNoPageController)
7815
+ return;
7816
+ const result = await this.paginationController.loadPreviousPage();
7817
+ if (!result)
7818
+ return;
7819
+ await this.persistModel(result);
7820
+ this.persistQueryStream({
7821
+ response: result,
7822
+ direction: "prev" /* Amity.LiveCollectionPageDirection.PREV */,
7823
+ });
7824
+ this.notifyChange({ origin: "server" /* Amity.LiveDataOrigin.SERVER */, loading: false });
7825
+ }
7826
+ catch (e) {
7827
+ this.notifyChange({ origin: "server" /* Amity.LiveDataOrigin.SERVER */, loading: false, error: e });
7828
+ }
7258
7829
  }
7259
- };
7260
- const handleSubChannelUpdated = async (subChannel) => {
7261
- var _a, _b, _c, _d;
7262
- const { channelId, subChannelId } = subChannel;
7263
- /** Channel Case */
7264
- const messagePreviewChannelCache = (_a = pullFromCache([
7265
- 'messagePreviewChannel',
7266
- 'get',
7267
- channelId,
7268
- ])) === null || _a === void 0 ? void 0 : _a.data;
7269
- if ((messagePreviewChannelCache === null || messagePreviewChannelCache === void 0 ? void 0 : messagePreviewChannelCache.subChannelId) === subChannelId) {
7270
- const subChannelCache = (_b = pullFromCache([
7271
- 'subChannel',
7272
- 'get',
7273
- subChannelId,
7274
- ])) === null || _b === void 0 ? void 0 : _b.data;
7275
- pushToCache(['messagePreviewChannel', 'get', channelId], Object.assign(Object.assign({}, messagePreviewChannelCache), { subChannelName: subChannelCache === null || subChannelCache === void 0 ? void 0 : subChannelCache.displayName, subChannelUpdatedAt: subChannelCache === null || subChannelCache === void 0 ? void 0 : subChannelCache.updatedAt }));
7830
+ shouldNotify(data) {
7831
+ const newData = data.map(convertGetterPropsToStatic).map(removeFunctionProperties);
7832
+ if (isEqual(this.snapshot, newData))
7833
+ return false;
7834
+ this.snapshot = newData;
7835
+ return true;
7276
7836
  }
7277
- /** SubChannel Case */
7278
- const messagePreviewSubChannelCache = (_c = pullFromCache([
7279
- 'messagePreviewSubChannel',
7280
- 'get',
7281
- subChannelId,
7282
- ])) === null || _c === void 0 ? void 0 : _c.data;
7283
- if (messagePreviewSubChannelCache &&
7284
- new Date(messagePreviewSubChannelCache.updatedAt).valueOf() >
7285
- new Date(subChannel.updatedAt).valueOf()) {
7286
- const subChannelCache = (_d = pullFromCache([
7287
- 'subChannel',
7288
- 'get',
7289
- subChannelId,
7290
- ])) === null || _d === void 0 ? void 0 : _d.data;
7291
- pushToCache(['messagePreviewSubChannel', 'get', subChannelId], Object.assign(Object.assign({}, messagePreviewSubChannelCache), { subChannelName: subChannelCache === null || subChannelCache === void 0 ? void 0 : subChannelCache.displayName, subChannelUpdatedAt: subChannelCache === null || subChannelCache === void 0 ? void 0 : subChannelCache.updatedAt }));
7837
+ getCacheKey() {
7838
+ return this.cacheKey;
7292
7839
  }
7840
+ }
7841
+
7842
+ /**
7843
+ * ```js
7844
+ * import { onLocalInvitationCreated } from '@amityco/ts-sdk'
7845
+ * const dispose = onLocalInvitationCreated(data => {
7846
+ * // ...
7847
+ * })
7848
+ * ```
7849
+ *
7850
+ * Fired when an {@link Amity.InvitationPayload} has been created
7851
+ *
7852
+ * @param callback The function to call when the event was fired
7853
+ * @returns an {@link Amity.Unsubscriber} function to stop listening
7854
+ *
7855
+ * @category Invitation Events
7856
+ */
7857
+ const onLocalInvitationCreated = (callback) => {
7858
+ const client = getActiveClient();
7859
+ const disposers = [
7860
+ createEventSubscriber(client, 'onLocalInvitationCreated', 'local.invitation.created', payload => callback(payload)),
7861
+ ];
7862
+ return () => {
7863
+ disposers.forEach(fn => fn());
7864
+ };
7293
7865
  };
7294
7866
 
7295
- function convertRawUserToInternalUser(rawUser) {
7296
- return Object.assign(Object.assign({}, rawUser), { isGlobalBanned: (rawUser === null || rawUser === void 0 ? void 0 : rawUser.isGlobalBan) || false });
7297
- }
7867
+ /**
7868
+ * ```js
7869
+ * import { onLocalInvitationUpdated } from '@amityco/ts-sdk'
7870
+ * const dispose = onLocalInvitationUpdated(data => {
7871
+ * // ...
7872
+ * })
7873
+ * ```
7874
+ *
7875
+ * Fired when an {@link Amity.InvitationPayload} has been updated
7876
+ *
7877
+ * @param callback The function to call when the event was fired
7878
+ * @returns an {@link Amity.Unsubscriber} function to stop listening
7879
+ *
7880
+ * @category Invitation Events
7881
+ */
7882
+ const onLocalInvitationUpdated = (callback) => {
7883
+ const client = getActiveClient();
7884
+ const disposers = [
7885
+ createEventSubscriber(client, 'onLocalInvitationUpdated', 'local.invitation.updated', payload => callback(payload)),
7886
+ ];
7887
+ return () => {
7888
+ disposers.forEach(fn => fn());
7889
+ };
7890
+ };
7298
7891
 
7299
- const MARKER_INCLUDED_CHANNEL_TYPE = ['broadcast', 'conversation', 'community'];
7300
- const isUnreadCountSupport = ({ type }) => MARKER_INCLUDED_CHANNEL_TYPE.includes(type);
7301
- function convertFromRaw(channel, options = { isMessagePreviewUpdated: true }) {
7302
- var _a;
7303
- let { messagePreviewId } = channel;
7304
- const messagePreviewChannelCache = (_a = pullFromCache([
7305
- 'messagePreviewChannel',
7306
- 'get',
7307
- channel.channelId,
7308
- ])) === null || _a === void 0 ? void 0 : _a.data;
7309
- if ((messagePreviewChannelCache === null || messagePreviewChannelCache === void 0 ? void 0 : messagePreviewChannelCache.messagePreviewId) && !options.isMessagePreviewUpdated) {
7310
- messagePreviewId = messagePreviewChannelCache.messagePreviewId;
7892
+ /**
7893
+ * ```js
7894
+ * import { onLocalInvitationDeleted } from '@amityco/ts-sdk'
7895
+ * const dispose = onLocalInvitationDeleted(data => {
7896
+ * // ...
7897
+ * })
7898
+ * ```
7899
+ *
7900
+ * Fired when an {@link Amity.InvitationPayload} has been deleted
7901
+ *
7902
+ * @param callback The function to call when the event was fired
7903
+ * @returns an {@link Amity.Unsubscriber} function to stop listening
7904
+ *
7905
+ * @category Invitation Events
7906
+ */
7907
+ const onLocalInvitationDeleted = (callback) => {
7908
+ const client = getActiveClient();
7909
+ const disposers = [
7910
+ createEventSubscriber(client, 'onLocalInvitationDeleted', 'local.invitation.deleted', payload => callback(payload)),
7911
+ ];
7912
+ return () => {
7913
+ disposers.forEach(fn => fn());
7914
+ };
7915
+ };
7916
+
7917
+ class InvitationsLiveCollectionController extends LiveCollectionController {
7918
+ constructor(query, callback) {
7919
+ const queryStreamId = hash__default["default"](query);
7920
+ const cacheKey = ['invitation', 'collection', queryStreamId];
7921
+ const paginationController = new InvitationsPaginationController(query);
7922
+ super(paginationController, queryStreamId, cacheKey, callback);
7923
+ this.query = query;
7924
+ this.queryStreamController = new InvitationsQueryStreamController(this.query, this.cacheKey, this.notifyChange.bind(this), prepareInvitationPayload);
7925
+ this.callback = callback.bind(this);
7926
+ this.loadPage({ initial: true });
7311
7927
  }
7312
- return Object.assign(Object.assign({}, channel), { defaultSubChannelId: channel.channelInternalId, isUnreadCountSupport: isUnreadCountSupport(channel), messagePreviewId });
7313
- }
7314
- const preUpdateChannelCache = (rawPayload, options = { isMessagePreviewUpdated: true }) => {
7315
- ingestInCache({
7316
- channels: rawPayload.channels.map(channel => convertFromRaw(channel, { isMessagePreviewUpdated: options.isMessagePreviewUpdated })),
7317
- });
7318
- };
7319
- const updateChannelUnread = ({ currentUserId, channels, channelUsers, }) => {
7320
- for (let i = 0; i < channels.length; i += 1) {
7321
- const cacheKey = ['channelUnread', 'get', channels[i].channelId];
7322
- const channelUser = channelUsers.find(channelUser => channelUser.channelId === channels[i].channelId && channelUser.userId === currentUserId);
7323
- let unreadCount = 0;
7324
- let readToSegment = null;
7325
- let lastMentionedSegment = null;
7326
- let isMentioned = false;
7327
- if (channelUser) {
7328
- readToSegment = channelUser.readToSegment;
7329
- lastMentionedSegment = channelUser.lastMentionedSegment;
7330
- unreadCount = Math.max(channels[i].messageCount - readToSegment, 0);
7331
- isMentioned = lastMentionedSegment > readToSegment;
7928
+ setup() {
7929
+ var _a;
7930
+ const collection = (_a = pullFromCache(this.cacheKey)) === null || _a === void 0 ? void 0 : _a.data;
7931
+ if (!collection) {
7932
+ pushToCache(this.cacheKey, {
7933
+ data: [],
7934
+ params: this.query,
7935
+ });
7332
7936
  }
7333
- const cacheChannelUnread = {
7334
- channelId: channels[i].channelId,
7335
- lastSegment: channels[i].messageCount,
7336
- readToSegment,
7337
- lastMentionedSegment,
7338
- unreadCount,
7339
- isMentioned,
7340
- isDeleted: channels[i].isDeleted || false,
7341
- };
7342
- pushToCache(cacheKey, cacheChannelUnread);
7343
7937
  }
7344
- };
7345
- const prepareChannelPayload = async (rawPayload, options = { isMessagePreviewUpdated: true }) => {
7346
- const client = getActiveClient();
7347
- const networkPreviewSetting = await client.getMessagePreviewSetting(false);
7348
- if (options.isMessagePreviewUpdated &&
7349
- networkPreviewSetting !== "no-message-preview" /* Amity.MessagePreviewSetting.NO_MESSAGE_PREVIEW */ &&
7350
- rawPayload.messagePreviews &&
7351
- rawPayload.messagePreviews.length > 0) {
7352
- updateChannelMessagePreviewCache(rawPayload);
7938
+ async persistModel(queryPayload) {
7939
+ await this.queryStreamController.saveToMainDB(queryPayload);
7353
7940
  }
7354
- if (client.useLegacyUnreadCount) {
7355
- updateChannelUnread({
7356
- channels: rawPayload.channels,
7357
- channelUsers: rawPayload.channelUsers,
7358
- currentUserId: client.userId,
7941
+ persistQueryStream({ response, direction, refresh, }) {
7942
+ this.queryStreamController.appendToQueryStream(response, direction, refresh);
7943
+ }
7944
+ startSubscription() {
7945
+ return this.queryStreamController.subscribeRTE([
7946
+ {
7947
+ fn: onLocalInvitationCreated,
7948
+ action: InvitationActionsEnum.OnLocalInvitationCreated,
7949
+ },
7950
+ {
7951
+ fn: onLocalInvitationUpdated,
7952
+ action: InvitationActionsEnum.OnLocalInvitationUpdated,
7953
+ },
7954
+ {
7955
+ fn: onLocalInvitationDeleted,
7956
+ action: InvitationActionsEnum.OnLocalInvitationDeleted,
7957
+ },
7958
+ ]);
7959
+ }
7960
+ notifyChange({ origin, loading, error }) {
7961
+ var _a, _b;
7962
+ const collection = (_a = pullFromCache(this.cacheKey)) === null || _a === void 0 ? void 0 : _a.data;
7963
+ if (!collection)
7964
+ return;
7965
+ const data = this.applyFilter((_b = collection.data
7966
+ .map(id => pullFromCache(['invitation', 'get', id]))
7967
+ .filter(isNonNullable)
7968
+ .map(({ data }) => invitationLinkedObject(data))) !== null && _b !== void 0 ? _b : []);
7969
+ if (!this.shouldNotify(data) && origin === 'event')
7970
+ return;
7971
+ this.callback({
7972
+ onNextPage: () => this.loadPage({ direction: "next" /* Amity.LiveCollectionPageDirection.NEXT */ }),
7973
+ data,
7974
+ hasNextPage: !!this.paginationController.getNextToken(),
7975
+ loading,
7976
+ error,
7359
7977
  });
7360
7978
  }
7361
- else {
7362
- const markerIds = rawPayload.channels
7363
- // filter channel by type. Only conversation, community and broadcast type are included.
7364
- .filter(isUnreadCountSupport)
7365
- .map(({ channelInternalId }) => channelInternalId);
7366
- if (markerIds.length > 0) {
7367
- // since the get markers method requires a channel cache to function with the reducer.
7368
- preUpdateChannelCache(rawPayload, {
7369
- isMessagePreviewUpdated: options.isMessagePreviewUpdated,
7370
- });
7371
- try {
7372
- await getChannelMarkers(markerIds);
7373
- }
7374
- catch (e) {
7375
- // empty block (from the spec, allow marker fetch to fail without having to do anything)
7376
- }
7979
+ applyFilter(data) {
7980
+ let invitations = data;
7981
+ if (this.query.targetId) {
7982
+ invitations = invitations.filter(invitation => invitation.targetId === this.query.targetId);
7377
7983
  }
7378
- }
7379
- // convert raw channel to internal channel
7380
- const channels = rawPayload.channels.map(payload => convertFromRaw(payload, { isMessagePreviewUpdated: options.isMessagePreviewUpdated }));
7381
- // convert raw channel user to membership (add user object)
7382
- const channelUsers = rawPayload.channelUsers.map(channelUser => {
7383
- return convertRawMembershipToMembership(channelUser);
7384
- });
7385
- const users = rawPayload.users.map(convertRawUserToInternalUser);
7386
- const restRawPayload = __rest(rawPayload, ["messageFeedsInfo", "messagePreviews"]);
7387
- return Object.assign(Object.assign({}, restRawPayload), { users,
7388
- channels,
7389
- channelUsers });
7390
- };
7984
+ if (this.query.statuses) {
7985
+ invitations = invitations.filter(invitation => { var _a; return (_a = this.query.statuses) === null || _a === void 0 ? void 0 : _a.includes(invitation.status); });
7986
+ }
7987
+ if (this.query.targetType) {
7988
+ invitations = invitations.filter(invitation => invitation.targetType === this.query.targetType);
7989
+ }
7990
+ if (this.query.type) {
7991
+ invitations = invitations.filter(invitation => invitation.type === this.query.type);
7992
+ }
7993
+ const sortFn = (() => {
7994
+ switch (this.query.sortBy) {
7995
+ case 'firstCreated':
7996
+ return sortByFirstCreated;
7997
+ case 'lastCreated':
7998
+ return sortByLastCreated;
7999
+ default:
8000
+ return sortByLastCreated;
8001
+ }
8002
+ })();
8003
+ invitations = invitations.sort(sortFn);
8004
+ return invitations;
8005
+ }
8006
+ }
7391
8007
 
7392
8008
  /**
7393
- * ```js
7394
- * import { getSubChannelMarkers } from '@amityco/ts-sdk'
7395
- * const subChannelMarkers = await getSubChannelMarkers(['sch1', 'sch2'])
7396
- * ```
7397
- *
7398
- * Fetches a paginable list of {@link Amity.SubChannelMarker} objects
8009
+ * Get invitations
7399
8010
  *
7400
- * @param messageFeedIds the feed IDs of the {@link Amity.RawSubChannel} marker to fetch
7401
- * @param page
7402
- * @returns A page of {@link Amity.SubChannelMarker} objects
8011
+ * @param params the query parameters
8012
+ * @param callback the callback to be called when the invitations are updated
8013
+ * @returns invitations
7403
8014
  *
7404
- * @category Channel API
7405
- * @async
7406
- * @private
7407
- */
7408
- const getUserMessageFeedMakers = async (channelIds) => {
7409
- const client = getActiveClient();
7410
- client.log('channel/getUserMessageFeedMakers', channelIds);
7411
- const { data } = await client.http.get(`/api/v1/markers/user-message-feed`, {
7412
- params: {
7413
- channelIds,
7414
- },
7415
- });
7416
- fireEvent('local.userMessageFeedMarker.fetched', { userMessageFeedMarker: data });
7417
- return data;
7418
- };
7419
-
7420
- const prepareUnreadCountInfo = async (rawPayload) => {
7421
- const client = getActiveClient();
7422
- // if consistent mode is enabled, persist the unread count info to the cache
7423
- // Marker service API uses channelInternalId as channelId
7424
- const queryPayload = await getUserMessageFeedMakers(rawPayload.channels.map(({ channelInternalId }) => channelInternalId));
7425
- const { feedMarkers, userFeedMarkers } = queryPayload;
7426
- persistUnreadCountInfo({
7427
- feedMarkers,
7428
- userFeedMarkers,
7429
- });
7430
- client.log('channel/prepareUnreadCountInfo', rawPayload.channels);
7431
- };
7432
-
7433
- const getCachedMarker$1 = (entityId) => {
7434
- var _a;
7435
- const key = {
7436
- entityId,
7437
- userId: getActiveUser()._id,
7438
- };
7439
- return (_a = pullFromCache([
7440
- 'channelMarker',
7441
- 'get',
7442
- getResolver('channelMarker')(key),
7443
- ])) === null || _a === void 0 ? void 0 : _a.data;
7444
- };
7445
- const getUnreadInfoCached$1 = (channelId) => {
7446
- var _a;
7447
- return (_a = pullFromCache(['channelUnreadInfo', 'get', channelId])) === null || _a === void 0 ? void 0 : _a.data;
7448
- };
7449
- /**
7450
- * The function use to get value of hasMentioned or isMentioned field.
7451
- * function will get the value from marker params first, if there is no hasMentioned field, will look in to the cache.
8015
+ * @category Invitation Live Collection
7452
8016
  *
7453
- * If consistent mode is enabled, the function will return the value from the channelUnreadCountInfo cache.
7454
- * If not, the function will return the value from the channelMarker cache.
7455
- * If not found in the both cache, use `false` as defaul value.
7456
8017
  */
7457
- const getChannelIsMentioned = (channel, marker) => {
7458
- var _a, _b, _c, _d;
7459
- const client = getActiveClient();
7460
- if (client.isUnreadCountEnabled && client.getMarkerSyncConsistentMode()) {
7461
- return (_b = (_a = getUnreadInfoCached$1(channel.channelPublicId)) === null || _a === void 0 ? void 0 : _a.isMentioned) !== null && _b !== void 0 ? _b : false;
8018
+ const getInvitations = (params, callback, config) => {
8019
+ const { log, cache } = getActiveClient();
8020
+ if (!cache) {
8021
+ console.log(ENABLE_CACHE_MESSAGE);
7462
8022
  }
7463
- return (marker === null || marker === void 0 ? void 0 : marker.hasMentioned) !== undefined
7464
- ? marker === null || marker === void 0 ? void 0 : marker.hasMentioned
7465
- : (_d = (_c = getCachedMarker$1(channel.channelPublicId)) === null || _c === void 0 ? void 0 : _c.hasMentioned) !== null && _d !== void 0 ? _d : false;
7466
- };
7467
-
7468
- const getCachedMarker = (entityId) => {
7469
- var _a;
7470
- const key = {
7471
- entityId,
7472
- userId: getActiveUser()._id,
8023
+ const timestamp = Date.now();
8024
+ log(`getInvitations: (tmpid: ${timestamp}) > listen`);
8025
+ const invitationsLiveCollection = new InvitationsLiveCollectionController(params, callback);
8026
+ const disposers = invitationsLiveCollection.startSubscription();
8027
+ const cacheKey = invitationsLiveCollection.getCacheKey();
8028
+ disposers.push(() => {
8029
+ dropFromCache(cacheKey);
8030
+ });
8031
+ return () => {
8032
+ log(`getInvitations (tmpid: ${timestamp}) > dispose`);
8033
+ disposers.forEach(fn => fn());
7473
8034
  };
7474
- return (_a = pullFromCache([
7475
- 'channelMarker',
7476
- 'get',
7477
- getResolver('channelMarker')(key),
7478
- ])) === null || _a === void 0 ? void 0 : _a.data;
7479
- };
7480
- const getUnreadInfoCached = (channelId) => {
7481
- var _a;
7482
- return (_a = pullFromCache(['channelUnreadInfo', 'get', channelId])) === null || _a === void 0 ? void 0 : _a.data;
7483
- };
7484
- /**
7485
- * The function use to get value of unreadCount field.
7486
- * function will get the value from marker params first, if there is no hasMentioned field, will look in to the cache.
7487
- *
7488
- * If consistent mode is enabled, the function will return the value from the channelUnreadCountInfo cache.
7489
- * If not, the function will return the value from the channelMarker cache.
7490
- * If not found in the both cache, use `0` as defaul value.
7491
- */
7492
- const getSubChannelsUnreadCount = (channel, marker) => {
7493
- var _a, _b, _c, _d, _e;
7494
- const client = getActiveClient();
7495
- if (client.isUnreadCountEnabled && client.getMarkerSyncConsistentMode()) {
7496
- // Marker service API uses channelInternalId as channelId
7497
- return (_b = (_a = getUnreadInfoCached(channel.channelInternalId)) === null || _a === void 0 ? void 0 : _a.unreadCount) !== null && _b !== void 0 ? _b : 0;
7498
- }
7499
- if (marker === null || marker === void 0 ? void 0 : marker.isDeleted) {
7500
- // NOTE: This is a temporary solution to handle the channel marker when the user is forced to
7501
- // leave the channel because currently backend can't handle this, so every time a user is banned
7502
- // from a channel or the channel is deleted the channel's unread count will reset to zero
7503
- return 0;
7504
- }
7505
- return (_e = (_c = marker === null || marker === void 0 ? void 0 : marker.unreadCount) !== null && _c !== void 0 ? _c : (_d = getCachedMarker(channel.channelInternalId)) === null || _d === void 0 ? void 0 : _d.unreadCount) !== null && _e !== void 0 ? _e : 0;
7506
8035
  };
7507
8036
 
7508
- const getLegacyChannelUnread = (channelId) => {
7509
- var _a;
7510
- return (_a = pullFromCache(['channelUnread', 'get', channelId])) === null || _a === void 0 ? void 0 : _a.data;
8037
+ const communityLinkedObject = (community) => {
8038
+ return Object.assign(Object.assign({}, community), { createInvitations: async (userIds) => {
8039
+ await createInvitations({
8040
+ type: "communityMemberInvite" /* InvitationTypeEnum.CommunityMemberInvite */,
8041
+ targetType: 'community',
8042
+ targetId: community.communityId,
8043
+ userIds,
8044
+ });
8045
+ }, getMemberInvitations: (params, callback) => {
8046
+ return getInvitations(Object.assign(Object.assign({}, params), { targetId: community.communityId, targetType: 'community', type: "communityMemberInvite" /* InvitationTypeEnum.CommunityMemberInvite */ }), callback);
8047
+ }, getInvitation: async () => {
8048
+ const { data } = await getInvitation('community', community.communityId);
8049
+ return data;
8050
+ } });
7511
8051
  };
7512
8052
 
7513
- const constructChannelDynamicValue = (channel) => {
7514
- const client = getActiveClient();
7515
- const rest = __rest(channel, ["messageCount"]);
7516
- return shallowClone(rest, {
7517
- get unreadCount() {
7518
- var _a, _b;
7519
- return (_b = (_a = getLegacyChannelUnread(rest.channelId)) === null || _a === void 0 ? void 0 : _a.unreadCount) !== null && _b !== void 0 ? _b : 0;
7520
- },
7521
- get subChannelsUnreadCount() {
7522
- return getSubChannelsUnreadCount(rest);
7523
- },
7524
- get isMentioned() {
7525
- var _a, _b;
7526
- if (client.useLegacyUnreadCount)
7527
- return (_b = (_a = getLegacyChannelUnread(rest.channelId)) === null || _a === void 0 ? void 0 : _a.isMentioned) !== null && _b !== void 0 ? _b : false;
7528
- return getChannelIsMentioned(rest);
7529
- },
7530
- });
8053
+ const LinkedObject = {
8054
+ ad: adLinkedObject,
8055
+ comment: commentLinkedObject,
8056
+ post: postLinkedObject,
8057
+ user: userLinkedObject,
8058
+ category: categoryLinkedObject,
8059
+ stream: streamLinkedObject,
8060
+ story: storyLinkedObject,
8061
+ storyTarget: storyTargetLinkedObject,
8062
+ message: messageLinkedObject,
8063
+ reactor: reactorLinkedObject,
8064
+ channel: channelLinkedObject,
8065
+ pinnedPost: pinnedPostLinkedObject,
8066
+ notificationTray: notificationTrayLinkedObject,
8067
+ community: communityLinkedObject,
8068
+ invitation: invitationLinkedObject,
7531
8069
  };
7532
8070
 
7533
8071
  const constructChannelObject = (channel) => {
@@ -10249,38 +10787,6 @@ const onMessageMarked = (callback) => {
10249
10787
  return createEventSubscriber(client, 'messageMarker/onMessageMarked', 'marker.marked-message', filter);
10250
10788
  };
10251
10789
 
10252
- function isObject(value) {
10253
- return typeof value === 'object' && value !== null;
10254
- }
10255
- /**
10256
- * convert all object getter property to static value
10257
- */
10258
- const convertGetterPropsToStatic = (obj) => {
10259
- if (!isObject(obj)) {
10260
- return obj;
10261
- }
10262
- const entries = Object.entries(obj).map(([key, value]) => {
10263
- const descriptor = Object.getOwnPropertyDescriptor(obj, key);
10264
- if (typeof (descriptor === null || descriptor === void 0 ? void 0 : descriptor.get) === 'function') {
10265
- return [key, descriptor.get.call(obj)];
10266
- }
10267
- return [key, value];
10268
- });
10269
- return Object.fromEntries(entries);
10270
- };
10271
- const removeFunctionProperties = (obj) => {
10272
- if (!isObject(obj)) {
10273
- return obj;
10274
- }
10275
- const entries = Object.entries(obj).map(([key, value]) => {
10276
- if (typeof value === 'function') {
10277
- return [key, undefined];
10278
- }
10279
- return [key, value];
10280
- });
10281
- return Object.fromEntries(entries);
10282
- };
10283
-
10284
10790
  /**
10285
10791
  *
10286
10792
  * ```js
@@ -10894,68 +11400,16 @@ const onLocalFollowRequestAccepted = (callback) => createLocalFollowEventSubscri
10894
11400
 
10895
11401
  const onLocalFollowRequestDeclined = (callback) => createLocalFollowEventSubscriber('local.follow.requestDeclined', callback);
10896
11402
 
10897
- class PaginationController {
10898
- constructor(queryParams) {
10899
- const { http } = getActiveClient();
10900
- this.queryParams = queryParams;
10901
- this.http = http;
10902
- }
10903
- loadFirstPage() {
10904
- return this.onFetch("first" /* Amity.LiveCollectionPageDirection.FIRST */);
10905
- }
10906
- loadNextPage() {
10907
- return this.onFetch("next" /* Amity.LiveCollectionPageDirection.NEXT */);
10908
- }
10909
- loadPreviousPage() {
10910
- return this.onFetch("prev" /* Amity.LiveCollectionPageDirection.PREV */);
10911
- }
10912
- async onFetch(direction = "first" /* Amity.LiveCollectionPageDirection.FIRST */) {
10913
- var _a, _b, _c, _d;
10914
- if (direction === 'prev' && !this.previousToken)
10915
- return;
10916
- if (direction === 'next' && !this.nextToken)
10917
- return;
10918
- let token;
10919
- if (direction === 'prev')
10920
- token = this.previousToken;
10921
- if (direction === 'next')
10922
- token = this.nextToken;
10923
- const queryResponse = await this.getRequest(this.queryParams, token);
10924
- if (direction === 'first') {
10925
- this.nextToken = (_a = queryResponse.paging) === null || _a === void 0 ? void 0 : _a.next;
10926
- this.previousToken = (_b = queryResponse.paging) === null || _b === void 0 ? void 0 : _b.previous;
10927
- }
10928
- if (direction === 'prev')
10929
- this.previousToken = (_c = queryResponse.paging) === null || _c === void 0 ? void 0 : _c.previous;
10930
- if (direction === 'next')
10931
- this.nextToken = (_d = queryResponse.paging) === null || _d === void 0 ? void 0 : _d.next;
10932
- return queryResponse;
10933
- }
10934
- getNextToken() {
10935
- return this.nextToken;
10936
- }
10937
- getPrevToken() {
10938
- return this.previousToken;
10939
- }
10940
- }
10941
-
10942
11403
  class FollowerPaginationController extends PaginationController {
10943
11404
  async getRequest(queryParams, token) {
10944
11405
  const { limit = COLLECTION_DEFAULT_PAGINATION_LIMIT, userId } = queryParams, params = __rest(queryParams, ["limit", "userId"]);
10945
11406
  const options = token ? { token } : { limit };
10946
11407
  const client = getActiveClient();
10947
11408
  const path = client.userId === userId ? `/api/v4/me/followers` : `/api/v4/users/${userId}/followers`;
10948
- const { data: queryResponse } = await this.http.get(path, {
10949
- params: Object.assign(Object.assign({}, params), { options, isDeleted: false }),
10950
- });
10951
- return queryResponse;
10952
- }
10953
- }
10954
-
10955
- class QueryStreamController {
10956
- constructor(query, cacheKey) {
10957
- this.query = query;
10958
- this.cacheKey = cacheKey;
11409
+ const { data: queryResponse } = await this.http.get(path, {
11410
+ params: Object.assign(Object.assign({}, params), { options, isDeleted: false }),
11411
+ });
11412
+ return queryResponse;
10959
11413
  }
10960
11414
  }
10961
11415
 
@@ -11026,109 +11480,6 @@ class FollowerQueryStreamController extends QueryStreamController {
11026
11480
  }
11027
11481
  }
11028
11482
 
11029
- class PaginationNoPageController {
11030
- constructor(queryParams) {
11031
- const { http } = getActiveClient();
11032
- this.queryParams = queryParams;
11033
- this.http = http;
11034
- }
11035
- async onFetch() {
11036
- const queryResponse = await this.getRequest(this.queryParams);
11037
- return queryResponse;
11038
- }
11039
- }
11040
-
11041
- class LiveCollectionController {
11042
- constructor(paginationController, queryStreamId, cacheKey, callback) {
11043
- this.paginationController = paginationController;
11044
- this.queryStreamId = queryStreamId;
11045
- this.cacheKey = cacheKey;
11046
- this.callback = callback;
11047
- }
11048
- async refresh() {
11049
- try {
11050
- let result;
11051
- if (this.paginationController instanceof PaginationNoPageController) {
11052
- result = await this.paginationController.onFetch();
11053
- }
11054
- else {
11055
- result = await this.paginationController.loadFirstPage();
11056
- }
11057
- if (!result)
11058
- return;
11059
- await this.persistModel(result);
11060
- this.persistQueryStream({
11061
- response: result,
11062
- direction: "next" /* Amity.LiveCollectionPageDirection.NEXT */,
11063
- refresh: true,
11064
- });
11065
- this.notifyChange({ origin: "server" /* Amity.LiveDataOrigin.SERVER */, loading: false });
11066
- }
11067
- catch (e) {
11068
- this.notifyChange({ origin: "server" /* Amity.LiveDataOrigin.SERVER */, loading: false, error: e });
11069
- }
11070
- }
11071
- loadPage({ initial = false, direction = "next" /* Amity.LiveCollectionPageDirection.NEXT */, }) {
11072
- this.setup();
11073
- this.notifyChange({ origin: "local" /* Amity.LiveDataOrigin.LOCAL */, loading: true });
11074
- if (initial) {
11075
- this.refresh();
11076
- }
11077
- else if (direction === "prev" /* Amity.LiveCollectionPageDirection.PREV */) {
11078
- this.loadPrevPage();
11079
- }
11080
- else if (direction === "next" /* Amity.LiveCollectionPageDirection.NEXT */) {
11081
- this.loadNextPage();
11082
- }
11083
- }
11084
- async loadNextPage() {
11085
- try {
11086
- if (this.paginationController instanceof PaginationNoPageController)
11087
- return;
11088
- const result = await this.paginationController.loadNextPage();
11089
- if (!result)
11090
- return;
11091
- await this.persistModel(result);
11092
- this.persistQueryStream({
11093
- response: result,
11094
- direction: "next" /* Amity.LiveCollectionPageDirection.NEXT */,
11095
- });
11096
- this.notifyChange({ origin: "server" /* Amity.LiveDataOrigin.SERVER */, loading: false });
11097
- }
11098
- catch (e) {
11099
- this.notifyChange({ origin: "server" /* Amity.LiveDataOrigin.SERVER */, loading: false, error: e });
11100
- }
11101
- }
11102
- async loadPrevPage() {
11103
- try {
11104
- if (this.paginationController instanceof PaginationNoPageController)
11105
- return;
11106
- const result = await this.paginationController.loadPreviousPage();
11107
- if (!result)
11108
- return;
11109
- await this.persistModel(result);
11110
- this.persistQueryStream({
11111
- response: result,
11112
- direction: "prev" /* Amity.LiveCollectionPageDirection.PREV */,
11113
- });
11114
- this.notifyChange({ origin: "server" /* Amity.LiveDataOrigin.SERVER */, loading: false });
11115
- }
11116
- catch (e) {
11117
- this.notifyChange({ origin: "server" /* Amity.LiveDataOrigin.SERVER */, loading: false, error: e });
11118
- }
11119
- }
11120
- shouldNotify(data) {
11121
- const newData = data.map(convertGetterPropsToStatic).map(removeFunctionProperties);
11122
- if (isEqual(this.snapshot, newData))
11123
- return false;
11124
- this.snapshot = newData;
11125
- return true;
11126
- }
11127
- getCacheKey() {
11128
- return this.cacheKey;
11129
- }
11130
- }
11131
-
11132
11483
  const onFollowerUserDeleted = ({ userId }) => (callback) => {
11133
11484
  const client = getActiveClient();
11134
11485
  const filter = (data) => {
@@ -18727,12 +19078,15 @@ const saveCommunityUsers = (communities, communityUsers) => {
18727
19078
  * @category Community API
18728
19079
  * @async
18729
19080
  */
18730
- const getCommunities$1 = async (communityIds) => {
19081
+ const getCommunities$1 = async (communityIds, includeDiscoverablePrivateCommunity) => {
18731
19082
  const client = getActiveClient();
18732
19083
  client.log('community/getCommunities', communityIds);
18733
19084
  // API-FIX: endpoint should not be /list, parameters should be querystring.
18734
19085
  const { data: payload } = await client.http.get(`/api/v3/communities/list`, {
18735
- params: { communityIds },
19086
+ params: {
19087
+ communityIds,
19088
+ includeDiscoverablePrivateCommunity: includeDiscoverablePrivateCommunity !== null && includeDiscoverablePrivateCommunity !== void 0 ? includeDiscoverablePrivateCommunity : true,
19089
+ },
18736
19090
  });
18737
19091
  const data = prepareCommunityPayload(payload);
18738
19092
  const cachedAt = client.cache && Date.now();
@@ -18819,7 +19173,7 @@ const createCommunity = async (bundle) => {
18819
19173
  /**
18820
19174
  * ```js
18821
19175
  * import { updateCommunity } from '@amityco/ts-sdk'
18822
- * const updated = await updateCommunity(communityId, { displayName: 'foobar' })
19176
+ * const updated = await updateCommunity(communityId, { displayName: 'foobar', isDiscoverable: true, requiresJoinApproval: false })
18823
19177
  * ```
18824
19178
  *
18825
19179
  * Updates an {@link Amity.Community}
@@ -18903,7 +19257,7 @@ getCommunity$1.locally = (communityId) => {
18903
19257
  if (!cached)
18904
19258
  return;
18905
19259
  return {
18906
- data: cached.data,
19260
+ data: LinkedObject.community(cached.data),
18907
19261
  cachedAt: cached.cachedAt,
18908
19262
  };
18909
19263
  };
@@ -26628,34 +26982,204 @@ var index$1 = /*#__PURE__*/Object.freeze({
26628
26982
  onNotificationTraySeenUpdated: onNotificationTraySeenUpdated
26629
26983
  });
26630
26984
 
26985
+ class MyInvitationsPaginationController extends PaginationController {
26986
+ async getRequest(queryParams, token) {
26987
+ const { limit = COLLECTION_DEFAULT_PAGINATION_LIMIT } = queryParams, params = __rest(queryParams, ["limit"]);
26988
+ const options = token ? { token } : { limit };
26989
+ const { data } = await this.http.get('/api/v1/invitations/me', { params: Object.assign(Object.assign({}, params), { options }) });
26990
+ await getCommunities$1(data.invitations.map(invitation => invitation.targetId));
26991
+ return data;
26992
+ }
26993
+ }
26994
+
26995
+ class MyInvitationsQueryStreamController extends QueryStreamController {
26996
+ constructor(query, cacheKey, notifyChange, preparePayload) {
26997
+ super(query, cacheKey);
26998
+ this.notifyChange = notifyChange;
26999
+ this.preparePayload = preparePayload;
27000
+ }
27001
+ async saveToMainDB(response) {
27002
+ const processedPayload = await this.preparePayload(response);
27003
+ const client = getActiveClient();
27004
+ const cachedAt = client.cache && Date.now();
27005
+ if (client.cache) {
27006
+ ingestInCache(processedPayload, { cachedAt });
27007
+ }
27008
+ }
27009
+ appendToQueryStream(response, direction, refresh = false) {
27010
+ var _a, _b;
27011
+ if (refresh) {
27012
+ pushToCache(this.cacheKey, {
27013
+ data: response.invitations.map(getResolver('invitation')),
27014
+ });
27015
+ }
27016
+ else {
27017
+ const collection = (_a = pullFromCache(this.cacheKey)) === null || _a === void 0 ? void 0 : _a.data;
27018
+ const invitations = (_b = collection === null || collection === void 0 ? void 0 : collection.data) !== null && _b !== void 0 ? _b : [];
27019
+ pushToCache(this.cacheKey, Object.assign(Object.assign({}, collection), { data: [
27020
+ ...new Set([...invitations, ...response.invitations.map(getResolver('invitation'))]),
27021
+ ] }));
27022
+ }
27023
+ }
27024
+ reactor(action) {
27025
+ return (invitations) => {
27026
+ var _a;
27027
+ const collection = (_a = pullFromCache(this.cacheKey)) === null || _a === void 0 ? void 0 : _a.data;
27028
+ if (!collection)
27029
+ return;
27030
+ if (action === InvitationActionsEnum.OnLocalInvitationUpdated) {
27031
+ const isExist = collection.data.find(id => id === invitations[0].invitationId);
27032
+ if (!isExist)
27033
+ return;
27034
+ }
27035
+ if (action === InvitationActionsEnum.OnLocalInvitationCreated) {
27036
+ const client = getActiveClient();
27037
+ const myInvitations = invitations.filter(invitation => invitation.invitedUserId === client.userId);
27038
+ collection.data = [
27039
+ ...new Set([
27040
+ ...myInvitations.map(invitation => invitation.invitationId),
27041
+ ...collection.data,
27042
+ ]),
27043
+ ];
27044
+ }
27045
+ if (action === InvitationActionsEnum.OnLocalInvitationDeleted) {
27046
+ collection.data = collection.data.filter(id => id !== invitations[0].invitationId);
27047
+ }
27048
+ pushToCache(this.cacheKey, collection);
27049
+ this.notifyChange({ origin: "event" /* Amity.LiveDataOrigin.EVENT */, loading: false });
27050
+ };
27051
+ }
27052
+ subscribeRTE(createSubscriber) {
27053
+ return createSubscriber.map(subscriber => subscriber.fn(this.reactor(subscriber.action)));
27054
+ }
27055
+ }
27056
+
27057
+ class MyInvitationsLiveCollectionController extends LiveCollectionController {
27058
+ constructor(query, callback) {
27059
+ const queryStreamId = hash__default["default"](query);
27060
+ const cacheKey = ['invitation', 'collection', queryStreamId];
27061
+ const paginationController = new MyInvitationsPaginationController(query);
27062
+ super(paginationController, queryStreamId, cacheKey, callback);
27063
+ this.query = query;
27064
+ this.queryStreamController = new MyInvitationsQueryStreamController(this.query, this.cacheKey, this.notifyChange.bind(this), prepareMyInvitationsPayload);
27065
+ this.callback = callback.bind(this);
27066
+ this.loadPage({ initial: true });
27067
+ }
27068
+ setup() {
27069
+ var _a;
27070
+ const collection = (_a = pullFromCache(this.cacheKey)) === null || _a === void 0 ? void 0 : _a.data;
27071
+ if (!collection) {
27072
+ pushToCache(this.cacheKey, {
27073
+ data: [],
27074
+ params: this.query,
27075
+ });
27076
+ }
27077
+ }
27078
+ async persistModel(queryPayload) {
27079
+ await this.queryStreamController.saveToMainDB(queryPayload);
27080
+ }
27081
+ persistQueryStream({ response, direction, refresh, }) {
27082
+ this.queryStreamController.appendToQueryStream(response, direction, refresh);
27083
+ }
27084
+ startSubscription() {
27085
+ return this.queryStreamController.subscribeRTE([
27086
+ {
27087
+ fn: onLocalInvitationCreated,
27088
+ action: InvitationActionsEnum.OnLocalInvitationCreated,
27089
+ },
27090
+ {
27091
+ fn: onLocalInvitationUpdated,
27092
+ action: InvitationActionsEnum.OnLocalInvitationUpdated,
27093
+ },
27094
+ {
27095
+ fn: onLocalInvitationDeleted,
27096
+ action: InvitationActionsEnum.OnLocalInvitationDeleted,
27097
+ },
27098
+ ]);
27099
+ }
27100
+ notifyChange({ origin, loading, error }) {
27101
+ var _a, _b;
27102
+ const collection = (_a = pullFromCache(this.cacheKey)) === null || _a === void 0 ? void 0 : _a.data;
27103
+ if (!collection)
27104
+ return;
27105
+ const data = this.applyFilter((_b = collection.data
27106
+ .map(id => pullFromCache(['invitation', 'get', id]))
27107
+ .filter(isNonNullable)
27108
+ .map(({ data }) => invitationLinkedObject(data))) !== null && _b !== void 0 ? _b : []);
27109
+ if (!this.shouldNotify(data) && origin === 'event')
27110
+ return;
27111
+ this.callback({
27112
+ onNextPage: () => this.loadPage({ direction: "next" /* Amity.LiveCollectionPageDirection.NEXT */ }),
27113
+ data,
27114
+ hasNextPage: !!this.paginationController.getNextToken(),
27115
+ loading,
27116
+ error,
27117
+ });
27118
+ }
27119
+ applyFilter(data) {
27120
+ let invitations = data;
27121
+ if (this.query.targetId) {
27122
+ invitations = invitations.filter(invitation => invitation.targetId === this.query.targetId);
27123
+ }
27124
+ if (this.query.statuses) {
27125
+ invitations = invitations.filter(invitation => { var _a; return (_a = this.query.statuses) === null || _a === void 0 ? void 0 : _a.includes(invitation.status); });
27126
+ }
27127
+ if (this.query.targetType) {
27128
+ invitations = invitations.filter(invitation => invitation.targetType === this.query.targetType);
27129
+ }
27130
+ if (this.query.type) {
27131
+ invitations = invitations.filter(invitation => invitation.type === this.query.type);
27132
+ }
27133
+ const sortFn = (() => {
27134
+ switch (this.query.sortBy) {
27135
+ case 'firstCreated':
27136
+ return sortByFirstCreated;
27137
+ case 'lastCreated':
27138
+ return sortByLastCreated;
27139
+ default:
27140
+ return sortByLastCreated;
27141
+ }
27142
+ })();
27143
+ invitations = invitations.sort(sortFn);
27144
+ return invitations;
27145
+ }
27146
+ }
27147
+
26631
27148
  /**
26632
- * ```js
26633
- * import { onLocalInvitationCreated } from '@amityco/ts-sdk'
26634
- * const dispose = onLocalInvitationCreated(data => {
26635
- * // ...
26636
- * })
26637
- * ```
27149
+ * Get my community invitations
26638
27150
  *
26639
- * Fired when an {@link Amity.InvitationPayload} has been created
27151
+ * @param params the query parameters
27152
+ * @param callback the callback to be called when the invitations are fetched
27153
+ * @returns invitations
26640
27154
  *
26641
- * @param callback The function to call when the event was fired
26642
- * @returns an {@link Amity.Unsubscriber} function to stop listening
27155
+ * @category My Community Invitations Live Collection
26643
27156
  *
26644
- * @category Invitation Events
26645
27157
  */
26646
- const onLocalInvitationCreated = (callback) => {
26647
- const client = getActiveClient();
26648
- const disposers = [
26649
- createEventSubscriber(client, 'onLocalInvitationCreated', 'local.invitation.created', payload => callback(payload)),
26650
- ];
27158
+ const getMyCommunityInvitations = (params, callback, config) => {
27159
+ const { log, cache } = getActiveClient();
27160
+ if (!cache) {
27161
+ console.log(ENABLE_CACHE_MESSAGE);
27162
+ }
27163
+ const timestamp = Date.now();
27164
+ log(`getMyCommunityInvitations: (tmpid: ${timestamp}) > listen`);
27165
+ const invitationsLiveCollection = new MyInvitationsLiveCollectionController(Object.assign(Object.assign({}, params), { targetType: 'community', statuses: ["pending" /* InvitationStatusEnum.Pending */] }), callback);
27166
+ const disposers = invitationsLiveCollection.startSubscription();
27167
+ const cacheKey = invitationsLiveCollection.getCacheKey();
27168
+ disposers.push(() => {
27169
+ dropFromCache(cacheKey);
27170
+ });
26651
27171
  return () => {
27172
+ log(`getInvitations (tmpid: ${timestamp}) > dispose`);
26652
27173
  disposers.forEach(fn => fn());
26653
27174
  };
26654
27175
  };
26655
27176
 
26656
27177
  var index = /*#__PURE__*/Object.freeze({
26657
27178
  __proto__: null,
26658
- onLocalInvitationCreated: onLocalInvitationCreated
27179
+ onLocalInvitationCreated: onLocalInvitationCreated,
27180
+ onLocalInvitationUpdated: onLocalInvitationUpdated,
27181
+ onLocalInvitationDeleted: onLocalInvitationDeleted,
27182
+ getMyCommunityInvitations: getMyCommunityInvitations
26659
27183
  });
26660
27184
 
26661
27185
  exports.API_REGIONS = API_REGIONS;