@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.
- 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 -1
- package/dist/@types/domains/client.d.ts.map +1 -1
- package/dist/@types/domains/notification.d.ts +82 -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.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/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 +462 -579
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.esm.js +445 -563
- 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 -2
- package/src/@types/domains/notification.ts +91 -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 -66
- package/src/client/api/createClient.ts +0 -3
- 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/core/model/idResolvers.ts +3 -2
- package/src/core/model/index.ts +2 -0
- 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
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
export declare class LegacyMessageReadReceiptSyncEngine {
|
|
2
|
-
private client;
|
|
3
|
-
private isActive;
|
|
4
|
-
private MAX_RETRY;
|
|
5
|
-
private JOB_QUEUE_SIZE;
|
|
6
|
-
private jobQueue;
|
|
7
|
-
private timer;
|
|
8
|
-
private RECEIPT_SYNC_INTERVAL;
|
|
9
|
-
constructor();
|
|
10
|
-
startSyncReadReceipt(): void;
|
|
11
|
-
syncReadReceipts(): void;
|
|
12
|
-
private getUnsyncJobs;
|
|
13
|
-
private getReadReceipt;
|
|
14
|
-
private markReadApi;
|
|
15
|
-
private removeSynedReceipt;
|
|
16
|
-
private startObservingReadReceiptQueue;
|
|
17
|
-
private stopObservingReadReceiptQueue;
|
|
18
|
-
onSessionEstablished(): void;
|
|
19
|
-
onSessionDestroyed(): void;
|
|
20
|
-
onTokenExpired(): void;
|
|
21
|
-
onNetworkOffline(): void;
|
|
22
|
-
onNetworkOnline(): void;
|
|
23
|
-
markRead(subChannelId: string, segment: number): void;
|
|
24
|
-
private enqueueReadReceipt;
|
|
25
|
-
private getSyncJob;
|
|
26
|
-
private enqueueJob;
|
|
27
|
-
private removeJobFromQueue;
|
|
28
|
-
}
|
|
29
|
-
declare const _default: {
|
|
30
|
-
getInstance: () => LegacyMessageReadReceiptSyncEngine;
|
|
31
|
-
};
|
|
32
|
-
export default _default;
|
|
33
|
-
//# sourceMappingURL=legacyReadReceiptSyncEngine.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"legacyReadReceiptSyncEngine.d.ts","sourceRoot":"","sources":["../../../../src/client/utils/ReadReceiptSync/legacyReadReceiptSyncEngine.ts"],"names":[],"mappings":"AAMA,qBAAa,kCAAkC;IAC7C,OAAO,CAAC,MAAM,CAAe;IAE7B,OAAO,CAAC,QAAQ,CAAQ;IAExB,OAAO,CAAC,SAAS,CAAK;IAEtB,OAAO,CAAC,cAAc,CAAO;IAE7B,OAAO,CAAC,QAAQ,CAAwC;IAExD,OAAO,CAAC,KAAK,CAA2B;IAGxC,OAAO,CAAC,qBAAqB,CAAK;;IASlC,oBAAoB;IAQpB,gBAAgB,IAAI,IAAI;IASxB,OAAO,CAAC,aAAa;IAcrB,OAAO,CAAC,cAAc;YA2BR,WAAW;IA8BzB,OAAO,CAAC,kBAAkB;IAU1B,OAAO,CAAC,8BAA8B;IAOtC,OAAO,CAAC,6BAA6B;IAgBrC,oBAAoB,IAAI,IAAI;IAI5B,kBAAkB,IAAI,IAAI;IAK1B,cAAc,IAAI,IAAI;IAKtB,gBAAgB,IAAI,IAAI;IAKxB,eAAe,IAAI,IAAI;IAKvB,QAAQ,CAAC,YAAY,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI;IAoBrD,OAAO,CAAC,kBAAkB;IAsC1B,OAAO,CAAC,UAAU;IAQlB,OAAO,CAAC,UAAU;IAUlB,OAAO,CAAC,kBAAkB;CAM3B;;;;AAID,wBAME"}
|
package/dist/client/utils/ReadReceiptSync/legacyReadReceiptSyncEngineOnLoginHandler.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"legacyReadReceiptSyncEngineOnLoginHandler.d.ts","sourceRoot":"","sources":["../../../../src/client/utils/ReadReceiptSync/legacyReadReceiptSyncEngineOnLoginHandler.ts"],"names":[],"mappings":";AAGA,wBAiBE"}
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Internal used only
|
|
3
|
-
*
|
|
4
|
-
* Fired when an {@link Amity.channelUnreadInfo} has been updated.
|
|
5
|
-
*
|
|
6
|
-
* @param callback The function to call when the event was fired
|
|
7
|
-
* @returns an {@link Amity.Unsubscriber} function to stop listening
|
|
8
|
-
*
|
|
9
|
-
* @category ChannelMarker Events
|
|
10
|
-
*/
|
|
11
|
-
export declare const onChannelUnreadInfoUpdatedLocal: (callback: Amity.Listener<Amity.Events['local.channelUnreadInfo.updated']>) => Amity.Unsubscriber;
|
|
12
|
-
//# sourceMappingURL=onChannelUnreadInfoUpdatedLocal.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"onChannelUnreadInfoUpdatedLocal.d.ts","sourceRoot":"","sources":["../../../src/marker/events/onChannelUnreadInfoUpdatedLocal.ts"],"names":[],"mappings":"AAGA;;;;;;;;;GASG;AACH,eAAO,MAAM,+BAA+B,aAChC,MAAM,QAAQ,CAAC,MAAM,MAAM,CAAC,iCAAiC,CAAC,CAAC,KACxE,MAAM,YAaR,CAAC"}
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
import { getActiveClient } from '~/client/api/activeClient';
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
*
|
|
5
|
-
* Mark subChannel as read by readToSegment
|
|
6
|
-
*
|
|
7
|
-
* @param subChannelIds the IDs of the {@link Amity.SubChannel} to update
|
|
8
|
-
* @param readToSegment the segment to mark as read
|
|
9
|
-
* @returns a success boolean if the {@link Amity.SubChannel} was updated
|
|
10
|
-
*
|
|
11
|
-
* @category Channel API
|
|
12
|
-
* @async
|
|
13
|
-
*/
|
|
14
|
-
|
|
15
|
-
export const markChannelsAsReadBySegment = async (
|
|
16
|
-
readings: {
|
|
17
|
-
channelId: Amity.Channel['channelId'];
|
|
18
|
-
readToSegment: number;
|
|
19
|
-
}[],
|
|
20
|
-
): Promise<boolean> => {
|
|
21
|
-
const client = getActiveClient();
|
|
22
|
-
|
|
23
|
-
try {
|
|
24
|
-
await client.http.post<Amity.MarkAsReadPayload>('api/v3/channels/seen', { channels: readings });
|
|
25
|
-
return true;
|
|
26
|
-
} catch (e) {
|
|
27
|
-
return false;
|
|
28
|
-
}
|
|
29
|
-
};
|
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
import { queryCache } from '~/cache/api';
|
|
2
|
-
import { getActiveClient } from '~/client/api/activeClient';
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
*
|
|
6
|
-
* Calculate user unread from {@link Amity.ChannelUnread} objects
|
|
7
|
-
*
|
|
8
|
-
* @returns the {@link Amity.UserUnread} objects
|
|
9
|
-
*
|
|
10
|
-
* @category Channel API
|
|
11
|
-
* @async
|
|
12
|
-
*/
|
|
13
|
-
|
|
14
|
-
export const getTotalChannelsUnread = (): Amity.Cached<Amity.UserUnread> => {
|
|
15
|
-
const client = getActiveClient();
|
|
16
|
-
client.log('channel/getTotalChannelsUnread.locally');
|
|
17
|
-
|
|
18
|
-
const cachedChannelsUnread =
|
|
19
|
-
queryCache<Amity.ChannelUnread>(['channelUnread', 'get'])?.filter(({ data }) => {
|
|
20
|
-
return !data.isDeleted;
|
|
21
|
-
}) || [];
|
|
22
|
-
|
|
23
|
-
const totalChannelsUnread: Amity.UserUnread = cachedChannelsUnread?.reduce(
|
|
24
|
-
(acc, { data }) => {
|
|
25
|
-
acc.unreadCount += data.unreadCount;
|
|
26
|
-
acc.isMentioned = acc.isMentioned || data.isMentioned;
|
|
27
|
-
return acc;
|
|
28
|
-
},
|
|
29
|
-
{ unreadCount: 0, isMentioned: false as boolean },
|
|
30
|
-
) || { unreadCount: 0, isMentioned: false };
|
|
31
|
-
|
|
32
|
-
const cachedAt = client.cache && Date.now();
|
|
33
|
-
|
|
34
|
-
return {
|
|
35
|
-
data: totalChannelsUnread,
|
|
36
|
-
cachedAt,
|
|
37
|
-
};
|
|
38
|
-
};
|
|
@@ -1,129 +0,0 @@
|
|
|
1
|
-
import { getActiveUser } from '~/client/api/activeUser';
|
|
2
|
-
import { getTotalChannelsUnread as _getTotalChannelsUnread } from '../internalApi/getTotalChannelsUnread';
|
|
3
|
-
import { onChannelUnreadUpdatedLocal } from '../events/onChannelUnreadUpdatedLocal';
|
|
4
|
-
import { ASCApiError, ASCError } from '~/core/errors';
|
|
5
|
-
import { getActiveClient } from '~/client';
|
|
6
|
-
import { convertGetterPropsToStatic } from '~/utils/object';
|
|
7
|
-
import { createQuery, runQuery } from '~/core/query';
|
|
8
|
-
import {
|
|
9
|
-
UNSYNCED_OBJECT_CACHED_AT_MESSAGE,
|
|
10
|
-
UNSYNCED_OBJECT_CACHED_AT_VALUE,
|
|
11
|
-
} from '~/utils/constants';
|
|
12
|
-
import { isEqual } from '~/utils/isEqual';
|
|
13
|
-
|
|
14
|
-
/* begin_public_function
|
|
15
|
-
id: totalChannelsUnread.get
|
|
16
|
-
*/
|
|
17
|
-
/**
|
|
18
|
-
* ```js
|
|
19
|
-
* import { ChannelRepository } from '@amityco/ts-sdk';
|
|
20
|
-
*
|
|
21
|
-
* let totalChannelsUnread;
|
|
22
|
-
*
|
|
23
|
-
* const unsubscribe = ChannelRepository.getTotalChannelsUnread(response => {
|
|
24
|
-
* unread = response.data;
|
|
25
|
-
* });
|
|
26
|
-
* ```
|
|
27
|
-
*
|
|
28
|
-
* Observe all mutation on a given {@link Amity.UserUnread}
|
|
29
|
-
*
|
|
30
|
-
* @returns An {@link Amity.UserUnread} function to run when willing to stop observing the message
|
|
31
|
-
*
|
|
32
|
-
* @category User Unread Live Object
|
|
33
|
-
*
|
|
34
|
-
*/
|
|
35
|
-
|
|
36
|
-
export const getTotalChannelsUnread = (
|
|
37
|
-
callback: Amity.LiveObjectCallback<Amity.UserUnread | undefined>,
|
|
38
|
-
): Amity.Unsubscriber => {
|
|
39
|
-
const { _id: userId } = getActiveUser();
|
|
40
|
-
|
|
41
|
-
if (!userId)
|
|
42
|
-
throw new ASCError(
|
|
43
|
-
'The _id has not been defined in ActiveUser',
|
|
44
|
-
Amity.ClientError.UNKNOWN_ERROR,
|
|
45
|
-
Amity.ErrorLevel.ERROR,
|
|
46
|
-
);
|
|
47
|
-
|
|
48
|
-
const { log, cache } = getActiveClient();
|
|
49
|
-
|
|
50
|
-
if (!cache) {
|
|
51
|
-
console.log('For using Live Object feature you need to enable Cache!');
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
const timestamp = Date.now();
|
|
55
|
-
log(`liveTotalChannelsUnread(tmpid: ${timestamp}) > listen`);
|
|
56
|
-
|
|
57
|
-
const disposers: Amity.Unsubscriber[] = [];
|
|
58
|
-
|
|
59
|
-
let isUnsyncedModel = false; // for messages
|
|
60
|
-
|
|
61
|
-
let model: Amity.UserUnread | undefined;
|
|
62
|
-
|
|
63
|
-
const dispatcher = (data: Amity.LiveObject<Amity.UserUnread | undefined>) => {
|
|
64
|
-
const { data: userUnread } = data;
|
|
65
|
-
|
|
66
|
-
const callbackModel = userUnread
|
|
67
|
-
? {
|
|
68
|
-
unreadCount: userUnread.unreadCount,
|
|
69
|
-
isMentioned: userUnread.isMentioned,
|
|
70
|
-
}
|
|
71
|
-
: undefined;
|
|
72
|
-
|
|
73
|
-
model = callbackModel ? convertGetterPropsToStatic(callbackModel) : callbackModel;
|
|
74
|
-
|
|
75
|
-
callback({
|
|
76
|
-
data: callbackModel
|
|
77
|
-
? { ...callbackModel, isMentioned: callbackModel.isMentioned }
|
|
78
|
-
: callbackModel,
|
|
79
|
-
|
|
80
|
-
loading: data.loading,
|
|
81
|
-
error: data.error,
|
|
82
|
-
});
|
|
83
|
-
};
|
|
84
|
-
|
|
85
|
-
const realtimeRouter = (userUnread: Amity.UserUnread) => {
|
|
86
|
-
if (isEqual(model, userUnread)) return;
|
|
87
|
-
|
|
88
|
-
dispatcher({
|
|
89
|
-
loading: false,
|
|
90
|
-
data: userUnread,
|
|
91
|
-
});
|
|
92
|
-
};
|
|
93
|
-
|
|
94
|
-
const onFetch = () => {
|
|
95
|
-
const query = createQuery(async () => _getTotalChannelsUnread());
|
|
96
|
-
|
|
97
|
-
runQuery(query, ({ error, data, loading, origin, cachedAt }) => {
|
|
98
|
-
if (cachedAt === UNSYNCED_OBJECT_CACHED_AT_VALUE) {
|
|
99
|
-
dispatcher({
|
|
100
|
-
data,
|
|
101
|
-
origin,
|
|
102
|
-
loading: false,
|
|
103
|
-
error: new ASCApiError(
|
|
104
|
-
UNSYNCED_OBJECT_CACHED_AT_MESSAGE,
|
|
105
|
-
Amity.ClientError.DISALOOW_UNSYNCED_OBJECT,
|
|
106
|
-
Amity.ErrorLevel.ERROR,
|
|
107
|
-
),
|
|
108
|
-
});
|
|
109
|
-
|
|
110
|
-
isUnsyncedModel = true;
|
|
111
|
-
disposers.forEach(fn => fn());
|
|
112
|
-
} else if (!isUnsyncedModel) {
|
|
113
|
-
dispatcher({ loading, data, origin, error });
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
if (error) {
|
|
117
|
-
disposers.forEach(fn => fn());
|
|
118
|
-
}
|
|
119
|
-
});
|
|
120
|
-
};
|
|
121
|
-
|
|
122
|
-
disposers.push(onChannelUnreadUpdatedLocal(realtimeRouter));
|
|
123
|
-
|
|
124
|
-
onFetch();
|
|
125
|
-
|
|
126
|
-
return () => {
|
|
127
|
-
disposers.forEach(fn => fn());
|
|
128
|
-
};
|
|
129
|
-
};
|
|
@@ -1,267 +0,0 @@
|
|
|
1
|
-
import { pullFromCache, pushToCache, queryCache } from '~/cache/api';
|
|
2
|
-
import { getActiveClient } from '../../api/activeClient';
|
|
3
|
-
import { markAsReadBySegment } from '~/subChannelRepository/api/markAsReadBySegment';
|
|
4
|
-
import { reCalculateChannelUnreadInfo } from '~/marker/utils/reCalculateChannelUnreadInfo';
|
|
5
|
-
import { fireEvent } from '~/core/events';
|
|
6
|
-
|
|
7
|
-
export class LegacyMessageReadReceiptSyncEngine {
|
|
8
|
-
private client: Amity.Client;
|
|
9
|
-
|
|
10
|
-
private isActive = true;
|
|
11
|
-
|
|
12
|
-
private MAX_RETRY = 3;
|
|
13
|
-
|
|
14
|
-
private JOB_QUEUE_SIZE = 120;
|
|
15
|
-
|
|
16
|
-
private jobQueue: Amity.LegacyReadReceiptSyncJob[] = [];
|
|
17
|
-
|
|
18
|
-
private timer: NodeJS.Timer | undefined;
|
|
19
|
-
|
|
20
|
-
// Interval for message read receipt sync in seconds
|
|
21
|
-
private RECEIPT_SYNC_INTERVAL = 1;
|
|
22
|
-
|
|
23
|
-
constructor() {
|
|
24
|
-
this.client = getActiveClient();
|
|
25
|
-
// Get remaining unsync read receipts from cache
|
|
26
|
-
this.getUnsyncJobs();
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
// Call this when client call client.login
|
|
30
|
-
startSyncReadReceipt() {
|
|
31
|
-
// Start timer when start receipt sync
|
|
32
|
-
this.timer = setInterval(() => {
|
|
33
|
-
this.syncReadReceipts();
|
|
34
|
-
}, this.RECEIPT_SYNC_INTERVAL * 1000);
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
// Read receipt observer handling
|
|
38
|
-
syncReadReceipts(): void {
|
|
39
|
-
if (this.jobQueue.length === 0 || this.isActive === false) return;
|
|
40
|
-
|
|
41
|
-
const readReceipt = this.getReadReceipt();
|
|
42
|
-
if (readReceipt) {
|
|
43
|
-
this.markReadApi(readReceipt);
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
private getUnsyncJobs(): void {
|
|
48
|
-
// Get all read receipts that has latestSyncSegment < latestSegment
|
|
49
|
-
const readReceipts = queryCache<Amity.LegacyReadReceipt>(['legacyReadReceipt'])?.filter(
|
|
50
|
-
({ data }) => {
|
|
51
|
-
return data.latestSyncSegment < data.latestSegment;
|
|
52
|
-
},
|
|
53
|
-
);
|
|
54
|
-
|
|
55
|
-
// Enqueue unsync read receipts to the job queue
|
|
56
|
-
readReceipts?.forEach(({ data: readReceipt }) => {
|
|
57
|
-
this.enqueueReadReceipt(readReceipt.subChannelId, readReceipt.latestSegment);
|
|
58
|
-
});
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
private getReadReceipt(): Amity.LegacyReadReceiptSyncJob | undefined {
|
|
62
|
-
// Get first read receipt in queue
|
|
63
|
-
const syncJob = this.jobQueue[0];
|
|
64
|
-
|
|
65
|
-
if (!syncJob) return;
|
|
66
|
-
// Skip when it's syncing
|
|
67
|
-
if (syncJob.syncState === Amity.ReadReceiptSyncState.SYNCING) return;
|
|
68
|
-
|
|
69
|
-
// Get readReceipt from cache by subChannelId
|
|
70
|
-
const readReceipt = pullFromCache<Amity.LegacyReadReceipt>([
|
|
71
|
-
'legacyReadReceipt',
|
|
72
|
-
syncJob.subChannelId,
|
|
73
|
-
])?.data;
|
|
74
|
-
|
|
75
|
-
if (!readReceipt) return;
|
|
76
|
-
|
|
77
|
-
if (readReceipt?.latestSegment > readReceipt?.latestSyncSegment) {
|
|
78
|
-
syncJob.segment = readReceipt.latestSegment;
|
|
79
|
-
return syncJob;
|
|
80
|
-
}
|
|
81
|
-
// Clear all synced job in job queue
|
|
82
|
-
this.removeSynedReceipt(readReceipt.subChannelId, readReceipt.latestSegment);
|
|
83
|
-
|
|
84
|
-
// Recursion getReadReceipt() until get unsync read receipt or job queue is empty
|
|
85
|
-
return this.getReadReceipt();
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
private async markReadApi(syncJob: Amity.LegacyReadReceiptSyncJob): Promise<void> {
|
|
89
|
-
const newSyncJob = syncJob;
|
|
90
|
-
newSyncJob.syncState = Amity.ReadReceiptSyncState.SYNCING;
|
|
91
|
-
|
|
92
|
-
const { subChannelId, segment } = newSyncJob;
|
|
93
|
-
|
|
94
|
-
const response = await markAsReadBySegment({ subChannelId, readToSegment: segment });
|
|
95
|
-
|
|
96
|
-
if (response) {
|
|
97
|
-
this.removeSynedReceipt(syncJob.subChannelId, syncJob.segment);
|
|
98
|
-
|
|
99
|
-
const readReceiptCache = pullFromCache<Amity.LegacyReadReceipt>([
|
|
100
|
-
'legacyReadReceipt',
|
|
101
|
-
subChannelId,
|
|
102
|
-
])?.data;
|
|
103
|
-
|
|
104
|
-
pushToCache(['legacyReadReceipt', subChannelId], {
|
|
105
|
-
...readReceiptCache,
|
|
106
|
-
latestSyncSegment: segment,
|
|
107
|
-
});
|
|
108
|
-
} else if (!response) {
|
|
109
|
-
if (newSyncJob.retryCount > this.MAX_RETRY) {
|
|
110
|
-
this.removeJobFromQueue(newSyncJob);
|
|
111
|
-
} else {
|
|
112
|
-
newSyncJob.retryCount += 1;
|
|
113
|
-
newSyncJob.syncState = Amity.ReadReceiptSyncState.CREATED;
|
|
114
|
-
}
|
|
115
|
-
}
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
private removeSynedReceipt(subChannelId: string, segment: number) {
|
|
119
|
-
const syncJobs = this.jobQueue;
|
|
120
|
-
|
|
121
|
-
syncJobs.forEach(job => {
|
|
122
|
-
if (job.subChannelId === subChannelId && job.segment <= segment) {
|
|
123
|
-
this.removeJobFromQueue(job);
|
|
124
|
-
}
|
|
125
|
-
});
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
private startObservingReadReceiptQueue(): void {
|
|
129
|
-
if (this.client.isUnreadCountEnabled) {
|
|
130
|
-
this.isActive = true;
|
|
131
|
-
this.startSyncReadReceipt();
|
|
132
|
-
}
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
private stopObservingReadReceiptQueue(): void {
|
|
136
|
-
this.isActive = false;
|
|
137
|
-
|
|
138
|
-
const syncJobs = this.jobQueue;
|
|
139
|
-
syncJobs.map(job => {
|
|
140
|
-
if (job.syncState === Amity.ReadReceiptSyncState.SYNCING) {
|
|
141
|
-
return { ...job, syncState: Amity.ReadReceiptSyncState.CREATED };
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
return job;
|
|
145
|
-
});
|
|
146
|
-
|
|
147
|
-
if (this.timer) clearInterval(this.timer);
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
// Session Management
|
|
151
|
-
onSessionEstablished(): void {
|
|
152
|
-
this.startObservingReadReceiptQueue();
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
onSessionDestroyed(): void {
|
|
156
|
-
this.stopObservingReadReceiptQueue();
|
|
157
|
-
this.jobQueue = [];
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
onTokenExpired(): void {
|
|
161
|
-
this.stopObservingReadReceiptQueue();
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
// Network Connection Management
|
|
165
|
-
onNetworkOffline(): void {
|
|
166
|
-
// Stop observing to the read receipt queue.
|
|
167
|
-
this.stopObservingReadReceiptQueue();
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
onNetworkOnline(): void {
|
|
171
|
-
// Resume observing to the read receipt queue.
|
|
172
|
-
this.startObservingReadReceiptQueue();
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
markRead(subChannelId: string, segment: number): void {
|
|
176
|
-
// Step 1: Optimistic update of subChannelUnreadInfo.readToSegment to message.segment
|
|
177
|
-
const cacheKey = ['subChannelUnreadInfo', 'get', subChannelId];
|
|
178
|
-
const subChannelUnreadInfo = pullFromCache<Amity.SubChannelUnreadInfo>(cacheKey)?.data;
|
|
179
|
-
|
|
180
|
-
if (subChannelUnreadInfo && segment > subChannelUnreadInfo.readToSegment) {
|
|
181
|
-
subChannelUnreadInfo.readToSegment = segment;
|
|
182
|
-
subChannelUnreadInfo.unreadCount = Math.max(subChannelUnreadInfo.lastSegment - segment, 0);
|
|
183
|
-
|
|
184
|
-
const channelUnreadInfo = reCalculateChannelUnreadInfo(subChannelUnreadInfo.channelId);
|
|
185
|
-
fireEvent('local.channelUnreadInfo.updated', channelUnreadInfo);
|
|
186
|
-
|
|
187
|
-
pushToCache(cacheKey, subChannelUnreadInfo);
|
|
188
|
-
fireEvent('local.subChannelUnread.updated', subChannelUnreadInfo);
|
|
189
|
-
}
|
|
190
|
-
|
|
191
|
-
// Step 2: Enqueue the read receipt
|
|
192
|
-
this.enqueueReadReceipt(subChannelId, segment);
|
|
193
|
-
}
|
|
194
|
-
|
|
195
|
-
private enqueueReadReceipt(subChannelId: string, segment: number): void {
|
|
196
|
-
const readReceipt = pullFromCache<Amity.LegacyReadReceipt>([
|
|
197
|
-
'legacyReadReceipt',
|
|
198
|
-
subChannelId,
|
|
199
|
-
])?.data;
|
|
200
|
-
|
|
201
|
-
// Create new read receipt if it's not exists and add job to queue
|
|
202
|
-
if (!readReceipt) {
|
|
203
|
-
const readReceiptSubChannel: Amity.LegacyReadReceipt = {
|
|
204
|
-
subChannelId,
|
|
205
|
-
latestSegment: segment,
|
|
206
|
-
latestSyncSegment: 0,
|
|
207
|
-
};
|
|
208
|
-
|
|
209
|
-
pushToCache(['legacyReadReceipt', subChannelId], readReceiptSubChannel);
|
|
210
|
-
} else if (readReceipt.latestSegment < segment) {
|
|
211
|
-
pushToCache(['legacyReadReceipt', subChannelId], { ...readReceipt, latestSegment: segment });
|
|
212
|
-
} else if (readReceipt.latestSyncSegment >= segment) {
|
|
213
|
-
// Skip the job when lastSyncSegment > = segment
|
|
214
|
-
return;
|
|
215
|
-
}
|
|
216
|
-
|
|
217
|
-
let syncJob: Amity.LegacyReadReceiptSyncJob | null = this.getSyncJob(subChannelId);
|
|
218
|
-
|
|
219
|
-
if (syncJob === null || syncJob.syncState === Amity.ReadReceiptSyncState.SYNCING) {
|
|
220
|
-
syncJob = {
|
|
221
|
-
subChannelId,
|
|
222
|
-
segment,
|
|
223
|
-
syncState: Amity.ReadReceiptSyncState.CREATED,
|
|
224
|
-
retryCount: 0,
|
|
225
|
-
};
|
|
226
|
-
|
|
227
|
-
this.enqueueJob(syncJob);
|
|
228
|
-
} else if (syncJob.segment < segment) {
|
|
229
|
-
syncJob.segment = segment;
|
|
230
|
-
}
|
|
231
|
-
}
|
|
232
|
-
|
|
233
|
-
private getSyncJob(subChannelId: string): Amity.LegacyReadReceiptSyncJob | null {
|
|
234
|
-
const syncJobs = this.jobQueue;
|
|
235
|
-
|
|
236
|
-
const targetJob = syncJobs.find(job => job.subChannelId === subChannelId);
|
|
237
|
-
|
|
238
|
-
return targetJob || null;
|
|
239
|
-
}
|
|
240
|
-
|
|
241
|
-
private enqueueJob(syncJob: Amity.LegacyReadReceiptSyncJob) {
|
|
242
|
-
if (this.jobQueue.length < this.JOB_QUEUE_SIZE) {
|
|
243
|
-
this.jobQueue.push(syncJob);
|
|
244
|
-
} else {
|
|
245
|
-
// Remove oldest job when queue reach maximum capacity
|
|
246
|
-
this.jobQueue.shift();
|
|
247
|
-
this.jobQueue.push(syncJob);
|
|
248
|
-
}
|
|
249
|
-
}
|
|
250
|
-
|
|
251
|
-
private removeJobFromQueue(item: Amity.LegacyReadReceiptSyncJob) {
|
|
252
|
-
const index = this.jobQueue.indexOf(item);
|
|
253
|
-
if (index > -1) {
|
|
254
|
-
this.jobQueue.splice(index, 1);
|
|
255
|
-
}
|
|
256
|
-
}
|
|
257
|
-
}
|
|
258
|
-
|
|
259
|
-
let instance: LegacyMessageReadReceiptSyncEngine | null = null;
|
|
260
|
-
|
|
261
|
-
export default {
|
|
262
|
-
getInstance: () => {
|
|
263
|
-
if (!instance) instance = new LegacyMessageReadReceiptSyncEngine();
|
|
264
|
-
|
|
265
|
-
return instance;
|
|
266
|
-
},
|
|
267
|
-
};
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
import { onSessionStateChange } from '~/client/events/onSessionStateChange';
|
|
2
|
-
import LegacyReadReceiptSyncEngine from '~/client/utils/ReadReceiptSync/legacyReadReceiptSyncEngine';
|
|
3
|
-
|
|
4
|
-
export default () => {
|
|
5
|
-
const readReceiptSyncEngine = LegacyReadReceiptSyncEngine.getInstance();
|
|
6
|
-
readReceiptSyncEngine.startSyncReadReceipt();
|
|
7
|
-
|
|
8
|
-
onSessionStateChange(state => {
|
|
9
|
-
if (state === Amity.SessionStates.ESTABLISHED) {
|
|
10
|
-
readReceiptSyncEngine.onSessionEstablished();
|
|
11
|
-
} else if (state === Amity.SessionStates.TOKEN_EXPIRED) {
|
|
12
|
-
readReceiptSyncEngine.onTokenExpired();
|
|
13
|
-
} else {
|
|
14
|
-
readReceiptSyncEngine.onSessionDestroyed();
|
|
15
|
-
}
|
|
16
|
-
});
|
|
17
|
-
|
|
18
|
-
return () => {
|
|
19
|
-
readReceiptSyncEngine.onSessionDestroyed();
|
|
20
|
-
};
|
|
21
|
-
};
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
import { getActiveClient } from '~/client/api/activeClient';
|
|
2
|
-
import { createEventSubscriber } from '~/core/events';
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* Internal used only
|
|
6
|
-
*
|
|
7
|
-
* Fired when an {@link Amity.channelUnreadInfo} has been updated.
|
|
8
|
-
*
|
|
9
|
-
* @param callback The function to call when the event was fired
|
|
10
|
-
* @returns an {@link Amity.Unsubscriber} function to stop listening
|
|
11
|
-
*
|
|
12
|
-
* @category ChannelMarker Events
|
|
13
|
-
*/
|
|
14
|
-
export const onChannelUnreadInfoUpdatedLocal = (
|
|
15
|
-
callback: Amity.Listener<Amity.Events['local.channelUnreadInfo.updated']>,
|
|
16
|
-
): Amity.Unsubscriber => {
|
|
17
|
-
const client = getActiveClient();
|
|
18
|
-
|
|
19
|
-
const filter = (payload: Amity.Events['local.channelUnreadInfo.updated']) => {
|
|
20
|
-
callback(payload);
|
|
21
|
-
};
|
|
22
|
-
|
|
23
|
-
return createEventSubscriber(
|
|
24
|
-
client,
|
|
25
|
-
'channelMarker/onChannelUnreadInfoUpdatedLocal',
|
|
26
|
-
'local.channelUnreadInfo.updated',
|
|
27
|
-
filter,
|
|
28
|
-
);
|
|
29
|
-
};
|