@amityco/ts-sdk 7.1.1-dbdbe662.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 -579
  35. package/dist/index.d.ts +1 -0
  36. package/dist/index.d.ts.map +1 -1
  37. package/dist/index.esm.js +445 -563
  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 -66
  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 -74
  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 -45
  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,46 +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 channelUser = channelUsers.find(
62
- channelUser =>
63
- channelUser.channelId === channels[i].channelId && channelUser.userId === currentUserId,
64
- );
65
-
66
- let unreadCount = 0;
67
- let readToSegment = null;
68
- let lastMentionedSegment = null;
69
- let isMentioned = false;
70
-
71
- if (channelUser) {
72
- readToSegment = channelUser.readToSegment;
73
- lastMentionedSegment = channelUser.lastMentionedSegment;
74
- unreadCount = Math.max(channels[i].messageCount - readToSegment, 0);
75
- isMentioned = lastMentionedSegment > readToSegment;
76
- }
77
-
78
- pushToCache(cacheKey, {
79
- channelId: channels[i].channelId,
80
- lastSegment: channels[i].messageCount,
81
- readToSegment,
82
- lastMentionedSegment,
83
- unreadCount,
84
- isMentioned,
85
- isDeleted: channels[i].isDeleted,
86
- });
87
- }
88
- };
89
-
90
51
  export const prepareChannelPayload = async (
91
52
  rawPayload: Amity.ChannelPayload,
92
53
  options: { isMessagePreviewUpdated?: boolean } = { isMessagePreviewUpdated: true },
@@ -103,38 +64,28 @@ export const prepareChannelPayload = async (
103
64
  updateChannelMessagePreviewCache(rawPayload);
104
65
  }
105
66
 
106
- if (client.useLegacyUnreadCount) {
107
- updateChannelUnread({
108
- channels: rawPayload.channels,
109
- channelUsers: rawPayload.channelUsers,
110
- currentUserId: client.userId!,
111
- });
112
- } else {
113
- const markerIds = rawPayload.channels
114
- // filter channel by type. Only conversation, community and broadcast type are included.
115
- .filter(isUnreadCountSupport)
116
- .map(({ channelInternalId }) => channelInternalId);
117
-
118
- if (markerIds.length > 0) {
119
- // since the get markers method requires a channel cache to function with the reducer.
120
- preUpdateChannelCache(rawPayload, {
121
- isMessagePreviewUpdated: options.isMessagePreviewUpdated,
122
- });
123
-
124
- try {
125
- await getChannelMarkers(markerIds);
126
- } catch (e) {
127
- // empty block (from the spec, allow marker fetch to fail without having to do anything)
128
- }
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)
129
80
  }
130
81
  }
131
82
 
132
- // convert raw channel to internal channel
83
+ // attach marker to channel
133
84
  const channels = rawPayload.channels.map(payload =>
134
85
  convertFromRaw(payload, { isMessagePreviewUpdated: options.isMessagePreviewUpdated }),
135
86
  );
136
87
 
137
- // convert raw channel user to membership (add user object)
88
+ // user marker to channel users
138
89
  const channelUsers: Amity.Membership<'channel'>[] = rawPayload.channelUsers.map(channelUser => {
139
90
  return convertRawMembershipToMembership<'channel'>(channelUser);
140
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,51 +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 (
162
- typeof channelUnread?.readToSegment === 'number' &&
163
- channelUnread &&
164
- segment > channelUnread.readToSegment
165
- ) {
166
- channelUnread.readToSegment = segment;
167
- 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);
168
181
 
169
- pushToCache(cacheKey, channelUnread);
170
- 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);
171
187
  }
172
188
 
173
189
  // Step 2: Enqueue the read receipt
174
- this.enqueueReadReceipt(channelId, segment);
190
+ this.enqueueReadReceipt(subChannelId, segment);
175
191
  }
176
192
 
177
- private enqueueReadReceipt(channelId: string, segment: number): void {
178
- 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;
179
195
 
180
- // 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
181
197
  if (!readReceipt) {
182
- const readReceiptChannel: Amity.ReadReceipt = {
183
- channelId,
198
+ const readReceiptSubChannel: Amity.ReadReceipt = {
199
+ subChannelId,
184
200
  latestSegment: segment,
185
201
  latestSyncSegment: 0,
186
202
  };
187
- pushToCache(['readReceipt', channelId], readReceiptChannel);
203
+
204
+ pushToCache(['readReceipt', subChannelId], readReceiptSubChannel);
188
205
  } else if (readReceipt.latestSegment < segment) {
189
- // Update latestSegment in read receipt cache
190
- pushToCache(['readReceipt', channelId], { ...readReceipt, latestSegment: segment });
206
+ pushToCache(['readReceipt', subChannelId], { ...readReceipt, latestSegment: segment });
191
207
  } else if (readReceipt.latestSyncSegment >= segment) {
192
208
  // Skip the job when lastSyncSegment > = segment
193
209
  return;
194
210
  }
195
211
 
196
- let syncJob: Amity.ReadReceiptSyncJob | null = this.getSyncJob(channelId);
212
+ let syncJob: Amity.ReadReceiptSyncJob | null = this.getSyncJob(subChannelId);
197
213
 
198
214
  if (syncJob === null || syncJob.syncState === Amity.ReadReceiptSyncState.SYNCING) {
199
215
  syncJob = {
200
- channelId,
216
+ subChannelId,
201
217
  segment,
202
218
  syncState: Amity.ReadReceiptSyncState.CREATED,
203
219
  retryCount: 0,
@@ -209,9 +225,11 @@ export class MessageReadReceiptSyncEngine {
209
225
  }
210
226
  }
211
227
 
212
- private getSyncJob(channelId: string): Amity.ReadReceiptSyncJob | null {
213
- const { jobQueue } = this;
214
- 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
+
215
233
  return targetJob || null;
216
234
  }
217
235
 
@@ -224,6 +242,13 @@ export class MessageReadReceiptSyncEngine {
224
242
  this.jobQueue.push(syncJob);
225
243
  }
226
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
+ }
227
252
  }
228
253
 
229
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,49 +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
-
52
- if (
53
- !channelUnread ||
54
- channelUnread.lastSegment >= message.segment ||
55
- typeof channelUnread.readToSegment !== 'number' ||
56
- typeof channelUnread.lastMentionSegment !== 'number'
57
- )
58
- return;
59
-
60
- const lastSegment = message.segment;
61
- const isMentionedInMessage = message.mentionedUsers?.some(mention => {
62
- return (
63
- mention.type === 'channel' ||
64
- (mention.type === 'user' &&
65
- client.userId &&
66
- mention.userPublicIds.includes(client.userId))
67
- );
68
- });
69
-
70
- const lastMentionSegment = isMentionedInMessage
71
- ? message.segment
72
- : channelUnread.lastMentionSegment;
73
-
74
- const updatedChannelUnread = {
75
- ...channelUnread,
76
- lastSegment,
77
- unreadCount: Math.max(lastSegment - channelUnread.readToSegment, 0),
78
- lastMentionSegment,
79
- isMentioned: !(channelUnread.readToSegment >= lastMentionSegment),
80
- };
81
-
82
- pushToCache(['channelUnread', 'get', message.channelId], updatedChannelUnread);
83
- fireEvent('local.channelUnread.updated', updatedChannelUnread);
84
- });
85
- }
86
-
87
43
  // Update in cache
88
44
  ingestInCache(payload);
89
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';