@amityco/ts-sdk 7.1.1-ce25d503.0 → 7.1.1-e23f973a.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (140) hide show
  1. package/dist/@types/core/events.d.ts +5 -2
  2. package/dist/@types/core/events.d.ts.map +1 -1
  3. package/dist/@types/core/model.d.ts +4 -2
  4. package/dist/@types/core/model.d.ts.map +1 -1
  5. package/dist/@types/core/payload.d.ts +18 -0
  6. package/dist/@types/core/payload.d.ts.map +1 -1
  7. package/dist/@types/core/readReceipt.d.ts +1 -12
  8. package/dist/@types/core/readReceipt.d.ts.map +1 -1
  9. package/dist/@types/domains/channel.d.ts +0 -10
  10. package/dist/@types/domains/channel.d.ts.map +1 -1
  11. package/dist/@types/domains/client.d.ts +0 -1
  12. package/dist/@types/domains/client.d.ts.map +1 -1
  13. package/dist/@types/domains/notification.d.ts +82 -0
  14. package/dist/@types/domains/notification.d.ts.map +1 -0
  15. package/dist/@types/index.d.ts +1 -0
  16. package/dist/@types/index.d.ts.map +1 -1
  17. package/dist/channelRepository/events/onChannelDeleted.d.ts.map +1 -1
  18. package/dist/channelRepository/events/onChannelLeft.d.ts.map +1 -1
  19. package/dist/channelRepository/observers/getChannel.d.ts.map +1 -1
  20. package/dist/channelRepository/observers/getChannels/ChannelLiveCollectionController.d.ts.map +1 -1
  21. package/dist/channelRepository/observers/index.d.ts +0 -1
  22. package/dist/channelRepository/observers/index.d.ts.map +1 -1
  23. package/dist/channelRepository/utils/constructChannelDynamicValue.d.ts.map +1 -1
  24. package/dist/channelRepository/utils/prepareChannelPayload.d.ts.map +1 -1
  25. package/dist/client/api/createClient.d.ts.map +1 -1
  26. package/dist/client/api/enableUnreadCount.d.ts.map +1 -1
  27. package/dist/client/api/login.d.ts.map +1 -1
  28. package/dist/client/utils/ReadReceiptSync/readReceiptSyncEngine.d.ts +4 -2
  29. package/dist/client/utils/ReadReceiptSync/readReceiptSyncEngine.d.ts.map +1 -1
  30. package/dist/core/events.d.ts +3 -3
  31. package/dist/core/events.d.ts.map +1 -1
  32. package/dist/core/model/idResolvers.d.ts.map +1 -1
  33. package/dist/core/model/index.d.ts.map +1 -1
  34. package/dist/index.cjs.js +462 -567
  35. package/dist/index.d.ts +1 -0
  36. package/dist/index.d.ts.map +1 -1
  37. package/dist/index.esm.js +445 -551
  38. package/dist/index.umd.js +4 -4
  39. package/dist/{channelRepository → marker}/events/onChannelUnreadUpdatedLocal.d.ts +2 -2
  40. package/dist/marker/events/onChannelUnreadUpdatedLocal.d.ts.map +1 -0
  41. package/dist/messageRepository/events/onMessageCreated.d.ts.map +1 -1
  42. package/dist/messageRepository/observers/getMessage.d.ts.map +1 -1
  43. package/dist/messageRepository/utils/markReadMessage.d.ts.map +1 -1
  44. package/dist/notificationTray/api/index.d.ts +3 -0
  45. package/dist/notificationTray/api/index.d.ts.map +1 -0
  46. package/dist/notificationTray/api/markItemsSeen.d.ts +16 -0
  47. package/dist/notificationTray/api/markItemsSeen.d.ts.map +1 -0
  48. package/dist/notificationTray/api/markTraySeen.d.ts +19 -0
  49. package/dist/notificationTray/api/markTraySeen.d.ts.map +1 -0
  50. package/dist/notificationTray/events/index.d.ts +2 -0
  51. package/dist/notificationTray/events/index.d.ts.map +1 -0
  52. package/dist/notificationTray/events/onNotificationTraySeenUpdated.d.ts +17 -0
  53. package/dist/notificationTray/events/onNotificationTraySeenUpdated.d.ts.map +1 -0
  54. package/dist/notificationTray/index.d.ts +4 -0
  55. package/dist/notificationTray/index.d.ts.map +1 -0
  56. package/dist/notificationTray/internalApi/getNotificationTraySeen.d.ts +30 -0
  57. package/dist/notificationTray/internalApi/getNotificationTraySeen.d.ts.map +1 -0
  58. package/dist/notificationTray/observers/getNotificationTrayItems/NotificationTrayItemsLiveCollectionController.d.ts +13 -0
  59. package/dist/notificationTray/observers/getNotificationTrayItems/NotificationTrayItemsLiveCollectionController.d.ts.map +1 -0
  60. package/dist/notificationTray/observers/getNotificationTrayItems/NotificationTrayItemsPaginationController.d.ts +9 -0
  61. package/dist/notificationTray/observers/getNotificationTrayItems/NotificationTrayItemsPaginationController.d.ts.map +1 -0
  62. package/dist/notificationTray/observers/getNotificationTrayItems/NotificationTrayItemsQuerystreamController.d.ts +9 -0
  63. package/dist/notificationTray/observers/getNotificationTrayItems/NotificationTrayItemsQuerystreamController.d.ts.map +1 -0
  64. package/dist/notificationTray/observers/getNotificationTrayItems.d.ts +12 -0
  65. package/dist/notificationTray/observers/getNotificationTrayItems.d.ts.map +1 -0
  66. package/dist/notificationTray/observers/getNotificationTraySeen.d.ts +21 -0
  67. package/dist/notificationTray/observers/getNotificationTraySeen.d.ts.map +1 -0
  68. package/dist/notificationTray/observers/index.d.ts +3 -0
  69. package/dist/notificationTray/observers/index.d.ts.map +1 -0
  70. package/dist/notificationTray/utils/prepareNotificationTrayItemsPayload.d.ts +2 -0
  71. package/dist/notificationTray/utils/prepareNotificationTrayItemsPayload.d.ts.map +1 -0
  72. package/dist/utils/linkedObject/index.d.ts +1 -0
  73. package/dist/utils/linkedObject/index.d.ts.map +1 -1
  74. package/dist/utils/linkedObject/notificationTrayLinkedObject.d.ts +2 -0
  75. package/dist/utils/linkedObject/notificationTrayLinkedObject.d.ts.map +1 -0
  76. package/package.json +1 -1
  77. package/src/@types/core/events.ts +6 -2
  78. package/src/@types/core/model.ts +6 -4
  79. package/src/@types/core/payload.ts +25 -0
  80. package/src/@types/core/readReceipt.ts +1 -14
  81. package/src/@types/domains/channel.ts +0 -13
  82. package/src/@types/domains/client.ts +0 -2
  83. package/src/@types/domains/notification.ts +91 -0
  84. package/src/@types/index.ts +1 -0
  85. package/src/channelRepository/events/onChannelDeleted.ts +4 -17
  86. package/src/channelRepository/events/onChannelLeft.ts +3 -11
  87. package/src/channelRepository/observers/getChannel.ts +1 -3
  88. package/src/channelRepository/observers/getChannels/ChannelLiveCollectionController.ts +1 -6
  89. package/src/channelRepository/observers/index.ts +0 -1
  90. package/src/channelRepository/utils/constructChannelDynamicValue.ts +2 -12
  91. package/src/channelRepository/utils/prepareChannelPayload.ts +17 -57
  92. package/src/client/api/createClient.ts +0 -3
  93. package/src/client/api/enableUnreadCount.ts +0 -1
  94. package/src/client/api/login.ts +1 -5
  95. package/src/client/utils/ReadReceiptSync/readReceiptSyncEngine.ts +99 -70
  96. package/src/core/model/idResolvers.ts +3 -2
  97. package/src/core/model/index.ts +2 -0
  98. package/src/index.ts +2 -0
  99. package/src/{channelRepository → marker}/events/onChannelUnreadUpdatedLocal.ts +3 -3
  100. package/src/messageRepository/events/onMessageCreated.ts +1 -38
  101. package/src/messageRepository/observers/getMessage.ts +1 -0
  102. package/src/messageRepository/utils/markReadMessage.ts +3 -10
  103. package/src/notificationTray/api/index.ts +2 -0
  104. package/src/notificationTray/api/markItemsSeen.ts +59 -0
  105. package/src/notificationTray/api/markTraySeen.ts +65 -0
  106. package/src/notificationTray/events/index.ts +1 -0
  107. package/src/notificationTray/events/onNotificationTraySeenUpdated.ts +36 -0
  108. package/src/notificationTray/index.ts +3 -0
  109. package/src/notificationTray/internalApi/getNotificationTraySeen.ts +81 -0
  110. package/src/notificationTray/observers/getNotificationTrayItems/NotificationTrayItemsLiveCollectionController.ts +96 -0
  111. package/src/notificationTray/observers/getNotificationTrayItems/NotificationTrayItemsPaginationController.ts +31 -0
  112. package/src/notificationTray/observers/getNotificationTrayItems/NotificationTrayItemsQuerystreamController.ts +68 -0
  113. package/src/notificationTray/observers/getNotificationTrayItems.ts +44 -0
  114. package/src/notificationTray/observers/getNotificationTraySeen.ts +43 -0
  115. package/src/notificationTray/observers/index.ts +2 -0
  116. package/src/notificationTray/utils/prepareNotificationTrayItemsPayload.ts +12 -0
  117. package/src/utils/linkedObject/index.ts +2 -0
  118. package/src/utils/linkedObject/notificationTrayLinkedObject.ts +19 -0
  119. package/dist/channelRepository/api/markChannelsAsReadBySegment.d.ts +0 -16
  120. package/dist/channelRepository/api/markChannelsAsReadBySegment.d.ts.map +0 -1
  121. package/dist/channelRepository/events/onChannelUnreadUpdatedLocal.d.ts.map +0 -1
  122. package/dist/channelRepository/internalApi/getTotalChannelsUnread.d.ts +0 -11
  123. package/dist/channelRepository/internalApi/getTotalChannelsUnread.d.ts.map +0 -1
  124. package/dist/channelRepository/observers/getTotalChannelsUnread.d.ts +0 -20
  125. package/dist/channelRepository/observers/getTotalChannelsUnread.d.ts.map +0 -1
  126. package/dist/channelRepository/utils/getLegacyChannelUnread.d.ts +0 -2
  127. package/dist/channelRepository/utils/getLegacyChannelUnread.d.ts.map +0 -1
  128. package/dist/client/utils/ReadReceiptSync/legacyReadReceiptSyncEngine.d.ts +0 -33
  129. package/dist/client/utils/ReadReceiptSync/legacyReadReceiptSyncEngine.d.ts.map +0 -1
  130. package/dist/client/utils/ReadReceiptSync/legacyReadReceiptSyncEngineOnLoginHandler.d.ts +0 -3
  131. package/dist/client/utils/ReadReceiptSync/legacyReadReceiptSyncEngineOnLoginHandler.d.ts.map +0 -1
  132. package/dist/marker/events/onChannelUnreadInfoUpdatedLocal.d.ts +0 -12
  133. package/dist/marker/events/onChannelUnreadInfoUpdatedLocal.d.ts.map +0 -1
  134. package/src/channelRepository/api/markChannelsAsReadBySegment.ts +0 -29
  135. package/src/channelRepository/internalApi/getTotalChannelsUnread.ts +0 -38
  136. package/src/channelRepository/observers/getTotalChannelsUnread.ts +0 -129
  137. package/src/channelRepository/utils/getLegacyChannelUnread.ts +0 -5
  138. package/src/client/utils/ReadReceiptSync/legacyReadReceiptSyncEngine.ts +0 -267
  139. package/src/client/utils/ReadReceiptSync/legacyReadReceiptSyncEngineOnLoginHandler.ts +0 -21
  140. package/src/marker/events/onChannelUnreadInfoUpdatedLocal.ts +0 -29
@@ -32,9 +32,8 @@ import { isEqual } from '~/utils/isEqual';
32
32
  import { updateChannelCache } from '../utils/updateChannelCache';
33
33
  import { onChannelMarkerUpdated } from '~/marker/events/onChannelMarkerUpdated';
34
34
  import { onSubChannelCreated } from '~/subChannelRepository';
35
- import { onChannelUnreadInfoUpdatedLocal } from '~/marker/events/onChannelUnreadInfoUpdatedLocal';
35
+ import { onChannelUnreadUpdatedLocal } from '~/marker/events/onChannelUnreadUpdatedLocal';
36
36
  import { constructChannelObject } from '../utils/constructChannelObject';
37
- import { onChannelUnreadUpdatedLocal } from '../events/onChannelUnreadUpdatedLocal';
38
37
 
39
38
  /* begin_public_function
40
39
  id: channel.get
@@ -296,7 +295,6 @@ export const getChannel = (
296
295
  'channel',
297
296
  ),
298
297
  convertEventPayload(onSubChannelCreated, 'channelId', 'channel'),
299
- convertEventPayload(onChannelUnreadInfoUpdatedLocal, 'channelId', 'channel'),
300
298
  convertEventPayload(onChannelUnreadUpdatedLocal, 'channelId', 'channel'),
301
299
  ],
302
300
  {
@@ -55,9 +55,8 @@ import { prepareUnreadCountInfo } from '~/channelRepository/utils/prepareUnreadC
55
55
  import { resolveUnreadInfoOnChannelEvent } from '~/channelRepository/utils/resolveUnreadInfoOnChannelEvent';
56
56
  import { onChannelResolved } from '~/channelRepository/events/onChannelResolved';
57
57
  import { onUserMessageFeedMarkerResolved } from '~/marker/events/onUserMessageFeedMarkerResolved';
58
- import { onChannelUnreadInfoUpdatedLocal } from '~/marker/events/onChannelUnreadInfoUpdatedLocal';
58
+ import { onChannelUnreadUpdatedLocal } from '~/marker/events/onChannelUnreadUpdatedLocal';
59
59
  import { constructChannelObject } from '~/channelRepository/utils/constructChannelObject';
60
- import { onChannelUnreadUpdatedLocal } from '~/channelRepository/events/onChannelUnreadUpdatedLocal';
61
60
 
62
61
  export class ChannelLiveCollectionController extends LiveCollectionController<
63
62
  'channel',
@@ -567,10 +566,6 @@ export class ChannelLiveCollectionController extends LiveCollectionController<
567
566
  },
568
567
  action: Amity.ChannelActionType.OnResolveUnread,
569
568
  },
570
- {
571
- fn: convertEventPayload(onChannelUnreadInfoUpdatedLocal, 'channelId', 'channel'),
572
- action: Amity.ChannelActionType.OnUpdate,
573
- },
574
569
  {
575
570
  fn: convertEventPayload(onChannelUnreadUpdatedLocal, 'channelId', 'channel'),
576
571
  action: Amity.ChannelActionType.OnUpdate,
@@ -1,3 +1,2 @@
1
1
  export * from './getChannel';
2
2
  export * from './getChannels';
3
- export * from './getTotalChannelsUnread';
@@ -1,27 +1,17 @@
1
- import { get } from 'http';
2
1
  import { shallowClone } from '~/utils/shallowClone';
3
2
  import { getChannelIsMentioned } from './getChannelIsMentioned';
4
3
  import { getSubChannelsUnreadCount } from './getSubChannelsUnreadCount';
5
- import { getActiveClient } from '~/client/api/activeClient';
6
- import { getLegacyChannelUnread } from './getLegacyChannelUnread';
7
4
 
8
5
  export const constructChannelDynamicValue = (
9
6
  channel: Amity.StaticInternalChannel,
10
7
  ): Amity.InternalChannel => {
11
- const client = getActiveClient();
12
8
  const { messageCount, ...rest } = channel;
13
-
14
9
  return shallowClone(rest, {
15
- get unreadCount() {
16
- return getLegacyChannelUnread(rest.channelId)?.unreadCount ?? 0;
10
+ get isMentioned() {
11
+ return getChannelIsMentioned(rest);
17
12
  },
18
13
  get subChannelsUnreadCount() {
19
14
  return getSubChannelsUnreadCount(rest);
20
15
  },
21
- get isMentioned() {
22
- if (client.useLegacyUnreadCount)
23
- return getLegacyChannelUnread(rest.channelId)?.isMentioned ?? false;
24
- return getChannelIsMentioned(rest);
25
- },
26
16
  });
27
17
  };
@@ -5,8 +5,9 @@ import { getChannelMarkers } from '~/marker/api/getChannelMarkers';
5
5
  import { updateChannelMessagePreviewCache } from '~/messagePreview/utils';
6
6
  import { getActiveClient } from '~/client/api/activeClient';
7
7
  import { pullFromCache } from '~/cache/api/pullFromCache';
8
+ import { getSubChannelsUnreadCount } from './getSubChannelsUnreadCount';
9
+ import { getChannelIsMentioned } from './getChannelIsMentioned';
8
10
  import { convertRawUserToInternalUser } from '~/userRepository/utils/convertRawUserToInternalUser';
9
- import { pushToCache } from '~/cache/api';
10
11
 
11
12
  export const MARKER_INCLUDED_CHANNEL_TYPE = ['broadcast', 'conversation', 'community'];
12
13
  export const isUnreadCountSupport = ({ type }: Pick<Amity.RawChannel, 'type'>) =>
@@ -47,37 +48,6 @@ export const preUpdateChannelCache = (
47
48
  });
48
49
  };
49
50
 
50
- const updateChannelUnread = ({
51
- currentUserId,
52
- channels,
53
- channelUsers,
54
- }: {
55
- currentUserId: Amity.User['userId'];
56
- channels: Amity.RawChannel[];
57
- channelUsers: Amity.RawMembership<'channel'>[];
58
- }) => {
59
- for (let i = 0; i < channels.length; i += 1) {
60
- const cacheKey = ['channelUnread', 'get', channels[i].channelId];
61
- const { readToSegment, lastMentionedSegment } = channelUsers.find(
62
- channelUser =>
63
- channelUser.channelId === channels[i].channelId && channelUser.userId === currentUserId,
64
- ) || {
65
- readToSegment: 0,
66
- lastMentionedSegment: 0,
67
- };
68
-
69
- pushToCache(cacheKey, {
70
- channelId: channels[i].channelId,
71
- lastSegment: channels[i].messageCount,
72
- readToSegment,
73
- lastMentionedSegment,
74
- unreadCount: Math.max(channels[i].messageCount - readToSegment, 0),
75
- isMentioned: lastMentionedSegment > readToSegment,
76
- isDeleted: channels[i].isDeleted,
77
- });
78
- }
79
- };
80
-
81
51
  export const prepareChannelPayload = async (
82
52
  rawPayload: Amity.ChannelPayload,
83
53
  options: { isMessagePreviewUpdated?: boolean } = { isMessagePreviewUpdated: true },
@@ -94,38 +64,28 @@ export const prepareChannelPayload = async (
94
64
  updateChannelMessagePreviewCache(rawPayload);
95
65
  }
96
66
 
97
- if (client.useLegacyUnreadCount) {
98
- updateChannelUnread({
99
- channels: rawPayload.channels,
100
- channelUsers: rawPayload.channelUsers,
101
- currentUserId: client.userId!,
102
- });
103
- } else {
104
- const markerIds = rawPayload.channels
105
- // filter channel by type. Only conversation, community and broadcast type are included.
106
- .filter(isUnreadCountSupport)
107
- .map(({ channelInternalId }) => channelInternalId);
108
-
109
- if (markerIds.length > 0) {
110
- // since the get markers method requires a channel cache to function with the reducer.
111
- preUpdateChannelCache(rawPayload, {
112
- isMessagePreviewUpdated: options.isMessagePreviewUpdated,
113
- });
114
-
115
- try {
116
- await getChannelMarkers(markerIds);
117
- } catch (e) {
118
- // empty block (from the spec, allow marker fetch to fail without having to do anything)
119
- }
67
+ const markerIds = rawPayload.channels
68
+ // filter channel by type. Only conversation, community and broadcast type are included.
69
+ .filter(isUnreadCountSupport)
70
+ .map(({ channelInternalId }) => channelInternalId);
71
+
72
+ if (markerIds.length > 0) {
73
+ // since the get markers method requires a channel cache to function with the reducer.
74
+ preUpdateChannelCache(rawPayload, { isMessagePreviewUpdated: options.isMessagePreviewUpdated });
75
+
76
+ try {
77
+ await getChannelMarkers(markerIds);
78
+ } catch (e) {
79
+ // empty block (from the spec, allow marker fetch to fail without having to do anything)
120
80
  }
121
81
  }
122
82
 
123
- // convert raw channel to internal channel
83
+ // attach marker to channel
124
84
  const channels = rawPayload.channels.map(payload =>
125
85
  convertFromRaw(payload, { isMessagePreviewUpdated: options.isMessagePreviewUpdated }),
126
86
  );
127
87
 
128
- // convert raw channel user to membership (add user object)
88
+ // user marker to channel users
129
89
  const channelUsers: Amity.Membership<'channel'>[] = rawPayload.channelUsers.map(channelUser => {
130
90
  return convertRawMembershipToMembership<'channel'>(channelUser);
131
91
  });
@@ -86,8 +86,6 @@ export const createClient = (
86
86
  const sessionHandler = undefined;
87
87
 
88
88
  const isUnreadCountEnabled = false;
89
- // Legacy unread count is true by default
90
- const useLegacyUnreadCount = true;
91
89
 
92
90
  const client = {
93
91
  version: `${VERSION}`,
@@ -124,7 +122,6 @@ export const createClient = (
124
122
  use: () => setActiveClient(client),
125
123
 
126
124
  isUnreadCountEnabled,
127
- useLegacyUnreadCount,
128
125
 
129
126
  getMarkerSyncConsistentMode,
130
127
 
@@ -17,7 +17,6 @@ export const enableUnreadCount = () => {
17
17
  if (client.isUnreadCountEnabled) return false;
18
18
 
19
19
  client.isUnreadCountEnabled = true;
20
- client.useLegacyUnreadCount = false;
21
20
 
22
21
  client.emitter.emit('unreadCountEnabled', true);
23
22
 
@@ -11,7 +11,6 @@ import { onUserDeleted } from '~/userRepository/events/onUserDeleted';
11
11
 
12
12
  import analyticsEngineOnLoginHandler from '~/analytic/utils/analyticsEngineOnLoginHandler';
13
13
  import readReceiptSyncEngineOnLoginHandler from '~/client/utils/ReadReceiptSync/readReceiptSyncEngineOnLoginHandler';
14
- import legacyReadReceiptSyncEngineOnLoginHandler from '~/client/utils/ReadReceiptSync/legacyReadReceiptSyncEngineOnLoginHandler';
15
14
  import objectResolverEngineOnLoginHandler from '~/client/utils/ObjectResolver/objectResolverEngineOnLoginHandler';
16
15
  import { logout } from './logout';
17
16
 
@@ -201,13 +200,10 @@ export const login = async (
201
200
 
202
201
  markReadEngineOnLoginHandler(),
203
202
  analyticsEngineOnLoginHandler(),
203
+ readReceiptSyncEngineOnLoginHandler(),
204
204
  objectResolverEngineOnLoginHandler(),
205
205
  );
206
206
 
207
- if (client.useLegacyUnreadCount) {
208
- subscriptions.push(readReceiptSyncEngineOnLoginHandler());
209
- } else subscriptions.push(legacyReadReceiptSyncEngineOnLoginHandler());
210
-
211
207
  const markerSyncUnsubscriber = await startMarkerSync();
212
208
  subscriptions.push(markerSyncUnsubscriber);
213
209
  }
@@ -1,7 +1,8 @@
1
1
  import { pullFromCache, pushToCache, queryCache } from '~/cache/api';
2
2
  import { getActiveClient } from '../../api/activeClient';
3
+ import { markAsReadBySegment } from '~/subChannelRepository/api/markAsReadBySegment';
4
+ import { reCalculateChannelUnreadInfo } from '~/marker/utils/reCalculateChannelUnreadInfo';
3
5
  import { fireEvent } from '~/core/events';
4
- import { markChannelsAsReadBySegment } from '~/channelRepository/api/markChannelsAsReadBySegment';
5
6
 
6
7
  export class MessageReadReceiptSyncEngine {
7
8
  private client: Amity.Client;
@@ -37,9 +38,9 @@ export class MessageReadReceiptSyncEngine {
37
38
  syncReadReceipts(): void {
38
39
  if (this.jobQueue.length === 0 || this.isActive === false) return;
39
40
 
40
- const readReceipts = this.getReadReceipts();
41
- if (readReceipts) {
42
- this.markReadApi(readReceipts);
41
+ const readReceipt = this.getReadReceipt();
42
+ if (readReceipt) {
43
+ this.markReadApi(readReceipt);
43
44
  }
44
45
  }
45
46
 
@@ -51,64 +52,79 @@ export class MessageReadReceiptSyncEngine {
51
52
 
52
53
  // Enqueue unsync read receipts to the job queue
53
54
  readReceipts?.forEach(({ data: readReceipt }) => {
54
- this.enqueueReadReceipt(readReceipt.channelId, readReceipt.latestSegment);
55
+ this.enqueueReadReceipt(readReceipt.subChannelId, readReceipt.latestSegment);
55
56
  });
56
57
  }
57
58
 
58
- private getReadReceipts(): Amity.ReadReceiptSyncJob[] | undefined {
59
- // get all read receipts from queue, now the queue is empty
60
- const syncJob = this.jobQueue.splice(0, this.jobQueue.length);
61
- if (syncJob.length === 0) return;
59
+ private getReadReceipt(): Amity.ReadReceiptSyncJob | undefined {
60
+ // Get first read receipt in queue
61
+ const syncJob = this.jobQueue[0];
62
62
 
63
- return syncJob.filter(job => {
64
- const readReceipt = pullFromCache<Amity.ReadReceipt>(['readReceipt', job.channelId])?.data;
65
- if (!readReceipt) return false;
66
- if (readReceipt.latestSegment > readReceipt.latestSyncSegment) return true;
67
- return false;
68
- });
63
+ if (!syncJob) return;
64
+ // Skip when it's syncing
65
+ if (syncJob.syncState === Amity.ReadReceiptSyncState.SYNCING) return;
66
+
67
+ // Get readReceipt from cache by subChannelId
68
+ const readReceipt = pullFromCache<Amity.ReadReceipt>([
69
+ 'readReceipt',
70
+ syncJob.subChannelId,
71
+ ])?.data;
72
+
73
+ if (!readReceipt) return;
74
+
75
+ if (readReceipt?.latestSegment > readReceipt?.latestSyncSegment) {
76
+ syncJob.segment = readReceipt.latestSegment;
77
+ return syncJob;
78
+ }
79
+ // Clear all synced job in job queue
80
+ this.removeSynedReceipt(readReceipt.subChannelId, readReceipt.latestSegment);
81
+
82
+ // Recursion getReadReceipt() until get unsync read receipt or job queue is empty
83
+ return this.getReadReceipt();
69
84
  }
70
85
 
71
- private async markReadApi(syncJobs: Amity.ReadReceiptSyncJob[]): Promise<void> {
72
- // constuct payload
73
- // example: [{ channelId: 'channelId', readToSegment: 2 }]
74
- const syncJobsPayload = syncJobs.map(job => {
75
- return {
76
- channelId: job.channelId,
77
- readToSegment: job.segment,
78
- };
79
- });
86
+ private async markReadApi(syncJob: Amity.ReadReceiptSyncJob): Promise<void> {
87
+ const newSyncJob = syncJob;
88
+ newSyncJob.syncState = Amity.ReadReceiptSyncState.SYNCING;
89
+
90
+ const { subChannelId, segment } = newSyncJob;
80
91
 
81
- const response = await markChannelsAsReadBySegment(syncJobsPayload);
92
+ const response = await markAsReadBySegment({ subChannelId, readToSegment: segment });
82
93
 
83
94
  if (response) {
84
- for (let i = 0; i < syncJobs.length; i += 1) {
85
- // update lastestSyncSegment in read receipt cache
86
- const cacheKey = ['readReceipt', syncJobs[i].channelId];
87
- const readReceiptCache = pullFromCache<Amity.ReadReceipt>(cacheKey)?.data;
88
-
89
- pushToCache(cacheKey, {
90
- ...readReceiptCache,
91
- latestSyncSegment: syncJobs[i].segment,
92
- });
95
+ this.removeSynedReceipt(syncJob.subChannelId, syncJob.segment);
96
+
97
+ const readReceiptCache = pullFromCache<Amity.ReadReceipt>([
98
+ 'readReceipt',
99
+ subChannelId,
100
+ ])?.data;
101
+
102
+ pushToCache(['readReceipt', subChannelId], {
103
+ ...readReceiptCache,
104
+ latestSyncSegment: segment,
105
+ });
106
+ } else if (!response) {
107
+ if (newSyncJob.retryCount > this.MAX_RETRY) {
108
+ this.removeJobFromQueue(newSyncJob);
109
+ } else {
110
+ newSyncJob.retryCount += 1;
111
+ newSyncJob.syncState = Amity.ReadReceiptSyncState.CREATED;
93
112
  }
94
- } else {
95
- for (let i = 0; i < syncJobs.length; i += 1) {
96
- // push them back to queue if the syncing is failed and retry count is less than max retry
97
- if (syncJobs[i].retryCount >= this.MAX_RETRY) return;
113
+ }
114
+ }
98
115
 
99
- const updatedJob = {
100
- ...syncJobs[i],
101
- syncState: Amity.ReadReceiptSyncState.CREATED,
102
- retryCount: syncJobs[i].retryCount + 1,
103
- };
116
+ private removeSynedReceipt(subChannelId: string, segment: number) {
117
+ const syncJobs = this.jobQueue;
104
118
 
105
- this.enqueueJob(updatedJob);
119
+ syncJobs.forEach(job => {
120
+ if (job.subChannelId === subChannelId && job.segment <= segment) {
121
+ this.removeJobFromQueue(job);
106
122
  }
107
- }
123
+ });
108
124
  }
109
125
 
110
126
  private startObservingReadReceiptQueue(): void {
111
- if (this.client.useLegacyUnreadCount) {
127
+ if (this.client.isUnreadCountEnabled) {
112
128
  this.isActive = true;
113
129
  this.startSyncReadReceipt();
114
130
  }
@@ -117,7 +133,8 @@ export class MessageReadReceiptSyncEngine {
117
133
  private stopObservingReadReceiptQueue(): void {
118
134
  this.isActive = false;
119
135
 
120
- this.jobQueue.map(job => {
136
+ const syncJobs = this.jobQueue;
137
+ syncJobs.map(job => {
121
138
  if (job.syncState === Amity.ReadReceiptSyncState.SYNCING) {
122
139
  return { ...job, syncState: Amity.ReadReceiptSyncState.CREATED };
123
140
  }
@@ -153,47 +170,50 @@ export class MessageReadReceiptSyncEngine {
153
170
  this.startObservingReadReceiptQueue();
154
171
  }
155
172
 
156
- markRead(channelId: string, segment: number): void {
157
- // Step 1: Optimistic update of channelUnread.readToSegment to message.segment and update unreadCount value
158
- const cacheKey = ['channelUnread', 'get', channelId];
159
- const channelUnread = pullFromCache<Amity.ChannelUnread>(cacheKey)?.data;
173
+ markRead(subChannelId: string, segment: number): void {
174
+ // Step 1: Optimistic update of subChannelUnreadInfo.readToSegment to message.segment
175
+ const cacheKey = ['subChannelUnreadInfo', 'get', subChannelId];
176
+ const subChannelUnreadInfo = pullFromCache<Amity.SubChannelUnreadInfo>(cacheKey)?.data;
160
177
 
161
- if (channelUnread && segment > channelUnread.readToSegment) {
162
- channelUnread.readToSegment = segment;
163
- channelUnread.unreadCount = Math.max(channelUnread.lastSegment - segment, 0);
178
+ if (subChannelUnreadInfo && segment > subChannelUnreadInfo.readToSegment) {
179
+ subChannelUnreadInfo.readToSegment = segment;
180
+ subChannelUnreadInfo.unreadCount = Math.max(subChannelUnreadInfo.lastSegment - segment, 0);
164
181
 
165
- pushToCache(cacheKey, channelUnread);
166
- fireEvent('local.channelUnread.updated', channelUnread);
182
+ const channelUnreadInfo = reCalculateChannelUnreadInfo(subChannelUnreadInfo.channelId);
183
+ fireEvent('local.channelUnread.updated', channelUnreadInfo);
184
+
185
+ pushToCache(cacheKey, subChannelUnreadInfo);
186
+ fireEvent('local.subChannelUnread.updated', subChannelUnreadInfo);
167
187
  }
168
188
 
169
189
  // Step 2: Enqueue the read receipt
170
- this.enqueueReadReceipt(channelId, segment);
190
+ this.enqueueReadReceipt(subChannelId, segment);
171
191
  }
172
192
 
173
- private enqueueReadReceipt(channelId: string, segment: number): void {
174
- const readReceipt = pullFromCache<Amity.ReadReceipt>(['readReceipt', channelId])?.data;
193
+ private enqueueReadReceipt(subChannelId: string, segment: number): void {
194
+ const readReceipt = pullFromCache<Amity.ReadReceipt>(['readReceipt', subChannelId])?.data;
175
195
 
176
- // Create new read receipt if it's not exists and add the job to queue
196
+ // Create new read receipt if it's not exists and add job to queue
177
197
  if (!readReceipt) {
178
- const readReceiptChannel: Amity.ReadReceipt = {
179
- channelId,
198
+ const readReceiptSubChannel: Amity.ReadReceipt = {
199
+ subChannelId,
180
200
  latestSegment: segment,
181
201
  latestSyncSegment: 0,
182
202
  };
183
- pushToCache(['readReceipt', channelId], readReceiptChannel);
203
+
204
+ pushToCache(['readReceipt', subChannelId], readReceiptSubChannel);
184
205
  } else if (readReceipt.latestSegment < segment) {
185
- // Update latestSegment in read receipt cache
186
- pushToCache(['readReceipt', channelId], { ...readReceipt, latestSegment: segment });
206
+ pushToCache(['readReceipt', subChannelId], { ...readReceipt, latestSegment: segment });
187
207
  } else if (readReceipt.latestSyncSegment >= segment) {
188
208
  // Skip the job when lastSyncSegment > = segment
189
209
  return;
190
210
  }
191
211
 
192
- let syncJob: Amity.ReadReceiptSyncJob | null = this.getSyncJob(channelId);
212
+ let syncJob: Amity.ReadReceiptSyncJob | null = this.getSyncJob(subChannelId);
193
213
 
194
214
  if (syncJob === null || syncJob.syncState === Amity.ReadReceiptSyncState.SYNCING) {
195
215
  syncJob = {
196
- channelId,
216
+ subChannelId,
197
217
  segment,
198
218
  syncState: Amity.ReadReceiptSyncState.CREATED,
199
219
  retryCount: 0,
@@ -205,9 +225,11 @@ export class MessageReadReceiptSyncEngine {
205
225
  }
206
226
  }
207
227
 
208
- private getSyncJob(channelId: string): Amity.ReadReceiptSyncJob | null {
209
- const { jobQueue } = this;
210
- const targetJob = jobQueue.find(job => job.channelId === channelId);
228
+ private getSyncJob(subChannelId: string): Amity.ReadReceiptSyncJob | null {
229
+ const syncJobs = this.jobQueue;
230
+
231
+ const targetJob = syncJobs.find(job => job.subChannelId === subChannelId);
232
+
211
233
  return targetJob || null;
212
234
  }
213
235
 
@@ -220,6 +242,13 @@ export class MessageReadReceiptSyncEngine {
220
242
  this.jobQueue.push(syncJob);
221
243
  }
222
244
  }
245
+
246
+ private removeJobFromQueue(item: Amity.ReadReceiptSyncJob) {
247
+ const index = this.jobQueue.indexOf(item);
248
+ if (index > -1) {
249
+ this.jobQueue.splice(index, 1);
250
+ }
251
+ }
223
252
  }
224
253
 
225
254
  let instance: MessageReadReceiptSyncEngine | null = null;
@@ -26,8 +26,6 @@ const idResolvers: Resolvers = {
26
26
  channelUnreadInfo: ({ channelId }) => channelId,
27
27
  subChannelUnreadInfo: ({ subChannelId }) => subChannelId,
28
28
 
29
- channelUnread: ({ channelId }) => channelId,
30
-
31
29
  channelMarker: ({ entityId, userId }) => `${entityId}#${userId}`,
32
30
  subChannelMarker: ({ entityId, feedId, userId }) => `${entityId}#${feedId}#${userId}`,
33
31
  messageMarker: ({ feedId, contentId, creatorId }) => `${feedId}#${contentId}#${creatorId}`,
@@ -61,6 +59,9 @@ const idResolvers: Resolvers = {
61
59
 
62
60
  pin: ({ placement, referenceId }) => `${placement}#${referenceId}`,
63
61
  pinTarget: ({ targetId }) => targetId,
62
+
63
+ notificationTrayItem: ({ _id }) => _id,
64
+ notificationTraySeen: ({ userId }) => userId,
64
65
  };
65
66
 
66
67
  /**
@@ -52,6 +52,8 @@ export const PAYLOAD2MODEL: Record<string, Amity.Domain> = {
52
52
 
53
53
  pinTargets: 'pinTarget',
54
54
  pins: 'pin',
55
+
56
+ notificationTrayItems: 'notificationTrayItem',
55
57
  };
56
58
 
57
59
  /** hidden */
package/src/index.ts CHANGED
@@ -49,3 +49,5 @@ export * as AdRepository from './adRepository';
49
49
 
50
50
  // // external apis
51
51
  export * from './external/api';
52
+
53
+ export * as notificationTray from './notificationTray';
@@ -4,12 +4,12 @@ import { createEventSubscriber } from '~/core/events';
4
4
  /**
5
5
  * Internal used only
6
6
  *
7
- * Fired when an {@link Amity.ChannelUnread} has been updated.
7
+ * Fired when an {@link Amity.userMessageFeedMarkers} has been resolved by Object Rsesolver
8
8
  *
9
9
  * @param callback The function to call when the event was fired
10
10
  * @returns an {@link Amity.Unsubscriber} function to stop listening
11
11
  *
12
- * @category Channel Events
12
+ * @category MessageMarker Events
13
13
  */
14
14
  export const onChannelUnreadUpdatedLocal = (
15
15
  callback: Amity.Listener<Amity.Events['local.channelUnread.updated']>,
@@ -22,7 +22,7 @@ export const onChannelUnreadUpdatedLocal = (
22
22
 
23
23
  return createEventSubscriber(
24
24
  client,
25
- 'channel/onChannelUnreadUpdatedLocal',
25
+ 'channelMarker/onChannelUnreadUpdatedLocal',
26
26
  'local.channelUnread.updated',
27
27
  filter,
28
28
  );
@@ -1,12 +1,11 @@
1
1
  import { getActiveClient } from '~/client/api/activeClient';
2
- import { createEventSubscriber, fireEvent } from '~/core/events';
2
+ import { createEventSubscriber } from '~/core/events';
3
3
  import { ingestInCache } from '~/cache/api/ingestInCache';
4
4
  import { updateSubChannelUnreadFromMessage } from '~/marker/utils/updateSubChannelUnreadFromMessage';
5
5
  import { reCalculateChannelUnreadInfo } from '~/marker/utils/reCalculateChannelUnreadInfo';
6
6
  import { getActiveUser } from '~/client/api/activeUser';
7
7
  import { markReadMessage } from '../utils/markReadMessage';
8
8
  import { prepareMessagePayload } from '../utils';
9
- import { pullFromCache, pushToCache } from '~/cache/api';
10
9
 
11
10
  /**
12
11
  * ```js
@@ -41,42 +40,6 @@ export const onMessageCreatedMqtt = (
41
40
  });
42
41
  }
43
42
 
44
- if (client.useLegacyUnreadCount) {
45
- rawPayload.messages.forEach(message => {
46
- const channelUnread = pullFromCache<Amity.ChannelUnread>([
47
- 'channelUnread',
48
- 'get',
49
- message.channelId,
50
- ])?.data;
51
- if (!channelUnread || channelUnread.lastSegment >= message.segment) return;
52
-
53
- const lastSegment = message.segment;
54
- const isMentionedInMessage = message.mentionedUsers?.some(mention => {
55
- return (
56
- mention.type === 'channel' ||
57
- (mention.type === 'user' &&
58
- client.userId &&
59
- mention.userPublicIds.includes(client.userId))
60
- );
61
- });
62
-
63
- const lastMentionSegment = isMentionedInMessage
64
- ? message.segment
65
- : channelUnread.lastMentionSegment;
66
-
67
- const updatedChannelUnread = {
68
- ...channelUnread,
69
- lastSegment,
70
- unreadCount: Math.max(lastSegment - channelUnread.readToSegment, 0),
71
- lastMentionSegment,
72
- isMentioned: !(channelUnread.readToSegment >= lastMentionSegment),
73
- };
74
-
75
- pushToCache(['channelUnread', 'get', message.channelId], updatedChannelUnread);
76
- fireEvent('local.channelUnread.updated', updatedChannelUnread);
77
- });
78
- }
79
-
80
43
  // Update in cache
81
44
  ingestInCache(payload);
82
45
 
@@ -13,6 +13,7 @@ import {
13
13
  } from '../events';
14
14
  import { onMessageFetched } from '../events/onMessageFetched';
15
15
  import { LinkedObject } from '~/utils/linkedObject';
16
+ import { date } from '~/utils/tests';
16
17
 
17
18
  /* begin_public_function
18
19
  id: message.get
@@ -1,15 +1,8 @@
1
- import { getActiveClient } from '~/client/api/activeClient';
2
1
  import ReadReceiptSyncEngine from '~/client/utils/ReadReceiptSync/readReceiptSyncEngine';
3
- import LegacyReadReceiptSyncEngine from '~/client/utils/ReadReceiptSync/legacyReadReceiptSyncEngine';
4
2
 
5
3
  export const markReadMessage = (message: Amity.InternalMessage) => {
6
- const client = getActiveClient();
4
+ const { subChannelId, channelSegment } = message;
5
+ const markReadReceiptEngine = ReadReceiptSyncEngine.getInstance();
7
6
 
8
- if (client.useLegacyUnreadCount) {
9
- const markReadReceiptEngine = ReadReceiptSyncEngine.getInstance();
10
- markReadReceiptEngine.markRead(message.channelId, message.channelSegment);
11
- } else {
12
- const markReadReceiptEngine = LegacyReadReceiptSyncEngine.getInstance();
13
- markReadReceiptEngine.markRead(message.subChannelId, message.channelSegment);
14
- }
7
+ markReadReceiptEngine.markRead(subChannelId, channelSegment);
15
8
  };
@@ -0,0 +1,2 @@
1
+ export * from './markItemsSeen';
2
+ export * from './markTraySeen';