@amityco/ts-sdk 7.1.1-67cf0d9.0 → 7.1.1-6dd179b0.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/@types/core/events.d.ts +5 -2
- package/dist/@types/core/events.d.ts.map +1 -1
- package/dist/@types/core/model.d.ts +4 -2
- package/dist/@types/core/model.d.ts.map +1 -1
- package/dist/@types/core/payload.d.ts +18 -0
- package/dist/@types/core/payload.d.ts.map +1 -1
- package/dist/@types/core/readReceipt.d.ts +1 -12
- package/dist/@types/core/readReceipt.d.ts.map +1 -1
- package/dist/@types/domains/channel.d.ts +0 -10
- package/dist/@types/domains/channel.d.ts.map +1 -1
- package/dist/@types/domains/client.d.ts +0 -2
- package/dist/@types/domains/client.d.ts.map +1 -1
- package/dist/@types/domains/notification.d.ts +81 -0
- package/dist/@types/domains/notification.d.ts.map +1 -0
- package/dist/@types/index.d.ts +1 -0
- package/dist/@types/index.d.ts.map +1 -1
- package/dist/channelRepository/events/onChannelDeleted.d.ts.map +1 -1
- package/dist/channelRepository/events/onChannelLeft.d.ts.map +1 -1
- package/dist/channelRepository/observers/getChannel.d.ts.map +1 -1
- package/dist/channelRepository/observers/getChannels/ChannelLiveCollectionController.d.ts.map +1 -1
- package/dist/channelRepository/observers/index.d.ts +0 -1
- package/dist/channelRepository/observers/index.d.ts.map +1 -1
- package/dist/channelRepository/utils/constructChannelDynamicValue.d.ts.map +1 -1
- package/dist/channelRepository/utils/prepareChannelPayload.d.ts.map +1 -1
- package/dist/client/api/createClient.d.ts +0 -1
- package/dist/client/api/createClient.d.ts.map +1 -1
- package/dist/client/api/enableUnreadCount.d.ts.map +1 -1
- package/dist/client/api/login.d.ts.map +1 -1
- package/dist/client/utils/ReadReceiptSync/readReceiptSyncEngine.d.ts +4 -2
- package/dist/client/utils/ReadReceiptSync/readReceiptSyncEngine.d.ts.map +1 -1
- package/dist/client/utils/endpoints.d.ts +0 -1
- package/dist/client/utils/endpoints.d.ts.map +1 -1
- package/dist/client/utils/setClientToken.d.ts.map +1 -1
- package/dist/core/events.d.ts +3 -3
- package/dist/core/events.d.ts.map +1 -1
- package/dist/core/model/idResolvers.d.ts.map +1 -1
- package/dist/core/model/index.d.ts.map +1 -1
- package/dist/index.cjs.js +468 -596
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.esm.js +451 -580
- package/dist/index.umd.js +4 -4
- package/dist/{channelRepository → marker}/events/onChannelUnreadUpdatedLocal.d.ts +2 -2
- package/dist/marker/events/onChannelUnreadUpdatedLocal.d.ts.map +1 -0
- package/dist/messageRepository/events/onMessageCreated.d.ts.map +1 -1
- package/dist/messageRepository/observers/getMessage.d.ts.map +1 -1
- package/dist/messageRepository/utils/markReadMessage.d.ts.map +1 -1
- package/dist/notificationTray/api/index.d.ts +3 -0
- package/dist/notificationTray/api/index.d.ts.map +1 -0
- package/dist/notificationTray/api/markItemsSeen.d.ts +16 -0
- package/dist/notificationTray/api/markItemsSeen.d.ts.map +1 -0
- package/dist/notificationTray/api/markTraySeen.d.ts +19 -0
- package/dist/notificationTray/api/markTraySeen.d.ts.map +1 -0
- package/dist/notificationTray/events/index.d.ts +2 -0
- package/dist/notificationTray/events/index.d.ts.map +1 -0
- package/dist/notificationTray/events/onNotificationTraySeenUpdated.d.ts +17 -0
- package/dist/notificationTray/events/onNotificationTraySeenUpdated.d.ts.map +1 -0
- package/dist/notificationTray/index.d.ts +4 -0
- package/dist/notificationTray/index.d.ts.map +1 -0
- package/dist/notificationTray/internalApi/getNotificationTraySeen.d.ts +30 -0
- package/dist/notificationTray/internalApi/getNotificationTraySeen.d.ts.map +1 -0
- package/dist/notificationTray/observers/getNotificationTrayItems/NotificationTrayItemsLiveCollectionController.d.ts +13 -0
- package/dist/notificationTray/observers/getNotificationTrayItems/NotificationTrayItemsLiveCollectionController.d.ts.map +1 -0
- package/dist/notificationTray/observers/getNotificationTrayItems/NotificationTrayItemsPaginationController.d.ts +9 -0
- package/dist/notificationTray/observers/getNotificationTrayItems/NotificationTrayItemsPaginationController.d.ts.map +1 -0
- package/dist/notificationTray/observers/getNotificationTrayItems/NotificationTrayItemsQuerystreamController.d.ts +9 -0
- package/dist/notificationTray/observers/getNotificationTrayItems/NotificationTrayItemsQuerystreamController.d.ts.map +1 -0
- package/dist/notificationTray/observers/getNotificationTrayItems.d.ts +12 -0
- package/dist/notificationTray/observers/getNotificationTrayItems.d.ts.map +1 -0
- package/dist/notificationTray/observers/getNotificationTraySeen.d.ts +21 -0
- package/dist/notificationTray/observers/getNotificationTraySeen.d.ts.map +1 -0
- package/dist/notificationTray/observers/index.d.ts +3 -0
- package/dist/notificationTray/observers/index.d.ts.map +1 -0
- package/dist/notificationTray/utils/prepareNotificationTrayItemsPayload.d.ts +2 -0
- package/dist/notificationTray/utils/prepareNotificationTrayItemsPayload.d.ts.map +1 -0
- package/dist/utils/linkedObject/index.d.ts +1 -0
- package/dist/utils/linkedObject/index.d.ts.map +1 -1
- package/dist/utils/linkedObject/notificationTrayLinkedObject.d.ts +2 -0
- package/dist/utils/linkedObject/notificationTrayLinkedObject.d.ts.map +1 -0
- package/package.json +1 -1
- package/src/@types/core/events.ts +6 -2
- package/src/@types/core/model.ts +6 -4
- package/src/@types/core/payload.ts +25 -0
- package/src/@types/core/readReceipt.ts +1 -14
- package/src/@types/domains/channel.ts +0 -13
- package/src/@types/domains/client.ts +0 -3
- package/src/@types/domains/notification.ts +90 -0
- package/src/@types/index.ts +1 -0
- package/src/channelRepository/events/onChannelDeleted.ts +4 -17
- package/src/channelRepository/events/onChannelLeft.ts +3 -11
- package/src/channelRepository/observers/getChannel.ts +1 -3
- package/src/channelRepository/observers/getChannels/ChannelLiveCollectionController.ts +1 -6
- package/src/channelRepository/observers/index.ts +0 -1
- package/src/channelRepository/utils/constructChannelDynamicValue.ts +2 -12
- package/src/channelRepository/utils/prepareChannelPayload.ts +17 -68
- package/src/client/api/createClient.ts +1 -7
- package/src/client/api/enableUnreadCount.ts +0 -1
- package/src/client/api/login.ts +1 -5
- package/src/client/utils/ReadReceiptSync/readReceiptSyncEngine.ts +99 -74
- package/src/client/utils/endpoints.ts +0 -1
- package/src/client/utils/setClientToken.ts +0 -8
- package/src/core/model/idResolvers.ts +3 -2
- package/src/core/model/index.ts +2 -0
- package/src/fileRepository/api/uploadFile.ts +1 -1
- package/src/fileRepository/api/uploadImage.ts +1 -1
- package/src/fileRepository/api/uploadVideo.ts +1 -1
- package/src/index.ts +2 -0
- package/src/{channelRepository → marker}/events/onChannelUnreadUpdatedLocal.ts +3 -3
- package/src/messageRepository/events/onMessageCreated.ts +1 -45
- package/src/messageRepository/observers/getMessage.ts +1 -0
- package/src/messageRepository/utils/markReadMessage.ts +3 -10
- package/src/notificationTray/api/index.ts +2 -0
- package/src/notificationTray/api/markItemsSeen.ts +59 -0
- package/src/notificationTray/api/markTraySeen.ts +65 -0
- package/src/notificationTray/events/index.ts +1 -0
- package/src/notificationTray/events/onNotificationTraySeenUpdated.ts +36 -0
- package/src/notificationTray/index.ts +3 -0
- package/src/notificationTray/internalApi/getNotificationTraySeen.ts +81 -0
- package/src/notificationTray/observers/getNotificationTrayItems/NotificationTrayItemsLiveCollectionController.ts +96 -0
- package/src/notificationTray/observers/getNotificationTrayItems/NotificationTrayItemsPaginationController.ts +31 -0
- package/src/notificationTray/observers/getNotificationTrayItems/NotificationTrayItemsQuerystreamController.ts +68 -0
- package/src/notificationTray/observers/getNotificationTrayItems.ts +44 -0
- package/src/notificationTray/observers/getNotificationTraySeen.ts +43 -0
- package/src/notificationTray/observers/index.ts +2 -0
- package/src/notificationTray/utils/prepareNotificationTrayItemsPayload.ts +12 -0
- package/src/utils/linkedObject/index.ts +2 -0
- package/src/utils/linkedObject/notificationTrayLinkedObject.ts +19 -0
- package/dist/channelRepository/api/markChannelsAsReadBySegment.d.ts +0 -16
- package/dist/channelRepository/api/markChannelsAsReadBySegment.d.ts.map +0 -1
- package/dist/channelRepository/events/onChannelUnreadUpdatedLocal.d.ts.map +0 -1
- package/dist/channelRepository/internalApi/getTotalChannelsUnread.d.ts +0 -11
- package/dist/channelRepository/internalApi/getTotalChannelsUnread.d.ts.map +0 -1
- package/dist/channelRepository/observers/getTotalChannelsUnread.d.ts +0 -20
- package/dist/channelRepository/observers/getTotalChannelsUnread.d.ts.map +0 -1
- package/dist/channelRepository/utils/getLegacyChannelUnread.d.ts +0 -2
- package/dist/channelRepository/utils/getLegacyChannelUnread.d.ts.map +0 -1
- package/dist/client/utils/ReadReceiptSync/legacyReadReceiptSyncEngine.d.ts +0 -33
- package/dist/client/utils/ReadReceiptSync/legacyReadReceiptSyncEngine.d.ts.map +0 -1
- package/dist/client/utils/ReadReceiptSync/legacyReadReceiptSyncEngineOnLoginHandler.d.ts +0 -3
- package/dist/client/utils/ReadReceiptSync/legacyReadReceiptSyncEngineOnLoginHandler.d.ts.map +0 -1
- package/dist/marker/events/onChannelUnreadInfoUpdatedLocal.d.ts +0 -12
- package/dist/marker/events/onChannelUnreadInfoUpdatedLocal.d.ts.map +0 -1
- package/src/channelRepository/api/markChannelsAsReadBySegment.ts +0 -29
- package/src/channelRepository/internalApi/getTotalChannelsUnread.ts +0 -38
- package/src/channelRepository/observers/getTotalChannelsUnread.ts +0 -129
- package/src/channelRepository/utils/getLegacyChannelUnread.ts +0 -5
- package/src/client/utils/ReadReceiptSync/legacyReadReceiptSyncEngine.ts +0 -267
- package/src/client/utils/ReadReceiptSync/legacyReadReceiptSyncEngineOnLoginHandler.ts +0 -21
- package/src/marker/events/onChannelUnreadInfoUpdatedLocal.ts +0 -29
|
@@ -6,7 +6,6 @@ import { ingestInCache } from '~/cache/api/ingestInCache';
|
|
|
6
6
|
import { prepareChannelPayload } from '../utils';
|
|
7
7
|
import { deleteChannelUnreadByChannelId } from '../../marker/utils/deleteChannelUnreadByChannelId';
|
|
8
8
|
import { addFlagIsDeletedSubChannelUnreadByChannelId } from '~/marker/utils/addFlagIsDeletedSubChannelUnreadByChannelId';
|
|
9
|
-
import { dropFromCache } from '~/cache/api';
|
|
10
9
|
|
|
11
10
|
type CallbackFn = (
|
|
12
11
|
channel: Amity.StaticInternalChannel,
|
|
@@ -41,17 +40,10 @@ export const onChannelLeft = (
|
|
|
41
40
|
isMessagePreviewUpdated: isLeftByMe,
|
|
42
41
|
});
|
|
43
42
|
|
|
44
|
-
|
|
45
|
-
const isLegacyUnreadCount = client.useLegacyUnreadCount;
|
|
46
|
-
|
|
47
|
-
if (isLeftByMe) {
|
|
43
|
+
if (client.isUnreadCountEnabled && client.getMarkerSyncConsistentMode() && isLeftByMe) {
|
|
48
44
|
preparedPayload.channels.forEach(channel => {
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
deleteChannelUnreadByChannelId(channel.channelId);
|
|
52
|
-
} else if (isLegacyUnreadCount) {
|
|
53
|
-
dropFromCache(['channelUnread', 'get', channel.channelId]);
|
|
54
|
-
}
|
|
45
|
+
addFlagIsDeletedSubChannelUnreadByChannelId(channel.channelId);
|
|
46
|
+
deleteChannelUnreadByChannelId(channel.channelId);
|
|
55
47
|
});
|
|
56
48
|
}
|
|
57
49
|
|
|
@@ -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 {
|
|
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 {
|
|
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,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
|
|
16
|
-
return
|
|
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,48 +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
|
-
const cacheChannelUnread: Amity.ChannelUnread = {
|
|
79
|
-
channelId: channels[i].channelId,
|
|
80
|
-
lastSegment: channels[i].messageCount,
|
|
81
|
-
readToSegment,
|
|
82
|
-
lastMentionedSegment,
|
|
83
|
-
unreadCount,
|
|
84
|
-
isMentioned,
|
|
85
|
-
isDeleted: channels[i].isDeleted || false,
|
|
86
|
-
};
|
|
87
|
-
|
|
88
|
-
pushToCache(cacheKey, cacheChannelUnread);
|
|
89
|
-
}
|
|
90
|
-
};
|
|
91
|
-
|
|
92
51
|
export const prepareChannelPayload = async (
|
|
93
52
|
rawPayload: Amity.ChannelPayload,
|
|
94
53
|
options: { isMessagePreviewUpdated?: boolean } = { isMessagePreviewUpdated: true },
|
|
@@ -105,38 +64,28 @@ export const prepareChannelPayload = async (
|
|
|
105
64
|
updateChannelMessagePreviewCache(rawPayload);
|
|
106
65
|
}
|
|
107
66
|
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
// since the get markers method requires a channel cache to function with the reducer.
|
|
122
|
-
preUpdateChannelCache(rawPayload, {
|
|
123
|
-
isMessagePreviewUpdated: options.isMessagePreviewUpdated,
|
|
124
|
-
});
|
|
125
|
-
|
|
126
|
-
try {
|
|
127
|
-
await getChannelMarkers(markerIds);
|
|
128
|
-
} catch (e) {
|
|
129
|
-
// empty block (from the spec, allow marker fetch to fail without having to do anything)
|
|
130
|
-
}
|
|
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)
|
|
131
80
|
}
|
|
132
81
|
}
|
|
133
82
|
|
|
134
|
-
//
|
|
83
|
+
// attach marker to channel
|
|
135
84
|
const channels = rawPayload.channels.map(payload =>
|
|
136
85
|
convertFromRaw(payload, { isMessagePreviewUpdated: options.isMessagePreviewUpdated }),
|
|
137
86
|
);
|
|
138
87
|
|
|
139
|
-
//
|
|
88
|
+
// user marker to channel users
|
|
140
89
|
const channelUsers: Amity.Membership<'channel'>[] = rawPayload.channelUsers.map(channelUser => {
|
|
141
90
|
return convertRawMembershipToMembership<'channel'>(channelUser);
|
|
142
91
|
});
|
|
@@ -50,7 +50,7 @@ export const createClient = (
|
|
|
50
50
|
rteEnabled = true,
|
|
51
51
|
}: {
|
|
52
52
|
debugSession?: string;
|
|
53
|
-
apiEndpoint?: { http?: string; mqtt?: string
|
|
53
|
+
apiEndpoint?: { http?: string; mqtt?: string };
|
|
54
54
|
prefixDeviceIdKey?: string;
|
|
55
55
|
rteEnabled?: boolean;
|
|
56
56
|
} = {},
|
|
@@ -63,11 +63,9 @@ export const createClient = (
|
|
|
63
63
|
});
|
|
64
64
|
|
|
65
65
|
const httpEndpoint = apiEndpoint?.http ?? computeUrl('http', apiRegion);
|
|
66
|
-
const uploadEndpoint = apiEndpoint?.upload ?? computeUrl('upload', apiRegion);
|
|
67
66
|
const mqttEndpoint = apiEndpoint?.mqtt ?? computeUrl('mqtt', apiRegion);
|
|
68
67
|
|
|
69
68
|
const http = createHttpTransport(httpEndpoint);
|
|
70
|
-
const upload = createHttpTransport(uploadEndpoint);
|
|
71
69
|
|
|
72
70
|
let ws;
|
|
73
71
|
let mqtt;
|
|
@@ -88,8 +86,6 @@ export const createClient = (
|
|
|
88
86
|
const sessionHandler = undefined;
|
|
89
87
|
|
|
90
88
|
const isUnreadCountEnabled = false;
|
|
91
|
-
// Legacy unread count is true by default
|
|
92
|
-
const useLegacyUnreadCount = true;
|
|
93
89
|
|
|
94
90
|
const client = {
|
|
95
91
|
version: `${VERSION}`,
|
|
@@ -107,7 +103,6 @@ export const createClient = (
|
|
|
107
103
|
http,
|
|
108
104
|
ws,
|
|
109
105
|
mqtt,
|
|
110
|
-
upload,
|
|
111
106
|
emitter,
|
|
112
107
|
|
|
113
108
|
/*
|
|
@@ -127,7 +122,6 @@ export const createClient = (
|
|
|
127
122
|
use: () => setActiveClient(client),
|
|
128
123
|
|
|
129
124
|
isUnreadCountEnabled,
|
|
130
|
-
useLegacyUnreadCount,
|
|
131
125
|
|
|
132
126
|
getMarkerSyncConsistentMode,
|
|
133
127
|
|
package/src/client/api/login.ts
CHANGED
|
@@ -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
|
|
41
|
-
if (
|
|
42
|
-
this.markReadApi(
|
|
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.
|
|
55
|
+
this.enqueueReadReceipt(readReceipt.subChannelId, readReceipt.latestSegment);
|
|
55
56
|
});
|
|
56
57
|
}
|
|
57
58
|
|
|
58
|
-
private
|
|
59
|
-
//
|
|
60
|
-
const syncJob = this.jobQueue
|
|
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
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
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(
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
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
|
|
92
|
+
const response = await markAsReadBySegment({ subChannelId, readToSegment: segment });
|
|
82
93
|
|
|
83
94
|
if (response) {
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
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
|
-
}
|
|
95
|
-
|
|
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
|
-
|
|
100
|
-
|
|
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
|
-
|
|
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.
|
|
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
|
|
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(
|
|
157
|
-
// Step 1: Optimistic update of
|
|
158
|
-
const cacheKey = ['
|
|
159
|
-
const
|
|
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
|
-
|
|
163
|
-
|
|
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
|
-
|
|
170
|
-
fireEvent('local.channelUnread.updated',
|
|
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(
|
|
190
|
+
this.enqueueReadReceipt(subChannelId, segment);
|
|
175
191
|
}
|
|
176
192
|
|
|
177
|
-
private enqueueReadReceipt(
|
|
178
|
-
const readReceipt = pullFromCache<Amity.ReadReceipt>(['readReceipt',
|
|
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
|
|
196
|
+
// Create new read receipt if it's not exists and add job to queue
|
|
181
197
|
if (!readReceipt) {
|
|
182
|
-
const
|
|
183
|
-
|
|
198
|
+
const readReceiptSubChannel: Amity.ReadReceipt = {
|
|
199
|
+
subChannelId,
|
|
184
200
|
latestSegment: segment,
|
|
185
201
|
latestSyncSegment: 0,
|
|
186
202
|
};
|
|
187
|
-
|
|
203
|
+
|
|
204
|
+
pushToCache(['readReceipt', subChannelId], readReceiptSubChannel);
|
|
188
205
|
} else if (readReceipt.latestSegment < segment) {
|
|
189
|
-
|
|
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(
|
|
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
|
-
|
|
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(
|
|
213
|
-
const
|
|
214
|
-
|
|
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;
|
|
@@ -30,14 +30,6 @@ export const setClientToken = async (params: Parameters<typeof getToken>[0]) =>
|
|
|
30
30
|
isUserDeleted: false,
|
|
31
31
|
};
|
|
32
32
|
|
|
33
|
-
client.upload.defaults.headers.common.Authorization = `Bearer ${accessToken}`;
|
|
34
|
-
|
|
35
|
-
client.upload.defaults.metadata = {
|
|
36
|
-
tokenExpiry: expiresAt,
|
|
37
|
-
isGlobalBanned: false,
|
|
38
|
-
isUserDeleted: false,
|
|
39
|
-
};
|
|
40
|
-
|
|
41
33
|
// manually setup the token for ws transport
|
|
42
34
|
if (client.ws) client.ws.io.opts.query = { token: accessToken };
|
|
43
35
|
|
|
@@ -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
|
/**
|
package/src/core/model/index.ts
CHANGED
|
@@ -42,7 +42,7 @@ export const uploadFile = async <T extends Amity.FileType = any>(
|
|
|
42
42
|
? (formData as any).getHeaders()
|
|
43
43
|
: { 'content-type': 'multipart/form-data' };
|
|
44
44
|
|
|
45
|
-
const { data } = await client.
|
|
45
|
+
const { data } = await client.http.post<Amity.CreateFilePayload<T>>('/api/v4/files', formData, {
|
|
46
46
|
headers,
|
|
47
47
|
onUploadProgress({ loaded, total = 100 }) {
|
|
48
48
|
onProgress && onProgress(Math.round((loaded * 100) / total));
|
|
@@ -42,7 +42,7 @@ export const uploadImage = async (
|
|
|
42
42
|
? (formData as any).getHeaders()
|
|
43
43
|
: { 'content-type': 'multipart/form-data' };
|
|
44
44
|
|
|
45
|
-
const { data } = await client.
|
|
45
|
+
const { data } = await client.http.post<Amity.CreateFilePayload<'image'>>(
|
|
46
46
|
'/api/v4/images',
|
|
47
47
|
formData,
|
|
48
48
|
{
|
|
@@ -48,7 +48,7 @@ export const uploadVideo = async (
|
|
|
48
48
|
? (formData as any).getHeaders()
|
|
49
49
|
: { 'content-type': 'multipart/form-data' };
|
|
50
50
|
|
|
51
|
-
const { data } = await client.
|
|
51
|
+
const { data } = await client.http.post<Amity.CreateFilePayload<'video'>>(
|
|
52
52
|
'/api/v4/videos',
|
|
53
53
|
formData,
|
|
54
54
|
{
|