@amityco/ts-sdk 7.5.3-bab1d06.0 → 7.5.3-d42be10.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/client/api/enableUnreadCount.d.ts.map +1 -1
- package/dist/client/api/login.d.ts.map +1 -1
- package/dist/client/utils/markerSyncEngine.d.ts +1 -1
- package/dist/client/utils/markerSyncEngine.d.ts.map +1 -1
- package/dist/index.cjs.js +430 -319
- package/dist/index.esm.js +430 -319
- package/dist/index.umd.js +1 -1
- package/package.json +1 -1
- package/src/client/api/enableUnreadCount.ts +22 -0
- package/src/client/api/login.ts +4 -0
- package/src/client/utils/markerSyncEngine.ts +24 -3
- package/src/reactionRepository/api/addReaction.ts +1 -1
package/dist/index.esm.js
CHANGED
|
@@ -25987,266 +25987,6 @@ const removeChannelMarkerCache = (channel) => {
|
|
|
25987
25987
|
dropFromCache(['channelMarker', 'get', id], true);
|
|
25988
25988
|
};
|
|
25989
25989
|
|
|
25990
|
-
/* eslint-disable no-param-reassign */
|
|
25991
|
-
/*
|
|
25992
|
-
* declared earlier to accomodate case when logging in with a different user
|
|
25993
|
-
* than the one already connected, in which case the existing subscriptions need
|
|
25994
|
-
* to be cleared
|
|
25995
|
-
*/
|
|
25996
|
-
let subscriptions = [];
|
|
25997
|
-
async function runMqtt() {
|
|
25998
|
-
await modifyMqttConnection();
|
|
25999
|
-
}
|
|
26000
|
-
/* begin_public_function
|
|
26001
|
-
id: client.login
|
|
26002
|
-
*/
|
|
26003
|
-
/**
|
|
26004
|
-
* ```js
|
|
26005
|
-
* import { login } from '@amityco/ts-sdk/client/api'
|
|
26006
|
-
* const success = await login({
|
|
26007
|
-
* userId: 'XYZ123456789',
|
|
26008
|
-
* })
|
|
26009
|
-
* ```
|
|
26010
|
-
*
|
|
26011
|
-
* Connects an {@link Amity.Client} instance to ASC servers
|
|
26012
|
-
*
|
|
26013
|
-
* @param params the connect parameters
|
|
26014
|
-
* @param params.userId the user ID for the current session
|
|
26015
|
-
* @param params.displayName the user's displayName for the current session
|
|
26016
|
-
* @param params.deviceId Manual override of the user's device id (for device management)
|
|
26017
|
-
* @param params.authToken The authentication token - necessary when network option is set to secure
|
|
26018
|
-
* @returns a success boolean if connected
|
|
26019
|
-
*
|
|
26020
|
-
* @category Client API
|
|
26021
|
-
* @async
|
|
26022
|
-
*/
|
|
26023
|
-
const login = async (params, sessionHandler, config) => {
|
|
26024
|
-
var _a;
|
|
26025
|
-
const client = getActiveClient();
|
|
26026
|
-
let unsubWatcher;
|
|
26027
|
-
client.log('client/api/connectClient', Object.assign({ apiKey: client.apiKey, sessionState: client.sessionState }, params));
|
|
26028
|
-
// if connecting to a different userId than the one that is connected currently
|
|
26029
|
-
if (client.userId && client.userId !== params.userId) {
|
|
26030
|
-
await logout();
|
|
26031
|
-
// Remove subscription to ban and delete
|
|
26032
|
-
subscriptions.forEach(fn => fn());
|
|
26033
|
-
subscriptions = [];
|
|
26034
|
-
}
|
|
26035
|
-
// default values
|
|
26036
|
-
const defaultDeviceId = await getDeviceId();
|
|
26037
|
-
try {
|
|
26038
|
-
const { users } = await setClientToken({
|
|
26039
|
-
params: Object.assign(Object.assign({}, params), { displayName: params === null || params === void 0 ? void 0 : params.displayName, deviceId: (params === null || params === void 0 ? void 0 : params.deviceId) || defaultDeviceId }),
|
|
26040
|
-
options: {
|
|
26041
|
-
setAccessTokenCookie: true,
|
|
26042
|
-
},
|
|
26043
|
-
});
|
|
26044
|
-
const user = users.find(u => u.userId === params.userId);
|
|
26045
|
-
if (user == null) {
|
|
26046
|
-
throw new ASCError(`${params.userId} has not been founded`, 800000 /* Amity.ClientError.UNKNOWN_ERROR */, "error" /* Amity.ErrorLevel.ERROR */);
|
|
26047
|
-
}
|
|
26048
|
-
if (user.isDeleted) {
|
|
26049
|
-
terminateClient("userDeleted" /* Amity.TokenTerminationReason.USER_DELETED */);
|
|
26050
|
-
return false;
|
|
26051
|
-
}
|
|
26052
|
-
if (user.isGlobalBanned) {
|
|
26053
|
-
terminateClient("globalBan" /* Amity.TokenTerminationReason.GLOBAL_BAN */);
|
|
26054
|
-
return false;
|
|
26055
|
-
}
|
|
26056
|
-
// FIXME: events are duplicated if connectClient is called few times without disconnectClient
|
|
26057
|
-
// wire websocket events to our event emitter
|
|
26058
|
-
proxyWebsocketEvents(client.ws, client.emitter);
|
|
26059
|
-
(_a = client.ws) === null || _a === void 0 ? void 0 : _a.open();
|
|
26060
|
-
client.userId = user.userId;
|
|
26061
|
-
client.sessionHandler = sessionHandler;
|
|
26062
|
-
/*
|
|
26063
|
-
* Cannot push to subscriptions as watcher needs to continue working even if
|
|
26064
|
-
* token expires
|
|
26065
|
-
*/
|
|
26066
|
-
unsubWatcher = client.accessTokenExpiryWatcher(sessionHandler);
|
|
26067
|
-
setActiveUser(user);
|
|
26068
|
-
}
|
|
26069
|
-
catch (error) {
|
|
26070
|
-
/*
|
|
26071
|
-
* if getting token failed session state reverts to initial state when app
|
|
26072
|
-
* is first launched
|
|
26073
|
-
*/
|
|
26074
|
-
SessionWatcher$1.getInstance().setSessionState("notLoggedIn" /* Amity.SessionStates.NOT_LOGGED_IN */);
|
|
26075
|
-
// pass error down tree so the calling function handle it
|
|
26076
|
-
throw error;
|
|
26077
|
-
}
|
|
26078
|
-
if ((config === null || config === void 0 ? void 0 : config.disableRTE) !== true) {
|
|
26079
|
-
runMqtt();
|
|
26080
|
-
}
|
|
26081
|
-
await initializeMessagePreviewSetting();
|
|
26082
|
-
if (subscriptions.length === 0) {
|
|
26083
|
-
subscriptions.push(
|
|
26084
|
-
// GLOBAL_BAN
|
|
26085
|
-
onClientBanned((_) => {
|
|
26086
|
-
terminateClient("globalBan" /* Amity.TokenTerminationReason.GLOBAL_BAN */);
|
|
26087
|
-
subscriptions.forEach(fn => fn());
|
|
26088
|
-
unsubWatcher();
|
|
26089
|
-
}), onTokenTerminated(_ => {
|
|
26090
|
-
terminateClient();
|
|
26091
|
-
subscriptions.forEach(fn => fn());
|
|
26092
|
-
unsubWatcher();
|
|
26093
|
-
}), onUserDeleted$2((user) => {
|
|
26094
|
-
if (user.userId === client.userId) {
|
|
26095
|
-
terminateClient("userDeleted" /* Amity.TokenTerminationReason.USER_DELETED */);
|
|
26096
|
-
subscriptions.forEach(fn => fn());
|
|
26097
|
-
unsubWatcher();
|
|
26098
|
-
}
|
|
26099
|
-
}), onTokenExpired(state => {
|
|
26100
|
-
SessionWatcher$1.getInstance().setSessionState(state);
|
|
26101
|
-
logout();
|
|
26102
|
-
subscriptions.forEach(fn => fn());
|
|
26103
|
-
}),
|
|
26104
|
-
// NOTE: This is a temporary solution to handle the channel marker when the user is forced to leave
|
|
26105
|
-
// the channel because currently backend can't handle this, so every time a user is banned from
|
|
26106
|
-
// a channel or the channel is deleted the channel's unread count will not be reset to zero
|
|
26107
|
-
onChannelDeleted(removeChannelMarkerCache), onChannelMemberBanned(removeChannelMarkerCache), markReadEngineOnLoginHandler(), analyticsEngineOnLoginHandler(), objectResolverEngineOnLoginHandler());
|
|
26108
|
-
if (client.useLegacyUnreadCount) {
|
|
26109
|
-
subscriptions.push(readReceiptSyncEngineOnLoginHandler());
|
|
26110
|
-
}
|
|
26111
|
-
else
|
|
26112
|
-
subscriptions.push(legacyReadReceiptSyncEngineOnLoginHandler());
|
|
26113
|
-
}
|
|
26114
|
-
return true;
|
|
26115
|
-
};
|
|
26116
|
-
/* end_public_function */
|
|
26117
|
-
|
|
26118
|
-
/* begin_public_function
|
|
26119
|
-
id: client.renew_access_token
|
|
26120
|
-
*/
|
|
26121
|
-
/*
|
|
26122
|
-
* Renewal defintion accepted by SessionHandler interface
|
|
26123
|
-
*
|
|
26124
|
-
* Tech Spec:
|
|
26125
|
-
* https://ekoapp.atlassian.net/wiki/spaces/UP/pages/2082537485/ASC+Core+-+Session+Management+3.0#Session-Handler
|
|
26126
|
-
*
|
|
26127
|
-
* @category private
|
|
26128
|
-
*/
|
|
26129
|
-
const renewal = () => {
|
|
26130
|
-
let tokenRenewed = false;
|
|
26131
|
-
let renewTimeoutId;
|
|
26132
|
-
const client = getActiveClient();
|
|
26133
|
-
client.log('initiating access token renewal');
|
|
26134
|
-
/*
|
|
26135
|
-
* Renews a token if it is hasn't been renewed before. Also marks token as
|
|
26136
|
-
* renewed once done
|
|
26137
|
-
* Per instance of Renewal, only one renewal is allowed
|
|
26138
|
-
*/
|
|
26139
|
-
const renewToken = async (authToken) => {
|
|
26140
|
-
const { userId, displayName } = getActiveUser();
|
|
26141
|
-
const deviceId = await getDeviceId();
|
|
26142
|
-
const params = { userId, displayName, authToken, deviceId };
|
|
26143
|
-
if (client.sessionState === "tokenExpired" /* Amity.SessionStates.TOKEN_EXPIRED */ && client.sessionHandler) {
|
|
26144
|
-
await login(params, client.sessionHandler);
|
|
26145
|
-
}
|
|
26146
|
-
else {
|
|
26147
|
-
// about to expire
|
|
26148
|
-
await setClientToken({
|
|
26149
|
-
params,
|
|
26150
|
-
options: {
|
|
26151
|
-
setAccessTokenCookie: true,
|
|
26152
|
-
},
|
|
26153
|
-
});
|
|
26154
|
-
}
|
|
26155
|
-
tokenRenewed = true;
|
|
26156
|
-
if (renewTimeoutId)
|
|
26157
|
-
clearTimeout(renewTimeoutId);
|
|
26158
|
-
};
|
|
26159
|
-
return {
|
|
26160
|
-
renew: () => {
|
|
26161
|
-
if (tokenRenewed) {
|
|
26162
|
-
console.log("'renew' method can be called only once per renewal instance");
|
|
26163
|
-
return;
|
|
26164
|
-
}
|
|
26165
|
-
renewToken();
|
|
26166
|
-
},
|
|
26167
|
-
renewWithAuthToken: (authToken) => {
|
|
26168
|
-
if (tokenRenewed) {
|
|
26169
|
-
console.log("'renewWithAuthToken' method can be called only once per renewal instance");
|
|
26170
|
-
return;
|
|
26171
|
-
}
|
|
26172
|
-
renewToken(authToken);
|
|
26173
|
-
},
|
|
26174
|
-
unableToRetrieveAuthToken: () => {
|
|
26175
|
-
renewTimeoutId = setTimeout(() => {
|
|
26176
|
-
var _a;
|
|
26177
|
-
(_a = client.sessionHandler) === null || _a === void 0 ? void 0 : _a.sessionWillRenewAccessToken(renewal());
|
|
26178
|
-
}, ACCESS_TOKEN_WATCHER_INTERVAL);
|
|
26179
|
-
},
|
|
26180
|
-
};
|
|
26181
|
-
};
|
|
26182
|
-
/* end_public_function */
|
|
26183
|
-
|
|
26184
|
-
const ABOUT_TO_EXPIRE_THRESHOLD = 80 / 100;
|
|
26185
|
-
const COMPENSATED_DELAY = 5 * MINUTE;
|
|
26186
|
-
/*
|
|
26187
|
-
* a helper function to check if the token has expires
|
|
26188
|
-
*
|
|
26189
|
-
* @param token to be checked
|
|
26190
|
-
* @returns boolean indicating if token expires
|
|
26191
|
-
*
|
|
26192
|
-
* @category private
|
|
26193
|
-
*/
|
|
26194
|
-
const isExpired = (expiresAt) => Date.now() > Date.parse(expiresAt) - COMPENSATED_DELAY;
|
|
26195
|
-
/*
|
|
26196
|
-
* a helper function to check if the token is about to expire
|
|
26197
|
-
*
|
|
26198
|
-
* @param token to be checked
|
|
26199
|
-
* @returns boolean indicating if token is aboutToExpire
|
|
26200
|
-
*
|
|
26201
|
-
* @category private
|
|
26202
|
-
*/
|
|
26203
|
-
const isAboutToExpire = (params) => {
|
|
26204
|
-
const { expiresAt, issuedAt } = params;
|
|
26205
|
-
const expires = Date.parse(expiresAt);
|
|
26206
|
-
const issued = Date.parse(issuedAt);
|
|
26207
|
-
const now = Date.now();
|
|
26208
|
-
const duration = expires - issued - COMPENSATED_DELAY;
|
|
26209
|
-
const aboutToExpireAt = issued + duration * ABOUT_TO_EXPIRE_THRESHOLD;
|
|
26210
|
-
return now > aboutToExpireAt && now < expires;
|
|
26211
|
-
};
|
|
26212
|
-
/*
|
|
26213
|
-
* Monitors time to expire of token and updates session state to aboutToExpire
|
|
26214
|
-
*
|
|
26215
|
-
* @returns intervalId to be cleared after trigger
|
|
26216
|
-
*
|
|
26217
|
-
* @category private
|
|
26218
|
-
*/
|
|
26219
|
-
const accessTokenExpiryWatcher = (sessionHandler) => {
|
|
26220
|
-
const interval = setInterval(() => {
|
|
26221
|
-
const client = getActiveClient();
|
|
26222
|
-
if (!client.token)
|
|
26223
|
-
return;
|
|
26224
|
-
const { issuedAt, expiresAt } = client.token;
|
|
26225
|
-
if (isExpired(expiresAt)) {
|
|
26226
|
-
/*
|
|
26227
|
-
* the event handler will take care of updating session state
|
|
26228
|
-
* Note, this will also clear the interval id, so this event will only be
|
|
26229
|
-
* fired once
|
|
26230
|
-
*/
|
|
26231
|
-
fireEvent('tokenExpired', "tokenExpired" /* Amity.SessionStates.TOKEN_EXPIRED */);
|
|
26232
|
-
/*
|
|
26233
|
-
* https://ekoapp.atlassian.net/wiki/spaces/UP/pages/2082537485/ASC+Core+-+Session+Management+3.0#Automatically-initiate-renewal-flow
|
|
26234
|
-
*
|
|
26235
|
-
* Why sechduled task?
|
|
26236
|
-
* Since fireEvent is scheduled, it will be called
|
|
26237
|
-
* after sessionHandler leading to an invalid state change from
|
|
26238
|
-
* establishing to tokenExpired
|
|
26239
|
-
*/
|
|
26240
|
-
scheduleTask(() => sessionHandler.sessionWillRenewAccessToken(renewal()));
|
|
26241
|
-
return;
|
|
26242
|
-
}
|
|
26243
|
-
if (isAboutToExpire({ expiresAt, issuedAt })) {
|
|
26244
|
-
sessionHandler.sessionWillRenewAccessToken(renewal());
|
|
26245
|
-
}
|
|
26246
|
-
}, ACCESS_TOKEN_WATCHER_INTERVAL);
|
|
26247
|
-
return () => clearInterval(interval);
|
|
26248
|
-
};
|
|
26249
|
-
|
|
26250
25990
|
const callbacks$9 = [];
|
|
26251
25991
|
let mainDisposer$8 = null;
|
|
26252
25992
|
const dispose$9 = (cb) => {
|
|
@@ -26519,6 +26259,33 @@ const onChannelMemberRoleRemoved = (callback) => {
|
|
|
26519
26259
|
return () => dispose(callback);
|
|
26520
26260
|
};
|
|
26521
26261
|
|
|
26262
|
+
/**
|
|
26263
|
+
* ```js
|
|
26264
|
+
* import { onUserMarkerSync } from '@amityco/ts-sdk'
|
|
26265
|
+
* const dispose = onUserMarkerSync(UserMarker => {
|
|
26266
|
+
* // ...
|
|
26267
|
+
* })
|
|
26268
|
+
* ```
|
|
26269
|
+
*
|
|
26270
|
+
* Fired when an {@link Amity.UserMarker} has been sync
|
|
26271
|
+
*
|
|
26272
|
+
* @param callback The function to call when the event was fired
|
|
26273
|
+
* @returns an {@link Amity.Unsubscriber} function to stop listening
|
|
26274
|
+
*
|
|
26275
|
+
* @category UserMarker Events
|
|
26276
|
+
*/
|
|
26277
|
+
const onUserMarkerSync = (callback) => {
|
|
26278
|
+
const client = getActiveClient();
|
|
26279
|
+
const filter = (payload) => {
|
|
26280
|
+
const { userMarkers, userEntityMarkers: userEntityMarkersPayload, userFeedMarkers: userFeedMarkersPayload } = payload, rest = __rest(payload, ["userMarkers", "userEntityMarkers", "userFeedMarkers"]);
|
|
26281
|
+
const userEntityMarkers = convertChannelMarkerResponse(userEntityMarkersPayload);
|
|
26282
|
+
const userFeedMarker = convertSubChannelMarkerResponse(userFeedMarkersPayload);
|
|
26283
|
+
ingestInCache(Object.assign({ userMarkers, userEntityMarkers, userFeedMarker }, rest));
|
|
26284
|
+
callback(userMarkers[0]);
|
|
26285
|
+
};
|
|
26286
|
+
return createEventSubscriber(client, 'UserMarker/onUserMarkerSync', 'marker.user-sync', filter);
|
|
26287
|
+
};
|
|
26288
|
+
|
|
26522
26289
|
/**
|
|
26523
26290
|
* ```js
|
|
26524
26291
|
* import { onFeedMarkerUpdated } from '@amityco/ts-sdk'
|
|
@@ -26790,11 +26557,52 @@ const markerSync = async (deviceLastSyncAt) => {
|
|
|
26790
26557
|
};
|
|
26791
26558
|
};
|
|
26792
26559
|
|
|
26560
|
+
const enableUnreadCount = () => {
|
|
26561
|
+
const client = getActiveClient();
|
|
26562
|
+
client.log('client/api/isUnreadCountEnabled', client.isUnreadCountEnabled);
|
|
26563
|
+
if (!client) {
|
|
26564
|
+
throw new ASCError('There is no active client', 800000 /* Amity.ClientError.UNKNOWN_ERROR */, "fatal" /* Amity.ErrorLevel.FATAL */);
|
|
26565
|
+
}
|
|
26566
|
+
if (client.isUnreadCountEnabled)
|
|
26567
|
+
return false;
|
|
26568
|
+
client.isUnreadCountEnabled = true;
|
|
26569
|
+
client.useLegacyUnreadCount = false;
|
|
26570
|
+
client.emitter.emit('unreadCountEnabled', true);
|
|
26571
|
+
return true;
|
|
26572
|
+
};
|
|
26573
|
+
|
|
26574
|
+
/**
|
|
26575
|
+
* ```js
|
|
26576
|
+
* import { onFeedMarkerUpdated } from '@amityco/ts-sdk'
|
|
26577
|
+
* const dispose = onFeedMarkerUpdated(feedMarker => {
|
|
26578
|
+
* // ...
|
|
26579
|
+
* })
|
|
26580
|
+
* ```
|
|
26581
|
+
*
|
|
26582
|
+
* Fired when an {@link Amity.UserFeedMarker} has been updated
|
|
26583
|
+
*
|
|
26584
|
+
* @param callback The function to call when the event was fired
|
|
26585
|
+
* @returns an {@link Amity.Unsubscriber} function to stop listening
|
|
26586
|
+
*
|
|
26587
|
+
* @category FeedMarker Events
|
|
26588
|
+
*/
|
|
26589
|
+
const onUserFeedMarkerUpdated = (callback) => {
|
|
26590
|
+
const client = getActiveClient();
|
|
26591
|
+
const filter = (payload) => {
|
|
26592
|
+
persistUnreadCountInfo(payload);
|
|
26593
|
+
payload.feedMarkers.forEach(feedMarker => {
|
|
26594
|
+
callback(feedMarker);
|
|
26595
|
+
});
|
|
26596
|
+
};
|
|
26597
|
+
return createEventSubscriber(client, 'feedMarker/onUserFeedMarkerUpdated', 'marker.userFeed-updated', filter);
|
|
26598
|
+
};
|
|
26599
|
+
|
|
26793
26600
|
const SYNC_TRIGGER_INTERVAL_TIME = 2000;
|
|
26601
|
+
const ON_SUB_CHANNEL_DELETE_SYNC_TRIGGER_DELAY = 2000;
|
|
26794
26602
|
let isSyncRunning = false;
|
|
26795
26603
|
let disposers$1 = [];
|
|
26796
26604
|
let isWaitingForResponse = false;
|
|
26797
|
-
|
|
26605
|
+
let isConsistentMode = true;
|
|
26798
26606
|
let deviceLastSyncAt = null;
|
|
26799
26607
|
const getDeviceLastSyncAt = () => {
|
|
26800
26608
|
if (deviceLastSyncAt == null) {
|
|
@@ -26809,6 +26617,12 @@ const saveDeviceLastSyncAt = (lastSyncAt) => {
|
|
|
26809
26617
|
deviceLastSyncAt = lastSyncAt;
|
|
26810
26618
|
}
|
|
26811
26619
|
};
|
|
26620
|
+
const fetchDeviceLastSyncAt = async () => {
|
|
26621
|
+
const { data: userMarker } = await getUserMarker();
|
|
26622
|
+
if (userMarker == null)
|
|
26623
|
+
return;
|
|
26624
|
+
saveDeviceLastSyncAt(new Date(userMarker.lastSyncAt));
|
|
26625
|
+
};
|
|
26812
26626
|
/**
|
|
26813
26627
|
* list of conditions that make timer still trigger the syncing process.
|
|
26814
26628
|
* If it's empty, it means sync is stopped.
|
|
@@ -26846,71 +26660,372 @@ const markerSyncTrigger = async () => {
|
|
|
26846
26660
|
return;
|
|
26847
26661
|
}
|
|
26848
26662
|
try {
|
|
26849
|
-
isWaitingForResponse = true;
|
|
26850
|
-
// any past events are considered processed here.
|
|
26851
|
-
// however during waiting for the response, RTE could add the new message event;
|
|
26852
|
-
// which will make the engine trigger another call next round.
|
|
26853
|
-
events = [];
|
|
26854
|
-
const response = await markerSync(getDeviceLastSyncAt().toISOString());
|
|
26855
|
-
const latestLastSyncAt = response.data.userMarkers.reduce((maxLastSyncAt, userMarker) => {
|
|
26856
|
-
if (maxLastSyncAt == null ||
|
|
26857
|
-
maxLastSyncAt.getTime() < new Date(userMarker.lastSyncAt).getTime()) {
|
|
26858
|
-
return new Date(userMarker.lastSyncAt);
|
|
26859
|
-
}
|
|
26860
|
-
return maxLastSyncAt;
|
|
26861
|
-
}, null);
|
|
26862
|
-
saveDeviceLastSyncAt(latestLastSyncAt);
|
|
26863
|
-
if (response.hasMore) {
|
|
26864
|
-
events.push("has_more" /* Amity.MarkerSyncEvent.HAS_MORE */);
|
|
26663
|
+
isWaitingForResponse = true;
|
|
26664
|
+
// any past events are considered processed here.
|
|
26665
|
+
// however during waiting for the response, RTE could add the new message event;
|
|
26666
|
+
// which will make the engine trigger another call next round.
|
|
26667
|
+
events = [];
|
|
26668
|
+
const response = await markerSync(getDeviceLastSyncAt().toISOString());
|
|
26669
|
+
const latestLastSyncAt = response.data.userMarkers.reduce((maxLastSyncAt, userMarker) => {
|
|
26670
|
+
if (maxLastSyncAt == null ||
|
|
26671
|
+
maxLastSyncAt.getTime() < new Date(userMarker.lastSyncAt).getTime()) {
|
|
26672
|
+
return new Date(userMarker.lastSyncAt);
|
|
26673
|
+
}
|
|
26674
|
+
return maxLastSyncAt;
|
|
26675
|
+
}, null);
|
|
26676
|
+
saveDeviceLastSyncAt(latestLastSyncAt);
|
|
26677
|
+
if (response.hasMore) {
|
|
26678
|
+
events.push("has_more" /* Amity.MarkerSyncEvent.HAS_MORE */);
|
|
26679
|
+
}
|
|
26680
|
+
}
|
|
26681
|
+
catch (_a) {
|
|
26682
|
+
// prevent sync from stopping
|
|
26683
|
+
}
|
|
26684
|
+
finally {
|
|
26685
|
+
if (isWaitingForResponse) {
|
|
26686
|
+
isWaitingForResponse = false;
|
|
26687
|
+
}
|
|
26688
|
+
}
|
|
26689
|
+
};
|
|
26690
|
+
const registerEventListeners = () => {
|
|
26691
|
+
if (disposers$1.length > 0) {
|
|
26692
|
+
return;
|
|
26693
|
+
}
|
|
26694
|
+
// based on the tech spec design, we designed a fetch marker in case of these events
|
|
26695
|
+
// - new message
|
|
26696
|
+
// - create channel
|
|
26697
|
+
// - remove channel
|
|
26698
|
+
// - app going to online again after offline
|
|
26699
|
+
disposers$1.push(onOnline(() => {
|
|
26700
|
+
// should add RESUME to the event to trigger marker syncing again
|
|
26701
|
+
events.push("resume" /* Amity.MarkerSyncEvent.RESUME */);
|
|
26702
|
+
}), onMessageCreatedMqtt(message => {
|
|
26703
|
+
// only conversation, community and broadcast types can sync
|
|
26704
|
+
const client = getActiveClient();
|
|
26705
|
+
if (isUnreadCountSupport$1(message) && message.creatorId !== client.userId)
|
|
26706
|
+
events.push("new message" /* Amity.MarkerSyncEvent.NEW_MESSAGE */);
|
|
26707
|
+
}), onChannelCreated(() => events.push("subchannel is created" /* Amity.MarkerSyncEvent.CHANNEL_CREATED */)), onChannelDeleted(() => events.push("subchannel is deleted" /* Amity.MarkerSyncEvent.CHANNEL_DELETED */)), onChannelJoined(() => events.push("subchannel is joined" /* Amity.MarkerSyncEvent.CHANNEL_JOINED */)), onChannelLeft(() => events.push("subchannel is left" /* Amity.MarkerSyncEvent.CHANNEL_LEFT */)), onSubChannelCreated(() => events.push("subchannel is created" /* Amity.MarkerSyncEvent.SUB_CHANNEL_CREATED */)), onSubChannelDeleted(() =>
|
|
26708
|
+
/*
|
|
26709
|
+
workaround: when receiving the event for sub-channel deletion,
|
|
26710
|
+
before triggering marker update, the SDK will have to add a 2-second delay.
|
|
26711
|
+
so that the unread count is calculated correctly.
|
|
26712
|
+
*/
|
|
26713
|
+
setTimeout(() => events.push("subchannel is deleted" /* Amity.MarkerSyncEvent.SUBCHANNEL_IS_DELETED */), ON_SUB_CHANNEL_DELETE_SYNC_TRIGGER_DELAY)), onFeedMarkerUpdated(() => events.push("feed marker updated" /* Amity.MarkerSyncEvent.MARKER_UPDATED */)), onUserMarkerSync(() => events.push("feed marker updated" /* Amity.MarkerSyncEvent.MARKER_UPDATED */)), onUserFeedMarkerUpdated(() => events.push("feed marker updated" /* Amity.MarkerSyncEvent.MARKER_UPDATED */)));
|
|
26714
|
+
};
|
|
26715
|
+
const unRegisterEventListeners = () => {
|
|
26716
|
+
disposers$1.forEach(fn => fn());
|
|
26717
|
+
disposers$1 = [];
|
|
26718
|
+
};
|
|
26719
|
+
const startMarkerSync = async () => {
|
|
26720
|
+
await fetchDeviceLastSyncAt();
|
|
26721
|
+
pushMarkerSyncEvent("start syncing" /* Amity.MarkerSyncEvent.START_SYNCING */);
|
|
26722
|
+
isConsistentMode = true;
|
|
26723
|
+
isSyncRunning = true;
|
|
26724
|
+
registerEventListeners();
|
|
26725
|
+
return unRegisterEventListeners;
|
|
26726
|
+
};
|
|
26727
|
+
/**
|
|
26728
|
+
```js
|
|
26729
|
+
* import { startUnreadSync } from '@amityco/ts-sdk'
|
|
26730
|
+
* startUnreadSync()
|
|
26731
|
+
* ```
|
|
26732
|
+
*
|
|
26733
|
+
* start syncing to keep feed markers, channel markers and user makers cache
|
|
26734
|
+
* update to the server.
|
|
26735
|
+
*
|
|
26736
|
+
* @category Marker API
|
|
26737
|
+
*/
|
|
26738
|
+
const startUnreadSync = async () => {
|
|
26739
|
+
await fetchDeviceLastSyncAt();
|
|
26740
|
+
pushMarkerSyncEvent("start syncing" /* Amity.MarkerSyncEvent.START_SYNCING */);
|
|
26741
|
+
enableUnreadCount();
|
|
26742
|
+
isConsistentMode = false;
|
|
26743
|
+
isSyncRunning = true;
|
|
26744
|
+
registerEventListeners();
|
|
26745
|
+
};
|
|
26746
|
+
/**
|
|
26747
|
+
```js
|
|
26748
|
+
* import { stopUnreadSync } from '@amityco/ts-sdk'
|
|
26749
|
+
* stopUnreadSync()
|
|
26750
|
+
* ```
|
|
26751
|
+
*
|
|
26752
|
+
* stop unread syncing
|
|
26753
|
+
*
|
|
26754
|
+
* @category Marker API
|
|
26755
|
+
*/
|
|
26756
|
+
const stopUnreadSync = () => {
|
|
26757
|
+
isSyncRunning = false;
|
|
26758
|
+
setMarkerSyncEvents([]);
|
|
26759
|
+
unRegisterEventListeners();
|
|
26760
|
+
};
|
|
26761
|
+
setIntervalTask(async () => {
|
|
26762
|
+
if (!isSyncRunning)
|
|
26763
|
+
return;
|
|
26764
|
+
await markerSyncTrigger();
|
|
26765
|
+
}, SYNC_TRIGGER_INTERVAL_TIME);
|
|
26766
|
+
const getMarkerSyncConsistentMode = () => isConsistentMode;
|
|
26767
|
+
|
|
26768
|
+
/* eslint-disable no-param-reassign */
|
|
26769
|
+
/*
|
|
26770
|
+
* declared earlier to accomodate case when logging in with a different user
|
|
26771
|
+
* than the one already connected, in which case the existing subscriptions need
|
|
26772
|
+
* to be cleared
|
|
26773
|
+
*/
|
|
26774
|
+
let subscriptions = [];
|
|
26775
|
+
async function runMqtt() {
|
|
26776
|
+
await modifyMqttConnection();
|
|
26777
|
+
}
|
|
26778
|
+
/* begin_public_function
|
|
26779
|
+
id: client.login
|
|
26780
|
+
*/
|
|
26781
|
+
/**
|
|
26782
|
+
* ```js
|
|
26783
|
+
* import { login } from '@amityco/ts-sdk/client/api'
|
|
26784
|
+
* const success = await login({
|
|
26785
|
+
* userId: 'XYZ123456789',
|
|
26786
|
+
* })
|
|
26787
|
+
* ```
|
|
26788
|
+
*
|
|
26789
|
+
* Connects an {@link Amity.Client} instance to ASC servers
|
|
26790
|
+
*
|
|
26791
|
+
* @param params the connect parameters
|
|
26792
|
+
* @param params.userId the user ID for the current session
|
|
26793
|
+
* @param params.displayName the user's displayName for the current session
|
|
26794
|
+
* @param params.deviceId Manual override of the user's device id (for device management)
|
|
26795
|
+
* @param params.authToken The authentication token - necessary when network option is set to secure
|
|
26796
|
+
* @returns a success boolean if connected
|
|
26797
|
+
*
|
|
26798
|
+
* @category Client API
|
|
26799
|
+
* @async
|
|
26800
|
+
*/
|
|
26801
|
+
const login = async (params, sessionHandler, config) => {
|
|
26802
|
+
var _a;
|
|
26803
|
+
const client = getActiveClient();
|
|
26804
|
+
let unsubWatcher;
|
|
26805
|
+
client.log('client/api/connectClient', Object.assign({ apiKey: client.apiKey, sessionState: client.sessionState }, params));
|
|
26806
|
+
// if connecting to a different userId than the one that is connected currently
|
|
26807
|
+
if (client.userId && client.userId !== params.userId) {
|
|
26808
|
+
await logout();
|
|
26809
|
+
// Remove subscription to ban and delete
|
|
26810
|
+
subscriptions.forEach(fn => fn());
|
|
26811
|
+
subscriptions = [];
|
|
26812
|
+
}
|
|
26813
|
+
// default values
|
|
26814
|
+
const defaultDeviceId = await getDeviceId();
|
|
26815
|
+
try {
|
|
26816
|
+
const { users } = await setClientToken({
|
|
26817
|
+
params: Object.assign(Object.assign({}, params), { displayName: params === null || params === void 0 ? void 0 : params.displayName, deviceId: (params === null || params === void 0 ? void 0 : params.deviceId) || defaultDeviceId }),
|
|
26818
|
+
options: {
|
|
26819
|
+
setAccessTokenCookie: true,
|
|
26820
|
+
},
|
|
26821
|
+
});
|
|
26822
|
+
const user = users.find(u => u.userId === params.userId);
|
|
26823
|
+
if (user == null) {
|
|
26824
|
+
throw new ASCError(`${params.userId} has not been founded`, 800000 /* Amity.ClientError.UNKNOWN_ERROR */, "error" /* Amity.ErrorLevel.ERROR */);
|
|
26825
|
+
}
|
|
26826
|
+
if (user.isDeleted) {
|
|
26827
|
+
terminateClient("userDeleted" /* Amity.TokenTerminationReason.USER_DELETED */);
|
|
26828
|
+
return false;
|
|
26865
26829
|
}
|
|
26830
|
+
if (user.isGlobalBanned) {
|
|
26831
|
+
terminateClient("globalBan" /* Amity.TokenTerminationReason.GLOBAL_BAN */);
|
|
26832
|
+
return false;
|
|
26833
|
+
}
|
|
26834
|
+
// FIXME: events are duplicated if connectClient is called few times without disconnectClient
|
|
26835
|
+
// wire websocket events to our event emitter
|
|
26836
|
+
proxyWebsocketEvents(client.ws, client.emitter);
|
|
26837
|
+
(_a = client.ws) === null || _a === void 0 ? void 0 : _a.open();
|
|
26838
|
+
client.userId = user.userId;
|
|
26839
|
+
client.sessionHandler = sessionHandler;
|
|
26840
|
+
/*
|
|
26841
|
+
* Cannot push to subscriptions as watcher needs to continue working even if
|
|
26842
|
+
* token expires
|
|
26843
|
+
*/
|
|
26844
|
+
unsubWatcher = client.accessTokenExpiryWatcher(sessionHandler);
|
|
26845
|
+
setActiveUser(user);
|
|
26866
26846
|
}
|
|
26867
|
-
catch (
|
|
26868
|
-
|
|
26847
|
+
catch (error) {
|
|
26848
|
+
/*
|
|
26849
|
+
* if getting token failed session state reverts to initial state when app
|
|
26850
|
+
* is first launched
|
|
26851
|
+
*/
|
|
26852
|
+
SessionWatcher$1.getInstance().setSessionState("notLoggedIn" /* Amity.SessionStates.NOT_LOGGED_IN */);
|
|
26853
|
+
// pass error down tree so the calling function handle it
|
|
26854
|
+
throw error;
|
|
26869
26855
|
}
|
|
26870
|
-
|
|
26871
|
-
|
|
26872
|
-
|
|
26856
|
+
if ((config === null || config === void 0 ? void 0 : config.disableRTE) !== true) {
|
|
26857
|
+
runMqtt();
|
|
26858
|
+
}
|
|
26859
|
+
await initializeMessagePreviewSetting();
|
|
26860
|
+
if (subscriptions.length === 0) {
|
|
26861
|
+
subscriptions.push(
|
|
26862
|
+
// GLOBAL_BAN
|
|
26863
|
+
onClientBanned((_) => {
|
|
26864
|
+
terminateClient("globalBan" /* Amity.TokenTerminationReason.GLOBAL_BAN */);
|
|
26865
|
+
subscriptions.forEach(fn => fn());
|
|
26866
|
+
unsubWatcher();
|
|
26867
|
+
}), onTokenTerminated(_ => {
|
|
26868
|
+
terminateClient();
|
|
26869
|
+
subscriptions.forEach(fn => fn());
|
|
26870
|
+
unsubWatcher();
|
|
26871
|
+
}), onUserDeleted$2((user) => {
|
|
26872
|
+
if (user.userId === client.userId) {
|
|
26873
|
+
terminateClient("userDeleted" /* Amity.TokenTerminationReason.USER_DELETED */);
|
|
26874
|
+
subscriptions.forEach(fn => fn());
|
|
26875
|
+
unsubWatcher();
|
|
26876
|
+
}
|
|
26877
|
+
}), onTokenExpired(state => {
|
|
26878
|
+
SessionWatcher$1.getInstance().setSessionState(state);
|
|
26879
|
+
logout();
|
|
26880
|
+
subscriptions.forEach(fn => fn());
|
|
26881
|
+
}),
|
|
26882
|
+
// NOTE: This is a temporary solution to handle the channel marker when the user is forced to leave
|
|
26883
|
+
// the channel because currently backend can't handle this, so every time a user is banned from
|
|
26884
|
+
// a channel or the channel is deleted the channel's unread count will not be reset to zero
|
|
26885
|
+
onChannelDeleted(removeChannelMarkerCache), onChannelMemberBanned(removeChannelMarkerCache), markReadEngineOnLoginHandler(), analyticsEngineOnLoginHandler(), objectResolverEngineOnLoginHandler());
|
|
26886
|
+
if (client.useLegacyUnreadCount) {
|
|
26887
|
+
subscriptions.push(readReceiptSyncEngineOnLoginHandler());
|
|
26873
26888
|
}
|
|
26889
|
+
else
|
|
26890
|
+
subscriptions.push(legacyReadReceiptSyncEngineOnLoginHandler());
|
|
26891
|
+
const markerSyncUnsubscriber = await startMarkerSync();
|
|
26892
|
+
subscriptions.push(markerSyncUnsubscriber);
|
|
26874
26893
|
}
|
|
26894
|
+
return true;
|
|
26875
26895
|
};
|
|
26876
|
-
|
|
26877
|
-
|
|
26878
|
-
|
|
26896
|
+
/* end_public_function */
|
|
26897
|
+
|
|
26898
|
+
/* begin_public_function
|
|
26899
|
+
id: client.renew_access_token
|
|
26900
|
+
*/
|
|
26901
|
+
/*
|
|
26902
|
+
* Renewal defintion accepted by SessionHandler interface
|
|
26903
|
+
*
|
|
26904
|
+
* Tech Spec:
|
|
26905
|
+
* https://ekoapp.atlassian.net/wiki/spaces/UP/pages/2082537485/ASC+Core+-+Session+Management+3.0#Session-Handler
|
|
26906
|
+
*
|
|
26907
|
+
* @category private
|
|
26908
|
+
*/
|
|
26909
|
+
const renewal = () => {
|
|
26910
|
+
let tokenRenewed = false;
|
|
26911
|
+
let renewTimeoutId;
|
|
26912
|
+
const client = getActiveClient();
|
|
26913
|
+
client.log('initiating access token renewal');
|
|
26914
|
+
/*
|
|
26915
|
+
* Renews a token if it is hasn't been renewed before. Also marks token as
|
|
26916
|
+
* renewed once done
|
|
26917
|
+
* Per instance of Renewal, only one renewal is allowed
|
|
26918
|
+
*/
|
|
26919
|
+
const renewToken = async (authToken) => {
|
|
26920
|
+
const { userId, displayName } = getActiveUser();
|
|
26921
|
+
const deviceId = await getDeviceId();
|
|
26922
|
+
const params = { userId, displayName, authToken, deviceId };
|
|
26923
|
+
if (client.sessionState === "tokenExpired" /* Amity.SessionStates.TOKEN_EXPIRED */ && client.sessionHandler) {
|
|
26924
|
+
await login(params, client.sessionHandler);
|
|
26925
|
+
}
|
|
26926
|
+
else {
|
|
26927
|
+
// about to expire
|
|
26928
|
+
await setClientToken({
|
|
26929
|
+
params,
|
|
26930
|
+
options: {
|
|
26931
|
+
setAccessTokenCookie: true,
|
|
26932
|
+
},
|
|
26933
|
+
});
|
|
26934
|
+
}
|
|
26935
|
+
tokenRenewed = true;
|
|
26936
|
+
if (renewTimeoutId)
|
|
26937
|
+
clearTimeout(renewTimeoutId);
|
|
26938
|
+
};
|
|
26939
|
+
return {
|
|
26940
|
+
renew: () => {
|
|
26941
|
+
if (tokenRenewed) {
|
|
26942
|
+
console.log("'renew' method can be called only once per renewal instance");
|
|
26943
|
+
return;
|
|
26944
|
+
}
|
|
26945
|
+
renewToken();
|
|
26946
|
+
},
|
|
26947
|
+
renewWithAuthToken: (authToken) => {
|
|
26948
|
+
if (tokenRenewed) {
|
|
26949
|
+
console.log("'renewWithAuthToken' method can be called only once per renewal instance");
|
|
26950
|
+
return;
|
|
26951
|
+
}
|
|
26952
|
+
renewToken(authToken);
|
|
26953
|
+
},
|
|
26954
|
+
unableToRetrieveAuthToken: () => {
|
|
26955
|
+
renewTimeoutId = setTimeout(() => {
|
|
26956
|
+
var _a;
|
|
26957
|
+
(_a = client.sessionHandler) === null || _a === void 0 ? void 0 : _a.sessionWillRenewAccessToken(renewal());
|
|
26958
|
+
}, ACCESS_TOKEN_WATCHER_INTERVAL);
|
|
26959
|
+
},
|
|
26960
|
+
};
|
|
26879
26961
|
};
|
|
26880
|
-
|
|
26881
|
-
|
|
26882
|
-
|
|
26883
|
-
|
|
26884
|
-
|
|
26885
|
-
*
|
|
26962
|
+
/* end_public_function */
|
|
26963
|
+
|
|
26964
|
+
const ABOUT_TO_EXPIRE_THRESHOLD = 80 / 100;
|
|
26965
|
+
const COMPENSATED_DELAY = 5 * MINUTE;
|
|
26966
|
+
/*
|
|
26967
|
+
* a helper function to check if the token has expires
|
|
26886
26968
|
*
|
|
26887
|
-
*
|
|
26888
|
-
*
|
|
26969
|
+
* @param token to be checked
|
|
26970
|
+
* @returns boolean indicating if token expires
|
|
26889
26971
|
*
|
|
26890
|
-
* @category
|
|
26972
|
+
* @category private
|
|
26891
26973
|
*/
|
|
26892
|
-
const
|
|
26893
|
-
|
|
26894
|
-
|
|
26895
|
-
* import { stopUnreadSync } from '@amityco/ts-sdk'
|
|
26896
|
-
* stopUnreadSync()
|
|
26897
|
-
* ```
|
|
26974
|
+
const isExpired = (expiresAt) => Date.now() > Date.parse(expiresAt) - COMPENSATED_DELAY;
|
|
26975
|
+
/*
|
|
26976
|
+
* a helper function to check if the token is about to expire
|
|
26898
26977
|
*
|
|
26899
|
-
*
|
|
26978
|
+
* @param token to be checked
|
|
26979
|
+
* @returns boolean indicating if token is aboutToExpire
|
|
26900
26980
|
*
|
|
26901
|
-
* @category
|
|
26981
|
+
* @category private
|
|
26902
26982
|
*/
|
|
26903
|
-
const
|
|
26904
|
-
|
|
26905
|
-
|
|
26906
|
-
|
|
26983
|
+
const isAboutToExpire = (params) => {
|
|
26984
|
+
const { expiresAt, issuedAt } = params;
|
|
26985
|
+
const expires = Date.parse(expiresAt);
|
|
26986
|
+
const issued = Date.parse(issuedAt);
|
|
26987
|
+
const now = Date.now();
|
|
26988
|
+
const duration = expires - issued - COMPENSATED_DELAY;
|
|
26989
|
+
const aboutToExpireAt = issued + duration * ABOUT_TO_EXPIRE_THRESHOLD;
|
|
26990
|
+
return now > aboutToExpireAt && now < expires;
|
|
26907
26991
|
};
|
|
26908
|
-
|
|
26909
|
-
|
|
26910
|
-
|
|
26911
|
-
|
|
26912
|
-
|
|
26913
|
-
|
|
26992
|
+
/*
|
|
26993
|
+
* Monitors time to expire of token and updates session state to aboutToExpire
|
|
26994
|
+
*
|
|
26995
|
+
* @returns intervalId to be cleared after trigger
|
|
26996
|
+
*
|
|
26997
|
+
* @category private
|
|
26998
|
+
*/
|
|
26999
|
+
const accessTokenExpiryWatcher = (sessionHandler) => {
|
|
27000
|
+
const interval = setInterval(() => {
|
|
27001
|
+
const client = getActiveClient();
|
|
27002
|
+
if (!client.token)
|
|
27003
|
+
return;
|
|
27004
|
+
const { issuedAt, expiresAt } = client.token;
|
|
27005
|
+
if (isExpired(expiresAt)) {
|
|
27006
|
+
/*
|
|
27007
|
+
* the event handler will take care of updating session state
|
|
27008
|
+
* Note, this will also clear the interval id, so this event will only be
|
|
27009
|
+
* fired once
|
|
27010
|
+
*/
|
|
27011
|
+
fireEvent('tokenExpired', "tokenExpired" /* Amity.SessionStates.TOKEN_EXPIRED */);
|
|
27012
|
+
/*
|
|
27013
|
+
* https://ekoapp.atlassian.net/wiki/spaces/UP/pages/2082537485/ASC+Core+-+Session+Management+3.0#Automatically-initiate-renewal-flow
|
|
27014
|
+
*
|
|
27015
|
+
* Why sechduled task?
|
|
27016
|
+
* Since fireEvent is scheduled, it will be called
|
|
27017
|
+
* after sessionHandler leading to an invalid state change from
|
|
27018
|
+
* establishing to tokenExpired
|
|
27019
|
+
*/
|
|
27020
|
+
scheduleTask(() => sessionHandler.sessionWillRenewAccessToken(renewal()));
|
|
27021
|
+
return;
|
|
27022
|
+
}
|
|
27023
|
+
if (isAboutToExpire({ expiresAt, issuedAt })) {
|
|
27024
|
+
sessionHandler.sessionWillRenewAccessToken(renewal());
|
|
27025
|
+
}
|
|
27026
|
+
}, ACCESS_TOKEN_WATCHER_INTERVAL);
|
|
27027
|
+
return () => clearInterval(interval);
|
|
27028
|
+
};
|
|
26914
27029
|
|
|
26915
27030
|
const DEFAULT_DEBUG_SESSION = 'amity';
|
|
26916
27031
|
/**
|
|
@@ -27057,10 +27172,6 @@ const isConnected = () => {
|
|
|
27057
27172
|
isWsConnected);
|
|
27058
27173
|
};
|
|
27059
27174
|
|
|
27060
|
-
const enableUnreadCount = () => {
|
|
27061
|
-
return true;
|
|
27062
|
-
};
|
|
27063
|
-
|
|
27064
27175
|
var _GlobalFileAccessType_fileAccessType;
|
|
27065
27176
|
class GlobalFileAccessType {
|
|
27066
27177
|
constructor() {
|
|
@@ -30246,7 +30357,7 @@ const prepareCommentFromFlaggedEvent = (payload) => {
|
|
|
30246
30357
|
* @async
|
|
30247
30358
|
* */
|
|
30248
30359
|
const addReaction = async (referenceType, referenceId, reactionName) => {
|
|
30249
|
-
var _a, _b
|
|
30360
|
+
var _a, _b;
|
|
30250
30361
|
const client = getActiveClient();
|
|
30251
30362
|
client.log('reaction/createReaction', {
|
|
30252
30363
|
referenceId,
|
|
@@ -30267,9 +30378,9 @@ const addReaction = async (referenceType, referenceId, reactionName) => {
|
|
|
30267
30378
|
'get',
|
|
30268
30379
|
referenceId,
|
|
30269
30380
|
]);
|
|
30270
|
-
if (!model
|
|
30381
|
+
if (!model)
|
|
30271
30382
|
return true;
|
|
30272
|
-
const updatedModel = Object.assign(Object.assign({}, model.data), { reactionsCount: model.data.reactionsCount + 1, myReactions: [...((
|
|
30383
|
+
const updatedModel = Object.assign(Object.assign({}, model.data), { reactionsCount: model.data.reactionsCount + 1, myReactions: [...((_a = model.data.myReactions) !== null && _a !== void 0 ? _a : []), reactionName], reactions: Object.assign(Object.assign({}, model.data.reactions), { [reactionName]: ((_b = model.data.reactions[reactionName]) !== null && _b !== void 0 ? _b : 0) + 1 }) });
|
|
30273
30384
|
if (referenceType === 'comment') {
|
|
30274
30385
|
fireEvent('local.comment.addReaction', {
|
|
30275
30386
|
comment: updatedModel,
|