@amityco/ts-sdk-react-native 6.35.2-412ed8b.0 → 6.35.3-2859517.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.
package/dist/index.cjs.js CHANGED
@@ -123,8 +123,8 @@ const PostContentType = Object.freeze({
123
123
 
124
124
  function getVersion() {
125
125
  try {
126
- // the string ''v6.35.1-cjs'' should be replaced by actual value by @rollup/plugin-replace
127
- return 'v6.35.1-cjs';
126
+ // the string ''v6.35.2-cjs'' should be replaced by actual value by @rollup/plugin-replace
127
+ return 'v6.35.2-cjs';
128
128
  }
129
129
  catch (error) {
130
130
  return '__dev__';
@@ -6149,268 +6149,66 @@ function updateSubChannelCache(subChannelId, subChannel, params) {
6149
6149
  shallowClone(subChannel, params));
6150
6150
  }
6151
6151
 
6152
- const handleMessageCreated = async (message) => {
6153
- var _a, _b, _c, _d;
6154
- const { channelId, messageId: messagePreviewId, creatorId, createdAt, updatedAt, data, dataType, subChannelId, channelSegment: segment, isDeleted, } = message;
6155
- /**
6156
- * SubChannel Case
6157
- *
6158
- */
6159
- const messagePreviewSubChannelCache = (_a = pullFromCache([
6160
- 'messagePreviewSubChannel',
6161
- 'get',
6162
- message.subChannelId,
6163
- ])) === null || _a === void 0 ? void 0 : _a.data;
6164
- if (!messagePreviewSubChannelCache ||
6165
- messagePreviewSubChannelCache.segment <= message.channelSegment) {
6166
- const subChannelCache = (_b = pullFromCache([
6167
- 'subChannel',
6168
- 'get',
6169
- subChannelId,
6170
- ])) === null || _b === void 0 ? void 0 : _b.data;
6171
- pushToCache(['messagePreviewSubChannel', 'get', message.subChannelId], {
6172
- channelId,
6173
- creatorId,
6174
- messagePreviewId,
6175
- createdAt,
6176
- updatedAt,
6177
- subChannelId,
6178
- data,
6179
- dataType,
6180
- segment,
6181
- isDeleted,
6182
- subChannelUpdatedAt: subChannelCache === null || subChannelCache === void 0 ? void 0 : subChannelCache.updatedAt,
6183
- subChannelName: subChannelCache === null || subChannelCache === void 0 ? void 0 : subChannelCache.displayName,
6184
- });
6185
- updateSubChannelCache(message.subChannelId, subChannelCache, {
6186
- messagePreviewId,
6187
- });
6188
- }
6189
- /**
6190
- * Channel Case
6191
- */
6192
- const messagePreviewChannelCache = (_c = pullFromCache([
6193
- 'messagePreviewChannel',
6194
- 'get',
6195
- message.channelId,
6196
- ])) === null || _c === void 0 ? void 0 : _c.data;
6197
- if (!messagePreviewChannelCache ||
6198
- new Date(messagePreviewChannelCache.createdAt).valueOf() <=
6199
- new Date(message.createdAt).valueOf()) {
6200
- const subChannelCache = (_d = pullFromCache([
6201
- 'subChannel',
6202
- 'get',
6203
- subChannelId,
6204
- ])) === null || _d === void 0 ? void 0 : _d.data;
6205
- pushToCache(['messagePreviewChannel', 'get', message.channelId], {
6206
- channelId,
6207
- creatorId,
6208
- messagePreviewId,
6209
- createdAt,
6210
- updatedAt,
6211
- subChannelId,
6212
- data,
6213
- dataType,
6214
- segment,
6215
- isDeleted,
6216
- subChannelUpdatedAt: subChannelCache === null || subChannelCache === void 0 ? void 0 : subChannelCache.updatedAt,
6217
- subChannelName: subChannelCache === null || subChannelCache === void 0 ? void 0 : subChannelCache.displayName,
6218
- });
6219
- }
6220
- };
6221
- const handleMessageUpdated = async (message) => {
6222
- var _a, _b, _c, _d;
6223
- const { channelId, messageId: messagePreviewId, creatorId, createdAt, updatedAt, data, dataType, subChannelId, channelSegment: segment, isDeleted, } = message;
6224
- /**
6225
- * SubChannel Case
6226
- *
6227
- */
6228
- const messagePreviewSubChannelCache = (_a = pullFromCache([
6229
- 'messagePreviewSubChannel',
6230
- 'get',
6231
- message.subChannelId,
6232
- ])) === null || _a === void 0 ? void 0 : _a.data;
6233
- if (messagePreviewSubChannelCache &&
6234
- messagePreviewSubChannelCache.messagePreviewId === message.messageId) {
6235
- /**
6236
- * subChannelCache not have messagePreviewId so update it directly
6237
- * because this function allow only corresponding subChannel
6238
- */
6239
- const subChannelCache = (_b = pullFromCache([
6240
- 'subChannel',
6241
- 'get',
6242
- subChannelId,
6243
- ])) === null || _b === void 0 ? void 0 : _b.data;
6244
- updateSubChannelCache(message.subChannelId, subChannelCache, {
6245
- messagePreviewId,
6246
- });
6247
- pushToCache(['messagePreviewSubChannel', 'get', message.subChannelId], {
6248
- channelId,
6249
- creatorId,
6250
- messagePreviewId,
6251
- createdAt,
6252
- updatedAt,
6253
- subChannelId,
6254
- data,
6255
- dataType,
6256
- segment,
6257
- isDeleted,
6258
- subChannelUpdatedAt: message === null || message === void 0 ? void 0 : message.updatedAt,
6259
- subChannelName: subChannelCache === null || subChannelCache === void 0 ? void 0 : subChannelCache.displayName,
6260
- });
6261
- }
6262
- /**
6263
- * Channel Case
6264
- */
6265
- const messagePreviewChannelCache = (_c = pullFromCache([
6266
- 'messagePreviewChannel',
6267
- 'get',
6268
- message.channelId,
6269
- ])) === null || _c === void 0 ? void 0 : _c.data;
6270
- if (messagePreviewChannelCache &&
6271
- messagePreviewChannelCache.messagePreviewId === message.messageId) {
6272
- const subChannelCache = (_d = pullFromCache([
6273
- 'subChannel',
6274
- 'get',
6275
- subChannelId,
6276
- ])) === null || _d === void 0 ? void 0 : _d.data;
6277
- pushToCache(['messagePreviewChannel', 'get', message.channelId], {
6278
- channelId,
6279
- creatorId,
6280
- messagePreviewId,
6281
- createdAt,
6282
- updatedAt,
6283
- subChannelId,
6284
- data,
6285
- dataType,
6286
- segment,
6287
- isDeleted,
6288
- subChannelUpdatedAt: subChannelCache === null || subChannelCache === void 0 ? void 0 : subChannelCache.updatedAt,
6289
- subChannelName: subChannelCache === null || subChannelCache === void 0 ? void 0 : subChannelCache.displayName,
6290
- });
6291
- }
6292
- };
6293
- const handleSubChannelUpdated = async (subChannel) => {
6294
- var _a, _b, _c, _d;
6295
- const { channelId, subChannelId } = subChannel;
6296
- /** Channel Case */
6297
- const messagePreviewChannelCache = (_a = pullFromCache([
6298
- 'messagePreviewChannel',
6299
- 'get',
6300
- channelId,
6301
- ])) === null || _a === void 0 ? void 0 : _a.data;
6302
- if ((messagePreviewChannelCache === null || messagePreviewChannelCache === void 0 ? void 0 : messagePreviewChannelCache.subChannelId) === subChannelId) {
6303
- const subChannelCache = (_b = pullFromCache([
6304
- 'subChannel',
6305
- 'get',
6306
- subChannelId,
6307
- ])) === null || _b === void 0 ? void 0 : _b.data;
6308
- 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 }));
6309
- }
6310
- /** SubChannel Case */
6311
- const messagePreviewSubChannelCache = (_c = pullFromCache([
6312
- 'messagePreviewSubChannel',
6313
- 'get',
6314
- subChannelId,
6315
- ])) === null || _c === void 0 ? void 0 : _c.data;
6316
- if (messagePreviewSubChannelCache &&
6317
- new Date(messagePreviewSubChannelCache.updatedAt).valueOf() >
6318
- new Date(subChannel.updatedAt).valueOf()) {
6319
- const subChannelCache = (_d = pullFromCache([
6320
- 'subChannel',
6321
- 'get',
6322
- subChannelId,
6323
- ])) === null || _d === void 0 ? void 0 : _d.data;
6324
- 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 }));
6325
- }
6326
- };
6327
-
6328
- function convertRawUserToInternalUser(rawUser) {
6329
- return Object.assign(Object.assign({}, rawUser), { isGlobalBanned: (rawUser === null || rawUser === void 0 ? void 0 : rawUser.isGlobalBan) || false });
6330
- }
6331
-
6332
- const MARKER_INCLUDED_CHANNEL_TYPE = ['broadcast', 'conversation', 'community'];
6333
- const isUnreadCountSupport$2 = ({ type }) => MARKER_INCLUDED_CHANNEL_TYPE.includes(type);
6334
- function convertFromRaw$2(channel, options = { isMessagePreviewUpdated: true }) {
6335
- var _a;
6336
- let { messagePreviewId } = channel;
6337
- const messagePreviewChannelCache = (_a = pullFromCache([
6338
- 'messagePreviewChannel',
6339
- 'get',
6340
- channel.channelId,
6341
- ])) === null || _a === void 0 ? void 0 : _a.data;
6342
- if ((messagePreviewChannelCache === null || messagePreviewChannelCache === void 0 ? void 0 : messagePreviewChannelCache.messagePreviewId) && !options.isMessagePreviewUpdated) {
6343
- messagePreviewId = messagePreviewChannelCache.messagePreviewId;
6344
- }
6345
- return Object.assign(Object.assign({}, channel), { defaultSubChannelId: channel.channelInternalId, isUnreadCountSupport: isUnreadCountSupport$2(channel), messagePreviewId });
6346
- }
6347
- const preUpdateChannelCache = (rawPayload, options = { isMessagePreviewUpdated: true }) => {
6348
- ingestInCache({
6349
- channels: rawPayload.channels.map(channel => convertFromRaw$2(channel, { isMessagePreviewUpdated: options.isMessagePreviewUpdated })),
6350
- });
6351
- };
6352
- const prepareChannelPayload = async (rawPayload, options = { isMessagePreviewUpdated: true }) => {
6353
- const client = getActiveClient();
6354
- const networkPreviewSetting = await client.getMessagePreviewSetting(false);
6355
- if (options.isMessagePreviewUpdated &&
6356
- networkPreviewSetting !== "no-message-preview" /* Amity.MessagePreviewSetting.NO_MESSAGE_PREVIEW */ &&
6357
- rawPayload.messagePreviews &&
6358
- rawPayload.messagePreviews.length > 0) {
6359
- updateChannelMessagePreviewCache(rawPayload);
6360
- }
6361
- const markerIds = rawPayload.channels
6362
- // filter channel by type. Only conversation, community and broadcast type are included.
6363
- .filter(isUnreadCountSupport$2)
6364
- .map(({ channelInternalId }) => channelInternalId);
6365
- if (markerIds.length > 0) {
6366
- // since the get markers method requires a channel cache to function with the reducer.
6367
- preUpdateChannelCache(rawPayload, { isMessagePreviewUpdated: options.isMessagePreviewUpdated });
6368
- try {
6369
- await getChannelMarkers(markerIds);
6370
- }
6371
- catch (e) {
6372
- // empty block (from the spec, allow marker fetch to fail without having to do anything)
6373
- }
6152
+ /**
6153
+ * ```js
6154
+ * import { isInTombstone } from '@amityco/ts-sdk-react-native'
6155
+ * const user = isInTombstone(["message", "messageId"])
6156
+ * ```
6157
+ *
6158
+ * Checks if the {@link Amity.TombstoneCacheOptions} exists
6159
+ * in cache and it's not expired means it's in tombstone
6160
+ * and we throw an Error
6161
+ *
6162
+ * @param model the model to check
6163
+ * @param modelId the object id to check
6164
+ * @returns the matching cache entry, or undefined.
6165
+ *
6166
+ * @category Cache API
6167
+ */
6168
+ const isInTombstone = (model, modelId) => {
6169
+ const { log, cache } = getActiveClient();
6170
+ const key = [model, CACHE_KEY_TOMBSTONE, modelId];
6171
+ if (!cache)
6172
+ return;
6173
+ log('cache/api/isInTombstone', key);
6174
+ const isInTombstone = pullFromCache(key);
6175
+ const { lifeSpan } = queryOptions('cache_then_server', CACHE_LIFESPAN_TOMBSTONE);
6176
+ if (isInTombstone && isFresh(isInTombstone.data, lifeSpan)) {
6177
+ throw new ASCApiError('Item not found!', 400400 /* Amity.ServerError.ITEM_NOT_FOUND */, "error" /* Amity.ErrorLevel.ERROR */);
6374
6178
  }
6375
- // attach marker to channel
6376
- const channels = rawPayload.channels.map(payload => convertFromRaw$2(payload, { isMessagePreviewUpdated: options.isMessagePreviewUpdated }));
6377
- // user marker to channel users
6378
- const channelUsers = rawPayload.channelUsers.map(channelUser => {
6379
- return convertRawMembershipToMembership(channelUser);
6380
- });
6381
- const users = rawPayload.users.map(convertRawUserToInternalUser);
6382
- const restRawPayload = __rest(rawPayload, ["messageFeedsInfo", "messagePreviews"]);
6383
- return Object.assign(Object.assign({}, restRawPayload), { users,
6384
- channels,
6385
- channelUsers });
6386
6179
  };
6387
6180
 
6388
6181
  /**
6389
6182
  * ```js
6390
- * import { getSubChannelMarkers } from '@amityco/ts-sdk-react-native'
6391
- * const subChannelMarkers = await getSubChannelMarkers(['sch1', 'sch2'])
6183
+ * import { getMessageMarkers } from '@amityco/ts-sdk-react-native'
6184
+ * const messageMarkers = await getMessageMarkers(['sch1', 'sch2'])
6392
6185
  * ```
6393
6186
  *
6394
- * Fetches a paginable list of {@link Amity.SubChannelMarker} objects
6187
+ * Fetches a list of {@link Amity.MessageMarker} by messageIds
6395
6188
  *
6396
- * @param messageFeedIds the feed IDs of the {@link Amity.RawSubChannel} marker to fetch
6397
- * @param page
6398
- * @returns A page of {@link Amity.SubChannelMarker} objects
6189
+ * @param messageIds the feed IDs of the {@link Amity.RawMessage} marker to fetch
6190
+ * @returns A list of {@link Amity.MessageMarker} by messageIds
6399
6191
  *
6400
6192
  * @category Channel API
6401
6193
  * @async
6402
6194
  * @private
6403
6195
  */
6404
- const getUserMessageFeedMakers = async (channelIds) => {
6196
+ const getMessageMarkers = async (messageIds) => {
6405
6197
  const client = getActiveClient();
6406
- client.log('channel/getUserMessageFeedMakers', channelIds);
6407
- const { data } = await client.http.get(`/api/v1/markers/user-message-feed`, {
6198
+ client.log('channel/getMessageMarkers', messageIds);
6199
+ const { data: queryPayload } = await client.http.get(`/api/v1/markers/messages`, {
6408
6200
  params: {
6409
- channelIds,
6201
+ messageIds,
6410
6202
  },
6411
6203
  });
6412
- fireEvent('local.userMessageFeedMarker.fetched', { userMessageFeedMarker: data });
6413
- return data;
6204
+ const { contentMarkers, feedMarkers, userMarkers } = queryPayload;
6205
+ const cachedAt = client.cache && Date.now();
6206
+ if (client.cache)
6207
+ ingestInCache({ contentMarkers, feedMarkers, userMarkers }, { cachedAt });
6208
+ fireEvent('local.feedMarker.fetched', { feedMarkers });
6209
+ fireEvent('local.messageMarker.fetched', { contentMarkers });
6210
+ fireEvent('local.userMarker.fetched', { userMarkers });
6211
+ return { data: contentMarkers, cachedAt };
6414
6212
  };
6415
6213
 
6416
6214
  const persistUnreadCountInfo = (payload) => {
@@ -6444,229 +6242,687 @@ const persistUnreadCountInfo = (payload) => {
6444
6242
  }
6445
6243
  }
6446
6244
  });
6447
- // re-calculate channel unread info in cache
6448
- channelIds.forEach(channelId => {
6449
- reCalculateChannelUnreadInfo(channelId);
6245
+ // re-calculate channel unread info in cache
6246
+ channelIds.forEach(channelId => {
6247
+ reCalculateChannelUnreadInfo(channelId);
6248
+ });
6249
+ }
6250
+ };
6251
+
6252
+ /**
6253
+ * ```js
6254
+ * import { getSubChannelMarkers } from '@amityco/ts-sdk-react-native'
6255
+ * const subChannelMarkers = await getSubChannelMarkers(['sch1', 'sch2'])
6256
+ * ```
6257
+ *
6258
+ * Fetches a paginable list of {@link Amity.SubChannelMarker} objects
6259
+ *
6260
+ * @param messageFeedIds the feed IDs of the {@link Amity.RawSubChannel} marker to fetch
6261
+ * @param page
6262
+ * @returns A page of {@link Amity.SubChannelMarker} objects
6263
+ *
6264
+ * @category Channel API
6265
+ * @async
6266
+ * @private
6267
+ */
6268
+ const getSubChannelMarkers = async (messageFeedIds, page = { limit: 100 }) => {
6269
+ const client = getActiveClient();
6270
+ client.log('channel/getSubChannelMarkers', messageFeedIds, page);
6271
+ const { data: queryPayload } = await client.http.get(`/api/v1/markers/message-feeds`, {
6272
+ params: {
6273
+ messageFeedIds,
6274
+ options: {
6275
+ token: toToken(page, 'skiplimit'),
6276
+ },
6277
+ },
6278
+ });
6279
+ const { paging } = queryPayload, payload = __rest(queryPayload, ["paging"]);
6280
+ const { userEntityMarkers: userEntityMarkersPayload, userFeedMarkers: userFeedMarkersPayload, userMarkers, feedMarkers: feedMarkersPayload, } = payload;
6281
+ // if consistent mode is enabled, persist the unread count info to the cache
6282
+ if (client.isUnreadCountEnabled && client.getMarkerSyncConsistentMode()) {
6283
+ persistUnreadCountInfo({
6284
+ feedMarkers: feedMarkersPayload,
6285
+ userFeedMarkers: userFeedMarkersPayload,
6286
+ });
6287
+ }
6288
+ const userEntityMarkers = convertChannelMarkerResponse(userEntityMarkersPayload);
6289
+ const userFeedMarkers = convertSubChannelMarkerResponse(userFeedMarkersPayload);
6290
+ const cachedAt = client.cache && Date.now();
6291
+ if (client.cache)
6292
+ ingestInCache({ userEntityMarkers, userFeedMarkers, userMarkers }, { cachedAt });
6293
+ fireEvent('local.channelMarker.fetched', { userEntityMarkers });
6294
+ fireEvent('local.subChannelMarker.fetched', { userFeedMarkers });
6295
+ fireEvent('local.userMarker.fetched', { userMarkers });
6296
+ const nextPage = toPage(paging.next);
6297
+ const prevPage = toPage(paging.previous);
6298
+ return { data: userFeedMarkers, cachedAt, prevPage, nextPage };
6299
+ };
6300
+
6301
+ const getUserMarker = async () => {
6302
+ const client = getActiveClient();
6303
+ client.log('channel/getUserMarker');
6304
+ const { data: payload } = await client.http.get(`/api/v1/markers/userMarker`);
6305
+ const { userMarkers } = payload;
6306
+ const cachedAt = client.cache && Date.now();
6307
+ if (client.cache)
6308
+ ingestInCache({ userMarkers }, { cachedAt });
6309
+ fireEvent('local.userMarker.fetched', { userMarkers });
6310
+ const latestUserMarker = userMarkers.reduce((maxUserMarker, userMarker) => {
6311
+ if (maxUserMarker == null ||
6312
+ new Date(maxUserMarker.lastSyncAt).getTime() < new Date(userMarker.lastSyncAt).getTime()) {
6313
+ return userMarker;
6314
+ }
6315
+ return maxUserMarker;
6316
+ }, undefined);
6317
+ return { data: latestUserMarker, cachedAt };
6318
+ };
6319
+
6320
+ /** @hidden */
6321
+ /*
6322
+ * @param message payload from http request without myReactions
6323
+ * add myReactions to http response if the event was a reaction event
6324
+ */
6325
+ const prepareMessagePayloadForCache = (payload, reactors, event) => {
6326
+ const client = getActiveClient();
6327
+ const cached = pullFromCache(['message', 'get', payload.messageId]);
6328
+ // '[]' in cases where the new reaction is the first one
6329
+ const myReactions = (cached === null || cached === void 0 ? void 0 : cached.data.myReactions) || [];
6330
+ // add myReactions to the payload
6331
+ Object.assign(payload, { myReactions });
6332
+ // check if there are any updates to the reactions
6333
+ const latestReaction = reactors[0];
6334
+ const isLatestReactionMine = latestReaction && latestReaction.userId === client.userId;
6335
+ if (!isLatestReactionMine) {
6336
+ return;
6337
+ }
6338
+ // new reaction added
6339
+ if (event === 'message.reactionAdded' && !myReactions.includes(latestReaction.reactionName)) {
6340
+ Object.assign(payload, {
6341
+ myReactions: [...myReactions, latestReaction.reactionName],
6342
+ });
6343
+ }
6344
+ // existing reaction removed
6345
+ if (event === 'message.reactionRemoved' && myReactions.includes(latestReaction.reactionName)) {
6346
+ Object.assign(payload, {
6347
+ myReactions: myReactions.filter(x => x !== latestReaction.reactionName),
6450
6348
  });
6451
6349
  }
6452
6350
  };
6453
6351
 
6454
- const prepareUnreadCountInfo = async (rawPayload) => {
6455
- const client = getActiveClient();
6456
- // if consistent mode is enabled, persist the unread count info to the cache
6457
- // Marker service API uses channelInternalId as channelId
6458
- const queryPayload = await getUserMessageFeedMakers(rawPayload.channels.map(({ channelInternalId }) => channelInternalId));
6459
- const { feedMarkers, userFeedMarkers } = queryPayload;
6460
- persistUnreadCountInfo({
6461
- feedMarkers,
6462
- userFeedMarkers,
6463
- });
6464
- client.log('channel/prepareUnreadCountInfo', rawPayload.channels);
6465
- };
6352
+ /*
6353
+ * This is a simple utility that infers the value of isDeleted based on the
6354
+ * value of includeDeleted
6355
+ *
6356
+ * There are two important things to note here:
6357
+ * 1. `includeDeleted` is purely client side query param and not recognized by
6358
+ * the server
6359
+ * 2. The only values we wish to expose with regards to `isDeleted` (the server
6360
+ * param for queries) is false | undefined and want to disallow users to query
6361
+ * for deleted entities
6362
+ *
6363
+ * Although this is a very simple utility, it's only purpose is to keep things
6364
+ * DRY
6365
+ */
6366
+ const inferIsDeleted = (includeDeleted) => includeDeleted === true ? undefined : false;
6466
6367
 
6467
- const getCachedMarker$1 = (entityId) => {
6468
- var _a;
6368
+ function getSubChannelIsMentioned(channelId, subChannelId, marker) {
6369
+ var _a, _b;
6370
+ // Look for `unreadCount` in the marker param first
6371
+ if (marker) {
6372
+ return marker.hasMentioned;
6373
+ }
6374
+ const client = getActiveClient();
6375
+ // If consistent mode is enabled, look in the SubChannelUnreadCountInfo cache
6376
+ if (client.isUnreadCountEnabled && client.getMarkerSyncConsistentMode()) {
6377
+ const cachedUnreadCount = (_a = pullFromCache([
6378
+ 'subChannelUnreadInfo',
6379
+ 'get',
6380
+ subChannelId,
6381
+ ])) === null || _a === void 0 ? void 0 : _a.data;
6382
+ if (cachedUnreadCount) {
6383
+ return cachedUnreadCount.isMentioned;
6384
+ }
6385
+ return false;
6386
+ }
6469
6387
  const key = {
6470
- entityId,
6388
+ entityId: channelId,
6389
+ feedId: subChannelId,
6471
6390
  userId: getActiveUser()._id,
6472
6391
  };
6473
- return (_a = pullFromCache([
6474
- 'channelMarker',
6392
+ // If the marker param is not set, look in the cache
6393
+ const cachedMarker = (_b = pullFromCache([
6394
+ 'subChannelMarker',
6475
6395
  'get',
6476
- getResolver('channelMarker')(key),
6477
- ])) === null || _a === void 0 ? void 0 : _a.data;
6478
- };
6479
- const getUnreadInfoCached$1 = (channelId) => {
6480
- var _a;
6481
- return (_a = pullFromCache(['channelUnreadInfo', 'get', channelId])) === null || _a === void 0 ? void 0 : _a.data;
6482
- };
6483
- /**
6484
- * The function use to get value of hasMentioned or isMentioned field.
6485
- * function will get the value from marker params first, if there is no hasMentioned field, will look in to the cache.
6486
- *
6487
- * If consistent mode is enabled, the function will return the value from the channelUnreadCountInfo cache.
6488
- * If not, the function will return the value from the channelMarker cache.
6489
- * If not found in the both cache, use `false` as defaul value.
6490
- */
6491
- const getChannelIsMentioned = (channel, marker) => {
6492
- var _a, _b, _c, _d;
6396
+ getResolver('subChannelMarker')(key),
6397
+ ])) === null || _b === void 0 ? void 0 : _b.data;
6398
+ if (cachedMarker) {
6399
+ return cachedMarker.hasMentioned;
6400
+ }
6401
+ // and if not found in cache use default value `false`
6402
+ return false;
6403
+ }
6404
+
6405
+ function getSubChannelUnreadCount(channelId, subChannelId, marker) {
6406
+ var _a, _b;
6407
+ // Look for `unreadCount` in the marker param first
6408
+ if (marker) {
6409
+ return marker.unreadCount;
6410
+ }
6493
6411
  const client = getActiveClient();
6412
+ // If consistent mode is enabled, look in the SubChannelUnreadCountInfo cache
6494
6413
  if (client.isUnreadCountEnabled && client.getMarkerSyncConsistentMode()) {
6495
- return (_b = (_a = getUnreadInfoCached$1(channel.channelPublicId)) === null || _a === void 0 ? void 0 : _a.isMentioned) !== null && _b !== void 0 ? _b : false;
6414
+ const cachedUnreadCount = (_a = pullFromCache([
6415
+ 'subChannelUnreadInfo',
6416
+ 'get',
6417
+ subChannelId,
6418
+ ])) === null || _a === void 0 ? void 0 : _a.data;
6419
+ if (cachedUnreadCount) {
6420
+ return cachedUnreadCount.isDeleted ? 0 : cachedUnreadCount.unreadCount;
6421
+ }
6422
+ return 0;
6496
6423
  }
6497
- return (marker === null || marker === void 0 ? void 0 : marker.hasMentioned) !== undefined
6498
- ? marker === null || marker === void 0 ? void 0 : marker.hasMentioned
6499
- : (_d = (_c = getCachedMarker$1(channel.channelPublicId)) === null || _c === void 0 ? void 0 : _c.hasMentioned) !== null && _d !== void 0 ? _d : false;
6500
- };
6501
-
6502
- const getCachedMarker = (entityId) => {
6503
- var _a;
6504
6424
  const key = {
6505
- entityId,
6425
+ entityId: channelId,
6426
+ feedId: subChannelId,
6506
6427
  userId: getActiveUser()._id,
6507
6428
  };
6508
- return (_a = pullFromCache([
6509
- 'channelMarker',
6429
+ // If the marker param is not set, look in the cache
6430
+ const cachedMarker = (_b = pullFromCache([
6431
+ 'subChannelMarker',
6510
6432
  'get',
6511
- getResolver('channelMarker')(key),
6512
- ])) === null || _a === void 0 ? void 0 : _a.data;
6433
+ getResolver('subChannelMarker')(key),
6434
+ ])) === null || _b === void 0 ? void 0 : _b.data;
6435
+ if (cachedMarker) {
6436
+ return cachedMarker.unreadCount;
6437
+ }
6438
+ // and if not found in cache use default value `0`
6439
+ return 0;
6440
+ }
6441
+
6442
+ const MARKER_INCLUDED_SUB_CHANNEL_TYPE$1 = ['broadcast', 'conversation', 'community'];
6443
+ const isUnreadCountSupport$2 = ({ channelType }) => MARKER_INCLUDED_SUB_CHANNEL_TYPE$1.includes(channelType);
6444
+ function convertFromRaw$2(_a) {
6445
+ 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"]);
6446
+ return Object.assign(Object.assign({ get unreadCount() {
6447
+ return getSubChannelUnreadCount(channelId, messageFeedId);
6448
+ },
6449
+ get hasMentioned() {
6450
+ return getSubChannelIsMentioned(channelId, messageFeedId);
6451
+ },
6452
+ get isMentioned() {
6453
+ return getSubChannelIsMentioned(channelId, messageFeedId);
6454
+ } }, rest), { channelId: channelPublicId, creatorId: creatorPublicId, displayName: name, lastActivity: lastMessageTimestamp, latestMessageId: lastMessageId, messageCount: childCount, subChannelId: messageFeedId, isUnreadCountSupport: isUnreadCountSupport$2({ channelType }) });
6455
+ }
6456
+
6457
+ const addLocalReferenceId = (payload) => {
6458
+ const client = getActiveClient();
6459
+ const { objectSyncMap } = client;
6460
+ return Object.assign(Object.assign({}, payload), {
6461
+ /* NOTE: This logic is used to get local referenceId for each message.
6462
+ *
6463
+ * if messageId is a local reference id, use it as referenceId else get referenceId from objectSyncMap.
6464
+ * if find referenceId in objectSyncMap, this means this message is a local created message. The referenceId will be local reference id.
6465
+ * if cannot find referenceId in objectSyncMap, referenceId will be undefined.
6466
+ *
6467
+ * The referenceId is undefined means this message is not a local created message (optimistic creation message).
6468
+ */
6469
+ referenceId: isLocalId(payload.messageId)
6470
+ ? payload.messageId
6471
+ : objectSyncMap.get(payload.messageId) });
6513
6472
  };
6514
- const getUnreadInfoCached = (channelId) => {
6473
+ function convertFromRaw$1(message, reactors, event) {
6515
6474
  var _a;
6516
- return (_a = pullFromCache(['channelUnreadInfo', 'get', channelId])) === null || _a === void 0 ? void 0 : _a.data;
6475
+ const messageWithReferenceId = addLocalReferenceId(message);
6476
+ const { channelPublicId, childCount, creatorPublicId, mentionedUsers, messageFeedId, myReactions, reactionCount, reactions, referenceId, segment, messageId, creatorId } = messageWithReferenceId, rest = __rest(messageWithReferenceId, ["channelPublicId", "childCount", "creatorPublicId", "mentionedUsers", "messageFeedId", "myReactions", "reactionCount", "reactions", "referenceId", "segment", "messageId", "creatorId"]);
6477
+ let cache;
6478
+ if (referenceId) {
6479
+ cache = pullFromCache(['message', 'get', referenceId]);
6480
+ }
6481
+ if (!cache) {
6482
+ cache = pullFromCache(['message', 'get', messageId]);
6483
+ }
6484
+ 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 : {},
6485
+ /*
6486
+ * Previously, myReactions were added only if it was part of the payload.
6487
+ * So empty myReactions were not present. So I've edited the payload to add
6488
+ * a default for those cases.
6489
+ *
6490
+ * Check git blame for previous iteration
6491
+ */
6492
+ 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 */ });
6493
+ if (mentionedUsers) {
6494
+ out.mentionees = mentionedUsers.map(mention => {
6495
+ if (mention.type === 'channel') {
6496
+ return mention;
6497
+ }
6498
+ return { type: 'user', userIds: mention.userPublicIds };
6499
+ });
6500
+ }
6501
+ if (reactors && reactors.length && event) {
6502
+ // mqtt event
6503
+ prepareMessagePayloadForCache(out, reactors, event);
6504
+ }
6505
+ return out;
6506
+ }
6507
+ const preUpdateMessageCache = (rawPayload) => {
6508
+ ingestInCache({
6509
+ messages: rawPayload.messages.map(message => convertFromRaw$1(message, rawPayload.reactions)),
6510
+ });
6517
6511
  };
6518
- /**
6519
- * The function use to get value of unreadCount field.
6520
- * function will get the value from marker params first, if there is no hasMentioned field, will look in to the cache.
6521
- *
6522
- * If consistent mode is enabled, the function will return the value from the channelUnreadCountInfo cache.
6523
- * If not, the function will return the value from the channelMarker cache.
6524
- * If not found in the both cache, use `0` as defaul value.
6525
- */
6526
- const getSubChannelsUnreadCount = (channel, marker) => {
6527
- var _a, _b, _c, _d, _e;
6528
- const client = getActiveClient();
6529
- if (client.isUnreadCountEnabled && client.getMarkerSyncConsistentMode()) {
6530
- // Marker service API uses channelInternalId as channelId
6531
- return (_b = (_a = getUnreadInfoCached(channel.channelInternalId)) === null || _a === void 0 ? void 0 : _a.unreadCount) !== null && _b !== void 0 ? _b : 0;
6512
+ const DEBOUNCE_TIME = 2000;
6513
+ const currentDebounceMap = {};
6514
+ const prepareMessagePayload = async (payload, event) => {
6515
+ const markerIds = payload.messages.map(({ messageId }) => messageId);
6516
+ if (markerIds.length > 0) {
6517
+ // since the get markers method requires a channel cache to function with the reducer.
6518
+ preUpdateMessageCache(payload);
6519
+ const markerIdsKey = markerIds.join('');
6520
+ if (currentDebounceMap[markerIdsKey]) {
6521
+ clearTimeout(currentDebounceMap[markerIdsKey]);
6522
+ }
6523
+ currentDebounceMap[markerIdsKey] = setTimeout(() => {
6524
+ try {
6525
+ getMessageMarkers(markerIds);
6526
+ }
6527
+ catch (_error) {
6528
+ // do nothing
6529
+ }
6530
+ }, DEBOUNCE_TIME);
6531
+ }
6532
+ const { messageFeeds } = payload, restPayload = __rest(payload, ["messageFeeds"]);
6533
+ // upsert messageFeeds to subchannel cache because messageFeeds from event payload not include messagePreviewId
6534
+ if (messageFeeds && messageFeeds.length > 0) {
6535
+ messageFeeds === null || messageFeeds === void 0 ? void 0 : messageFeeds.forEach(messageFeed => {
6536
+ var _a, _b;
6537
+ const subChannelCache = (_b = (_a = pullFromCache(['subChannel', 'get', messageFeed.messageFeedId])) === null || _a === void 0 ? void 0 : _a.data) !== null && _b !== void 0 ? _b : {};
6538
+ // exclude getter properties from existing subChannel cache, update only other properties to existing subChannel cache
6539
+ const _c = convertFromRaw$2(messageFeed), restSubChannel = __rest(_c, ["unreadCount", "hasMentioned", "isMentioned"]);
6540
+ updateSubChannelCache(messageFeed.messageFeedId, subChannelCache, restSubChannel);
6541
+ });
6542
+ }
6543
+ return Object.assign(Object.assign({}, restPayload), { messages: payload.messages.map(m => convertFromRaw$1(m, payload.reactions, event)) });
6544
+ };
6545
+ function convertParams(_a) {
6546
+ var { subChannelId, mentionees, dataType, data } = _a, rest = __rest(_a, ["subChannelId", "mentionees", "dataType", "data"]);
6547
+ if (dataType === MessageContentType.IMAGE || dataType === MessageContentType.FILE) {
6548
+ return Object.assign({ messageFeedId: subChannelId, mentionedUsers: mentionees, dataType, data: Object.assign({ caption: '' }, data) }, rest);
6549
+ }
6550
+ return Object.assign({ messageFeedId: subChannelId, mentionedUsers: mentionees, dataType, data }, rest);
6551
+ }
6552
+ function convertQueryParams$1(_a) {
6553
+ var { sortBy, subChannelId, tags, includingTags, excludingTags, includeDeleted, aroundMessageId, limit, type } = _a, rest = __rest(_a, ["sortBy", "subChannelId", "tags", "includingTags", "excludingTags", "includeDeleted", "aroundMessageId", "limit", "type"]);
6554
+ const out = Object.assign(Object.assign({}, rest), { messageFeedId: subChannelId, isDeleted: inferIsDeleted(includeDeleted), options: {
6555
+ sortBy,
6556
+ limit: limit || COLLECTION_DEFAULT_PAGINATION_LIMIT,
6557
+ around: aroundMessageId,
6558
+ } });
6559
+ if (tags) {
6560
+ out.includeTags = tags;
6532
6561
  }
6533
- if (marker === null || marker === void 0 ? void 0 : marker.isDeleted) {
6534
- // NOTE: This is a temporary solution to handle the channel marker when the user is forced to
6535
- // leave the channel because currently backend can't handle this, so every time a user is banned
6536
- // from a channel or the channel is deleted the channel's unread count will reset to zero
6537
- return 0;
6562
+ if (includingTags) {
6563
+ out.includeTags = includingTags;
6538
6564
  }
6539
- 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;
6540
- };
6565
+ if (type) {
6566
+ out.dataType = type;
6567
+ }
6568
+ if (excludingTags) {
6569
+ out.excludeTags = excludingTags;
6570
+ }
6571
+ return out;
6572
+ }
6541
6573
 
6542
- const constructChannelDynamicValue = (channel) => {
6543
- return shallowClone(channel, {
6544
- get unreadCount() {
6545
- return getSubChannelsUnreadCount(channel);
6546
- },
6547
- get hasMentioned() {
6548
- return getChannelIsMentioned(channel);
6549
- },
6550
- get isMentioned() {
6551
- return getChannelIsMentioned(channel);
6552
- },
6553
- get subChannelsUnreadCount() {
6554
- return getSubChannelsUnreadCount(channel);
6555
- },
6574
+ const MARKER_INCLUDED_SUB_CHANNEL_TYPE = ['broadcast', 'conversation', 'community'];
6575
+ /**
6576
+ * Filter sub channel by type. Only conversation, community and broadcast type are included.
6577
+ */
6578
+ const isUnreadCountSupport$1 = ({ channelType }) => MARKER_INCLUDED_SUB_CHANNEL_TYPE.includes(channelType);
6579
+ const preUpdateSubChannelCache = (rawPayload) => {
6580
+ ingestInCache({
6581
+ messageFeeds: rawPayload.messageFeeds.map(messageFeed => convertFromRaw$2(messageFeed)),
6556
6582
  });
6557
- };
6583
+ };
6584
+ const prepareSubChannelPayload = async (rawPayload) => {
6585
+ const markerIds = rawPayload.messageFeeds
6586
+ .filter(isUnreadCountSupport$1)
6587
+ .map(({ messageFeedId }) => messageFeedId);
6588
+ if (markerIds.length > 0) {
6589
+ // since the get markers method requires a channel cache to function with the reducer.
6590
+ preUpdateSubChannelCache(rawPayload);
6591
+ try {
6592
+ await getSubChannelMarkers(markerIds);
6593
+ }
6594
+ catch (e) {
6595
+ // empty block (from the spec, allow marker fetch to fail without having to do anything)
6596
+ }
6597
+ }
6598
+ updateSubChannelMessagePreviewCache(rawPayload);
6599
+ // attach marker to sub channel
6600
+ const messageFeeds = rawPayload.messageFeeds.map(convertFromRaw$2);
6601
+ const messages = rawPayload.messages.map(m => convertFromRaw$1(m));
6602
+ return Object.assign(Object.assign({}, rawPayload), { messageFeeds,
6603
+ messages });
6604
+ };
6605
+ function convertQueryParams(_a) {
6606
+ var { excludeDefaultSubChannel } = _a, rest = __rest(_a, ["excludeDefaultSubChannel"]);
6607
+ const out = Object.assign({}, rest);
6608
+ if (excludeDefaultSubChannel !== undefined) {
6609
+ out.excludeDefaultMessageFeed = excludeDefaultSubChannel;
6610
+ }
6611
+ return out;
6612
+ }
6558
6613
 
6559
6614
  /**
6560
6615
  * ```js
6561
- * import { getChannelByIds } from '@amityco/ts-sdk-react-native'
6562
- * const channels = await getChannelByIds(['foo', 'bar'])
6616
+ * import { getSubChannel } from '@amityco/ts-sdk-react-native'
6617
+ * const subChannel = await getSubChannel('foobar')
6563
6618
  * ```
6564
6619
  *
6565
- * Fetches a collection of {@link Amity.Channel} objects
6620
+ * Fetches a {@link Amity.SubChannel} object
6566
6621
  *
6567
- * @param channelIds the IDs of the {@link Amity.Channel} to fetch
6568
- * @returns the associated collection of {@link Amity.Channel} objects
6622
+ * @param subChannelId the ID of the {@link Amity.SubChannel} to fetch
6623
+ * @returns the associated {@link Amity.SubChannel} object
6569
6624
  *
6570
6625
  * @category Channel API
6571
6626
  * @async
6572
6627
  */
6573
- const getChannelByIds = async (channelIds) => {
6628
+ const getSubChannel$1 = async (subChannelId) => {
6574
6629
  const client = getActiveClient();
6575
- client.log('channel/getChannelByIds', channelIds);
6576
- const encodedChannelIds = channelIds.map(channelId => encodeURIComponent(channelId));
6577
- let payload;
6630
+ client.log('channel/getSubChannel', subChannelId);
6631
+ isInTombstone('subChannel', subChannelId);
6578
6632
  try {
6579
- // API-FIX: endpoint should not be /list, parameters should be querystring.
6580
- const response = await client.http.get(`/api/v3/channels/list`, {
6581
- params: { channelIds: encodedChannelIds },
6582
- });
6583
- payload = response.data;
6633
+ const response = await client.http.get(`/api/v5/message-feeds/${encodeURIComponent(subChannelId)}`);
6634
+ const data = await prepareSubChannelPayload(response.data);
6635
+ const cachedAt = client.cache && Date.now();
6636
+ if (client.cache)
6637
+ ingestInCache(data, { cachedAt });
6638
+ fireEvent('local.message-feed.fetched', data);
6639
+ return {
6640
+ data: data.messageFeeds[0],
6641
+ cachedAt,
6642
+ };
6584
6643
  }
6585
6644
  catch (error) {
6586
- channelIds.forEach(channelId => {
6587
- if (checkIfShouldGoesToTombstone(error === null || error === void 0 ? void 0 : error.code)) {
6588
- // NOTE: use channelPublicId as tombstone cache key since we cannot get the channelPrivateId that come along with channel data from server
6589
- pushToTombstone('channel', channelId);
6590
- }
6591
- });
6645
+ if (checkIfShouldGoesToTombstone(error === null || error === void 0 ? void 0 : error.code)) {
6646
+ pushToTombstone('subChannel', subChannelId);
6647
+ }
6592
6648
  throw error;
6593
6649
  }
6594
- const data = await prepareChannelPayload(payload);
6595
- if (client.isUnreadCountEnabled && client.getMarkerSyncConsistentMode()) {
6596
- await prepareUnreadCountInfo(payload);
6597
- }
6598
- const cachedAt = client.cache && Date.now();
6599
- if (client.cache)
6600
- ingestInCache(data, { cachedAt });
6601
- fireEvent('local.channel.fetched', data.channels);
6602
- return {
6603
- data: data.channels.map(channel => LinkedObject.channel(constructChannelDynamicValue(channel))),
6604
- cachedAt,
6605
- };
6606
6650
  };
6607
6651
  /**
6608
6652
  * ```js
6609
- * import { getChannelByIds } from '@amityco/ts-sdk-react-native'
6610
- * const channels = getChannelByIds.locally(['foo', 'bar']) ?? []
6653
+ * import { getSubChannel } from '@amityco/ts-sdk-react-native'
6654
+ * const subChannel = getSubChannel.locally('foobar')
6611
6655
  * ```
6612
6656
  *
6613
- * Fetches a collection of {@link Amity.Channel} objects from cache
6657
+ * Fetches a {@link Amity.SubChannel} object from cache
6614
6658
  *
6615
- * @param channelIds the IDs of the {@link Amity.Channel} to fetch
6616
- * @returns the associated collection of {@link Amity.Channel} objects
6659
+ * @param subChannelId the ID of the {@link Amity.SubChannel} to fetch
6660
+ * @returns the associated {@link Amity.SubChannel} object
6617
6661
  *
6618
6662
  * @category Channel API
6619
6663
  */
6620
- getChannelByIds.locally = (channelIds) => {
6621
- var _a, _b;
6664
+ getSubChannel$1.locally = (subChannelId) => {
6622
6665
  const client = getActiveClient();
6623
- client.log('channel/getChannelByIds.locally', channelIds);
6666
+ client.log('channel/getSubChannel.locally', subChannelId);
6624
6667
  if (!client.cache)
6625
6668
  return;
6626
- const cached = (_a = queryCache(['channel', 'get'])) === null || _a === void 0 ? void 0 : _a.filter(({ data }) => {
6627
- return channelIds.includes(data.channelPublicId);
6628
- });
6629
- if (!cached || (cached === null || cached === void 0 ? void 0 : cached.length) < channelIds.length)
6669
+ const cached = pullFromCache(['subChannel', 'get', subChannelId]);
6670
+ if (!cached)
6630
6671
  return;
6631
- const channels = cached.map(({ data }) => data);
6632
- const oldest = (_b = cached.sort((a, b) => (a.cachedAt < b.cachedAt ? -1 : 1))) === null || _b === void 0 ? void 0 : _b[0];
6633
6672
  return {
6634
- data: channels.map(channel => LinkedObject.channel(channel)),
6635
- cachedAt: oldest.cachedAt,
6673
+ data: cached.data,
6674
+ cachedAt: cached.cachedAt,
6636
6675
  };
6637
6676
  };
6638
6677
 
6639
- /**
6640
- * ```js
6641
- * import { getMessageMarkers } from '@amityco/ts-sdk-react-native'
6642
- * const messageMarkers = await getMessageMarkers(['sch1', 'sch2'])
6643
- * ```
6644
- *
6645
- * Fetches a list of {@link Amity.MessageMarker} by messageIds
6646
- *
6647
- * @param messageIds the feed IDs of the {@link Amity.RawMessage} marker to fetch
6648
- * @returns A list of {@link Amity.MessageMarker} by messageIds
6649
- *
6650
- * @category Channel API
6651
- * @async
6652
- * @private
6653
- */
6654
- const getMessageMarkers = async (messageIds) => {
6678
+ const convertDateStringToTimestamp = (dateString) => {
6679
+ return new Date(dateString).getTime();
6680
+ };
6681
+
6682
+ const getMessagePreviewSetting$1 = async () => {
6683
+ const client = getActiveClient();
6684
+ return client.getMessagePreviewSetting(false);
6685
+ };
6686
+ const getSubChannelCache = async (subChannelId) => {
6687
+ var _a;
6688
+ let subChannelCache = (_a = pullFromCache(['subChannel', 'get', subChannelId])) === null || _a === void 0 ? void 0 : _a.data;
6689
+ if (!subChannelCache) {
6690
+ subChannelCache = (await getSubChannel$1(subChannelId)).data;
6691
+ }
6692
+ return subChannelCache;
6693
+ };
6694
+ const isLastestMessageOnSubchannel = (message) => {
6695
+ var _a;
6696
+ const cache = (_a = pullFromCache([
6697
+ 'messagePreviewSubChannel',
6698
+ 'get',
6699
+ message.subChannelId,
6700
+ ])) === null || _a === void 0 ? void 0 : _a.data;
6701
+ // The message payload from optimistic created event has no segment, so we check createdAt instead.
6702
+ return (!cache ||
6703
+ cache.segment <= message.channelSegment ||
6704
+ convertDateStringToTimestamp(cache.createdAt) <= convertDateStringToTimestamp(message.createdAt));
6705
+ };
6706
+ const isLastestMessageOnChannel = (message) => {
6707
+ var _a;
6708
+ const cache = (_a = pullFromCache([
6709
+ 'messagePreviewChannel',
6710
+ 'get',
6711
+ message.channelId,
6712
+ ])) === null || _a === void 0 ? void 0 : _a.data;
6713
+ return (!cache ||
6714
+ convertDateStringToTimestamp(cache.createdAt) <= convertDateStringToTimestamp(message.createdAt));
6715
+ };
6716
+ const handleMessageCreatedOnSubChannel = async (message) => {
6717
+ const messagePreviewSetting = await getMessagePreviewSetting$1();
6718
+ const { channelId, messageId: messagePreviewId, creatorId, createdAt, updatedAt, data, dataType, subChannelId, channelSegment: segment, isDeleted, } = message;
6719
+ // 1. get subChannel from cache, if not exist fetch from server
6720
+ const subChannelCache = await getSubChannelCache(subChannelId);
6721
+ // 2. if messagePreviewSetting is NO_MESSAGE_PREVEIW, update only lastActiviy in subChannel cache
6722
+ if (messagePreviewSetting === "no-message-preview" /* Amity.MessagePreviewSetting.NO_MESSAGE_PREVIEW */) {
6723
+ // 2.1 if the message is the latest message, update lastActivity to be createdAt in subChannel cache
6724
+ if (convertDateStringToTimestamp(subChannelCache.lastActivity) <
6725
+ convertDateStringToTimestamp(createdAt))
6726
+ updateSubChannelCache(message.subChannelId, subChannelCache, {
6727
+ lastActivity: createdAt,
6728
+ });
6729
+ return;
6730
+ }
6731
+ // 3. if messagePreviewSetting is `NOT` NO_MESSAGE_PREVEIW, update messagePreviewSubChannel and subChannel cache
6732
+ // 3.1 check if the message is the latest message, if not ignore the message.
6733
+ if (!isLastestMessageOnSubchannel(message))
6734
+ return;
6735
+ // 3.2 if the message is the latest message, update messagePreviewSubChannel and subChannel cache
6736
+ pushToCache(['messagePreviewSubChannel', 'get', message.subChannelId], {
6737
+ channelId,
6738
+ creatorId,
6739
+ messagePreviewId,
6740
+ createdAt,
6741
+ updatedAt,
6742
+ subChannelId,
6743
+ data,
6744
+ dataType,
6745
+ segment,
6746
+ isDeleted,
6747
+ subChannelUpdatedAt: subChannelCache === null || subChannelCache === void 0 ? void 0 : subChannelCache.updatedAt,
6748
+ subChannelName: subChannelCache === null || subChannelCache === void 0 ? void 0 : subChannelCache.displayName,
6749
+ });
6750
+ updateSubChannelCache(message.subChannelId, subChannelCache, {
6751
+ lastActivity: createdAt,
6752
+ messagePreviewId,
6753
+ });
6754
+ };
6755
+ const handleMessageUpdatedOnSubChannel = async (message) => {
6756
+ var _a;
6757
+ const { channelId, messageId: messagePreviewId, creatorId, createdAt, updatedAt, data, dataType, subChannelId, channelSegment: segment, isDeleted, } = message;
6758
+ const messagePreviewSubChannelCache = (_a = pullFromCache([
6759
+ 'messagePreviewSubChannel',
6760
+ 'get',
6761
+ message.subChannelId,
6762
+ ])) === null || _a === void 0 ? void 0 : _a.data;
6763
+ // if messagePreviewSubChannel is not exist, ignore the message.
6764
+ if (messagePreviewSubChannelCache &&
6765
+ messagePreviewSubChannelCache.messagePreviewId === message.messageId) {
6766
+ const subChannelCache = await getSubChannelCache(subChannelId);
6767
+ pushToCache(['messagePreviewSubChannel', 'get', message.subChannelId], {
6768
+ channelId,
6769
+ creatorId,
6770
+ messagePreviewId,
6771
+ createdAt,
6772
+ updatedAt,
6773
+ subChannelId,
6774
+ data,
6775
+ dataType,
6776
+ segment,
6777
+ isDeleted,
6778
+ subChannelUpdatedAt: subChannelCache.updatedAt,
6779
+ subChannelName: messagePreviewSubChannelCache.subChannelName,
6780
+ });
6781
+ }
6782
+ };
6783
+ const handleMessageCreated = async (message) => {
6784
+ const { channelId, messageId: messagePreviewId, creatorId, createdAt, updatedAt, data, dataType, subChannelId, channelSegment: segment, isDeleted, } = message;
6785
+ if (isLastestMessageOnChannel(message)) {
6786
+ const subChannelCache = await getSubChannelCache(subChannelId);
6787
+ pushToCache(['messagePreviewChannel', 'get', message.channelId], {
6788
+ channelId,
6789
+ creatorId,
6790
+ messagePreviewId,
6791
+ createdAt,
6792
+ updatedAt,
6793
+ subChannelId,
6794
+ data,
6795
+ dataType,
6796
+ segment,
6797
+ isDeleted,
6798
+ subChannelUpdatedAt: subChannelCache === null || subChannelCache === void 0 ? void 0 : subChannelCache.updatedAt,
6799
+ subChannelName: subChannelCache === null || subChannelCache === void 0 ? void 0 : subChannelCache.displayName,
6800
+ });
6801
+ }
6802
+ };
6803
+ const handleMessageUpdated = async (message) => {
6804
+ /**
6805
+ * Channel Case
6806
+ */
6807
+ var _a;
6808
+ const { channelId, messageId: messagePreviewId, creatorId, createdAt, updatedAt, data, dataType, subChannelId, channelSegment: segment, isDeleted, } = message;
6809
+ const messagePreviewChannelCache = (_a = pullFromCache([
6810
+ 'messagePreviewChannel',
6811
+ 'get',
6812
+ message.channelId,
6813
+ ])) === null || _a === void 0 ? void 0 : _a.data;
6814
+ if (messagePreviewChannelCache &&
6815
+ messagePreviewChannelCache.messagePreviewId === message.messageId) {
6816
+ const subChannelCache = await getSubChannelCache(subChannelId);
6817
+ pushToCache(['messagePreviewChannel', 'get', message.channelId], {
6818
+ channelId,
6819
+ creatorId,
6820
+ messagePreviewId,
6821
+ createdAt,
6822
+ updatedAt,
6823
+ subChannelId,
6824
+ data,
6825
+ dataType,
6826
+ segment,
6827
+ isDeleted,
6828
+ subChannelUpdatedAt: subChannelCache.updatedAt,
6829
+ subChannelName: messagePreviewChannelCache.subChannelName,
6830
+ });
6831
+ }
6832
+ };
6833
+ const handleSubChannelUpdated = async (subChannel) => {
6834
+ var _a, _b, _c, _d;
6835
+ const { channelId, subChannelId } = subChannel;
6836
+ /** Channel Case */
6837
+ const messagePreviewChannelCache = (_a = pullFromCache([
6838
+ 'messagePreviewChannel',
6839
+ 'get',
6840
+ channelId,
6841
+ ])) === null || _a === void 0 ? void 0 : _a.data;
6842
+ if ((messagePreviewChannelCache === null || messagePreviewChannelCache === void 0 ? void 0 : messagePreviewChannelCache.subChannelId) === subChannelId) {
6843
+ const subChannelCache = (_b = pullFromCache([
6844
+ 'subChannel',
6845
+ 'get',
6846
+ subChannelId,
6847
+ ])) === null || _b === void 0 ? void 0 : _b.data;
6848
+ 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 }));
6849
+ }
6850
+ /** SubChannel Case */
6851
+ const messagePreviewSubChannelCache = (_c = pullFromCache([
6852
+ 'messagePreviewSubChannel',
6853
+ 'get',
6854
+ subChannelId,
6855
+ ])) === null || _c === void 0 ? void 0 : _c.data;
6856
+ if (messagePreviewSubChannelCache &&
6857
+ new Date(messagePreviewSubChannelCache.updatedAt).valueOf() >
6858
+ new Date(subChannel.updatedAt).valueOf()) {
6859
+ const subChannelCache = (_d = pullFromCache([
6860
+ 'subChannel',
6861
+ 'get',
6862
+ subChannelId,
6863
+ ])) === null || _d === void 0 ? void 0 : _d.data;
6864
+ 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 }));
6865
+ }
6866
+ };
6867
+
6868
+ function convertRawUserToInternalUser(rawUser) {
6869
+ return Object.assign(Object.assign({}, rawUser), { isGlobalBanned: (rawUser === null || rawUser === void 0 ? void 0 : rawUser.isGlobalBan) || false });
6870
+ }
6871
+
6872
+ const MARKER_INCLUDED_CHANNEL_TYPE = ['broadcast', 'conversation', 'community'];
6873
+ const isUnreadCountSupport = ({ type }) => MARKER_INCLUDED_CHANNEL_TYPE.includes(type);
6874
+ function convertFromRaw(channel, options = { isMessagePreviewUpdated: true }) {
6875
+ var _a;
6876
+ let { messagePreviewId } = channel;
6877
+ const messagePreviewChannelCache = (_a = pullFromCache([
6878
+ 'messagePreviewChannel',
6879
+ 'get',
6880
+ channel.channelId,
6881
+ ])) === null || _a === void 0 ? void 0 : _a.data;
6882
+ if ((messagePreviewChannelCache === null || messagePreviewChannelCache === void 0 ? void 0 : messagePreviewChannelCache.messagePreviewId) && !options.isMessagePreviewUpdated) {
6883
+ messagePreviewId = messagePreviewChannelCache.messagePreviewId;
6884
+ }
6885
+ return Object.assign(Object.assign({}, channel), { defaultSubChannelId: channel.channelInternalId, isUnreadCountSupport: isUnreadCountSupport(channel), messagePreviewId });
6886
+ }
6887
+ const preUpdateChannelCache = (rawPayload, options = { isMessagePreviewUpdated: true }) => {
6888
+ ingestInCache({
6889
+ channels: rawPayload.channels.map(channel => convertFromRaw(channel, { isMessagePreviewUpdated: options.isMessagePreviewUpdated })),
6890
+ });
6891
+ };
6892
+ const prepareChannelPayload = async (rawPayload, options = { isMessagePreviewUpdated: true }) => {
6655
6893
  const client = getActiveClient();
6656
- client.log('channel/getMessageMarkers', messageIds);
6657
- const { data: queryPayload } = await client.http.get(`/api/v1/markers/messages`, {
6658
- params: {
6659
- messageIds,
6660
- },
6894
+ const networkPreviewSetting = await client.getMessagePreviewSetting(false);
6895
+ if (options.isMessagePreviewUpdated &&
6896
+ networkPreviewSetting !== "no-message-preview" /* Amity.MessagePreviewSetting.NO_MESSAGE_PREVIEW */ &&
6897
+ rawPayload.messagePreviews &&
6898
+ rawPayload.messagePreviews.length > 0) {
6899
+ updateChannelMessagePreviewCache(rawPayload);
6900
+ }
6901
+ const markerIds = rawPayload.channels
6902
+ // filter channel by type. Only conversation, community and broadcast type are included.
6903
+ .filter(isUnreadCountSupport)
6904
+ .map(({ channelInternalId }) => channelInternalId);
6905
+ if (markerIds.length > 0) {
6906
+ // since the get markers method requires a channel cache to function with the reducer.
6907
+ preUpdateChannelCache(rawPayload, { isMessagePreviewUpdated: options.isMessagePreviewUpdated });
6908
+ try {
6909
+ await getChannelMarkers(markerIds);
6910
+ }
6911
+ catch (e) {
6912
+ // empty block (from the spec, allow marker fetch to fail without having to do anything)
6913
+ }
6914
+ }
6915
+ // attach marker to channel
6916
+ const channels = rawPayload.channels.map(payload => convertFromRaw(payload, { isMessagePreviewUpdated: options.isMessagePreviewUpdated }));
6917
+ // user marker to channel users
6918
+ const channelUsers = rawPayload.channelUsers.map(channelUser => {
6919
+ return convertRawMembershipToMembership(channelUser);
6661
6920
  });
6662
- const { contentMarkers, feedMarkers, userMarkers } = queryPayload;
6663
- const cachedAt = client.cache && Date.now();
6664
- if (client.cache)
6665
- ingestInCache({ contentMarkers, feedMarkers, userMarkers }, { cachedAt });
6666
- fireEvent('local.feedMarker.fetched', { feedMarkers });
6667
- fireEvent('local.messageMarker.fetched', { contentMarkers });
6668
- fireEvent('local.userMarker.fetched', { userMarkers });
6669
- return { data: contentMarkers, cachedAt };
6921
+ const users = rawPayload.users.map(convertRawUserToInternalUser);
6922
+ const restRawPayload = __rest(rawPayload, ["messageFeedsInfo", "messagePreviews"]);
6923
+ return Object.assign(Object.assign({}, restRawPayload), { users,
6924
+ channels,
6925
+ channelUsers });
6670
6926
  };
6671
6927
 
6672
6928
  /**
@@ -6685,351 +6941,202 @@ const getMessageMarkers = async (messageIds) => {
6685
6941
  * @async
6686
6942
  * @private
6687
6943
  */
6688
- const getSubChannelMarkers = async (messageFeedIds, page = { limit: 100 }) => {
6944
+ const getUserMessageFeedMakers = async (channelIds) => {
6689
6945
  const client = getActiveClient();
6690
- client.log('channel/getSubChannelMarkers', messageFeedIds, page);
6691
- const { data: queryPayload } = await client.http.get(`/api/v1/markers/message-feeds`, {
6946
+ client.log('channel/getUserMessageFeedMakers', channelIds);
6947
+ const { data } = await client.http.get(`/api/v1/markers/user-message-feed`, {
6692
6948
  params: {
6693
- messageFeedIds,
6694
- options: {
6695
- token: toToken(page, 'skiplimit'),
6696
- },
6949
+ channelIds,
6697
6950
  },
6698
6951
  });
6699
- const { paging } = queryPayload, payload = __rest(queryPayload, ["paging"]);
6700
- const { userEntityMarkers: userEntityMarkersPayload, userFeedMarkers: userFeedMarkersPayload, userMarkers, feedMarkers: feedMarkersPayload, } = payload;
6701
- // if consistent mode is enabled, persist the unread count info to the cache
6702
- if (client.isUnreadCountEnabled && client.getMarkerSyncConsistentMode()) {
6703
- persistUnreadCountInfo({
6704
- feedMarkers: feedMarkersPayload,
6705
- userFeedMarkers: userFeedMarkersPayload,
6706
- });
6707
- }
6708
- const userEntityMarkers = convertChannelMarkerResponse(userEntityMarkersPayload);
6709
- const userFeedMarkers = convertSubChannelMarkerResponse(userFeedMarkersPayload);
6710
- const cachedAt = client.cache && Date.now();
6711
- if (client.cache)
6712
- ingestInCache({ userEntityMarkers, userFeedMarkers, userMarkers }, { cachedAt });
6713
- fireEvent('local.channelMarker.fetched', { userEntityMarkers });
6714
- fireEvent('local.subChannelMarker.fetched', { userFeedMarkers });
6715
- fireEvent('local.userMarker.fetched', { userMarkers });
6716
- const nextPage = toPage(paging.next);
6717
- const prevPage = toPage(paging.previous);
6718
- return { data: userFeedMarkers, cachedAt, prevPage, nextPage };
6719
- };
6720
-
6721
- const getUserMarker = async () => {
6722
- const client = getActiveClient();
6723
- client.log('channel/getUserMarker');
6724
- const { data: payload } = await client.http.get(`/api/v1/markers/userMarker`);
6725
- const { userMarkers } = payload;
6726
- const cachedAt = client.cache && Date.now();
6727
- if (client.cache)
6728
- ingestInCache({ userMarkers }, { cachedAt });
6729
- fireEvent('local.userMarker.fetched', { userMarkers });
6730
- const latestUserMarker = userMarkers.reduce((maxUserMarker, userMarker) => {
6731
- if (maxUserMarker == null ||
6732
- new Date(maxUserMarker.lastSyncAt).getTime() < new Date(userMarker.lastSyncAt).getTime()) {
6733
- return userMarker;
6734
- }
6735
- return maxUserMarker;
6736
- }, undefined);
6737
- return { data: latestUserMarker, cachedAt };
6952
+ fireEvent('local.userMessageFeedMarker.fetched', { userMessageFeedMarker: data });
6953
+ return data;
6738
6954
  };
6739
6955
 
6740
- /** @hidden */
6741
- /*
6742
- * @param message payload from http request without myReactions
6743
- * add myReactions to http response if the event was a reaction event
6744
- */
6745
- const prepareMessagePayloadForCache = (payload, reactors, event) => {
6956
+ const prepareUnreadCountInfo = async (rawPayload) => {
6746
6957
  const client = getActiveClient();
6747
- const cached = pullFromCache(['message', 'get', payload.messageId]);
6748
- // '[]' in cases where the new reaction is the first one
6749
- const myReactions = (cached === null || cached === void 0 ? void 0 : cached.data.myReactions) || [];
6750
- // add myReactions to the payload
6751
- Object.assign(payload, { myReactions });
6752
- // check if there are any updates to the reactions
6753
- const latestReaction = reactors[0];
6754
- const isLatestReactionMine = latestReaction && latestReaction.userId === client.userId;
6755
- if (!isLatestReactionMine) {
6756
- return;
6757
- }
6758
- // new reaction added
6759
- if (event === 'message.reactionAdded' && !myReactions.includes(latestReaction.reactionName)) {
6760
- Object.assign(payload, {
6761
- myReactions: [...myReactions, latestReaction.reactionName],
6762
- });
6763
- }
6764
- // existing reaction removed
6765
- if (event === 'message.reactionRemoved' && myReactions.includes(latestReaction.reactionName)) {
6766
- Object.assign(payload, {
6767
- myReactions: myReactions.filter(x => x !== latestReaction.reactionName),
6768
- });
6769
- }
6958
+ // if consistent mode is enabled, persist the unread count info to the cache
6959
+ // Marker service API uses channelInternalId as channelId
6960
+ const queryPayload = await getUserMessageFeedMakers(rawPayload.channels.map(({ channelInternalId }) => channelInternalId));
6961
+ const { feedMarkers, userFeedMarkers } = queryPayload;
6962
+ persistUnreadCountInfo({
6963
+ feedMarkers,
6964
+ userFeedMarkers,
6965
+ });
6966
+ client.log('channel/prepareUnreadCountInfo', rawPayload.channels);
6770
6967
  };
6771
6968
 
6772
- /*
6773
- * This is a simple utility that infers the value of isDeleted based on the
6774
- * value of includeDeleted
6775
- *
6776
- * There are two important things to note here:
6777
- * 1. `includeDeleted` is purely client side query param and not recognized by
6778
- * the server
6779
- * 2. The only values we wish to expose with regards to `isDeleted` (the server
6780
- * param for queries) is false | undefined and want to disallow users to query
6781
- * for deleted entities
6969
+ const getCachedMarker$1 = (entityId) => {
6970
+ var _a;
6971
+ const key = {
6972
+ entityId,
6973
+ userId: getActiveUser()._id,
6974
+ };
6975
+ return (_a = pullFromCache([
6976
+ 'channelMarker',
6977
+ 'get',
6978
+ getResolver('channelMarker')(key),
6979
+ ])) === null || _a === void 0 ? void 0 : _a.data;
6980
+ };
6981
+ const getUnreadInfoCached$1 = (channelId) => {
6982
+ var _a;
6983
+ return (_a = pullFromCache(['channelUnreadInfo', 'get', channelId])) === null || _a === void 0 ? void 0 : _a.data;
6984
+ };
6985
+ /**
6986
+ * The function use to get value of hasMentioned or isMentioned field.
6987
+ * function will get the value from marker params first, if there is no hasMentioned field, will look in to the cache.
6782
6988
  *
6783
- * Although this is a very simple utility, it's only purpose is to keep things
6784
- * DRY
6785
- */
6786
- const inferIsDeleted = (includeDeleted) => includeDeleted === true ? undefined : false;
6787
-
6788
- function getSubChannelIsMentioned(channelId, subChannelId, marker) {
6789
- var _a, _b;
6790
- // Look for `unreadCount` in the marker param first
6791
- if (marker) {
6792
- return marker.hasMentioned;
6793
- }
6794
- const client = getActiveClient();
6795
- // If consistent mode is enabled, look in the SubChannelUnreadCountInfo cache
6796
- if (client.isUnreadCountEnabled && client.getMarkerSyncConsistentMode()) {
6797
- const cachedUnreadCount = (_a = pullFromCache([
6798
- 'subChannelUnreadInfo',
6799
- 'get',
6800
- subChannelId,
6801
- ])) === null || _a === void 0 ? void 0 : _a.data;
6802
- if (cachedUnreadCount) {
6803
- return cachedUnreadCount.isMentioned;
6804
- }
6805
- return false;
6989
+ * If consistent mode is enabled, the function will return the value from the channelUnreadCountInfo cache.
6990
+ * If not, the function will return the value from the channelMarker cache.
6991
+ * If not found in the both cache, use `false` as defaul value.
6992
+ */
6993
+ const getChannelIsMentioned = (channel, marker) => {
6994
+ var _a, _b, _c, _d;
6995
+ const client = getActiveClient();
6996
+ if (client.isUnreadCountEnabled && client.getMarkerSyncConsistentMode()) {
6997
+ return (_b = (_a = getUnreadInfoCached$1(channel.channelPublicId)) === null || _a === void 0 ? void 0 : _a.isMentioned) !== null && _b !== void 0 ? _b : false;
6806
6998
  }
6999
+ return (marker === null || marker === void 0 ? void 0 : marker.hasMentioned) !== undefined
7000
+ ? marker === null || marker === void 0 ? void 0 : marker.hasMentioned
7001
+ : (_d = (_c = getCachedMarker$1(channel.channelPublicId)) === null || _c === void 0 ? void 0 : _c.hasMentioned) !== null && _d !== void 0 ? _d : false;
7002
+ };
7003
+
7004
+ const getCachedMarker = (entityId) => {
7005
+ var _a;
6807
7006
  const key = {
6808
- entityId: channelId,
6809
- feedId: subChannelId,
7007
+ entityId,
6810
7008
  userId: getActiveUser()._id,
6811
7009
  };
6812
- // If the marker param is not set, look in the cache
6813
- const cachedMarker = (_b = pullFromCache([
6814
- 'subChannelMarker',
7010
+ return (_a = pullFromCache([
7011
+ 'channelMarker',
6815
7012
  'get',
6816
- getResolver('subChannelMarker')(key),
6817
- ])) === null || _b === void 0 ? void 0 : _b.data;
6818
- if (cachedMarker) {
6819
- return cachedMarker.hasMentioned;
6820
- }
6821
- // and if not found in cache use default value `false`
6822
- return false;
6823
- }
6824
-
6825
- function getSubChannelUnreadCount(channelId, subChannelId, marker) {
6826
- var _a, _b;
6827
- // Look for `unreadCount` in the marker param first
6828
- if (marker) {
6829
- return marker.unreadCount;
6830
- }
7013
+ getResolver('channelMarker')(key),
7014
+ ])) === null || _a === void 0 ? void 0 : _a.data;
7015
+ };
7016
+ const getUnreadInfoCached = (channelId) => {
7017
+ var _a;
7018
+ return (_a = pullFromCache(['channelUnreadInfo', 'get', channelId])) === null || _a === void 0 ? void 0 : _a.data;
7019
+ };
7020
+ /**
7021
+ * The function use to get value of unreadCount field.
7022
+ * function will get the value from marker params first, if there is no hasMentioned field, will look in to the cache.
7023
+ *
7024
+ * If consistent mode is enabled, the function will return the value from the channelUnreadCountInfo cache.
7025
+ * If not, the function will return the value from the channelMarker cache.
7026
+ * If not found in the both cache, use `0` as defaul value.
7027
+ */
7028
+ const getSubChannelsUnreadCount = (channel, marker) => {
7029
+ var _a, _b, _c, _d, _e;
6831
7030
  const client = getActiveClient();
6832
- // If consistent mode is enabled, look in the SubChannelUnreadCountInfo cache
6833
7031
  if (client.isUnreadCountEnabled && client.getMarkerSyncConsistentMode()) {
6834
- const cachedUnreadCount = (_a = pullFromCache([
6835
- 'subChannelUnreadInfo',
6836
- 'get',
6837
- subChannelId,
6838
- ])) === null || _a === void 0 ? void 0 : _a.data;
6839
- if (cachedUnreadCount) {
6840
- return cachedUnreadCount.isDeleted ? 0 : cachedUnreadCount.unreadCount;
6841
- }
6842
- return 0;
7032
+ // Marker service API uses channelInternalId as channelId
7033
+ return (_b = (_a = getUnreadInfoCached(channel.channelInternalId)) === null || _a === void 0 ? void 0 : _a.unreadCount) !== null && _b !== void 0 ? _b : 0;
6843
7034
  }
6844
- const key = {
6845
- entityId: channelId,
6846
- feedId: subChannelId,
6847
- userId: getActiveUser()._id,
6848
- };
6849
- // If the marker param is not set, look in the cache
6850
- const cachedMarker = (_b = pullFromCache([
6851
- 'subChannelMarker',
6852
- 'get',
6853
- getResolver('subChannelMarker')(key),
6854
- ])) === null || _b === void 0 ? void 0 : _b.data;
6855
- if (cachedMarker) {
6856
- return cachedMarker.unreadCount;
7035
+ if (marker === null || marker === void 0 ? void 0 : marker.isDeleted) {
7036
+ // NOTE: This is a temporary solution to handle the channel marker when the user is forced to
7037
+ // leave the channel because currently backend can't handle this, so every time a user is banned
7038
+ // from a channel or the channel is deleted the channel's unread count will reset to zero
7039
+ return 0;
6857
7040
  }
6858
- // and if not found in cache use default value `0`
6859
- return 0;
6860
- }
7041
+ 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;
7042
+ };
6861
7043
 
6862
- const MARKER_INCLUDED_SUB_CHANNEL_TYPE$1 = ['broadcast', 'conversation', 'community'];
6863
- const isUnreadCountSupport$1 = ({ channelType }) => MARKER_INCLUDED_SUB_CHANNEL_TYPE$1.includes(channelType);
6864
- function convertFromRaw$1(_a) {
6865
- 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"]);
6866
- return Object.assign(Object.assign({ get unreadCount() {
6867
- return getSubChannelUnreadCount(channelId, messageFeedId);
7044
+ const constructChannelDynamicValue = (channel) => {
7045
+ return shallowClone(channel, {
7046
+ get unreadCount() {
7047
+ return getSubChannelsUnreadCount(channel);
6868
7048
  },
6869
7049
  get hasMentioned() {
6870
- return getSubChannelIsMentioned(channelId, messageFeedId);
7050
+ return getChannelIsMentioned(channel);
6871
7051
  },
6872
7052
  get isMentioned() {
6873
- return getSubChannelIsMentioned(channelId, messageFeedId);
6874
- } }, rest), { channelId: channelPublicId, creatorId: creatorPublicId, displayName: name, lastActivity: lastMessageTimestamp, latestMessageId: lastMessageId, messageCount: childCount, subChannelId: messageFeedId, isUnreadCountSupport: isUnreadCountSupport$1({ channelType }) });
6875
- }
7053
+ return getChannelIsMentioned(channel);
7054
+ },
7055
+ get subChannelsUnreadCount() {
7056
+ return getSubChannelsUnreadCount(channel);
7057
+ },
7058
+ });
7059
+ };
6876
7060
 
6877
- const addLocalReferenceId = (payload) => {
7061
+ /**
7062
+ * ```js
7063
+ * import { getChannelByIds } from '@amityco/ts-sdk-react-native'
7064
+ * const channels = await getChannelByIds(['foo', 'bar'])
7065
+ * ```
7066
+ *
7067
+ * Fetches a collection of {@link Amity.Channel} objects
7068
+ *
7069
+ * @param channelIds the IDs of the {@link Amity.Channel} to fetch
7070
+ * @returns the associated collection of {@link Amity.Channel} objects
7071
+ *
7072
+ * @category Channel API
7073
+ * @async
7074
+ */
7075
+ const getChannelByIds = async (channelIds) => {
6878
7076
  const client = getActiveClient();
6879
- const { objectSyncMap } = client;
6880
- return Object.assign(Object.assign({}, payload), {
6881
- /* NOTE: This logic is used to get local referenceId for each message.
6882
- *
6883
- * if messageId is a local reference id, use it as referenceId else get referenceId from objectSyncMap.
6884
- * if find referenceId in objectSyncMap, this means this message is a local created message. The referenceId will be local reference id.
6885
- * if cannot find referenceId in objectSyncMap, referenceId will be undefined.
6886
- *
6887
- * The referenceId is undefined means this message is not a local created message (optimistic creation message).
6888
- */
6889
- referenceId: isLocalId(payload.messageId)
6890
- ? payload.messageId
6891
- : objectSyncMap.get(payload.messageId) });
6892
- };
6893
- function convertFromRaw(message, reactors, event) {
6894
- var _a;
6895
- const messageWithReferenceId = addLocalReferenceId(message);
6896
- const { channelPublicId, childCount, creatorPublicId, mentionedUsers, messageFeedId, myReactions, reactionCount, reactions, referenceId, segment, messageId, creatorId } = messageWithReferenceId, rest = __rest(messageWithReferenceId, ["channelPublicId", "childCount", "creatorPublicId", "mentionedUsers", "messageFeedId", "myReactions", "reactionCount", "reactions", "referenceId", "segment", "messageId", "creatorId"]);
6897
- let cache;
6898
- if (referenceId) {
6899
- cache = pullFromCache(['message', 'get', referenceId]);
6900
- }
6901
- if (!cache) {
6902
- cache = pullFromCache(['message', 'get', messageId]);
6903
- }
6904
- 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 : {},
6905
- /*
6906
- * Previously, myReactions were added only if it was part of the payload.
6907
- * So empty myReactions were not present. So I've edited the payload to add
6908
- * a default for those cases.
6909
- *
6910
- * Check git blame for previous iteration
6911
- */
6912
- 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 */ });
6913
- if (mentionedUsers) {
6914
- out.mentionees = mentionedUsers.map(mention => {
6915
- if (mention.type === 'channel') {
6916
- return mention;
6917
- }
6918
- return { type: 'user', userIds: mention.userPublicIds };
7077
+ client.log('channel/getChannelByIds', channelIds);
7078
+ const encodedChannelIds = channelIds.map(channelId => encodeURIComponent(channelId));
7079
+ let payload;
7080
+ try {
7081
+ // API-FIX: endpoint should not be /list, parameters should be querystring.
7082
+ const response = await client.http.get(`/api/v3/channels/list`, {
7083
+ params: { channelIds: encodedChannelIds },
6919
7084
  });
7085
+ payload = response.data;
6920
7086
  }
6921
- if (reactors && reactors.length && event) {
6922
- // mqtt event
6923
- prepareMessagePayloadForCache(out, reactors, event);
6924
- }
6925
- return out;
6926
- }
6927
- const preUpdateMessageCache = (rawPayload) => {
6928
- ingestInCache({
6929
- messages: rawPayload.messages.map(message => convertFromRaw(message, rawPayload.reactions)),
6930
- });
6931
- };
6932
- const DEBOUNCE_TIME = 2000;
6933
- const currentDebounceMap = {};
6934
- const prepareMessagePayload = async (payload, event) => {
6935
- const markerIds = payload.messages.map(({ messageId }) => messageId);
6936
- if (markerIds.length > 0) {
6937
- // since the get markers method requires a channel cache to function with the reducer.
6938
- preUpdateMessageCache(payload);
6939
- const markerIdsKey = markerIds.join('');
6940
- if (currentDebounceMap[markerIdsKey]) {
6941
- clearTimeout(currentDebounceMap[markerIdsKey]);
6942
- }
6943
- currentDebounceMap[markerIdsKey] = setTimeout(() => {
6944
- try {
6945
- getMessageMarkers(markerIds);
6946
- }
6947
- catch (_error) {
6948
- // do nothing
7087
+ catch (error) {
7088
+ channelIds.forEach(channelId => {
7089
+ if (checkIfShouldGoesToTombstone(error === null || error === void 0 ? void 0 : error.code)) {
7090
+ // NOTE: use channelPublicId as tombstone cache key since we cannot get the channelPrivateId that come along with channel data from server
7091
+ pushToTombstone('channel', channelId);
6949
7092
  }
6950
- }, DEBOUNCE_TIME);
6951
- }
6952
- const { messageFeeds } = payload, restPayload = __rest(payload, ["messageFeeds"]);
6953
- // upsert messageFeeds to subchannel cache because messageFeeds from event payload not include messagePreviewId
6954
- if (messageFeeds && messageFeeds.length > 0) {
6955
- messageFeeds === null || messageFeeds === void 0 ? void 0 : messageFeeds.forEach(messageFeed => {
6956
- var _a, _b;
6957
- const subChannelCache = (_b = (_a = pullFromCache(['subChannel', 'get', messageFeed.messageFeedId])) === null || _a === void 0 ? void 0 : _a.data) !== null && _b !== void 0 ? _b : {};
6958
- // exclude getter properties from existing subChannel cache, update only other properties to existing subChannel cache
6959
- const _c = convertFromRaw$1(messageFeed), restSubChannel = __rest(_c, ["unreadCount", "hasMentioned", "isMentioned"]);
6960
- updateSubChannelCache(messageFeed.messageFeedId, subChannelCache, restSubChannel);
6961
7093
  });
7094
+ throw error;
6962
7095
  }
6963
- return Object.assign(Object.assign({}, restPayload), { messages: payload.messages.map(m => convertFromRaw(m, payload.reactions, event)) });
6964
- };
6965
- function convertParams(_a) {
6966
- var { subChannelId, mentionees, dataType, data } = _a, rest = __rest(_a, ["subChannelId", "mentionees", "dataType", "data"]);
6967
- if (dataType === MessageContentType.IMAGE || dataType === MessageContentType.FILE) {
6968
- return Object.assign({ messageFeedId: subChannelId, mentionedUsers: mentionees, dataType, data: Object.assign({ caption: '' }, data) }, rest);
6969
- }
6970
- return Object.assign({ messageFeedId: subChannelId, mentionedUsers: mentionees, dataType, data }, rest);
6971
- }
6972
- function convertQueryParams$1(_a) {
6973
- var { sortBy, subChannelId, tags, includingTags, excludingTags, includeDeleted, aroundMessageId, limit, type } = _a, rest = __rest(_a, ["sortBy", "subChannelId", "tags", "includingTags", "excludingTags", "includeDeleted", "aroundMessageId", "limit", "type"]);
6974
- const out = Object.assign(Object.assign({}, rest), { messageFeedId: subChannelId, isDeleted: inferIsDeleted(includeDeleted), options: {
6975
- sortBy,
6976
- limit: limit || COLLECTION_DEFAULT_PAGINATION_LIMIT,
6977
- around: aroundMessageId,
6978
- } });
6979
- if (tags) {
6980
- out.includeTags = tags;
6981
- }
6982
- if (includingTags) {
6983
- out.includeTags = includingTags;
6984
- }
6985
- if (type) {
6986
- out.dataType = type;
6987
- }
6988
- if (excludingTags) {
6989
- out.excludeTags = excludingTags;
7096
+ const data = await prepareChannelPayload(payload);
7097
+ if (client.isUnreadCountEnabled && client.getMarkerSyncConsistentMode()) {
7098
+ await prepareUnreadCountInfo(payload);
6990
7099
  }
6991
- return out;
6992
- }
6993
-
6994
- const MARKER_INCLUDED_SUB_CHANNEL_TYPE = ['broadcast', 'conversation', 'community'];
7100
+ const cachedAt = client.cache && Date.now();
7101
+ if (client.cache)
7102
+ ingestInCache(data, { cachedAt });
7103
+ fireEvent('local.channel.fetched', data.channels);
7104
+ return {
7105
+ data: data.channels.map(channel => LinkedObject.channel(constructChannelDynamicValue(channel))),
7106
+ cachedAt,
7107
+ };
7108
+ };
6995
7109
  /**
6996
- * Filter sub channel by type. Only conversation, community and broadcast type are included.
7110
+ * ```js
7111
+ * import { getChannelByIds } from '@amityco/ts-sdk-react-native'
7112
+ * const channels = getChannelByIds.locally(['foo', 'bar']) ?? []
7113
+ * ```
7114
+ *
7115
+ * Fetches a collection of {@link Amity.Channel} objects from cache
7116
+ *
7117
+ * @param channelIds the IDs of the {@link Amity.Channel} to fetch
7118
+ * @returns the associated collection of {@link Amity.Channel} objects
7119
+ *
7120
+ * @category Channel API
6997
7121
  */
6998
- const isUnreadCountSupport = ({ channelType }) => MARKER_INCLUDED_SUB_CHANNEL_TYPE.includes(channelType);
6999
- const preUpdateSubChannelCache = (rawPayload) => {
7000
- ingestInCache({
7001
- messageFeeds: rawPayload.messageFeeds.map(messageFeed => convertFromRaw$1(messageFeed)),
7122
+ getChannelByIds.locally = (channelIds) => {
7123
+ var _a, _b;
7124
+ const client = getActiveClient();
7125
+ client.log('channel/getChannelByIds.locally', channelIds);
7126
+ if (!client.cache)
7127
+ return;
7128
+ const cached = (_a = queryCache(['channel', 'get'])) === null || _a === void 0 ? void 0 : _a.filter(({ data }) => {
7129
+ return channelIds.includes(data.channelPublicId);
7002
7130
  });
7003
- };
7004
- const prepareSubChannelPayload = async (rawPayload) => {
7005
- const markerIds = rawPayload.messageFeeds
7006
- .filter(isUnreadCountSupport)
7007
- .map(({ messageFeedId }) => messageFeedId);
7008
- if (markerIds.length > 0) {
7009
- // since the get markers method requires a channel cache to function with the reducer.
7010
- preUpdateSubChannelCache(rawPayload);
7011
- try {
7012
- await getSubChannelMarkers(markerIds);
7013
- }
7014
- catch (e) {
7015
- // empty block (from the spec, allow marker fetch to fail without having to do anything)
7016
- }
7017
- }
7018
- updateSubChannelMessagePreviewCache(rawPayload);
7019
- // attach marker to sub channel
7020
- const messageFeeds = rawPayload.messageFeeds.map(convertFromRaw$1);
7021
- const messages = rawPayload.messages.map(m => convertFromRaw(m));
7022
- return Object.assign(Object.assign({}, rawPayload), { messageFeeds,
7023
- messages });
7024
- };
7025
- function convertQueryParams(_a) {
7026
- var { excludeDefaultSubChannel } = _a, rest = __rest(_a, ["excludeDefaultSubChannel"]);
7027
- const out = Object.assign({}, rest);
7028
- if (excludeDefaultSubChannel !== undefined) {
7029
- out.excludeDefaultMessageFeed = excludeDefaultSubChannel;
7030
- }
7031
- return out;
7032
- }
7131
+ if (!cached || (cached === null || cached === void 0 ? void 0 : cached.length) < channelIds.length)
7132
+ return;
7133
+ const channels = cached.map(({ data }) => data);
7134
+ const oldest = (_b = cached.sort((a, b) => (a.cachedAt < b.cachedAt ? -1 : 1))) === null || _b === void 0 ? void 0 : _b[0];
7135
+ return {
7136
+ data: channels.map(channel => LinkedObject.channel(channel)),
7137
+ cachedAt: oldest.cachedAt,
7138
+ };
7139
+ };
7033
7140
 
7034
7141
  class SessionWatcher {
7035
7142
  constructor() {
@@ -7113,99 +7220,6 @@ const onOnline = (callback) => {
7113
7220
  return () => console.error('Unsupported environment');
7114
7221
  };
7115
7222
 
7116
- /**
7117
- * ```js
7118
- * import { isInTombstone } from '@amityco/ts-sdk-react-native'
7119
- * const user = isInTombstone(["message", "messageId"])
7120
- * ```
7121
- *
7122
- * Checks if the {@link Amity.TombstoneCacheOptions} exists
7123
- * in cache and it's not expired means it's in tombstone
7124
- * and we throw an Error
7125
- *
7126
- * @param model the model to check
7127
- * @param modelId the object id to check
7128
- * @returns the matching cache entry, or undefined.
7129
- *
7130
- * @category Cache API
7131
- */
7132
- const isInTombstone = (model, modelId) => {
7133
- const { log, cache } = getActiveClient();
7134
- const key = [model, CACHE_KEY_TOMBSTONE, modelId];
7135
- if (!cache)
7136
- return;
7137
- log('cache/api/isInTombstone', key);
7138
- const isInTombstone = pullFromCache(key);
7139
- const { lifeSpan } = queryOptions('cache_then_server', CACHE_LIFESPAN_TOMBSTONE);
7140
- if (isInTombstone && isFresh(isInTombstone.data, lifeSpan)) {
7141
- throw new ASCApiError('Item not found!', 400400 /* Amity.ServerError.ITEM_NOT_FOUND */, "error" /* Amity.ErrorLevel.ERROR */);
7142
- }
7143
- };
7144
-
7145
- /**
7146
- * ```js
7147
- * import { getSubChannel } from '@amityco/ts-sdk-react-native'
7148
- * const subChannel = await getSubChannel('foobar')
7149
- * ```
7150
- *
7151
- * Fetches a {@link Amity.SubChannel} object
7152
- *
7153
- * @param subChannelId the ID of the {@link Amity.SubChannel} to fetch
7154
- * @returns the associated {@link Amity.SubChannel} object
7155
- *
7156
- * @category Channel API
7157
- * @async
7158
- */
7159
- const getSubChannel$1 = async (subChannelId) => {
7160
- const client = getActiveClient();
7161
- client.log('channel/getSubChannel', subChannelId);
7162
- isInTombstone('subChannel', subChannelId);
7163
- try {
7164
- const response = await client.http.get(`/api/v5/message-feeds/${encodeURIComponent(subChannelId)}`);
7165
- const data = await prepareSubChannelPayload(response.data);
7166
- const cachedAt = client.cache && Date.now();
7167
- if (client.cache)
7168
- ingestInCache(data, { cachedAt });
7169
- fireEvent('local.message-feed.fetched', data);
7170
- return {
7171
- data: data.messageFeeds[0],
7172
- cachedAt,
7173
- };
7174
- }
7175
- catch (error) {
7176
- if (checkIfShouldGoesToTombstone(error === null || error === void 0 ? void 0 : error.code)) {
7177
- pushToTombstone('subChannel', subChannelId);
7178
- }
7179
- throw error;
7180
- }
7181
- };
7182
- /**
7183
- * ```js
7184
- * import { getSubChannel } from '@amityco/ts-sdk-react-native'
7185
- * const subChannel = getSubChannel.locally('foobar')
7186
- * ```
7187
- *
7188
- * Fetches a {@link Amity.SubChannel} object from cache
7189
- *
7190
- * @param subChannelId the ID of the {@link Amity.SubChannel} to fetch
7191
- * @returns the associated {@link Amity.SubChannel} object
7192
- *
7193
- * @category Channel API
7194
- */
7195
- getSubChannel$1.locally = (subChannelId) => {
7196
- const client = getActiveClient();
7197
- client.log('channel/getSubChannel.locally', subChannelId);
7198
- if (!client.cache)
7199
- return;
7200
- const cached = pullFromCache(['subChannel', 'get', subChannelId]);
7201
- if (!cached)
7202
- return;
7203
- return {
7204
- data: cached.data,
7205
- cachedAt: cached.cachedAt,
7206
- };
7207
- };
7208
-
7209
7223
  /**
7210
7224
  * ```js
7211
7225
  * import { SubChannel } from '@amityco/ts-sdk-react-native'
@@ -9087,7 +9101,7 @@ const registerEventListeners = () => {
9087
9101
  }), onMessageCreatedMqtt(message => {
9088
9102
  // only conversation, community and broadcast types can sync
9089
9103
  const client = getActiveClient();
9090
- if (isUnreadCountSupport(message) && message.creatorId !== client.userId)
9104
+ if (isUnreadCountSupport$1(message) && message.creatorId !== client.userId)
9091
9105
  events.push("new message" /* Amity.MarkerSyncEvent.NEW_MESSAGE */);
9092
9106
  }), onChannelCreated(() => events.push("subchannel is created" /* Amity.MarkerSyncEvent.CHANNEL_CREATED */)), onChannelDeleted(() => events.push("subchannel is deleted" /* Amity.MarkerSyncEvent.CHANNEL_DELETED */)), onChannelJoined(() => events.push("subchannel is joined" /* Amity.MarkerSyncEvent.CHANNEL_JOINED */)), onChannelLeft(() => events.push("subchannel is left" /* Amity.MarkerSyncEvent.CHANNEL_LEFT */)), onSubChannelCreated(() => events.push("subchannel is created" /* Amity.MarkerSyncEvent.SUB_CHANNEL_CREATED */)), onSubChannelDeleted(() =>
9093
9107
  /*
@@ -17030,7 +17044,7 @@ var index$g = /*#__PURE__*/Object.freeze({
17030
17044
  getMessages: getMessages,
17031
17045
  observeMessage: observeMessage,
17032
17046
  observeMessages: observeMessages,
17033
- convertFromRaw: convertFromRaw,
17047
+ convertFromRaw: convertFromRaw$1,
17034
17048
  prepareMessagePayload: prepareMessagePayload,
17035
17049
  convertParams: convertParams,
17036
17050
  convertQueryParams: convertQueryParams$1,
@@ -17128,52 +17142,18 @@ const getSubChannel = (subChannelId, callback) => {
17128
17142
  });
17129
17143
  },
17130
17144
  convertEventPayload((callback) => {
17131
- const updateMessagePreview = async (message) => {
17132
- var _a;
17133
- const messagePreviewSetting = await client.getMessagePreviewSetting(false);
17134
- if (messagePreviewSetting === "no-message-preview" /* Amity.MessagePreviewSetting.NO_MESSAGE_PREVIEW */)
17135
- return;
17136
- await handleMessageCreated(message);
17145
+ return onMessageCreatedMqtt(async (message) => {
17137
17146
  if (message.subChannelId !== subChannelId)
17138
17147
  return;
17139
- const subChannel = (_a = pullFromCache([
17140
- 'subChannel',
17141
- 'get',
17142
- subChannelId,
17143
- ])) === null || _a === void 0 ? void 0 : _a.data;
17144
- if (!subChannel)
17145
- return;
17146
- updateSubChannelCache(message.subChannelId, subChannel, {
17147
- messagePreviewId: message.messageId,
17148
- });
17149
- };
17150
- return onMessageCreatedMqtt(async (message) => {
17151
- await updateMessagePreview(message);
17148
+ await handleMessageCreatedOnSubChannel(message);
17152
17149
  callback(message);
17153
17150
  });
17154
17151
  }, 'subChannelId', 'subChannel'),
17155
17152
  convertEventPayload((callback) => {
17156
- const updateMessagePreview = async (message) => {
17157
- var _a;
17158
- const messagePreviewSetting = await client.getMessagePreviewSetting(false);
17159
- if (messagePreviewSetting === "no-message-preview" /* Amity.MessagePreviewSetting.NO_MESSAGE_PREVIEW */)
17160
- return;
17161
- await handleMessageCreated(message);
17153
+ return onMessageCreatedLocal(async (message) => {
17162
17154
  if (message.subChannelId !== subChannelId)
17163
17155
  return;
17164
- const subChannel = (_a = pullFromCache([
17165
- 'subChannel',
17166
- 'get',
17167
- subChannelId,
17168
- ])) === null || _a === void 0 ? void 0 : _a.data;
17169
- if (!subChannel)
17170
- return;
17171
- updateSubChannelCache(message.subChannelId, subChannel, {
17172
- messagePreviewId: message.messageId,
17173
- });
17174
- };
17175
- return onMessageCreatedLocal(async (message) => {
17176
- await updateMessagePreview(message);
17156
+ await handleMessageCreatedOnSubChannel(message);
17177
17157
  callback(message);
17178
17158
  });
17179
17159
  }, 'subChannelId', 'subChannel'),
@@ -17184,7 +17164,7 @@ const getSubChannel = (subChannelId, callback) => {
17184
17164
  return;
17185
17165
  if (message.subChannelId !== subChannelId)
17186
17166
  return;
17187
- handleMessageUpdated(message);
17167
+ handleMessageUpdatedOnSubChannel(message);
17188
17168
  callback(message);
17189
17169
  // TODO: messageFeeds on onMessageUpdated event does not have messagePreviewId and it will save before that cause messagePreview
17190
17170
  };
@@ -17198,7 +17178,7 @@ const getSubChannel = (subChannelId, callback) => {
17198
17178
  if (message.subChannelId !== subChannelId)
17199
17179
  return;
17200
17180
  if (messagePreviewSetting === "message-preview-include-deleted" /* Amity.MessagePreviewSetting.MESSAGE_PREVIEW_INCLUDE_DELETED */)
17201
- await handleMessageUpdated(message);
17181
+ await handleMessageUpdatedOnSubChannel(message);
17202
17182
  if (messagePreviewSetting ===
17203
17183
  "message-preview-not-include-deleted" /* Amity.MessagePreviewSetting.MESSAGE_PREVIEW_NOT_INCLUDE_DELETED */) {
17204
17184
  await getSubChannel$1(message.subChannelId);
@@ -17322,15 +17302,15 @@ class SubChannelLiveCollectionController extends LiveCollectionController {
17322
17302
  {
17323
17303
  fn: callback => {
17324
17304
  return onSubChannelUpdated(async (subChannel) => {
17325
- var _a;
17326
- const collection = (_a = pullFromCache(this.cacheKey)) === null || _a === void 0 ? void 0 : _a.data;
17327
- if (!collection || !collection.data.includes(subChannel.subChannelId))
17305
+ if (!this.isRelatedCollection(subChannel.subChannelId))
17328
17306
  return;
17329
17307
  const client = getActiveClient();
17330
17308
  const messagePreviewSetting = await client.getMessagePreviewSetting(false);
17331
17309
  if (messagePreviewSetting !== "no-message-preview" /* Amity.MessagePreviewSetting.NO_MESSAGE_PREVIEW */) {
17332
17310
  const messagePreview = getSubChannelMessagePreview(subChannel.subChannelId);
17333
- if ((messagePreview === null || messagePreview === void 0 ? void 0 : messagePreview.subChannelId) === subChannel.subChannelId) {
17311
+ if ((messagePreview === null || messagePreview === void 0 ? void 0 : messagePreview.subChannelId) === subChannel.subChannelId &&
17312
+ convertDateStringToTimestamp(subChannel.updatedAt) >
17313
+ convertDateStringToTimestamp(messagePreview.subChannelUpdatedAt)) {
17334
17314
  pushToCache(['messagePreviewSubChannel', 'get', subChannel.subChannelId], Object.assign(Object.assign({}, messagePreview), { subChannelName: subChannel.displayName, subChannelUpdatedAt: subChannel.updatedAt }));
17335
17315
  }
17336
17316
  }
@@ -17340,76 +17320,27 @@ class SubChannelLiveCollectionController extends LiveCollectionController {
17340
17320
  action: 'onUpdate',
17341
17321
  },
17342
17322
  {
17343
- fn: callback => {
17344
- const updateMessagePreview = async (message) => {
17345
- const client = getActiveClient();
17346
- const messagePreviewSetting = await client.getMessagePreviewSetting(false);
17347
- if (messagePreviewSetting === "no-message-preview" /* Amity.MessagePreviewSetting.NO_MESSAGE_PREVIEW */)
17348
- return;
17349
- handleMessageCreated(message);
17350
- };
17323
+ fn: convertEventPayload((callback) => {
17351
17324
  return onMessageCreatedMqtt(async (message) => {
17352
- var _a, _b;
17353
- const cacheData = pullFromCache([
17354
- 'subChannel',
17355
- 'get',
17356
- message.subChannelId,
17357
- ]);
17358
- if (!cacheData)
17359
- return;
17360
- const collection = (_a = pullFromCache(this.cacheKey)) === null || _a === void 0 ? void 0 : _a.data;
17361
- if (!collection || !collection.data.includes(message.subChannelId))
17362
- return;
17363
- await updateMessagePreview(message);
17364
- const subChannelCache = (_b = pullFromCache([
17365
- 'subChannel',
17366
- 'get',
17367
- message.subChannelId,
17368
- ])) === null || _b === void 0 ? void 0 : _b.data;
17369
- if (!subChannelCache)
17325
+ if (!this.isRelatedCollection(message.subChannelId))
17370
17326
  return;
17371
- updateSubChannelCache(message.subChannelId, subChannelCache, {
17372
- lastActivity: message.createdAt,
17373
- messagePreviewId: message.messageId,
17374
- });
17375
- callback(Object.assign(Object.assign({}, cacheData.data), { messagePreviewId: message.messageId, subChannelId: message.subChannelId, lastActivity: message.createdAt }));
17327
+ // Update related cache including message preview and subChannel cache (lastActivity, messagePreviewId)
17328
+ await handleMessageCreatedOnSubChannel(message);
17329
+ callback(message);
17376
17330
  });
17377
- },
17331
+ }, 'subChannelId', 'subChannel'),
17378
17332
  action: 'onUpdate',
17379
17333
  },
17380
17334
  {
17381
- fn: callback => {
17335
+ fn: convertEventPayload((callback) => {
17382
17336
  return onMessageCreatedLocal(async (message) => {
17383
- var _a, _b;
17384
- const cacheData = pullFromCache([
17385
- 'subChannel',
17386
- 'get',
17387
- message.subChannelId,
17388
- ]);
17389
- if (!cacheData)
17390
- return;
17391
- const collection = (_a = pullFromCache(this.cacheKey)) === null || _a === void 0 ? void 0 : _a.data;
17392
- if (!collection || !collection.data.includes(message.subChannelId))
17393
- return;
17394
- const client = getActiveClient();
17395
- const messagePreviewSetting = await client.getMessagePreviewSetting(false);
17396
- if (messagePreviewSetting === "no-message-preview" /* Amity.MessagePreviewSetting.NO_MESSAGE_PREVIEW */)
17397
- return;
17398
- handleMessageCreated(message);
17399
- const subChannelCache = (_b = pullFromCache([
17400
- 'subChannel',
17401
- 'get',
17402
- message.subChannelId,
17403
- ])) === null || _b === void 0 ? void 0 : _b.data;
17404
- if (!subChannelCache)
17337
+ if (!this.isRelatedCollection(message.subChannelId))
17405
17338
  return;
17406
- updateSubChannelCache(message.subChannelId, subChannelCache, {
17407
- lastActivity: message.createdAt,
17408
- messagePreviewId: message.messageId,
17409
- });
17410
- callback(Object.assign(Object.assign({}, cacheData.data), { messagePreviewId: message.messageId, subChannelId: message.subChannelId, lastActivity: message.createdAt }));
17339
+ // Update related cache including message preview and subChannel cache (lastActivity, messagePreviewId)
17340
+ await handleMessageCreatedOnSubChannel(message);
17341
+ callback(message);
17411
17342
  });
17412
- },
17343
+ }, 'subChannelId', 'subChannel'),
17413
17344
  action: 'onUpdate',
17414
17345
  },
17415
17346
  {
@@ -17442,7 +17373,7 @@ class SubChannelLiveCollectionController extends LiveCollectionController {
17442
17373
  const collection = (_a = pullFromCache(this.cacheKey)) === null || _a === void 0 ? void 0 : _a.data;
17443
17374
  if (!collection || !collection.data.includes(message.subChannelId))
17444
17375
  return;
17445
- handleMessageUpdated(message);
17376
+ handleMessageUpdatedOnSubChannel(message);
17446
17377
  callback(message);
17447
17378
  };
17448
17379
  return onMessageUpdated(updateMessagePreview);
@@ -17452,20 +17383,18 @@ class SubChannelLiveCollectionController extends LiveCollectionController {
17452
17383
  {
17453
17384
  fn: convertEventPayload((callback) => {
17454
17385
  const updateMessagePreview = async (message) => {
17455
- var _a;
17456
17386
  const client = getActiveClient();
17457
17387
  const messagePreviewSetting = await client.getMessagePreviewSetting(false);
17458
17388
  if (messagePreviewSetting === "no-message-preview" /* Amity.MessagePreviewSetting.NO_MESSAGE_PREVIEW */)
17459
17389
  return;
17460
- const collection = (_a = pullFromCache(this.cacheKey)) === null || _a === void 0 ? void 0 : _a.data;
17461
- if (!collection || !collection.data.includes(message.subChannelId))
17390
+ if (!this.isRelatedCollection(message.subChannelId))
17462
17391
  return;
17463
17392
  if (messagePreviewSetting ===
17464
17393
  "message-preview-not-include-deleted" /* Amity.MessagePreviewSetting.MESSAGE_PREVIEW_NOT_INCLUDE_DELETED */) {
17465
17394
  await getSubChannel$1(message.subChannelId);
17466
17395
  }
17467
17396
  else {
17468
- await handleMessageUpdated(message);
17397
+ await handleMessageUpdatedOnSubChannel(message);
17469
17398
  }
17470
17399
  callback(message);
17471
17400
  };
@@ -17507,6 +17436,11 @@ class SubChannelLiveCollectionController extends LiveCollectionController {
17507
17436
  subChannels.sort(sortByLastActivity);
17508
17437
  return subChannels;
17509
17438
  }
17439
+ isRelatedCollection(subChannelId) {
17440
+ var _a;
17441
+ const collection = (_a = pullFromCache(this.cacheKey)) === null || _a === void 0 ? void 0 : _a.data;
17442
+ return collection && collection.data.includes(subChannelId);
17443
+ }
17510
17444
  }
17511
17445
 
17512
17446
  /* eslint-disable no-use-before-define */
@@ -19022,8 +18956,8 @@ var index$c = /*#__PURE__*/Object.freeze({
19022
18956
  getChannel: getChannel,
19023
18957
  getChannels: getChannels,
19024
18958
  MARKER_INCLUDED_CHANNEL_TYPE: MARKER_INCLUDED_CHANNEL_TYPE,
19025
- isUnreadCountSupport: isUnreadCountSupport$2,
19026
- convertFromRaw: convertFromRaw$2,
18959
+ isUnreadCountSupport: isUnreadCountSupport,
18960
+ convertFromRaw: convertFromRaw,
19027
18961
  preUpdateChannelCache: preUpdateChannelCache,
19028
18962
  prepareChannelPayload: prepareChannelPayload
19029
18963
  });