@amityco/ts-sdk 7.27.0 → 7.27.1-075c277.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 -0
- package/dist/@types/core/events.d.ts.map +1 -1
- package/dist/@types/core/payload.d.ts +26 -0
- package/dist/@types/core/payload.d.ts.map +1 -1
- package/dist/@types/core/permissions.d.ts +10 -4
- package/dist/@types/core/permissions.d.ts.map +1 -1
- package/dist/@types/domains/analytics.d.ts +3 -1
- package/dist/@types/domains/analytics.d.ts.map +1 -1
- package/dist/@types/domains/channel.d.ts +5 -0
- package/dist/@types/domains/channel.d.ts.map +1 -1
- package/dist/@types/domains/client.d.ts +18 -0
- package/dist/@types/domains/client.d.ts.map +1 -1
- package/dist/@types/domains/comment.d.ts +27 -0
- package/dist/@types/domains/comment.d.ts.map +1 -1
- package/dist/@types/domains/community.d.ts +1 -0
- package/dist/@types/domains/community.d.ts.map +1 -1
- package/dist/@types/domains/curatedContent.d.ts +25 -0
- package/dist/@types/domains/curatedContent.d.ts.map +1 -0
- package/dist/@types/domains/pinnedMessage.d.ts +43 -0
- package/dist/@types/domains/pinnedMessage.d.ts.map +1 -0
- package/dist/@types/domains/post.d.ts +11 -0
- package/dist/@types/domains/post.d.ts.map +1 -1
- package/dist/@types/index.d.ts +3 -1
- package/dist/@types/index.d.ts.map +1 -1
- package/dist/analytic/service/analytic/AnalyticsEngine.d.ts +3 -0
- package/dist/analytic/service/analytic/AnalyticsEngine.d.ts.map +1 -1
- package/dist/analytic/service/analytic/AnalyticsEventCapturer.d.ts +3 -0
- package/dist/analytic/service/analytic/AnalyticsEventCapturer.d.ts.map +1 -1
- package/dist/channelRepository/events/index.d.ts +2 -0
- package/dist/channelRepository/events/index.d.ts.map +1 -1
- package/dist/channelRepository/events/onChannelMemberRoleAdded.d.ts +22 -0
- package/dist/channelRepository/events/onChannelMemberRoleAdded.d.ts.map +1 -1
- package/dist/channelRepository/events/onChannelMemberRoleRemoved.d.ts +22 -0
- package/dist/channelRepository/events/onChannelMemberRoleRemoved.d.ts.map +1 -1
- package/dist/channelRepository/events/onChannelMessagePinned.d.ts +24 -0
- package/dist/channelRepository/events/onChannelMessagePinned.d.ts.map +1 -0
- package/dist/channelRepository/events/onChannelMessageUnpinned.d.ts +21 -0
- package/dist/channelRepository/events/onChannelMessageUnpinned.d.ts.map +1 -0
- package/dist/channelRepository/events/onChannelPinnedMessageDeleted.d.ts +12 -0
- package/dist/channelRepository/events/onChannelPinnedMessageDeleted.d.ts.map +1 -0
- package/dist/channelRepository/events/tests/onChannelMemberRoleAdded.test.d.ts +2 -0
- package/dist/channelRepository/events/tests/onChannelMemberRoleAdded.test.d.ts.map +1 -0
- package/dist/channelRepository/events/tests/onChannelMemberRoleRemoved.test.d.ts +2 -0
- package/dist/channelRepository/events/tests/onChannelMemberRoleRemoved.test.d.ts.map +1 -0
- package/dist/channelRepository/events/tests/onChannelMessagePinned.test.d.ts +2 -0
- package/dist/channelRepository/events/tests/onChannelMessagePinned.test.d.ts.map +1 -0
- 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/getMyMembership.d.ts.map +1 -1
- package/dist/channelRepository/observers/searchChannels/SearchChannelLiveCollectionController.d.ts.map +1 -1
- package/dist/channelRepository/utils/applyChannelRolePayload.d.ts +21 -0
- package/dist/channelRepository/utils/applyChannelRolePayload.d.ts.map +1 -0
- package/dist/channelRepository/utils/index.d.ts +2 -0
- package/dist/channelRepository/utils/index.d.ts.map +1 -1
- package/dist/channelRepository/utils/tests/pinnedMessage.test.d.ts +2 -0
- package/dist/channelRepository/utils/tests/pinnedMessage.test.d.ts.map +1 -0
- package/dist/channelRepository/utils/updatePinnedMessageCache.d.ts +24 -0
- package/dist/channelRepository/utils/updatePinnedMessageCache.d.ts.map +1 -0
- package/dist/client/api/createClient.d.ts +5 -1
- package/dist/client/api/createClient.d.ts.map +1 -1
- package/dist/client/api/getSocialSettings.d.ts.map +1 -1
- package/dist/client/api/setupLoginSubscriptions.d.ts.map +1 -1
- package/dist/client/api/tests/getSocialSettings.test.d.ts +2 -0
- package/dist/client/api/tests/getSocialSettings.test.d.ts.map +1 -0
- package/dist/commentRepository/api/approveComment.d.ts +17 -0
- package/dist/commentRepository/api/approveComment.d.ts.map +1 -0
- package/dist/commentRepository/api/createComment.d.ts +12 -1
- package/dist/commentRepository/api/createComment.d.ts.map +1 -1
- package/dist/commentRepository/api/declineComment.d.ts +18 -0
- package/dist/commentRepository/api/declineComment.d.ts.map +1 -0
- package/dist/commentRepository/api/deleteComment.d.ts.map +1 -1
- package/dist/commentRepository/api/index.d.ts +2 -0
- package/dist/commentRepository/api/index.d.ts.map +1 -1
- package/dist/commentRepository/api/tests/approveComment.test.d.ts +2 -0
- package/dist/commentRepository/api/tests/approveComment.test.d.ts.map +1 -0
- package/dist/commentRepository/api/tests/createComment.optimistic.test.d.ts +2 -0
- package/dist/commentRepository/api/tests/createComment.optimistic.test.d.ts.map +1 -0
- package/dist/commentRepository/api/tests/declineComment.test.d.ts +2 -0
- package/dist/commentRepository/api/tests/declineComment.test.d.ts.map +1 -0
- package/dist/commentRepository/api/updateComment.d.ts.map +1 -1
- package/dist/commentRepository/events/index.d.ts +1 -0
- package/dist/commentRepository/events/index.d.ts.map +1 -1
- package/dist/commentRepository/events/onCommentApproved.d.ts +17 -0
- package/dist/commentRepository/events/onCommentApproved.d.ts.map +1 -0
- package/dist/commentRepository/events/tests/onCommentApproved.test.d.ts +2 -0
- package/dist/commentRepository/events/tests/onCommentApproved.test.d.ts.map +1 -0
- package/dist/commentRepository/events/tests/onCommentCreated.count.test.d.ts +2 -0
- package/dist/commentRepository/events/tests/onCommentCreated.count.test.d.ts.map +1 -0
- package/dist/commentRepository/events/utils.d.ts.map +1 -1
- package/dist/commentRepository/internalApi/getComment.d.ts.map +1 -1
- package/dist/commentRepository/observers/getComment.d.ts.map +1 -1
- package/dist/commentRepository/observers/getCommentReviewQueue/LiveCollectionController.d.ts +13 -0
- package/dist/commentRepository/observers/getCommentReviewQueue/LiveCollectionController.d.ts.map +1 -0
- package/dist/commentRepository/observers/getCommentReviewQueue/PaginationController.d.ts +5 -0
- package/dist/commentRepository/observers/getCommentReviewQueue/PaginationController.d.ts.map +1 -0
- package/dist/commentRepository/observers/getCommentReviewQueue/QueryStreamController.d.ts +15 -0
- package/dist/commentRepository/observers/getCommentReviewQueue/QueryStreamController.d.ts.map +1 -0
- package/dist/commentRepository/observers/getCommentReviewQueue.d.ts +22 -0
- package/dist/commentRepository/observers/getCommentReviewQueue.d.ts.map +1 -0
- package/dist/commentRepository/observers/getComments/CommentLiveCollectionController.d.ts +1 -1
- package/dist/commentRepository/observers/getComments/CommentLiveCollectionController.d.ts.map +1 -1
- package/dist/commentRepository/observers/getComments/CommentQueryStreamController.d.ts.map +1 -1
- package/dist/commentRepository/observers/getComments/enums.d.ts +1 -0
- package/dist/commentRepository/observers/getComments/enums.d.ts.map +1 -1
- package/dist/commentRepository/observers/index.d.ts +1 -0
- package/dist/commentRepository/observers/index.d.ts.map +1 -1
- package/dist/commentRepository/observers/tests/integrations/getCommentReviewQueue.integration.test.d.ts +2 -0
- package/dist/commentRepository/observers/tests/integrations/getCommentReviewQueue.integration.test.d.ts.map +1 -0
- package/dist/commentRepository/utils/approval.d.ts +49 -0
- package/dist/commentRepository/utils/approval.d.ts.map +1 -0
- package/dist/commentRepository/utils/payload.d.ts +6 -0
- package/dist/commentRepository/utils/payload.d.ts.map +1 -1
- package/dist/commentRepository/utils/tests/approval.test.d.ts +2 -0
- package/dist/commentRepository/utils/tests/approval.test.d.ts.map +1 -0
- package/dist/commentRepository/utils/tests/payload.test.d.ts +2 -0
- package/dist/commentRepository/utils/tests/payload.test.d.ts.map +1 -0
- package/dist/communityRepository/api/createCommunity.d.ts +1 -1
- package/dist/communityRepository/api/createCommunity.d.ts.map +1 -1
- package/dist/communityRepository/api/updateCommunity.d.ts +1 -1
- package/dist/communityRepository/api/updateCommunity.d.ts.map +1 -1
- package/dist/core/device.d.ts +1 -1
- package/dist/core/device.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/tests/device.test.d.ts +2 -0
- package/dist/core/tests/device.test.d.ts.map +1 -0
- package/dist/core/transports/http.d.ts.map +1 -1
- package/dist/core/transports/utils.d.ts +8 -0
- package/dist/core/transports/utils.d.ts.map +1 -1
- package/dist/curatedContentRepository/api/getPool.d.ts +2 -0
- package/dist/curatedContentRepository/api/getPool.d.ts.map +1 -0
- package/dist/curatedContentRepository/api/index.d.ts +2 -0
- package/dist/curatedContentRepository/api/index.d.ts.map +1 -0
- package/dist/curatedContentRepository/api/tests/getPool.test.d.ts +2 -0
- package/dist/curatedContentRepository/api/tests/getPool.test.d.ts.map +1 -0
- package/dist/curatedContentRepository/api/tests/integration/getPool.integration.test.d.ts +2 -0
- package/dist/curatedContentRepository/api/tests/integration/getPool.integration.test.d.ts.map +1 -0
- package/dist/curatedContentRepository/index.d.ts +2 -0
- package/dist/curatedContentRepository/index.d.ts.map +1 -0
- package/dist/index.cjs.js +1730 -477
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.esm.js +1705 -453
- package/dist/index.umd.js +2 -2
- package/dist/messagePreview/utils/getChannelMessagePreviewWithUser.d.ts +1 -0
- package/dist/messagePreview/utils/getChannelMessagePreviewWithUser.d.ts.map +1 -1
- package/dist/messageRepository/api/index.d.ts +2 -0
- package/dist/messageRepository/api/index.d.ts.map +1 -1
- package/dist/messageRepository/api/pinMessage.d.ts +29 -0
- package/dist/messageRepository/api/pinMessage.d.ts.map +1 -0
- package/dist/messageRepository/api/tests/pinMessage.test.d.ts +2 -0
- package/dist/messageRepository/api/tests/pinMessage.test.d.ts.map +1 -0
- package/dist/messageRepository/api/tests/unpinMessage.test.d.ts +2 -0
- package/dist/messageRepository/api/tests/unpinMessage.test.d.ts.map +1 -0
- package/dist/messageRepository/api/unpinMessage.d.ts +28 -0
- package/dist/messageRepository/api/unpinMessage.d.ts.map +1 -0
- package/dist/messageRepository/utils/refreshChannelPermissionsForMessage.d.ts +13 -0
- package/dist/messageRepository/utils/refreshChannelPermissionsForMessage.d.ts.map +1 -0
- package/dist/postRepository/utils/PostCommentCountEngine/ApproveTask.d.ts +16 -0
- package/dist/postRepository/utils/PostCommentCountEngine/ApproveTask.d.ts.map +1 -0
- package/dist/postRepository/utils/PostCommentCountEngine/PostCommentCountEngine.d.ts +25 -1
- package/dist/postRepository/utils/PostCommentCountEngine/PostCommentCountEngine.d.ts.map +1 -1
- package/dist/postRepository/utils/PostCommentCountEngine/postCommentCountEngineOnLoginHandler.d.ts +9 -0
- package/dist/postRepository/utils/PostCommentCountEngine/postCommentCountEngineOnLoginHandler.d.ts.map +1 -0
- package/dist/postRepository/utils/PostCommentCountEngine/tests/getLocalCommentCount.test.d.ts +2 -0
- package/dist/postRepository/utils/PostCommentCountEngine/tests/getLocalCommentCount.test.d.ts.map +1 -0
- package/dist/postRepository/utils/PostCommentCountEngine/tests/pendingAuthoredComments.test.d.ts +2 -0
- package/dist/postRepository/utils/PostCommentCountEngine/tests/pendingAuthoredComments.test.d.ts.map +1 -0
- package/dist/postRepository/utils/latestComments.d.ts +10 -0
- package/dist/postRepository/utils/latestComments.d.ts.map +1 -0
- package/dist/postRepository/utils/payload.d.ts.map +1 -1
- package/dist/postRepository/utils/tests/latestComments.test.d.ts +2 -0
- package/dist/postRepository/utils/tests/latestComments.test.d.ts.map +1 -0
- package/dist/postRepository/utils/tests/payload.test.d.ts +2 -0
- package/dist/postRepository/utils/tests/payload.test.d.ts.map +1 -0
- package/dist/utils/constants.d.ts +4 -0
- package/dist/utils/constants.d.ts.map +1 -1
- package/dist/utils/linkedObject/commentLinkedObject.d.ts.map +1 -1
- package/dist/utils/linkedObject/curatedContentTopicLinkedObject.d.ts +2 -0
- package/dist/utils/linkedObject/curatedContentTopicLinkedObject.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/messageLinkedObject.d.ts.map +1 -1
- package/dist/utils/linkedObject/postLinkedObject.d.ts.map +1 -1
- package/dist/utils/linkedObject/tests/postLinkedObject.test.d.ts +2 -0
- package/dist/utils/linkedObject/tests/postLinkedObject.test.d.ts.map +1 -0
- package/dist/utils/tests/dummy/comment.d.ts +1 -0
- package/dist/utils/tests/dummy/comment.d.ts.map +1 -1
- package/dist/utils/tests/dummy/index.d.ts +1 -0
- package/dist/utils/tests/dummy/index.d.ts.map +1 -1
- package/dist/utils/tests/dummy/pinnedMessage.d.ts +2 -0
- package/dist/utils/tests/dummy/pinnedMessage.d.ts.map +1 -0
- package/dist/utils/tests/dummy/post.d.ts.map +1 -1
- package/package.json +3 -2
package/dist/index.cjs.js
CHANGED
|
@@ -7,8 +7,9 @@ var mitt = require('mitt');
|
|
|
7
7
|
var debug = require('debug');
|
|
8
8
|
var axios = require('axios');
|
|
9
9
|
var HttpAgent = require('agentkeepalive');
|
|
10
|
-
var mqtt = require('mqtt');
|
|
11
10
|
var uuid$1 = require('react-native-uuid');
|
|
11
|
+
var mqtt = require('mqtt');
|
|
12
|
+
var uaParserJs = require('ua-parser-js');
|
|
12
13
|
var jwtDecode = require('jwt-decode');
|
|
13
14
|
var hash = require('object-hash');
|
|
14
15
|
var Hls = require('hls.js');
|
|
@@ -19,8 +20,8 @@ var mitt__default = /*#__PURE__*/_interopDefaultLegacy(mitt);
|
|
|
19
20
|
var debug__default = /*#__PURE__*/_interopDefaultLegacy(debug);
|
|
20
21
|
var axios__default = /*#__PURE__*/_interopDefaultLegacy(axios);
|
|
21
22
|
var HttpAgent__default = /*#__PURE__*/_interopDefaultLegacy(HttpAgent);
|
|
22
|
-
var mqtt__default = /*#__PURE__*/_interopDefaultLegacy(mqtt);
|
|
23
23
|
var uuid__default = /*#__PURE__*/_interopDefaultLegacy(uuid$1);
|
|
24
|
+
var mqtt__default = /*#__PURE__*/_interopDefaultLegacy(mqtt);
|
|
24
25
|
var jwtDecode__default = /*#__PURE__*/_interopDefaultLegacy(jwtDecode);
|
|
25
26
|
var hash__default = /*#__PURE__*/_interopDefaultLegacy(hash);
|
|
26
27
|
var Hls__default = /*#__PURE__*/_interopDefaultLegacy(Hls);
|
|
@@ -341,6 +342,7 @@ function getVersion() {
|
|
|
341
342
|
const VERSION = getVersion();
|
|
342
343
|
|
|
343
344
|
const COLLECTION_DEFAULT_PAGINATION_LIMIT = 5;
|
|
345
|
+
const LATEST_COMMENTS_LIMIT = 5;
|
|
344
346
|
const COLLECTION_DEFAULT_PAGINATION_SIZE = 20;
|
|
345
347
|
const COLLECTION_DEFAULT_CACHING_POLICY = 'cache_then_server';
|
|
346
348
|
const ENABLE_CACHE_MESSAGE = 'For using Live Collection feature you need to enable Cache!';
|
|
@@ -356,7 +358,11 @@ const YEAR = 365 * DAY;
|
|
|
356
358
|
const ACCESS_TOKEN_WATCHER_INTERVAL = 10 * MINUTE;
|
|
357
359
|
const API_ENDPOINTS = {
|
|
358
360
|
forYouFeed: '/api/v1/feeds/for-you',
|
|
361
|
+
commentReviewQueue: (communityId) => `/api/v3/communities/${encodeURIComponent(communityId)}/comments/review-queue`,
|
|
359
362
|
};
|
|
363
|
+
// The review-queue route defaults to 10, not the SDK-wide page size, and caps at 100
|
|
364
|
+
const COMMENT_REVIEW_QUEUE_DEFAULT_PAGINATION_SIZE = 10;
|
|
365
|
+
const COMMENT_REVIEW_QUEUE_MAX_PAGINATION_SIZE = 100;
|
|
360
366
|
|
|
361
367
|
// cache constants
|
|
362
368
|
const CACHE_KEY_GET = 'get';
|
|
@@ -1953,6 +1959,8 @@ function computeUrl(type, region) {
|
|
|
1953
1959
|
return URLS[type].replace('{region}', region);
|
|
1954
1960
|
}
|
|
1955
1961
|
|
|
1962
|
+
const uuid = () => uuid__default["default"].v4().toString();
|
|
1963
|
+
|
|
1956
1964
|
/**
|
|
1957
1965
|
* Unwraps v3 server payload (for error handling and type extraction)
|
|
1958
1966
|
*
|
|
@@ -1977,6 +1985,24 @@ const unwrapPayload = (response) => {
|
|
|
1977
1985
|
// unjust, but helps force uncast "T | undefined" to allow deconstruction without warnings
|
|
1978
1986
|
return undefined;
|
|
1979
1987
|
};
|
|
1988
|
+
/**
|
|
1989
|
+
* Builds a hex string of `bytes` length from the SDK's uuid helper (a v4 UUID is
|
|
1990
|
+
* 16 bytes / 32 hex chars once hyphens are removed) — avoids a new crypto dependency.
|
|
1991
|
+
*/
|
|
1992
|
+
const randomHex = (bytes) => {
|
|
1993
|
+
let hex = '';
|
|
1994
|
+
while (hex.length < bytes * 2)
|
|
1995
|
+
hex += uuid().replace(/-/g, '');
|
|
1996
|
+
return hex.slice(0, bytes * 2);
|
|
1997
|
+
};
|
|
1998
|
+
/**
|
|
1999
|
+
* W3C Trace Context `traceparent`: `version-<16-byte trace-id>-<8-byte span-id>-<flags>`.
|
|
2000
|
+
* The SDK is the trace originator, so it mints a fresh trace + span id per request; flags `01` = sampled.
|
|
2001
|
+
*
|
|
2002
|
+
* @category Transport
|
|
2003
|
+
* @hidden
|
|
2004
|
+
*/
|
|
2005
|
+
const generateTraceparent = () => `00-${randomHex(16)}-${randomHex(8)}-01`;
|
|
1980
2006
|
|
|
1981
2007
|
class NetworkActivitiesWatcher {
|
|
1982
2008
|
constructor() {
|
|
@@ -2101,6 +2127,10 @@ const createHttpTransport = (endpoint) => {
|
|
|
2101
2127
|
});
|
|
2102
2128
|
instance.defaults.withCredentials = false;
|
|
2103
2129
|
instance.interceptors.request.use(config => {
|
|
2130
|
+
// Request tracing — set on every outbound request (login included), never persisted.
|
|
2131
|
+
// Must run before the session-url early-return below so /api/v5/sessions carries them too.
|
|
2132
|
+
config.headers.set('x-request-id', uuid());
|
|
2133
|
+
config.headers.set('traceparent', generateTraceparent());
|
|
2104
2134
|
// do not check expiration for token creation url
|
|
2105
2135
|
if (config.url === '/api/v5/sessions') {
|
|
2106
2136
|
return config;
|
|
@@ -2144,20 +2174,28 @@ const createHttpTransport = (endpoint) => {
|
|
|
2144
2174
|
});
|
|
2145
2175
|
return response;
|
|
2146
2176
|
}, error => {
|
|
2147
|
-
var _a, _b, _c;
|
|
2177
|
+
var _a, _b, _c, _d;
|
|
2148
2178
|
const { response } = error;
|
|
2149
2179
|
// handle unauthorized request
|
|
2150
2180
|
if ((response === null || response === void 0 ? void 0 : response.data.code) === 400100 /* Amity.ServerError.UNAUTHORIZED */) {
|
|
2151
2181
|
fireEvent('tokenTerminated', "terminated" /* Amity.SessionStates.TERMINATED */);
|
|
2152
2182
|
}
|
|
2183
|
+
// handle globally banned user. The realtime `user.didGlobalBan` event can be missed
|
|
2184
|
+
// (e.g. MQTT dropped before delivery), so mirror the 400100 handling above and fire
|
|
2185
|
+
// the same virtual event the login subscriptions already listen to. That terminates
|
|
2186
|
+
// the session with `TokenTerminationReason.GLOBAL_BAN` and notifies `onClientBanned`
|
|
2187
|
+
// consumers, instead of leaving the session `established` with a revoked token.
|
|
2188
|
+
if (((_a = response === null || response === void 0 ? void 0 : response.data) === null || _a === void 0 ? void 0 : _a.code) === 400312 /* Amity.ServerError.GLOBAL_BAN */) {
|
|
2189
|
+
fireEvent('user.didGlobalBan', { users: [], files: [] });
|
|
2190
|
+
}
|
|
2153
2191
|
// handle visitor daily usage limit exceeded
|
|
2154
|
-
if (((
|
|
2192
|
+
if (((_b = response === null || response === void 0 ? void 0 : response.data) === null || _b === void 0 ? void 0 : _b.code) === 400323 /* Amity.ServerError.VISITOR_USAGE_LIMIT_EXCEEDED */) {
|
|
2155
2193
|
throttledFireVisitorUsageLimit();
|
|
2156
2194
|
throw new ASCError('Visitor usage limit exceeded', 400323 /* Amity.ServerError.VISITOR_USAGE_LIMIT_EXCEEDED */, "error" /* Amity.ErrorLevel.ERROR */);
|
|
2157
2195
|
}
|
|
2158
2196
|
// if it's an error with status in the response payload,
|
|
2159
2197
|
// then it's an expected error.
|
|
2160
|
-
if ((
|
|
2198
|
+
if ((_c = response === null || response === void 0 ? void 0 : response.data) === null || _c === void 0 ? void 0 : _c.status) {
|
|
2161
2199
|
unwrapPayload(response === null || response === void 0 ? void 0 : response.data);
|
|
2162
2200
|
}
|
|
2163
2201
|
// as on request cancellation error is returned
|
|
@@ -2165,7 +2203,7 @@ const createHttpTransport = (endpoint) => {
|
|
|
2165
2203
|
throw error;
|
|
2166
2204
|
}
|
|
2167
2205
|
// unexpected error.
|
|
2168
|
-
throw new Error((
|
|
2206
|
+
throw new Error((_d = response === null || response === void 0 ? void 0 : response.data) !== null && _d !== void 0 ? _d : error);
|
|
2169
2207
|
});
|
|
2170
2208
|
instance.defaults.paramsSerializer = {
|
|
2171
2209
|
encode: params => encodeURIComponent(params),
|
|
@@ -2363,8 +2401,6 @@ const getItem = async (key) => {
|
|
|
2363
2401
|
});
|
|
2364
2402
|
};
|
|
2365
2403
|
|
|
2366
|
-
const uuid = () => uuid__default["default"].v4().toString();
|
|
2367
|
-
|
|
2368
2404
|
// TODO: find a way to uniquely identify the device
|
|
2369
2405
|
let tabIndex = 0;
|
|
2370
2406
|
// This logic is running on browser only
|
|
@@ -2424,22 +2460,60 @@ const getMQTTClientId = async (userId) => {
|
|
|
2424
2460
|
};
|
|
2425
2461
|
/** @hidden */
|
|
2426
2462
|
const getDeviceModel = () => {
|
|
2427
|
-
var _a
|
|
2463
|
+
var _a;
|
|
2428
2464
|
if ((_a = safeProcess.versions) === null || _a === void 0 ? void 0 : _a.node)
|
|
2429
2465
|
return safeProcess.versions.node;
|
|
2430
|
-
|
|
2431
|
-
|
|
2432
|
-
|
|
2466
|
+
return undefined;
|
|
2467
|
+
};
|
|
2468
|
+
const hasNavigator = () => typeof navigator !== 'undefined' && !!navigator;
|
|
2469
|
+
const getLocale = () => (hasNavigator() ? navigator.language : undefined);
|
|
2470
|
+
const getTimezone = () => {
|
|
2471
|
+
try {
|
|
2472
|
+
return Intl.DateTimeFormat().resolvedOptions().timeZone;
|
|
2473
|
+
}
|
|
2474
|
+
catch (_a) {
|
|
2475
|
+
return undefined;
|
|
2476
|
+
}
|
|
2477
|
+
};
|
|
2478
|
+
const getNetworkType = () => {
|
|
2479
|
+
var _a;
|
|
2480
|
+
if (!hasNavigator())
|
|
2481
|
+
return undefined;
|
|
2482
|
+
return (_a = navigator.connection) === null || _a === void 0 ? void 0 : _a.effectiveType;
|
|
2483
|
+
};
|
|
2484
|
+
const isNode = () => { var _a; return !!((_a = safeProcess.versions) === null || _a === void 0 ? void 0 : _a.node); };
|
|
2485
|
+
const parseUserAgent = () => {
|
|
2486
|
+
if (!hasNavigator() || !navigator.userAgent)
|
|
2487
|
+
return {};
|
|
2488
|
+
const { os, browser, device } = new uaParserJs.UAParser(navigator.userAgent).getResult();
|
|
2489
|
+
const result = {};
|
|
2490
|
+
if (os.name)
|
|
2491
|
+
result.osName = os.name;
|
|
2492
|
+
if (os.version)
|
|
2493
|
+
result.osVersion = os.version;
|
|
2494
|
+
if (browser.name)
|
|
2495
|
+
result.browserName = browser.name;
|
|
2496
|
+
if (browser.version)
|
|
2497
|
+
result.browserVersion = browser.version;
|
|
2498
|
+
if (device.type === 'tablet')
|
|
2499
|
+
result.deviceType = 'tablet';
|
|
2500
|
+
else if (device.type === 'mobile')
|
|
2501
|
+
result.deviceType = 'mobile';
|
|
2502
|
+
else
|
|
2503
|
+
result.deviceType = 'desktop';
|
|
2504
|
+
return result;
|
|
2433
2505
|
};
|
|
2434
2506
|
/** @hidden */
|
|
2435
2507
|
const getDeviceInfo = () => {
|
|
2436
|
-
|
|
2437
|
-
|
|
2438
|
-
|
|
2439
|
-
|
|
2440
|
-
|
|
2441
|
-
|
|
2442
|
-
|
|
2508
|
+
var _a;
|
|
2509
|
+
let client;
|
|
2510
|
+
try {
|
|
2511
|
+
client = getActiveClient();
|
|
2512
|
+
}
|
|
2513
|
+
catch (_b) {
|
|
2514
|
+
client = undefined;
|
|
2515
|
+
}
|
|
2516
|
+
return Object.assign({ kind: isNode() ? 'node' : 'web', model: getDeviceModel(), sdkVersion: VERSION, product: (_a = client === null || client === void 0 ? void 0 : client.product) !== null && _a !== void 0 ? _a : 'sdk', uikitVersion: client === null || client === void 0 ? void 0 : client.uikitVersion, appId: client === null || client === void 0 ? void 0 : client.appId, appVersion: client === null || client === void 0 ? void 0 : client.appVersion, locale: getLocale(), timezone: getTimezone(), networkType: getNetworkType() }, parseUserAgent());
|
|
2443
2517
|
};
|
|
2444
2518
|
|
|
2445
2519
|
/* eslint-disable no-console */
|
|
@@ -3848,6 +3922,95 @@ const prepareChannelPayload = async (rawPayload, options = { isMessagePreviewUpd
|
|
|
3848
3922
|
channelUsers });
|
|
3849
3923
|
};
|
|
3850
3924
|
|
|
3925
|
+
const channelCacheKey = (channel) => [
|
|
3926
|
+
'channel',
|
|
3927
|
+
'get',
|
|
3928
|
+
getResolver('channel')(channel),
|
|
3929
|
+
];
|
|
3930
|
+
/**
|
|
3931
|
+
* Find a cached channel by any of its ids (internal, public, or `channelId`).
|
|
3932
|
+
*
|
|
3933
|
+
* The channel cache is keyed by the channel internal id (see `idResolvers.channel`), but
|
|
3934
|
+
* realtime payloads reference channels by different ids: pin events carry the **public**
|
|
3935
|
+
* id, messages carry `channelId`. Try the cheap direct lookup first, then scan.
|
|
3936
|
+
*/
|
|
3937
|
+
const findCachedChannelByAnyId = (id) => {
|
|
3938
|
+
var _a, _b, _c;
|
|
3939
|
+
if (!id)
|
|
3940
|
+
return undefined;
|
|
3941
|
+
const direct = (_a = pullFromCache(['channel', 'get', id])) === null || _a === void 0 ? void 0 : _a.data;
|
|
3942
|
+
if (direct)
|
|
3943
|
+
return direct;
|
|
3944
|
+
return (_c = (_b = queryCache(['channel', 'get'])) === null || _b === void 0 ? void 0 : _b.find(({ data }) => data.channelInternalId === id || data.channelPublicId === id || data.channelId === id)) === null || _c === void 0 ? void 0 : _c.data;
|
|
3945
|
+
};
|
|
3946
|
+
/**
|
|
3947
|
+
* Resolve the cached channel a `channel.messagePinned` / `channel.messageUnpinned` event
|
|
3948
|
+
* refers to. `data.channelId` is the channel public id; a pinned message body (present on
|
|
3949
|
+
* `messagePinned` only) also carries the internal id, which is the direct cache key.
|
|
3950
|
+
*/
|
|
3951
|
+
const findCachedChannelForPin = (payload) => {
|
|
3952
|
+
var _a, _b;
|
|
3953
|
+
return (_b = findCachedChannelByAnyId((_a = payload.pinnedMessage) === null || _a === void 0 ? void 0 : _a.channelId)) !== null && _b !== void 0 ? _b : findCachedChannelByAnyId(payload.channelId);
|
|
3954
|
+
};
|
|
3955
|
+
/**
|
|
3956
|
+
* Write a new pin snapshot (or `null` to clear) on a cached channel and ingest any
|
|
3957
|
+
* users delivered with it (the pin author and the message author), so the banner can
|
|
3958
|
+
* render a byline without a second fetch.
|
|
3959
|
+
*
|
|
3960
|
+
* Every `messagePinned` payload is a full snapshot — "this is the pin now" — so the last
|
|
3961
|
+
* one received always wins; there is no merging with the previous pin.
|
|
3962
|
+
*/
|
|
3963
|
+
const updatePinnedMessageCache = (channel, pinnedMessage, users) => {
|
|
3964
|
+
if (users && users.length > 0) {
|
|
3965
|
+
ingestInCache({ users: users.map(convertRawUserToInternalUser) });
|
|
3966
|
+
}
|
|
3967
|
+
const updated = Object.assign(Object.assign({}, channel), { pinnedMessage });
|
|
3968
|
+
pushToCache(channelCacheKey(channel), updated);
|
|
3969
|
+
return updated;
|
|
3970
|
+
};
|
|
3971
|
+
|
|
3972
|
+
/**
|
|
3973
|
+
* Applies a `channel.roleAdded` / `channel.roleRemoved` realtime payload to the cache.
|
|
3974
|
+
*
|
|
3975
|
+
* The event names every member the role request affected together with the
|
|
3976
|
+
* roles and channel-scoped permissions each of them is left holding. That is a
|
|
3977
|
+
* full state, not a delta, so it is written straight over the cached membership.
|
|
3978
|
+
*
|
|
3979
|
+
* Members the SDK has not fetched yet are skipped: the payload does not carry
|
|
3980
|
+
* enough to build a full {@link Amity.Membership} and the live collections only
|
|
3981
|
+
* emit rows that already exist in cache.
|
|
3982
|
+
*
|
|
3983
|
+
* @param payload the `data` of the realtime event
|
|
3984
|
+
* @returns the refreshed channel (when resolvable) and the updated cached memberships
|
|
3985
|
+
*
|
|
3986
|
+
* @hidden
|
|
3987
|
+
*/
|
|
3988
|
+
const applyChannelRolePayload = (payload) => {
|
|
3989
|
+
var _a, _b, _c;
|
|
3990
|
+
const { channelId, users = [], channels = [] } = payload;
|
|
3991
|
+
const rawChannel = (_a = channels.find(channel => channel.channelId === channelId)) !== null && _a !== void 0 ? _a : channels[0];
|
|
3992
|
+
let channel;
|
|
3993
|
+
if (rawChannel) {
|
|
3994
|
+
const channelKey = ['channel', 'get', getResolver('channel')(rawChannel)];
|
|
3995
|
+
// the role event does not touch message previews, keep whatever preview is cached
|
|
3996
|
+
const converted = convertFromRaw(rawChannel, { isMessagePreviewUpdated: false });
|
|
3997
|
+
upsertInCache(channelKey, converted);
|
|
3998
|
+
channel = (_c = (_b = pullFromCache(channelKey)) === null || _b === void 0 ? void 0 : _b.data) !== null && _c !== void 0 ? _c : converted;
|
|
3999
|
+
}
|
|
4000
|
+
const members = [];
|
|
4001
|
+
users.forEach(({ userId, roles, permissions }) => {
|
|
4002
|
+
var _a, _b, _c;
|
|
4003
|
+
const memberKey = ['channelUsers', 'get', getResolver('channelUsers')({ channelId, userId })];
|
|
4004
|
+
const cached = (_a = pullFromCache(memberKey)) === null || _a === void 0 ? void 0 : _a.data;
|
|
4005
|
+
if (!cached)
|
|
4006
|
+
return;
|
|
4007
|
+
const updated = Object.assign(Object.assign({}, cached), { roles, permissions });
|
|
4008
|
+
pushToCache(memberKey, updated);
|
|
4009
|
+
members.push((_c = (_b = pullFromCache(memberKey)) === null || _b === void 0 ? void 0 : _b.data) !== null && _c !== void 0 ? _c : updated);
|
|
4010
|
+
});
|
|
4011
|
+
return { channel, members };
|
|
4012
|
+
};
|
|
4013
|
+
|
|
3851
4014
|
/**
|
|
3852
4015
|
* ```js
|
|
3853
4016
|
* import { getSubChannelMarkers } from '@amityco/ts-sdk'
|
|
@@ -4033,32 +4196,6 @@ const channelMemberLinkedObject = (channelMember) => {
|
|
|
4033
4196
|
} });
|
|
4034
4197
|
};
|
|
4035
4198
|
|
|
4036
|
-
/**
|
|
4037
|
-
*
|
|
4038
|
-
* get current user's membership data
|
|
4039
|
-
*
|
|
4040
|
-
* @returns the {@link Amity.Membership<'channel'>} objects
|
|
4041
|
-
*
|
|
4042
|
-
* @category Channel API
|
|
4043
|
-
* @async
|
|
4044
|
-
*/
|
|
4045
|
-
const getMyMembership$1 = (channelId) => {
|
|
4046
|
-
const client = getActiveClient();
|
|
4047
|
-
client.log('channel/getMyMembership.locally');
|
|
4048
|
-
const cacheChannelUser = pullFromCache([
|
|
4049
|
-
'channelUsers',
|
|
4050
|
-
'get',
|
|
4051
|
-
`${channelId}#${client.userId}`,
|
|
4052
|
-
]);
|
|
4053
|
-
if (!cacheChannelUser) {
|
|
4054
|
-
throw new ASCApiError('Item not found!', 400400 /* Amity.ServerError.ITEM_NOT_FOUND */, "error" /* Amity.ErrorLevel.ERROR */);
|
|
4055
|
-
}
|
|
4056
|
-
return {
|
|
4057
|
-
data: cacheChannelUser.data,
|
|
4058
|
-
cachedAt: cacheChannelUser.cachedAt,
|
|
4059
|
-
};
|
|
4060
|
-
};
|
|
4061
|
-
|
|
4062
4199
|
/**
|
|
4063
4200
|
* ```js
|
|
4064
4201
|
* import { isEqual } from '~/utils/isEqual'
|
|
@@ -4129,55 +4266,81 @@ function isEqual(x, y) {
|
|
|
4129
4266
|
}));
|
|
4130
4267
|
}
|
|
4131
4268
|
|
|
4132
|
-
|
|
4269
|
+
/**
|
|
4270
|
+
*
|
|
4271
|
+
* get current user's membership data
|
|
4272
|
+
*
|
|
4273
|
+
* @returns the {@link Amity.Membership<'channel'>} objects
|
|
4274
|
+
*
|
|
4275
|
+
* @category Channel API
|
|
4276
|
+
* @async
|
|
4277
|
+
*/
|
|
4278
|
+
const getMyMembership$1 = (channelId) => {
|
|
4279
|
+
const client = getActiveClient();
|
|
4280
|
+
client.log('channel/getMyMembership.locally');
|
|
4281
|
+
const cacheChannelUser = pullFromCache([
|
|
4282
|
+
'channelUsers',
|
|
4283
|
+
'get',
|
|
4284
|
+
`${channelId}#${client.userId}`,
|
|
4285
|
+
]);
|
|
4286
|
+
if (!cacheChannelUser) {
|
|
4287
|
+
throw new ASCApiError('Item not found!', 400400 /* Amity.ServerError.ITEM_NOT_FOUND */, "error" /* Amity.ErrorLevel.ERROR */);
|
|
4288
|
+
}
|
|
4289
|
+
return {
|
|
4290
|
+
data: cacheChannelUser.data,
|
|
4291
|
+
cachedAt: cacheChannelUser.cachedAt,
|
|
4292
|
+
};
|
|
4293
|
+
};
|
|
4294
|
+
|
|
4295
|
+
const callbacks$e = [];
|
|
4133
4296
|
let mainDisposer$b = null;
|
|
4134
|
-
const dispose$
|
|
4135
|
-
const index = callbacks$
|
|
4297
|
+
const dispose$e = (cb) => {
|
|
4298
|
+
const index = callbacks$e.indexOf(cb);
|
|
4136
4299
|
if (index > -1) {
|
|
4137
|
-
callbacks$
|
|
4300
|
+
callbacks$e.splice(index, 1);
|
|
4138
4301
|
}
|
|
4139
|
-
if (callbacks$
|
|
4302
|
+
if (callbacks$e.length === 0) {
|
|
4140
4303
|
mainDisposer$b === null || mainDisposer$b === void 0 ? void 0 : mainDisposer$b();
|
|
4141
4304
|
}
|
|
4142
4305
|
};
|
|
4143
4306
|
const onChannelCreated = (callback) => {
|
|
4144
|
-
if (callbacks$
|
|
4307
|
+
if (callbacks$e.length === 0) {
|
|
4145
4308
|
const client = getActiveClient();
|
|
4146
4309
|
const filter = async (payload) => {
|
|
4147
4310
|
const data = await prepareChannelPayload(payload);
|
|
4148
4311
|
ingestInCache(data);
|
|
4149
|
-
callbacks$
|
|
4312
|
+
callbacks$e.forEach(cb => cb(data.channels[0]));
|
|
4150
4313
|
};
|
|
4151
4314
|
mainDisposer$b = createEventSubscriber(client, 'onChannelCreated', 'channel.created', filter);
|
|
4152
4315
|
}
|
|
4153
|
-
callbacks$
|
|
4154
|
-
return () => dispose$
|
|
4316
|
+
callbacks$e.push(callback);
|
|
4317
|
+
return () => dispose$e(callback);
|
|
4155
4318
|
};
|
|
4156
4319
|
|
|
4157
|
-
const callbacks$
|
|
4158
|
-
const mainDisposers = [];
|
|
4159
|
-
const dispose$
|
|
4160
|
-
const index = callbacks$
|
|
4320
|
+
const callbacks$d = [];
|
|
4321
|
+
const mainDisposers$2 = [];
|
|
4322
|
+
const dispose$d = (cb) => {
|
|
4323
|
+
const index = callbacks$d.indexOf(cb);
|
|
4161
4324
|
if (index > -1) {
|
|
4162
|
-
callbacks$
|
|
4325
|
+
callbacks$d.splice(index, 1);
|
|
4163
4326
|
}
|
|
4164
|
-
if (callbacks$
|
|
4165
|
-
mainDisposers.forEach(fn => fn());
|
|
4327
|
+
if (callbacks$d.length === 0) {
|
|
4328
|
+
mainDisposers$2.forEach(fn => fn());
|
|
4166
4329
|
}
|
|
4167
4330
|
};
|
|
4168
4331
|
const onChannelUpdated = (callback) => {
|
|
4169
4332
|
const client = getActiveClient();
|
|
4170
|
-
if (callbacks$
|
|
4333
|
+
if (callbacks$d.length === 0) {
|
|
4171
4334
|
const filter = async (payload) => {
|
|
4172
4335
|
const data = await prepareChannelPayload(payload);
|
|
4173
4336
|
ingestInCache(data);
|
|
4174
|
-
callbacks$
|
|
4337
|
+
callbacks$d.forEach(cb => cb(data.channels[0]));
|
|
4175
4338
|
};
|
|
4176
|
-
mainDisposers.push(createEventSubscriber(client, 'onChannelUpdated', 'channel.updated', filter));
|
|
4177
|
-
mainDisposers.push(createEventSubscriber(client, 'onChannelUpdated', 'local.channel.updated', payload => callbacks$
|
|
4339
|
+
mainDisposers$2.push(createEventSubscriber(client, 'onChannelUpdated', 'channel.updated', filter));
|
|
4340
|
+
mainDisposers$2.push(createEventSubscriber(client, 'onChannelUpdated', 'local.channel.updated', payload => callbacks$d.forEach(cb => cb(payload.channels[0]))));
|
|
4178
4341
|
}
|
|
4179
|
-
callbacks$
|
|
4180
|
-
return () => dispose$
|
|
4342
|
+
callbacks$d.push(callback);
|
|
4343
|
+
return () => dispose$d(callback);
|
|
4181
4344
|
};
|
|
4182
4345
|
|
|
4183
4346
|
const addFlagIsDeletedSubChannelUnreadByChannelId = (channelId) => {
|
|
@@ -4200,19 +4363,19 @@ const deleteChannelUnreadByChannelId = (channelId) => {
|
|
|
4200
4363
|
}
|
|
4201
4364
|
};
|
|
4202
4365
|
|
|
4203
|
-
const callbacks$
|
|
4366
|
+
const callbacks$c = [];
|
|
4204
4367
|
let mainDisposer$a = null;
|
|
4205
|
-
const dispose$
|
|
4206
|
-
const index = callbacks$
|
|
4368
|
+
const dispose$c = (cb) => {
|
|
4369
|
+
const index = callbacks$c.indexOf(cb);
|
|
4207
4370
|
if (index > -1) {
|
|
4208
|
-
callbacks$
|
|
4371
|
+
callbacks$c.splice(index, 1);
|
|
4209
4372
|
}
|
|
4210
|
-
if (callbacks$
|
|
4373
|
+
if (callbacks$c.length === 0) {
|
|
4211
4374
|
mainDisposer$a === null || mainDisposer$a === void 0 ? void 0 : mainDisposer$a();
|
|
4212
4375
|
}
|
|
4213
4376
|
};
|
|
4214
4377
|
const onChannelDeleted = (callback) => {
|
|
4215
|
-
if (callbacks$
|
|
4378
|
+
if (callbacks$c.length === 0) {
|
|
4216
4379
|
const client = getActiveClient();
|
|
4217
4380
|
const filter = async (payload) => {
|
|
4218
4381
|
const data = await prepareChannelPayload(payload);
|
|
@@ -4232,53 +4395,53 @@ const onChannelDeleted = (callback) => {
|
|
|
4232
4395
|
}
|
|
4233
4396
|
});
|
|
4234
4397
|
ingestInCache(data);
|
|
4235
|
-
callbacks$
|
|
4398
|
+
callbacks$c.forEach(cb => cb(data.channels[0]));
|
|
4236
4399
|
};
|
|
4237
4400
|
mainDisposer$a = createEventSubscriber(client, 'onChannelDeleted', 'channel.deleted', filter);
|
|
4238
4401
|
}
|
|
4239
|
-
callbacks$
|
|
4240
|
-
return () => dispose$
|
|
4402
|
+
callbacks$c.push(callback);
|
|
4403
|
+
return () => dispose$c(callback);
|
|
4241
4404
|
};
|
|
4242
4405
|
|
|
4243
|
-
const callbacks$
|
|
4406
|
+
const callbacks$b = [];
|
|
4244
4407
|
let mainDisposer$9 = null;
|
|
4245
|
-
const dispose$
|
|
4246
|
-
const index = callbacks$
|
|
4408
|
+
const dispose$b = (cb) => {
|
|
4409
|
+
const index = callbacks$b.indexOf(cb);
|
|
4247
4410
|
if (index > -1) {
|
|
4248
|
-
callbacks$
|
|
4411
|
+
callbacks$b.splice(index, 1);
|
|
4249
4412
|
}
|
|
4250
|
-
if (callbacks$
|
|
4413
|
+
if (callbacks$b.length === 0) {
|
|
4251
4414
|
mainDisposer$9 === null || mainDisposer$9 === void 0 ? void 0 : mainDisposer$9();
|
|
4252
4415
|
}
|
|
4253
4416
|
};
|
|
4254
4417
|
const onChannelJoined = (callback) => {
|
|
4255
|
-
if (callbacks$
|
|
4418
|
+
if (callbacks$b.length === 0) {
|
|
4256
4419
|
const client = getActiveClient();
|
|
4257
4420
|
const filter = async (payload) => {
|
|
4258
4421
|
const preparedPayload = await prepareChannelPayload(payload);
|
|
4259
4422
|
const { channels, channelUsers } = preparedPayload;
|
|
4260
4423
|
ingestInCache(preparedPayload);
|
|
4261
|
-
callbacks$
|
|
4424
|
+
callbacks$b.forEach(cb => cb(channels[0], channelUsers[0]));
|
|
4262
4425
|
};
|
|
4263
4426
|
mainDisposer$9 = createEventSubscriber(client, 'onChannelJoined', 'channel.joined', filter);
|
|
4264
4427
|
}
|
|
4265
|
-
callbacks$
|
|
4266
|
-
return () => dispose$
|
|
4428
|
+
callbacks$b.push(callback);
|
|
4429
|
+
return () => dispose$b(callback);
|
|
4267
4430
|
};
|
|
4268
4431
|
|
|
4269
|
-
const callbacks$
|
|
4432
|
+
const callbacks$a = [];
|
|
4270
4433
|
let mainDisposer$8 = null;
|
|
4271
|
-
const dispose$
|
|
4272
|
-
const index = callbacks$
|
|
4434
|
+
const dispose$a = (cb) => {
|
|
4435
|
+
const index = callbacks$a.indexOf(cb);
|
|
4273
4436
|
if (index > -1) {
|
|
4274
|
-
callbacks$
|
|
4437
|
+
callbacks$a.splice(index, 1);
|
|
4275
4438
|
}
|
|
4276
|
-
if (callbacks$
|
|
4439
|
+
if (callbacks$a.length === 0) {
|
|
4277
4440
|
mainDisposer$8 === null || mainDisposer$8 === void 0 ? void 0 : mainDisposer$8();
|
|
4278
4441
|
}
|
|
4279
4442
|
};
|
|
4280
4443
|
const onChannelLeft = (callback) => {
|
|
4281
|
-
if (callbacks$
|
|
4444
|
+
if (callbacks$a.length === 0) {
|
|
4282
4445
|
const client = getActiveClient();
|
|
4283
4446
|
const filter = async (payload) => {
|
|
4284
4447
|
const { userId } = getActiveClient();
|
|
@@ -4302,27 +4465,27 @@ const onChannelLeft = (callback) => {
|
|
|
4302
4465
|
}
|
|
4303
4466
|
const { channels, channelUsers } = preparedPayload;
|
|
4304
4467
|
ingestInCache(preparedPayload);
|
|
4305
|
-
callbacks$
|
|
4468
|
+
callbacks$a.forEach(cb => cb(channels[0], channelUsers[0]));
|
|
4306
4469
|
};
|
|
4307
4470
|
mainDisposer$8 = createEventSubscriber(client, 'onChannelLeft', 'channel.left', filter);
|
|
4308
4471
|
}
|
|
4309
|
-
callbacks$
|
|
4310
|
-
return () => dispose$
|
|
4472
|
+
callbacks$a.push(callback);
|
|
4473
|
+
return () => dispose$a(callback);
|
|
4311
4474
|
};
|
|
4312
4475
|
|
|
4313
|
-
const callbacks$
|
|
4476
|
+
const callbacks$9 = [];
|
|
4314
4477
|
let mainDisposer$7 = null;
|
|
4315
|
-
const dispose$
|
|
4316
|
-
const index = callbacks$
|
|
4478
|
+
const dispose$9 = (cb) => {
|
|
4479
|
+
const index = callbacks$9.indexOf(cb);
|
|
4317
4480
|
if (index > -1) {
|
|
4318
|
-
callbacks$
|
|
4481
|
+
callbacks$9.splice(index, 1);
|
|
4319
4482
|
}
|
|
4320
|
-
if (callbacks$
|
|
4483
|
+
if (callbacks$9.length === 0) {
|
|
4321
4484
|
mainDisposer$7 === null || mainDisposer$7 === void 0 ? void 0 : mainDisposer$7();
|
|
4322
4485
|
}
|
|
4323
4486
|
};
|
|
4324
4487
|
const onChannelSetMuted = (callback) => {
|
|
4325
|
-
if (callbacks$
|
|
4488
|
+
if (callbacks$9.length === 0) {
|
|
4326
4489
|
const client = getActiveClient();
|
|
4327
4490
|
const filter = async (payload) => {
|
|
4328
4491
|
var _a;
|
|
@@ -4337,24 +4500,124 @@ const onChannelSetMuted = (callback) => {
|
|
|
4337
4500
|
payload.channelId,
|
|
4338
4501
|
])) === null || _a === void 0 ? void 0 : _a.data;
|
|
4339
4502
|
if (channel) {
|
|
4340
|
-
callbacks$
|
|
4503
|
+
callbacks$9.forEach(cb => cb(channel));
|
|
4341
4504
|
}
|
|
4342
4505
|
};
|
|
4343
4506
|
mainDisposer$7 = createEventSubscriber(client, 'onChannelMute', 'channel.setMuted', filter);
|
|
4344
4507
|
}
|
|
4508
|
+
callbacks$9.push(callback);
|
|
4509
|
+
return () => dispose$9(callback);
|
|
4510
|
+
};
|
|
4511
|
+
|
|
4512
|
+
const callbacks$8 = [];
|
|
4513
|
+
let mainDisposer$6 = null;
|
|
4514
|
+
const dispose$8 = (cb) => {
|
|
4515
|
+
const index = callbacks$8.indexOf(cb);
|
|
4516
|
+
if (index > -1) {
|
|
4517
|
+
callbacks$8.splice(index, 1);
|
|
4518
|
+
}
|
|
4519
|
+
if (callbacks$8.length === 0) {
|
|
4520
|
+
mainDisposer$6 === null || mainDisposer$6 === void 0 ? void 0 : mainDisposer$6();
|
|
4521
|
+
}
|
|
4522
|
+
};
|
|
4523
|
+
/* begin_public_function
|
|
4524
|
+
id: channel.event.message_pinned
|
|
4525
|
+
*/
|
|
4526
|
+
/**
|
|
4527
|
+
* ```js
|
|
4528
|
+
* import { onChannelMessagePinned } from '@amityco/ts-sdk'
|
|
4529
|
+
* const dispose = onChannelMessagePinned(channel => {
|
|
4530
|
+
* // channel.pinnedMessage is the new pin
|
|
4531
|
+
* })
|
|
4532
|
+
* ```
|
|
4533
|
+
*
|
|
4534
|
+
* Fired when a message is pinned in a channel (the `channel.messagePinned` realtime
|
|
4535
|
+
* event). Pinning a different message while one is already pinned emits a single
|
|
4536
|
+
* `messagePinned` carrying the replacement — treat every payload as a full snapshot.
|
|
4537
|
+
*
|
|
4538
|
+
* The updated channel is written to cache before the callback runs, so
|
|
4539
|
+
* `ChannelRepository.getChannel` observers see `channel.pinnedMessage` change.
|
|
4540
|
+
*
|
|
4541
|
+
* @param callback The function to call when the event was fired
|
|
4542
|
+
* @returns an {@link Amity.Unsubscriber} function to run when willing to stop listening
|
|
4543
|
+
*
|
|
4544
|
+
* @category Channel Events
|
|
4545
|
+
*/
|
|
4546
|
+
const onChannelMessagePinned = (callback) => {
|
|
4547
|
+
if (callbacks$8.length === 0) {
|
|
4548
|
+
const client = getActiveClient();
|
|
4549
|
+
const filter = (payload) => {
|
|
4550
|
+
var _a;
|
|
4551
|
+
const channel = findCachedChannelForPin(payload);
|
|
4552
|
+
if (!channel)
|
|
4553
|
+
return;
|
|
4554
|
+
const updated = updatePinnedMessageCache(channel, (_a = payload.pinnedMessage) !== null && _a !== void 0 ? _a : null, payload.users);
|
|
4555
|
+
callbacks$8.forEach(cb => cb(updated));
|
|
4556
|
+
};
|
|
4557
|
+
mainDisposer$6 = createEventSubscriber(client, 'onChannelMessagePinned', 'channel.messagePinned', filter);
|
|
4558
|
+
}
|
|
4559
|
+
callbacks$8.push(callback);
|
|
4560
|
+
return () => dispose$8(callback);
|
|
4561
|
+
};
|
|
4562
|
+
/* end_public_function */
|
|
4563
|
+
|
|
4564
|
+
const callbacks$7 = [];
|
|
4565
|
+
let mainDisposer$5 = null;
|
|
4566
|
+
const dispose$7 = (cb) => {
|
|
4567
|
+
const index = callbacks$7.indexOf(cb);
|
|
4568
|
+
if (index > -1) {
|
|
4569
|
+
callbacks$7.splice(index, 1);
|
|
4570
|
+
}
|
|
4571
|
+
if (callbacks$7.length === 0) {
|
|
4572
|
+
mainDisposer$5 === null || mainDisposer$5 === void 0 ? void 0 : mainDisposer$5();
|
|
4573
|
+
}
|
|
4574
|
+
};
|
|
4575
|
+
/* begin_public_function
|
|
4576
|
+
id: channel.event.message_unpinned
|
|
4577
|
+
*/
|
|
4578
|
+
/**
|
|
4579
|
+
* ```js
|
|
4580
|
+
* import { onChannelMessageUnpinned } from '@amityco/ts-sdk'
|
|
4581
|
+
* const dispose = onChannelMessageUnpinned(channel => {
|
|
4582
|
+
* // channel.pinnedMessage is now null
|
|
4583
|
+
* })
|
|
4584
|
+
* ```
|
|
4585
|
+
*
|
|
4586
|
+
* Fired when a channel's pinned message is removed (the `channel.messageUnpinned`
|
|
4587
|
+
* realtime event) — either by an explicit unpin or automatically by the server when the
|
|
4588
|
+
* pinned message is deleted or its author is banned from the channel / globally.
|
|
4589
|
+
*
|
|
4590
|
+
* @param callback The function to call when the event was fired
|
|
4591
|
+
* @returns an {@link Amity.Unsubscriber} function to run when willing to stop listening
|
|
4592
|
+
*
|
|
4593
|
+
* @category Channel Events
|
|
4594
|
+
*/
|
|
4595
|
+
const onChannelMessageUnpinned = (callback) => {
|
|
4596
|
+
if (callbacks$7.length === 0) {
|
|
4597
|
+
const client = getActiveClient();
|
|
4598
|
+
const filter = (payload) => {
|
|
4599
|
+
const channel = findCachedChannelForPin(payload);
|
|
4600
|
+
if (!channel)
|
|
4601
|
+
return;
|
|
4602
|
+
const updated = updatePinnedMessageCache(channel, null);
|
|
4603
|
+
callbacks$7.forEach(cb => cb(updated));
|
|
4604
|
+
};
|
|
4605
|
+
mainDisposer$5 = createEventSubscriber(client, 'onChannelMessageUnpinned', 'channel.messageUnpinned', filter);
|
|
4606
|
+
}
|
|
4345
4607
|
callbacks$7.push(callback);
|
|
4346
4608
|
return () => dispose$7(callback);
|
|
4347
4609
|
};
|
|
4610
|
+
/* end_public_function */
|
|
4348
4611
|
|
|
4349
4612
|
const callbacks$6 = [];
|
|
4350
|
-
let mainDisposer$
|
|
4613
|
+
let mainDisposer$4 = null;
|
|
4351
4614
|
const dispose$6 = (cb) => {
|
|
4352
4615
|
const index = callbacks$6.indexOf(cb);
|
|
4353
4616
|
if (index > -1) {
|
|
4354
4617
|
callbacks$6.splice(index, 1);
|
|
4355
4618
|
}
|
|
4356
4619
|
if (callbacks$6.length === 0) {
|
|
4357
|
-
mainDisposer$
|
|
4620
|
+
mainDisposer$4 === null || mainDisposer$4 === void 0 ? void 0 : mainDisposer$4();
|
|
4358
4621
|
}
|
|
4359
4622
|
};
|
|
4360
4623
|
const onChannelMemberAdded = (callback) => {
|
|
@@ -4366,21 +4629,21 @@ const onChannelMemberAdded = (callback) => {
|
|
|
4366
4629
|
ingestInCache(preparedPayload);
|
|
4367
4630
|
callbacks$6.forEach(cb => cb(channels[0], channelUsers.find(cu => cu.membership === 'member')));
|
|
4368
4631
|
};
|
|
4369
|
-
mainDisposer$
|
|
4632
|
+
mainDisposer$4 = createEventSubscriber(client, 'onChannelMemberAdded', 'channel.membersAdded', filter);
|
|
4370
4633
|
}
|
|
4371
4634
|
callbacks$6.push(callback);
|
|
4372
4635
|
return () => dispose$6(callback);
|
|
4373
4636
|
};
|
|
4374
4637
|
|
|
4375
4638
|
const callbacks$5 = [];
|
|
4376
|
-
let mainDisposer$
|
|
4639
|
+
let mainDisposer$3 = null;
|
|
4377
4640
|
const dispose$5 = (cb) => {
|
|
4378
4641
|
const index = callbacks$5.indexOf(cb);
|
|
4379
4642
|
if (index > -1) {
|
|
4380
4643
|
callbacks$5.splice(index, 1);
|
|
4381
4644
|
}
|
|
4382
4645
|
if (callbacks$5.length === 0) {
|
|
4383
|
-
mainDisposer$
|
|
4646
|
+
mainDisposer$3 === null || mainDisposer$3 === void 0 ? void 0 : mainDisposer$3();
|
|
4384
4647
|
}
|
|
4385
4648
|
};
|
|
4386
4649
|
const onChannelMemberRemoved = (callback) => {
|
|
@@ -4392,21 +4655,21 @@ const onChannelMemberRemoved = (callback) => {
|
|
|
4392
4655
|
ingestInCache(preparedPayload);
|
|
4393
4656
|
callbacks$5.forEach(cb => cb(channels[0], channelUsers[0]));
|
|
4394
4657
|
};
|
|
4395
|
-
mainDisposer$
|
|
4658
|
+
mainDisposer$3 = createEventSubscriber(client, 'onChannelMemberRemoved', 'channel.membersRemoved', filter);
|
|
4396
4659
|
}
|
|
4397
4660
|
callbacks$5.push(callback);
|
|
4398
4661
|
return () => dispose$5(callback);
|
|
4399
4662
|
};
|
|
4400
4663
|
|
|
4401
4664
|
const callbacks$4 = [];
|
|
4402
|
-
let mainDisposer$
|
|
4665
|
+
let mainDisposer$2 = null;
|
|
4403
4666
|
const dispose$4 = (cb) => {
|
|
4404
4667
|
const index = callbacks$4.indexOf(cb);
|
|
4405
4668
|
if (index > -1) {
|
|
4406
4669
|
callbacks$4.splice(index, 1);
|
|
4407
4670
|
}
|
|
4408
4671
|
if (callbacks$4.length === 0) {
|
|
4409
|
-
mainDisposer$
|
|
4672
|
+
mainDisposer$2 === null || mainDisposer$2 === void 0 ? void 0 : mainDisposer$2();
|
|
4410
4673
|
}
|
|
4411
4674
|
};
|
|
4412
4675
|
const onChannelMemberBanned = (callback) => {
|
|
@@ -4426,20 +4689,20 @@ const onChannelMemberBanned = (callback) => {
|
|
|
4426
4689
|
ingestInCache(preparedPayload);
|
|
4427
4690
|
callbacks$4.forEach(cb => cb(channels[0], channelUsers.find(cu => cu.membership === 'banned')));
|
|
4428
4691
|
};
|
|
4429
|
-
mainDisposer$
|
|
4692
|
+
mainDisposer$2 = createEventSubscriber(client, 'onChannelMemberBanned', 'channel.banned', filter);
|
|
4430
4693
|
callbacks$4.push(callback);
|
|
4431
4694
|
return () => dispose$4(callback);
|
|
4432
4695
|
};
|
|
4433
4696
|
|
|
4434
4697
|
const callbacks$3 = [];
|
|
4435
|
-
let mainDisposer$
|
|
4698
|
+
let mainDisposer$1 = null;
|
|
4436
4699
|
const dispose$3 = (cb) => {
|
|
4437
4700
|
const index = callbacks$3.indexOf(cb);
|
|
4438
4701
|
if (index > -1) {
|
|
4439
4702
|
callbacks$3.splice(index, 1);
|
|
4440
4703
|
}
|
|
4441
4704
|
if (callbacks$3.length === 0) {
|
|
4442
|
-
mainDisposer$
|
|
4705
|
+
mainDisposer$1 === null || mainDisposer$1 === void 0 ? void 0 : mainDisposer$1();
|
|
4443
4706
|
}
|
|
4444
4707
|
};
|
|
4445
4708
|
const onChannelMemberUnbanned = (callback) => {
|
|
@@ -4451,59 +4714,127 @@ const onChannelMemberUnbanned = (callback) => {
|
|
|
4451
4714
|
ingestInCache(preparedPayload);
|
|
4452
4715
|
callbacks$3.forEach(cb => cb(channels[0], channelUsers.find(cu => cu.membership === 'none')));
|
|
4453
4716
|
};
|
|
4454
|
-
mainDisposer$
|
|
4717
|
+
mainDisposer$1 = createEventSubscriber(client, 'onChannelMemberUnbanned', 'channel.unbanned', filter);
|
|
4455
4718
|
}
|
|
4456
4719
|
callbacks$3.push(callback);
|
|
4457
4720
|
return () => dispose$3(callback);
|
|
4458
4721
|
};
|
|
4459
4722
|
|
|
4460
4723
|
const callbacks$2 = [];
|
|
4461
|
-
|
|
4724
|
+
const mainDisposers$1 = [];
|
|
4462
4725
|
const dispose$2 = (cb) => {
|
|
4463
4726
|
const index = callbacks$2.indexOf(cb);
|
|
4464
4727
|
if (index > -1) {
|
|
4465
4728
|
callbacks$2.splice(index, 1);
|
|
4466
4729
|
}
|
|
4467
4730
|
if (callbacks$2.length === 0) {
|
|
4468
|
-
|
|
4731
|
+
mainDisposers$1.forEach(fn => fn());
|
|
4732
|
+
mainDisposers$1.length = 0;
|
|
4469
4733
|
}
|
|
4470
4734
|
};
|
|
4735
|
+
/* begin_public_function
|
|
4736
|
+
id: channel.event.member_role_added
|
|
4737
|
+
*/
|
|
4738
|
+
/**
|
|
4739
|
+
* ```js
|
|
4740
|
+
* import { onChannelMemberRoleAdded } from '@amityco/ts-sdk'
|
|
4741
|
+
* const dispose = onChannelMemberRoleAdded((channel, member) => {
|
|
4742
|
+
* // member.roles and member.permissions are the member's resulting state
|
|
4743
|
+
* })
|
|
4744
|
+
* ```
|
|
4745
|
+
*
|
|
4746
|
+
* Fired when a role is added to a member of a {@link Amity.Channel}, either by the
|
|
4747
|
+
* local `ChannelRepository.Moderation.addRole` call or by the `channel.roleAdded` realtime
|
|
4748
|
+
* event coming from any client or the admin console.
|
|
4749
|
+
*
|
|
4750
|
+
* The realtime event reaches every subscriber of the channel topic (see `getChannelTopic`),
|
|
4751
|
+
* not only the actor or the affected members. It carries the affected members' resulting
|
|
4752
|
+
* channel roles and channel-scoped permissions, which are written to cache before the
|
|
4753
|
+
* callback runs. The callback is invoked once per affected member already held in cache.
|
|
4754
|
+
*
|
|
4755
|
+
* @param callback The function to call when the event was fired
|
|
4756
|
+
* @returns an {@link Amity.Unsubscriber} function to run when willing to stop listening
|
|
4757
|
+
*
|
|
4758
|
+
* @category Channel Events
|
|
4759
|
+
*/
|
|
4471
4760
|
const onChannelMemberRoleAdded = (callback) => {
|
|
4472
4761
|
if (callbacks$2.length === 0) {
|
|
4473
4762
|
const client = getActiveClient();
|
|
4474
|
-
const
|
|
4763
|
+
const onLocal = async (payload) => {
|
|
4475
4764
|
const { channels, channelUsers } = payload;
|
|
4476
4765
|
callbacks$2.forEach(cb => cb(channels[0], channelUsers.find(channelUser => channelUser.membership === 'member')));
|
|
4477
4766
|
};
|
|
4478
|
-
|
|
4767
|
+
const onRealtime = (payload) => {
|
|
4768
|
+
const { channel, members } = applyChannelRolePayload(payload);
|
|
4769
|
+
if (!channel)
|
|
4770
|
+
return;
|
|
4771
|
+
members.forEach(member => callbacks$2.forEach(cb => cb(channel, member)));
|
|
4772
|
+
};
|
|
4773
|
+
mainDisposers$1.push(createEventSubscriber(client, 'onChannelMemberRoleAdded', 'local.channel-moderator.role-added', onLocal));
|
|
4774
|
+
mainDisposers$1.push(createEventSubscriber(client, 'onChannelMemberRoleAdded', 'channel.roleAdded', onRealtime));
|
|
4479
4775
|
}
|
|
4480
4776
|
callbacks$2.push(callback);
|
|
4481
4777
|
return () => dispose$2(callback);
|
|
4482
4778
|
};
|
|
4779
|
+
/* end_public_function */
|
|
4483
4780
|
|
|
4484
4781
|
const callbacks$1 = [];
|
|
4485
|
-
|
|
4782
|
+
const mainDisposers = [];
|
|
4486
4783
|
const dispose$1 = (cb) => {
|
|
4487
4784
|
const index = callbacks$1.indexOf(cb);
|
|
4488
4785
|
if (index > -1) {
|
|
4489
4786
|
callbacks$1.splice(index, 1);
|
|
4490
4787
|
}
|
|
4491
4788
|
if (callbacks$1.length === 0) {
|
|
4492
|
-
|
|
4789
|
+
mainDisposers.forEach(fn => fn());
|
|
4790
|
+
mainDisposers.length = 0;
|
|
4493
4791
|
}
|
|
4494
4792
|
};
|
|
4793
|
+
/* begin_public_function
|
|
4794
|
+
id: channel.event.member_role_removed
|
|
4795
|
+
*/
|
|
4796
|
+
/**
|
|
4797
|
+
* ```js
|
|
4798
|
+
* import { onChannelMemberRoleRemoved } from '@amityco/ts-sdk'
|
|
4799
|
+
* const dispose = onChannelMemberRoleRemoved((channel, member) => {
|
|
4800
|
+
* // member.roles and member.permissions are the member's resulting state
|
|
4801
|
+
* })
|
|
4802
|
+
* ```
|
|
4803
|
+
*
|
|
4804
|
+
* Fired when a role is removed from a member of a {@link Amity.Channel}, either by the
|
|
4805
|
+
* local `ChannelRepository.Moderation.removeRole` call or by the `channel.roleRemoved` realtime
|
|
4806
|
+
* event coming from any client or the admin console.
|
|
4807
|
+
*
|
|
4808
|
+
* The realtime event reaches every subscriber of the channel topic (see `getChannelTopic`),
|
|
4809
|
+
* not only the actor or the affected members. It carries the affected members' resulting
|
|
4810
|
+
* channel roles and channel-scoped permissions, which are written to cache before the
|
|
4811
|
+
* callback runs. The callback is invoked once per affected member already held in cache.
|
|
4812
|
+
*
|
|
4813
|
+
* @param callback The function to call when the event was fired
|
|
4814
|
+
* @returns an {@link Amity.Unsubscriber} function to run when willing to stop listening
|
|
4815
|
+
*
|
|
4816
|
+
* @category Channel Events
|
|
4817
|
+
*/
|
|
4495
4818
|
const onChannelMemberRoleRemoved = (callback) => {
|
|
4496
4819
|
if (callbacks$1.length === 0) {
|
|
4497
4820
|
const client = getActiveClient();
|
|
4498
|
-
const
|
|
4821
|
+
const onLocal = async (payload) => {
|
|
4499
4822
|
const { channels, channelUsers } = payload;
|
|
4500
4823
|
callbacks$1.forEach(cb => cb(channels[0], channelUsers.find(channelUser => channelUser.membership === 'member')));
|
|
4501
4824
|
};
|
|
4502
|
-
|
|
4825
|
+
const onRealtime = (payload) => {
|
|
4826
|
+
const { channel, members } = applyChannelRolePayload(payload);
|
|
4827
|
+
if (!channel)
|
|
4828
|
+
return;
|
|
4829
|
+
members.forEach(member => callbacks$1.forEach(cb => cb(channel, member)));
|
|
4830
|
+
};
|
|
4831
|
+
mainDisposers.push(createEventSubscriber(client, 'onChannelMemberRoleRemoved', 'local.channel-moderator.role-removed', onLocal));
|
|
4832
|
+
mainDisposers.push(createEventSubscriber(client, 'onChannelMemberRoleRemoved', 'channel.roleRemoved', onRealtime));
|
|
4503
4833
|
}
|
|
4504
4834
|
callbacks$1.push(callback);
|
|
4505
4835
|
return () => dispose$1(callback);
|
|
4506
4836
|
};
|
|
4837
|
+
/* end_public_function */
|
|
4507
4838
|
|
|
4508
4839
|
/**
|
|
4509
4840
|
* Fired when a {@link Amity.Channel} has been archived by the active user.
|
|
@@ -4627,6 +4958,8 @@ const getMyMembership = (channelId, callback) => {
|
|
|
4627
4958
|
disposers.push(onChannelMemberBanned(realtimeRouter));
|
|
4628
4959
|
disposers.push(onChannelMemberUnbanned(realtimeRouter));
|
|
4629
4960
|
disposers.push(onChannelSetUserMuted(realtimeRouter));
|
|
4961
|
+
disposers.push(onChannelMemberRoleAdded(realtimeRouter));
|
|
4962
|
+
disposers.push(onChannelMemberRoleRemoved(realtimeRouter));
|
|
4630
4963
|
onFetch();
|
|
4631
4964
|
return () => {
|
|
4632
4965
|
disposers.forEach(fn => fn());
|
|
@@ -5020,7 +5353,9 @@ const initializeMessagePreviewSetting = async () => {
|
|
|
5020
5353
|
const getSocialSettings = async () => {
|
|
5021
5354
|
const client = getActiveClient();
|
|
5022
5355
|
const { data } = await client.http.get(`/api/v3/network-settings/social`);
|
|
5023
|
-
return data.socialNetworkSetting
|
|
5356
|
+
return Object.assign(Object.assign({}, data.socialNetworkSetting), {
|
|
5357
|
+
// Networks that never set the comment edit switch allow the edit
|
|
5358
|
+
isAllowEditCommentWhenReviewingEnabled: data.socialNetworkSetting.isAllowEditCommentWhenReviewingEnabled });
|
|
5024
5359
|
};
|
|
5025
5360
|
|
|
5026
5361
|
/**
|
|
@@ -5706,6 +6041,32 @@ class AnalyticsEventCapturer {
|
|
|
5706
6041
|
activityType: "view" /* Amity.AnalyticEventActivityType.View */,
|
|
5707
6042
|
});
|
|
5708
6043
|
}
|
|
6044
|
+
markCuratedContentWidgetAsViewed(topicId) {
|
|
6045
|
+
this.markAs({
|
|
6046
|
+
uniqueId: `curatedContentWidget.${topicId}`,
|
|
6047
|
+
contentId: topicId,
|
|
6048
|
+
contentType: "curated_content_widget" /* Amity.AnalyticEventContentType.CuratedContentWidget */,
|
|
6049
|
+
activityType: "view" /* Amity.AnalyticEventActivityType.View */,
|
|
6050
|
+
});
|
|
6051
|
+
}
|
|
6052
|
+
markCuratedContentPostAsViewed(postId, topicId) {
|
|
6053
|
+
this.markAs({
|
|
6054
|
+
uniqueId: `curatedContentPost.${postId}.view`,
|
|
6055
|
+
contentId: postId,
|
|
6056
|
+
contentType: "curated_content_post" /* Amity.AnalyticEventContentType.CuratedContentPost */,
|
|
6057
|
+
activityType: "view" /* Amity.AnalyticEventActivityType.View */,
|
|
6058
|
+
metadata: { topicId },
|
|
6059
|
+
});
|
|
6060
|
+
}
|
|
6061
|
+
markCuratedContentPostAsClicked(postId, topicId) {
|
|
6062
|
+
this.markAs({
|
|
6063
|
+
uniqueId: `curatedContentPost.${postId}.click`,
|
|
6064
|
+
contentId: postId,
|
|
6065
|
+
contentType: "curated_content_post" /* Amity.AnalyticEventContentType.CuratedContentPost */,
|
|
6066
|
+
activityType: "linkClicked" /* Amity.AnalyticEventActivityType.Click */,
|
|
6067
|
+
metadata: { topicId },
|
|
6068
|
+
});
|
|
6069
|
+
}
|
|
5709
6070
|
markPostAsMeaningfullyViewed(postId, feedRenderPosition) {
|
|
5710
6071
|
var _a;
|
|
5711
6072
|
const cached = (_a = pullFromCache(['feedMetadata', 'get', postId])) === null || _a === void 0 ? void 0 : _a.data;
|
|
@@ -5869,6 +6230,24 @@ class AnalyticsEngine {
|
|
|
5869
6230
|
this._eventCapturer.markPostAsViewed(postId);
|
|
5870
6231
|
}
|
|
5871
6232
|
}
|
|
6233
|
+
markCuratedContentWidgetAsViewed(topicId) {
|
|
6234
|
+
if (this._client.sessionState === "established" /* Amity.SessionStates.ESTABLISHED */ ||
|
|
6235
|
+
this._client.sessionState === "tokenExpired" /* Amity.SessionStates.TOKEN_EXPIRED */) {
|
|
6236
|
+
this._eventCapturer.markCuratedContentWidgetAsViewed(topicId);
|
|
6237
|
+
}
|
|
6238
|
+
}
|
|
6239
|
+
markCuratedContentPostAsViewed(postId, topicId) {
|
|
6240
|
+
if (this._client.sessionState === "established" /* Amity.SessionStates.ESTABLISHED */ ||
|
|
6241
|
+
this._client.sessionState === "tokenExpired" /* Amity.SessionStates.TOKEN_EXPIRED */) {
|
|
6242
|
+
this._eventCapturer.markCuratedContentPostAsViewed(postId, topicId);
|
|
6243
|
+
}
|
|
6244
|
+
}
|
|
6245
|
+
markCuratedContentPostAsClicked(postId, topicId) {
|
|
6246
|
+
if (this._client.sessionState === "established" /* Amity.SessionStates.ESTABLISHED */ ||
|
|
6247
|
+
this._client.sessionState === "tokenExpired" /* Amity.SessionStates.TOKEN_EXPIRED */) {
|
|
6248
|
+
this._eventCapturer.markCuratedContentPostAsClicked(postId, topicId);
|
|
6249
|
+
}
|
|
6250
|
+
}
|
|
5872
6251
|
markPostAsMeaningfullyViewed(postId, feedRenderPosition) {
|
|
5873
6252
|
if (this._client.sessionState === "established" /* Amity.SessionStates.ESTABLISHED */ ||
|
|
5874
6253
|
this._client.sessionState === "tokenExpired" /* Amity.SessionStates.TOKEN_EXPIRED */) {
|
|
@@ -7265,6 +7644,265 @@ class CursorController {
|
|
|
7265
7644
|
}
|
|
7266
7645
|
}
|
|
7267
7646
|
|
|
7647
|
+
class ResetTask {
|
|
7648
|
+
constructor(postId, latestCreatedAt, serverCommentCount) {
|
|
7649
|
+
this.postId = postId;
|
|
7650
|
+
this.latestCreatedAt = latestCreatedAt;
|
|
7651
|
+
this.serverCommentCount = serverCommentCount;
|
|
7652
|
+
}
|
|
7653
|
+
}
|
|
7654
|
+
|
|
7655
|
+
// Task to track comment creation
|
|
7656
|
+
class CreateTask {
|
|
7657
|
+
constructor(postId, commentId, createdAt) {
|
|
7658
|
+
this.postId = postId;
|
|
7659
|
+
this.commentId = commentId;
|
|
7660
|
+
this.createdAt = createdAt;
|
|
7661
|
+
}
|
|
7662
|
+
}
|
|
7663
|
+
|
|
7664
|
+
/**
|
|
7665
|
+
* A pending comment was approved and now counts publicly. Unlike `CreateTask` it carries no
|
|
7666
|
+
* `createdAt` and bypasses the age guard on purpose: the comment was written before the last post
|
|
7667
|
+
* payload (so its `createdAt` is old) but entered the server count only now. Same rule as iOS.
|
|
7668
|
+
*
|
|
7669
|
+
* Accepted trade-off (plan 40 §9): if a `ResetTask` that already includes this comment lands
|
|
7670
|
+
* between the approve response and the late `comment.approved` event, the count reads +1 until
|
|
7671
|
+
* the next server sync — the same self-correcting drift accepted for stale deletes.
|
|
7672
|
+
*/
|
|
7673
|
+
class ApproveTask {
|
|
7674
|
+
constructor(postId, commentId) {
|
|
7675
|
+
this.postId = postId;
|
|
7676
|
+
this.commentId = commentId;
|
|
7677
|
+
}
|
|
7678
|
+
}
|
|
7679
|
+
|
|
7680
|
+
// Task to track comment deletion
|
|
7681
|
+
class DeleteTask {
|
|
7682
|
+
constructor(postId, commentId) {
|
|
7683
|
+
this.postId = postId;
|
|
7684
|
+
this.commentId = commentId;
|
|
7685
|
+
}
|
|
7686
|
+
}
|
|
7687
|
+
|
|
7688
|
+
class CommentChange {
|
|
7689
|
+
constructor(latestCreatedAt, serverCommentCount) {
|
|
7690
|
+
this.latestCommentCreatedAt = latestCreatedAt;
|
|
7691
|
+
this.serverCommentCount = serverCommentCount;
|
|
7692
|
+
this.createdCommentIds = new Set();
|
|
7693
|
+
this.deletedCommentIds = new Set();
|
|
7694
|
+
}
|
|
7695
|
+
}
|
|
7696
|
+
|
|
7697
|
+
class PostCommentCountEngine {
|
|
7698
|
+
constructor() {
|
|
7699
|
+
this.isProcessing = false;
|
|
7700
|
+
this.tasks = [];
|
|
7701
|
+
this.commentChangeTracker = new Map();
|
|
7702
|
+
// Ids of the LOGGED-IN USER's own pending comments, per post. Survives ResetTask, so the
|
|
7703
|
+
// author's +1 does not vanish on the next post refresh; emptied only when the comment leaves
|
|
7704
|
+
// the pending state (approval hands it to createdCommentIds, decline/delete drops it).
|
|
7705
|
+
this.pendingAuthoredCommentIds = new Map();
|
|
7706
|
+
}
|
|
7707
|
+
queueCommentChangeTask(task) {
|
|
7708
|
+
this.tasks.push(task);
|
|
7709
|
+
if (!this.isProcessing) {
|
|
7710
|
+
this.processCommentChangeTask();
|
|
7711
|
+
}
|
|
7712
|
+
}
|
|
7713
|
+
addPendingAuthoredComment(postId, commentId, { publish = true } = {}) {
|
|
7714
|
+
var _a;
|
|
7715
|
+
const ids = (_a = this.pendingAuthoredCommentIds.get(postId)) !== null && _a !== void 0 ? _a : new Set();
|
|
7716
|
+
if (ids.has(commentId))
|
|
7717
|
+
return;
|
|
7718
|
+
ids.add(commentId);
|
|
7719
|
+
this.pendingAuthoredCommentIds.set(postId, ids);
|
|
7720
|
+
if (publish)
|
|
7721
|
+
this.publishIfTracked(postId);
|
|
7722
|
+
}
|
|
7723
|
+
removePendingAuthoredComment(postId, commentId, { publish = true } = {}) {
|
|
7724
|
+
const ids = this.pendingAuthoredCommentIds.get(postId);
|
|
7725
|
+
if (!(ids === null || ids === void 0 ? void 0 : ids.delete(commentId)))
|
|
7726
|
+
return false;
|
|
7727
|
+
if (ids.size === 0)
|
|
7728
|
+
this.pendingAuthoredCommentIds.delete(postId);
|
|
7729
|
+
if (publish)
|
|
7730
|
+
this.publishIfTracked(postId);
|
|
7731
|
+
return true;
|
|
7732
|
+
}
|
|
7733
|
+
/** Whether a post payload has seeded this post; without one every count is `0`. */
|
|
7734
|
+
hasTracker(postId) {
|
|
7735
|
+
return this.commentChangeTracker.has(postId);
|
|
7736
|
+
}
|
|
7737
|
+
isPendingAuthoredComment(postId, commentId) {
|
|
7738
|
+
var _a, _b;
|
|
7739
|
+
return (_b = (_a = this.pendingAuthoredCommentIds.get(postId)) === null || _a === void 0 ? void 0 : _a.has(commentId)) !== null && _b !== void 0 ? _b : false;
|
|
7740
|
+
}
|
|
7741
|
+
// Drops every per-post state. Called on logout / user switch.
|
|
7742
|
+
reset() {
|
|
7743
|
+
this.tasks = [];
|
|
7744
|
+
this.commentChangeTracker.clear();
|
|
7745
|
+
this.pendingAuthoredCommentIds.clear();
|
|
7746
|
+
}
|
|
7747
|
+
publishIfTracked(postId) {
|
|
7748
|
+
// Without a tracker there is no server figure to add to; the next ResetTask picks it up.
|
|
7749
|
+
if (!this.commentChangeTracker.has(postId))
|
|
7750
|
+
return;
|
|
7751
|
+
PostCommentCountEngine.publishUpdate(postId, this.getLocalCommentCount(postId, true));
|
|
7752
|
+
}
|
|
7753
|
+
processCommentChangeTask() {
|
|
7754
|
+
if (this.isProcessing) {
|
|
7755
|
+
return;
|
|
7756
|
+
}
|
|
7757
|
+
this.isProcessing = true;
|
|
7758
|
+
if (this.tasks.length === 0) {
|
|
7759
|
+
this.isProcessing = false;
|
|
7760
|
+
return;
|
|
7761
|
+
}
|
|
7762
|
+
// Process in capped batches, coalescing updates
|
|
7763
|
+
const batch = this.tasks.splice(0, PostCommentCountEngine.BATCH_SIZE);
|
|
7764
|
+
const modifiedPostIds = new Set();
|
|
7765
|
+
batch.forEach(task => {
|
|
7766
|
+
let modified = false;
|
|
7767
|
+
if (task instanceof ResetTask) {
|
|
7768
|
+
modified = this.processResetTaskInternal(task);
|
|
7769
|
+
}
|
|
7770
|
+
else if (task instanceof CreateTask) {
|
|
7771
|
+
modified = this.processCreateTaskInternal(task);
|
|
7772
|
+
}
|
|
7773
|
+
else if (task instanceof ApproveTask) {
|
|
7774
|
+
modified = this.processApproveTaskInternal(task);
|
|
7775
|
+
}
|
|
7776
|
+
else if (task instanceof DeleteTask) {
|
|
7777
|
+
modified = this.processDeleteTaskInternal(task);
|
|
7778
|
+
}
|
|
7779
|
+
if (modified) {
|
|
7780
|
+
modifiedPostIds.add(task.postId);
|
|
7781
|
+
}
|
|
7782
|
+
});
|
|
7783
|
+
// Publish one update per modified post
|
|
7784
|
+
modifiedPostIds.forEach(postId => {
|
|
7785
|
+
PostCommentCountEngine.publishUpdate(postId, this.getLocalCommentCount(postId, true));
|
|
7786
|
+
});
|
|
7787
|
+
this.isProcessing = false;
|
|
7788
|
+
// Recurse if more tasks remain
|
|
7789
|
+
if (this.tasks.length > 0) {
|
|
7790
|
+
this.processCommentChangeTask();
|
|
7791
|
+
}
|
|
7792
|
+
}
|
|
7793
|
+
processResetTaskInternal(task) {
|
|
7794
|
+
// Always creates/overwrites tracker
|
|
7795
|
+
this.commentChangeTracker.set(task.postId, new CommentChange(task.latestCreatedAt, task.serverCommentCount));
|
|
7796
|
+
return true;
|
|
7797
|
+
}
|
|
7798
|
+
processCreateTaskInternal(task) {
|
|
7799
|
+
// The comment is public now: the author-local +1 hands over to the normal path, so the
|
|
7800
|
+
// count stays put instead of moving twice.
|
|
7801
|
+
const wasPendingAuthored = this.removePendingAuthoredComment(task.postId, task.commentId, {
|
|
7802
|
+
publish: false,
|
|
7803
|
+
});
|
|
7804
|
+
const tracker = this.commentChangeTracker.get(task.postId);
|
|
7805
|
+
if (!tracker)
|
|
7806
|
+
return false; // No tracker, skip
|
|
7807
|
+
if (tracker.deletedCommentIds.delete(task.commentId))
|
|
7808
|
+
return true; // Re-approval cancels the earlier removal
|
|
7809
|
+
if (tracker.createdCommentIds.has(task.commentId))
|
|
7810
|
+
return wasPendingAuthored; // Deduplication
|
|
7811
|
+
if (task.createdAt <= tracker.latestCommentCreatedAt)
|
|
7812
|
+
return wasPendingAuthored; // Timestamp filtering
|
|
7813
|
+
tracker.createdCommentIds.add(task.commentId);
|
|
7814
|
+
return true;
|
|
7815
|
+
}
|
|
7816
|
+
processApproveTaskInternal(task) {
|
|
7817
|
+
// The comment is public now: the author-local +1 hands over to the normal path, so the
|
|
7818
|
+
// count stays put instead of moving twice.
|
|
7819
|
+
const wasPendingAuthored = this.removePendingAuthoredComment(task.postId, task.commentId, {
|
|
7820
|
+
publish: false,
|
|
7821
|
+
});
|
|
7822
|
+
const tracker = this.commentChangeTracker.get(task.postId);
|
|
7823
|
+
if (!tracker)
|
|
7824
|
+
return false; // No tracker, skip
|
|
7825
|
+
if (tracker.deletedCommentIds.delete(task.commentId))
|
|
7826
|
+
return true; // Re-approval cancels the earlier re-review removal
|
|
7827
|
+
if (tracker.createdCommentIds.has(task.commentId))
|
|
7828
|
+
return wasPendingAuthored; // Approve response and comment.approved event dedupe by id
|
|
7829
|
+
// No timestamp filtering: approval is the moment the comment enters the count, not createdAt
|
|
7830
|
+
tracker.createdCommentIds.add(task.commentId);
|
|
7831
|
+
return true;
|
|
7832
|
+
}
|
|
7833
|
+
processDeleteTaskInternal(task) {
|
|
7834
|
+
const tracker = this.commentChangeTracker.get(task.postId);
|
|
7835
|
+
if (!tracker)
|
|
7836
|
+
return false; // No tracker, skip
|
|
7837
|
+
if (tracker.deletedCommentIds.has(task.commentId))
|
|
7838
|
+
return false; // Deduplication
|
|
7839
|
+
tracker.deletedCommentIds.add(task.commentId);
|
|
7840
|
+
return true;
|
|
7841
|
+
}
|
|
7842
|
+
/**
|
|
7843
|
+
* The count as this session sees it: the last server figure plus the local delta.
|
|
7844
|
+
*
|
|
7845
|
+
* `includePending` adds the logged-in user's own pending comments — the author's view. A
|
|
7846
|
+
* pending id is added only while the public delta does not already count it, so a comment
|
|
7847
|
+
* present in both sets counts once: a `comment.created` that arrives pending after the
|
|
7848
|
+
* `comment.approved` hand-over adds nothing, while an approved comment sent back to review
|
|
7849
|
+
* (created, deleted and pending all hold its id) keeps the author's +1.
|
|
7850
|
+
*
|
|
7851
|
+
* `0` for a post no payload has seeded yet; callers fall back to the post's own figure.
|
|
7852
|
+
*/
|
|
7853
|
+
getLocalCommentCount(postId, includePending = false) {
|
|
7854
|
+
var _a;
|
|
7855
|
+
const tracker = this.commentChangeTracker.get(postId);
|
|
7856
|
+
if (!tracker)
|
|
7857
|
+
return 0;
|
|
7858
|
+
const publicDelta = tracker.createdCommentIds.size - tracker.deletedCommentIds.size;
|
|
7859
|
+
if (!includePending)
|
|
7860
|
+
return Math.max(0, tracker.serverCommentCount + publicDelta);
|
|
7861
|
+
let pendingExtra = 0;
|
|
7862
|
+
(_a = this.pendingAuthoredCommentIds.get(postId)) === null || _a === void 0 ? void 0 : _a.forEach(commentId => {
|
|
7863
|
+
const countedPublicly = tracker.createdCommentIds.has(commentId) && !tracker.deletedCommentIds.has(commentId);
|
|
7864
|
+
if (!countedPublicly)
|
|
7865
|
+
pendingExtra += 1;
|
|
7866
|
+
});
|
|
7867
|
+
return Math.max(0, tracker.serverCommentCount + publicDelta + pendingExtra);
|
|
7868
|
+
}
|
|
7869
|
+
static publishUpdate(postId, newCount) {
|
|
7870
|
+
var _a;
|
|
7871
|
+
const queryKey = ['post', 'get', postId];
|
|
7872
|
+
mergeInCache(queryKey, {
|
|
7873
|
+
localCommentCount: newCount,
|
|
7874
|
+
});
|
|
7875
|
+
const postPayload = (_a = pullFromCache(queryKey)) === null || _a === void 0 ? void 0 : _a.data;
|
|
7876
|
+
if (!postPayload)
|
|
7877
|
+
return;
|
|
7878
|
+
fireEvent('local.post.updated', {
|
|
7879
|
+
posts: [postPayload],
|
|
7880
|
+
});
|
|
7881
|
+
}
|
|
7882
|
+
}
|
|
7883
|
+
PostCommentCountEngine.BATCH_SIZE = 50;
|
|
7884
|
+
let instance$1;
|
|
7885
|
+
var PostCommentCountEngine$1 = {
|
|
7886
|
+
getInstance: () => {
|
|
7887
|
+
if (!instance$1) {
|
|
7888
|
+
instance$1 = new PostCommentCountEngine();
|
|
7889
|
+
}
|
|
7890
|
+
return instance$1;
|
|
7891
|
+
},
|
|
7892
|
+
};
|
|
7893
|
+
|
|
7894
|
+
/**
|
|
7895
|
+
* Comment-count state is per user — in particular the ids of the logged-in user's own pending
|
|
7896
|
+
* comments — so it must not survive a logout or a user switch.
|
|
7897
|
+
*
|
|
7898
|
+
* @category private
|
|
7899
|
+
*/
|
|
7900
|
+
const postCommentCountEngineOnLoginHandler = () => onSessionStateChange(state => {
|
|
7901
|
+
if (state === "notLoggedIn" /* Amity.SessionStates.NOT_LOGGED_IN */ || state === "terminated" /* Amity.SessionStates.TERMINATED */) {
|
|
7902
|
+
PostCommentCountEngine$1.getInstance().reset();
|
|
7903
|
+
}
|
|
7904
|
+
});
|
|
7905
|
+
|
|
7268
7906
|
const EVENTS = [
|
|
7269
7907
|
'disconnected',
|
|
7270
7908
|
'error',
|
|
@@ -7454,7 +8092,7 @@ const setupLoginSubscriptions = (unsubWatcher) => {
|
|
|
7454
8092
|
// NOTE: This is a temporary solution to handle the channel marker when the user is forced to leave
|
|
7455
8093
|
// the channel because currently backend can't handle this, so every time a user is banned from
|
|
7456
8094
|
// a channel or the channel is deleted the channel's unread count will not be reset to zero
|
|
7457
|
-
onChannelDeleted(removeChannelMarkerCache), onChannelMemberBanned(removeChannelMarkerCache), markReadEngineOnLoginHandler(), analyticsEngineOnLoginHandler(), objectResolverEngineOnLoginHandler(), reactionSyncEngineOnLoginHandler(), blockedUserSyncEngineOnLoginHandler(), blockingUserSyncEngineOnLoginHandler(), blockRealtimeOnLoginHandler(), resetAutoSubscriptionsOnLogout(), CursorController.clearOnLogout());
|
|
8095
|
+
onChannelDeleted(removeChannelMarkerCache), onChannelMemberBanned(removeChannelMarkerCache), markReadEngineOnLoginHandler(), analyticsEngineOnLoginHandler(), objectResolverEngineOnLoginHandler(), reactionSyncEngineOnLoginHandler(), blockedUserSyncEngineOnLoginHandler(), blockingUserSyncEngineOnLoginHandler(), blockRealtimeOnLoginHandler(), resetAutoSubscriptionsOnLogout(), CursorController.clearOnLogout(), postCommentCountEngineOnLoginHandler());
|
|
7458
8096
|
if (client.useLegacyUnreadCount) {
|
|
7459
8097
|
subscriptions.push(readReceiptSyncEngineOnLoginHandler());
|
|
7460
8098
|
}
|
|
@@ -8490,7 +9128,7 @@ const DEFAULT_DEBUG_SESSION = 'amity';
|
|
|
8490
9128
|
*
|
|
8491
9129
|
* @category Client API
|
|
8492
9130
|
* */
|
|
8493
|
-
const createClient = (apiKey, apiRegion = API_REGIONS.SG, { debugSession = DEFAULT_DEBUG_SESSION, apiEndpoint, prefixDeviceIdKey, rteEnabled = true, } = {}) => {
|
|
9131
|
+
const createClient = (apiKey, apiRegion = API_REGIONS.SG, { debugSession = DEFAULT_DEBUG_SESSION, apiEndpoint, prefixDeviceIdKey, rteEnabled = true, product, uikitVersion, appId, appVersion, } = {}) => {
|
|
8494
9132
|
var _a, _b, _c;
|
|
8495
9133
|
const log = createLogger(debugSession);
|
|
8496
9134
|
log('client/api/createClient', {
|
|
@@ -8519,6 +9157,10 @@ const createClient = (apiKey, apiRegion = API_REGIONS.SG, { debugSession = DEFAU
|
|
|
8519
9157
|
const useLegacyUnreadCount = true;
|
|
8520
9158
|
const client = {
|
|
8521
9159
|
version: `${VERSION}`,
|
|
9160
|
+
product,
|
|
9161
|
+
uikitVersion,
|
|
9162
|
+
appId,
|
|
9163
|
+
appVersion,
|
|
8522
9164
|
apiKey,
|
|
8523
9165
|
/*
|
|
8524
9166
|
* SDK Components
|
|
@@ -8757,13 +9399,13 @@ class GlobalFileAccessType {
|
|
|
8757
9399
|
}
|
|
8758
9400
|
}
|
|
8759
9401
|
_GlobalFileAccessType_fileAccessType = new WeakMap();
|
|
8760
|
-
let instance
|
|
9402
|
+
let instance;
|
|
8761
9403
|
var GlobalFileAccessType$1 = {
|
|
8762
9404
|
getInstance: () => {
|
|
8763
|
-
if (!instance
|
|
8764
|
-
instance
|
|
9405
|
+
if (!instance) {
|
|
9406
|
+
instance = new GlobalFileAccessType();
|
|
8765
9407
|
}
|
|
8766
|
-
return instance
|
|
9408
|
+
return instance;
|
|
8767
9409
|
},
|
|
8768
9410
|
};
|
|
8769
9411
|
|
|
@@ -9600,7 +10242,7 @@ const getUserUnread = (callback) => {
|
|
|
9600
10242
|
};
|
|
9601
10243
|
};
|
|
9602
10244
|
|
|
9603
|
-
var index$
|
|
10245
|
+
var index$t = /*#__PURE__*/Object.freeze({
|
|
9604
10246
|
__proto__: null,
|
|
9605
10247
|
getActiveClient: getActiveClient,
|
|
9606
10248
|
getActiveUser: getActiveUser,
|
|
@@ -10826,7 +11468,7 @@ const getMyFollowInfo = (callback) => {
|
|
|
10826
11468
|
};
|
|
10827
11469
|
/* end_public_function */
|
|
10828
11470
|
|
|
10829
|
-
var index$
|
|
11471
|
+
var index$s = /*#__PURE__*/Object.freeze({
|
|
10830
11472
|
__proto__: null,
|
|
10831
11473
|
blockUser: blockUser,
|
|
10832
11474
|
unBlockUser: unBlockUser,
|
|
@@ -12338,8 +12980,32 @@ const streamLinkedObject = (stream) => {
|
|
|
12338
12980
|
} });
|
|
12339
12981
|
};
|
|
12340
12982
|
|
|
12983
|
+
const KNOWN_APPROVAL_STATUSES = [
|
|
12984
|
+
"pending" /* Amity.CommentApprovalStatusEnum.Pending */,
|
|
12985
|
+
"approved" /* Amity.CommentApprovalStatusEnum.Approved */,
|
|
12986
|
+
"rejected" /* Amity.CommentApprovalStatusEnum.Rejected */,
|
|
12987
|
+
];
|
|
12988
|
+
/**
|
|
12989
|
+
* The server sends `approvalStatus` only while a comment is held for review or after it was
|
|
12990
|
+
* rejected. Absent, `null`, or an unrecognised value all resolve to `approved` — never to
|
|
12991
|
+
* `pending`, which would mark every comment written before the feature as unpublished.
|
|
12992
|
+
*/
|
|
12993
|
+
const resolveCommentApprovalStatus = (approvalStatus) => {
|
|
12994
|
+
if (approvalStatus && KNOWN_APPROVAL_STATUSES.includes(approvalStatus)) {
|
|
12995
|
+
return approvalStatus;
|
|
12996
|
+
}
|
|
12997
|
+
return "approved" /* Amity.CommentApprovalStatusEnum.Approved */;
|
|
12998
|
+
};
|
|
12999
|
+
const prepareComment = (comment) => (Object.assign(Object.assign(Object.assign({}, (comment.hasOwnProperty('myReactions') ? {} : { myReactions: [] })), comment), { approvalStatus: resolveCommentApprovalStatus(comment.approvalStatus) }));
|
|
13000
|
+
function prepareCommentPayload(commentPayload) {
|
|
13001
|
+
const { comments, commentChildren } = commentPayload;
|
|
13002
|
+
return Object.assign(Object.assign(Object.assign({}, commentPayload), { comments: comments.map(prepareComment) }), (commentChildren ? { commentChildren: commentChildren.map(prepareComment) } : {}));
|
|
13003
|
+
}
|
|
13004
|
+
|
|
12341
13005
|
const commentLinkedObject = (comment) => {
|
|
12342
|
-
return Object.assign(Object.assign({}, comment), {
|
|
13006
|
+
return Object.assign(Object.assign({}, comment), {
|
|
13007
|
+
// Non-optional on the public model: absent on the wire means approved
|
|
13008
|
+
approvalStatus: resolveCommentApprovalStatus(comment.approvalStatus), get target() {
|
|
12343
13009
|
const commentTypes = {
|
|
12344
13010
|
type: comment.targetType,
|
|
12345
13011
|
};
|
|
@@ -12547,7 +13213,7 @@ const getWatchSessionStorage = () => {
|
|
|
12547
13213
|
return storageInstance;
|
|
12548
13214
|
};
|
|
12549
13215
|
|
|
12550
|
-
const privateKey = "
|
|
13216
|
+
const privateKey = "MIIEpQIBAAKCAQEAwAEc/oZgYIvKSUG/C3mONYLR4ZPgAjMEX4bJ+xqqakUDRtqlNO+eZs2blQ1Ko0DBkqPExyQezvjibH5W2UZBV5RaBTlTcNVKTToMBEGesAfaEcM3qUyQHxdbFYZv6P4sb14dcwxTQ8usmaV8ooiR1Fcaso5ZWYcZ8Hb46FbQ7OoVumsBtPWwfZ4f003o5VCl6AIM6lcLv9UDLlFVYhE+PeXpRHtfWlGqxMvqC9oinlwhL6nWv6VjQXW4nhcib72dPBzfHT7k/PMKto2SxALYdb68ENiAGuJLWi3AUHSyYCJK2w7wIlWfJUAI0v26ub10IpExr6D5QuW2577jjP93iwIDAQABAoIBAFWfqXhwIIatkFY+9Z1+ZcbDQimgsmMIsUiQaX6Lk7e0cxOj6czDlxYtVtaPiNtow2pLkjNkjkCqiP7tEHnwdK9DvylZOTa2R15NJpK3WLcTqVIGhsn/FL5owfvFah6zSsmXZParZm5zY9NZE03ALZhOB9/cz0e3kf/EbpfeL2mW7MApyiUt5i09ycchroOpcWp73ipIxvgigtZyUGFmsQicWhUs28F0D7w4Qfk76yG3nqXeb+BAMhCaIaa/k/aAxhiZG/ygEQWQrcC8gfe+jyicMAQPDEVS9YuUMGsLjIjKuVLZzp2xirQnhc2i2zVNEIvG6soprPOBEMQugzrtX5ECgYEA3b7KAbBIbDl1e4ZSCWhHdHkiWVZHaopsR/LhqDDNhXjWjq3AesgV6k0j9EdziMn/HmmOso0bz99GTV3JZf4A9ztTLumJlkHbdVtlgOqSjrFLj12rH9KXTheyIhWSpUmm8+WB1xasFbqpvJaGo7F3pd2Fqj1XR4mp5BO7c/t7LJ0CgYEA3aouEzXQ9THRKYocdfY69EI1Il1t/d/RSqqd9BxEjxBgxkM13ZiYIn/R4WW/nCUrlmhxG44Aa2Gob4Ahfsui2xKTg/g/3Zk/rAxAEGkfOLGoenaJMD41fH4wUq3FRYwkvnaMb9Hd6f/TlBHslIRa2NN58bSBGJCyBP2b59+2+EcCgYEAixDVRXvV37GlYUOa/XVdosk5Zoe6oDGRuQm0xbNdoUBoZvDHDvme7ONWEiQha/8qtVsD+CyQ7awcPfb8kK9c0bBt+bTS6d4BkTcxkEkMgtrkBVR8Nqfu5jXsLH4VCv4G61zbMhZw8+ut+az5YX2yCN7Frj9sFlxapMRPQmzMEe0CgYEAumsAzM8ZqNv4mAK65Mnr0rhLj1cbxcKRdUYACOgtEFQpzxN/HZnTeFAe5nx3pI3uFlRHq3DFEYnT6dHMWaJQmAULYpVIwMi9L6gtyJ9fzoI6uqMtxRDMUqKdaSsTGOY/kJ6KhQ/unXi1K3XXjR+yd1+C0q+HUm1+CYxvrZYLfskCgYEArsEy+IQOiqniJ0NE2vVUF+UK/IRZaic9YKcpov5Ot7Vvzm/MnnW4N1ljVskocETBWMmPUvNSExVjPebi+rxd8fa5kY8BJScPTzMFbunZn/wjtGdcM10qdlVQ9doG61A/9P3ezFKCfS4AvF/H/59LcSx2Bh28fp3/efiVIOpVd4Y=";
|
|
12551
13217
|
/*
|
|
12552
13218
|
* The crypto algorithm used for importing key and signing string
|
|
12553
13219
|
*/
|
|
@@ -12990,6 +13656,122 @@ const fileLinkedObject = (file) => {
|
|
|
12990
13656
|
return file;
|
|
12991
13657
|
};
|
|
12992
13658
|
|
|
13659
|
+
const isCommentPending = (comment) => resolveCommentApprovalStatus(comment.approvalStatus) === "pending" /* Amity.CommentApprovalStatusEnum.Pending */;
|
|
13660
|
+
const isCommentApproved = (comment) => resolveCommentApprovalStatus(comment.approvalStatus) === "approved" /* Amity.CommentApprovalStatusEnum.Approved */;
|
|
13661
|
+
// Only post and content references feed PostCommentCountEngine; story counts live on the story.
|
|
13662
|
+
const isCountedReference = (comment) => ['post', 'content'].includes(comment.referenceType);
|
|
13663
|
+
const isAuthoredByCurrentUser = (comment) => comment.userId === getActiveClient().userId;
|
|
13664
|
+
/**
|
|
13665
|
+
* Whether a comment on this reference would be held for review, read from the cached post's
|
|
13666
|
+
* community. `true` when that cannot be known — the post or its community is not cached yet.
|
|
13667
|
+
* A pending guess that turns out approved is corrected by the response and the comment then
|
|
13668
|
+
* enters the list; an approved guess that turns out pending has already been shown in a public
|
|
13669
|
+
* list with nothing to take it back out. Only shapes the optimistic object — the server
|
|
13670
|
+
* response is the authority on the actual status.
|
|
13671
|
+
*/
|
|
13672
|
+
const isCommentApprovalRequired = (bundle) => {
|
|
13673
|
+
var _a, _b;
|
|
13674
|
+
// Only comments on community posts are gated; every other reference is known-off
|
|
13675
|
+
if (bundle.referenceType !== 'post')
|
|
13676
|
+
return false;
|
|
13677
|
+
const post = (_a = pullFromCache(['post', 'get', bundle.referenceId])) === null || _a === void 0 ? void 0 : _a.data;
|
|
13678
|
+
if (!post)
|
|
13679
|
+
return true;
|
|
13680
|
+
// A user-feed post is known-off
|
|
13681
|
+
if (post.targetType !== 'community')
|
|
13682
|
+
return false;
|
|
13683
|
+
const community = (_b = pullFromCache([
|
|
13684
|
+
'community',
|
|
13685
|
+
'get',
|
|
13686
|
+
post.targetId,
|
|
13687
|
+
])) === null || _b === void 0 ? void 0 : _b.data;
|
|
13688
|
+
if (!community)
|
|
13689
|
+
return true;
|
|
13690
|
+
return community.needApprovalOnCommentCreation === true;
|
|
13691
|
+
};
|
|
13692
|
+
/**
|
|
13693
|
+
* An approved comment arrived over realtime: one `CreateTask` carrying its own `createdAt`, so
|
|
13694
|
+
* the timestamp filter skips anything the last post payload already counted. The author's own
|
|
13695
|
+
* comment reaches here as an echo too; the engine de-duplicates it by id against the task the
|
|
13696
|
+
* create response queued.
|
|
13697
|
+
*/
|
|
13698
|
+
const applyCommentCreatedCount = (comment) => {
|
|
13699
|
+
if (!isCountedReference(comment))
|
|
13700
|
+
return;
|
|
13701
|
+
PostCommentCountEngine$1.getInstance().queueCommentChangeTask(new CreateTask(comment.referenceId, comment.commentId, comment.createdAt));
|
|
13702
|
+
};
|
|
13703
|
+
/**
|
|
13704
|
+
* The author's own pending comment counts in their view only. Recorded as separate engine state
|
|
13705
|
+
* so it survives a post refresh (`ResetTask`).
|
|
13706
|
+
*/
|
|
13707
|
+
const recordPendingAuthoredComment = (comment, options) => {
|
|
13708
|
+
if (!isCountedReference(comment) || !isAuthoredByCurrentUser(comment))
|
|
13709
|
+
return;
|
|
13710
|
+
PostCommentCountEngine$1.getInstance().addPendingAuthoredComment(comment.referenceId, comment.commentId, options);
|
|
13711
|
+
};
|
|
13712
|
+
/**
|
|
13713
|
+
* A pending comment was declined or deleted: it was never in the server count, so no
|
|
13714
|
+
* `DeleteTask` — only the author-local +1 goes away.
|
|
13715
|
+
*/
|
|
13716
|
+
const releasePendingAuthoredComment = (comment) => {
|
|
13717
|
+
if (!isCountedReference(comment))
|
|
13718
|
+
return;
|
|
13719
|
+
PostCommentCountEngine$1.getInstance().removePendingAuthoredComment(comment.referenceId, comment.commentId);
|
|
13720
|
+
};
|
|
13721
|
+
/**
|
|
13722
|
+
* Reveal: exactly one `ApproveTask`. The engine de-duplicates by comment id, so the approve
|
|
13723
|
+
* response and the `comment.approved` event may both call this. `ApproveTask` bypasses the age
|
|
13724
|
+
* guard on purpose — the comment was written before the last server sync but enters the public
|
|
13725
|
+
* count now — matching the iOS `ApproveTask` (plan 40 §9, guard off for approve).
|
|
13726
|
+
*/
|
|
13727
|
+
const applyCommentApprovedCount = (comment) => {
|
|
13728
|
+
if (!isCountedReference(comment))
|
|
13729
|
+
return;
|
|
13730
|
+
PostCommentCountEngine$1.getInstance().queueCommentChangeTask(new ApproveTask(comment.referenceId, comment.commentId));
|
|
13731
|
+
};
|
|
13732
|
+
/**
|
|
13733
|
+
* Re-review: an approved comment edited back to pending leaves the public count once. The
|
|
13734
|
+
* author keeps their own +1 through the pending set, so their count does not move.
|
|
13735
|
+
*/
|
|
13736
|
+
const applyCommentReReviewCount = (comment) => {
|
|
13737
|
+
if (!isCountedReference(comment))
|
|
13738
|
+
return;
|
|
13739
|
+
recordPendingAuthoredComment(comment, { publish: false });
|
|
13740
|
+
PostCommentCountEngine$1.getInstance().queueCommentChangeTask(new DeleteTask(comment.referenceId, comment.commentId));
|
|
13741
|
+
};
|
|
13742
|
+
/** Adds a reply to its cached parent's `children` (and count) once. */
|
|
13743
|
+
const linkCommentToParent = (comment) => {
|
|
13744
|
+
var _a;
|
|
13745
|
+
if (!comment.parentId)
|
|
13746
|
+
return;
|
|
13747
|
+
const parentKey = ['comment', 'get', comment.parentId];
|
|
13748
|
+
const parent = (_a = pullFromCache(parentKey)) === null || _a === void 0 ? void 0 : _a.data;
|
|
13749
|
+
if (!parent || parent.children.includes(comment.commentId))
|
|
13750
|
+
return;
|
|
13751
|
+
pushToCache(parentKey, Object.assign(Object.assign({}, parent), { childrenNumber: parent.childrenNumber + 1, children: [...new Set([...parent.children, comment.commentId])] }));
|
|
13752
|
+
};
|
|
13753
|
+
/** Removes a reply from its cached parent's `children` (and count) once. */
|
|
13754
|
+
const unlinkCommentFromParent = (comment) => {
|
|
13755
|
+
var _a;
|
|
13756
|
+
if (!comment.parentId)
|
|
13757
|
+
return;
|
|
13758
|
+
const parentKey = ['comment', 'get', comment.parentId];
|
|
13759
|
+
const parent = (_a = pullFromCache(parentKey)) === null || _a === void 0 ? void 0 : _a.data;
|
|
13760
|
+
if (!parent || !parent.children.includes(comment.commentId))
|
|
13761
|
+
return;
|
|
13762
|
+
pushToCache(parentKey, Object.assign(Object.assign({}, parent), { childrenNumber: parent.childrenNumber - 1, children: parent.children.filter(id => id !== comment.commentId) }));
|
|
13763
|
+
};
|
|
13764
|
+
|
|
13765
|
+
/**
|
|
13766
|
+
* The server's list is oldest → newest, so the newest ids are the last ones. Kept unique so the
|
|
13767
|
+
* create response, the local event and the realtime echo cannot each add the same comment.
|
|
13768
|
+
*/
|
|
13769
|
+
const capLatestCommentIds = (commentIds) => [...new Set(commentIds)].slice(-LATEST_COMMENTS_LIMIT);
|
|
13770
|
+
/** A comment belongs in the post preview only while it is cached, not deleted and public. */
|
|
13771
|
+
const isPreviewableComment = (comment) => comment !== undefined && !comment.isDeleted && isCommentApproved(comment);
|
|
13772
|
+
/** The post's preview list after one of the user's own top-level comments is created. */
|
|
13773
|
+
const appendLatestCommentId = (post, commentId) => { var _a; return capLatestCommentIds([...((_a = post.comments) !== null && _a !== void 0 ? _a : []), commentId]); };
|
|
13774
|
+
|
|
12993
13775
|
const postLinkedObject = (post) => {
|
|
12994
13776
|
return shallowClone(post, {
|
|
12995
13777
|
childrenPosts: post.children
|
|
@@ -13013,19 +13795,13 @@ const postLinkedObject = (post) => {
|
|
|
13013
13795
|
get latestComments() {
|
|
13014
13796
|
if (!post.comments)
|
|
13015
13797
|
return [];
|
|
13016
|
-
|
|
13017
|
-
|
|
13018
|
-
|
|
13019
|
-
|
|
13020
|
-
|
|
13021
|
-
|
|
13022
|
-
|
|
13023
|
-
])) === null || _a === void 0 ? void 0 : _a.data;
|
|
13024
|
-
if (!commentCached)
|
|
13025
|
-
return null;
|
|
13026
|
-
return commentLinkedObject(commentCached);
|
|
13027
|
-
})
|
|
13028
|
-
.filter(Boolean) || []);
|
|
13798
|
+
// Same rule as the server's own list and as iOS: deleted and non-public comments are
|
|
13799
|
+
// dropped first, then the newest LATEST_COMMENTS_LIMIT remain
|
|
13800
|
+
return post.comments
|
|
13801
|
+
.map(commentId => { var _a; return (_a = pullFromCache(['comment', 'get', commentId])) === null || _a === void 0 ? void 0 : _a.data; })
|
|
13802
|
+
.filter(isPreviewableComment)
|
|
13803
|
+
.slice(-LATEST_COMMENTS_LIMIT)
|
|
13804
|
+
.map(commentLinkedObject);
|
|
13029
13805
|
},
|
|
13030
13806
|
get creator() {
|
|
13031
13807
|
// The id is checked for a value, not just for presence: a payload can
|
|
@@ -13038,6 +13814,15 @@ const postLinkedObject = (post) => {
|
|
|
13038
13814
|
return undefined;
|
|
13039
13815
|
return userLinkedObject(cacheData.data);
|
|
13040
13816
|
},
|
|
13817
|
+
getLocalCommentCount(includePending = false) {
|
|
13818
|
+
var _a;
|
|
13819
|
+
const engine = PostCommentCountEngine$1.getInstance();
|
|
13820
|
+
// Before any payload has seeded the engine for this post there is no tracker; the
|
|
13821
|
+
// post's own figure is the best answer then.
|
|
13822
|
+
return engine.hasTracker(post.postId)
|
|
13823
|
+
? engine.getLocalCommentCount(post.postId, includePending)
|
|
13824
|
+
: (_a = post.localCommentCount) !== null && _a !== void 0 ? _a : post.commentsCount;
|
|
13825
|
+
},
|
|
13041
13826
|
get targetCommunity() {
|
|
13042
13827
|
var _a;
|
|
13043
13828
|
if (!post.targetId)
|
|
@@ -13402,7 +14187,8 @@ const messageLinkedObject = (message) => {
|
|
|
13402
14187
|
},
|
|
13403
14188
|
get creator() {
|
|
13404
14189
|
var _a;
|
|
13405
|
-
|
|
14190
|
+
const creator = (_a = pullFromCache(['user', 'get', message.creatorId])) === null || _a === void 0 ? void 0 : _a.data;
|
|
14191
|
+
return creator ? userLinkedObject(creator) : undefined;
|
|
13406
14192
|
}, markRead: () => markReadMessage(message), addReaction: (reactionName) => addReactionToMessage(reactionName, message), removeReaction: (reactionName) => removeReactionToMessage(reactionName, message) });
|
|
13407
14193
|
};
|
|
13408
14194
|
|
|
@@ -14063,6 +14849,22 @@ const eventLinkedObject = (event) => {
|
|
|
14063
14849
|
} });
|
|
14064
14850
|
};
|
|
14065
14851
|
|
|
14852
|
+
const curatedContentTopicLinkedObject = (topic) => {
|
|
14853
|
+
return shallowClone(topic, {
|
|
14854
|
+
analytics: {
|
|
14855
|
+
markAsViewed: () => {
|
|
14856
|
+
AnalyticsEngine$1.getInstance().markCuratedContentWidgetAsViewed(topic.topicId);
|
|
14857
|
+
},
|
|
14858
|
+
markPostAsViewed: (postId) => {
|
|
14859
|
+
AnalyticsEngine$1.getInstance().markCuratedContentPostAsViewed(postId, topic.topicId);
|
|
14860
|
+
},
|
|
14861
|
+
markPostClick: (postId) => {
|
|
14862
|
+
AnalyticsEngine$1.getInstance().markCuratedContentPostAsClicked(postId, topic.topicId);
|
|
14863
|
+
},
|
|
14864
|
+
},
|
|
14865
|
+
});
|
|
14866
|
+
};
|
|
14867
|
+
|
|
14066
14868
|
const LinkedObject = {
|
|
14067
14869
|
file: fileLinkedObject,
|
|
14068
14870
|
ad: adLinkedObject,
|
|
@@ -14087,6 +14889,7 @@ const LinkedObject = {
|
|
|
14087
14889
|
eventResponse: eventResponseLinkedObject,
|
|
14088
14890
|
product: productLinkedObject,
|
|
14089
14891
|
poll: pollLinkedObject,
|
|
14892
|
+
curatedContentTopic: curatedContentTopicLinkedObject,
|
|
14090
14893
|
};
|
|
14091
14894
|
|
|
14092
14895
|
/* begin_public_function
|
|
@@ -15409,9 +16212,9 @@ var AmityUserSearchMatchType;
|
|
|
15409
16212
|
AmityUserSearchMatchType["PARTIAL"] = "partial";
|
|
15410
16213
|
})(AmityUserSearchMatchType || (AmityUserSearchMatchType = {}));
|
|
15411
16214
|
|
|
15412
|
-
var index$
|
|
16215
|
+
var index$r = /*#__PURE__*/Object.freeze({
|
|
15413
16216
|
__proto__: null,
|
|
15414
|
-
Relationship: index$
|
|
16217
|
+
Relationship: index$s,
|
|
15415
16218
|
getUserByIds: getUserByIds,
|
|
15416
16219
|
updateUser: updateUser,
|
|
15417
16220
|
flagUser: flagUser,
|
|
@@ -15819,7 +16622,7 @@ const uploadAudio = async (formData, onProgress) => {
|
|
|
15819
16622
|
};
|
|
15820
16623
|
/* end_public_function */
|
|
15821
16624
|
|
|
15822
|
-
var index$
|
|
16625
|
+
var index$q = /*#__PURE__*/Object.freeze({
|
|
15823
16626
|
__proto__: null,
|
|
15824
16627
|
getFile: getFile,
|
|
15825
16628
|
uploadFile: uploadFile,
|
|
@@ -16012,147 +16815,6 @@ getMessage$1.locally = (messageId) => {
|
|
|
16012
16815
|
};
|
|
16013
16816
|
};
|
|
16014
16817
|
|
|
16015
|
-
class ResetTask {
|
|
16016
|
-
constructor(postId, latestCreatedAt, serverCommentCount) {
|
|
16017
|
-
this.postId = postId;
|
|
16018
|
-
this.latestCreatedAt = latestCreatedAt;
|
|
16019
|
-
this.serverCommentCount = serverCommentCount;
|
|
16020
|
-
}
|
|
16021
|
-
}
|
|
16022
|
-
|
|
16023
|
-
// Task to track comment creation
|
|
16024
|
-
class CreateTask {
|
|
16025
|
-
constructor(postId, commentId, createdAt) {
|
|
16026
|
-
this.postId = postId;
|
|
16027
|
-
this.commentId = commentId;
|
|
16028
|
-
this.createdAt = createdAt;
|
|
16029
|
-
}
|
|
16030
|
-
}
|
|
16031
|
-
|
|
16032
|
-
// Task to track comment deletion
|
|
16033
|
-
class DeleteTask {
|
|
16034
|
-
constructor(postId, commentId) {
|
|
16035
|
-
this.postId = postId;
|
|
16036
|
-
this.commentId = commentId;
|
|
16037
|
-
}
|
|
16038
|
-
}
|
|
16039
|
-
|
|
16040
|
-
class CommentChange {
|
|
16041
|
-
constructor(latestCreatedAt, serverCommentCount) {
|
|
16042
|
-
this.latestCommentCreatedAt = latestCreatedAt;
|
|
16043
|
-
this.serverCommentCount = serverCommentCount;
|
|
16044
|
-
this.createdCommentIds = new Set();
|
|
16045
|
-
this.deletedCommentIds = new Set();
|
|
16046
|
-
}
|
|
16047
|
-
}
|
|
16048
|
-
|
|
16049
|
-
class PostCommentCountEngine {
|
|
16050
|
-
constructor() {
|
|
16051
|
-
this.isProcessing = false;
|
|
16052
|
-
this.tasks = [];
|
|
16053
|
-
this.commentChangeTracker = new Map();
|
|
16054
|
-
}
|
|
16055
|
-
queueCommentChangeTask(task) {
|
|
16056
|
-
this.tasks.push(task);
|
|
16057
|
-
if (!this.isProcessing) {
|
|
16058
|
-
this.processCommentChangeTask();
|
|
16059
|
-
}
|
|
16060
|
-
}
|
|
16061
|
-
processCommentChangeTask() {
|
|
16062
|
-
if (this.isProcessing) {
|
|
16063
|
-
return;
|
|
16064
|
-
}
|
|
16065
|
-
this.isProcessing = true;
|
|
16066
|
-
if (this.tasks.length === 0) {
|
|
16067
|
-
this.isProcessing = false;
|
|
16068
|
-
return;
|
|
16069
|
-
}
|
|
16070
|
-
// Process in capped batches, coalescing updates
|
|
16071
|
-
const batch = this.tasks.splice(0, PostCommentCountEngine.BATCH_SIZE);
|
|
16072
|
-
const modifiedPostIds = new Set();
|
|
16073
|
-
batch.forEach(task => {
|
|
16074
|
-
let modified = false;
|
|
16075
|
-
if (task instanceof ResetTask) {
|
|
16076
|
-
modified = this.processResetTaskInternal(task);
|
|
16077
|
-
}
|
|
16078
|
-
else if (task instanceof CreateTask) {
|
|
16079
|
-
modified = this.processCreateTaskInternal(task);
|
|
16080
|
-
}
|
|
16081
|
-
else if (task instanceof DeleteTask) {
|
|
16082
|
-
modified = this.processDeleteTaskInternal(task);
|
|
16083
|
-
}
|
|
16084
|
-
if (modified) {
|
|
16085
|
-
modifiedPostIds.add(task.postId);
|
|
16086
|
-
}
|
|
16087
|
-
});
|
|
16088
|
-
// Publish one update per modified post
|
|
16089
|
-
modifiedPostIds.forEach(postId => {
|
|
16090
|
-
const count = this.computeCommentCount(postId);
|
|
16091
|
-
PostCommentCountEngine.publishUpdate(postId, count);
|
|
16092
|
-
});
|
|
16093
|
-
this.isProcessing = false;
|
|
16094
|
-
// Recurse if more tasks remain
|
|
16095
|
-
if (this.tasks.length > 0) {
|
|
16096
|
-
this.processCommentChangeTask();
|
|
16097
|
-
}
|
|
16098
|
-
}
|
|
16099
|
-
processResetTaskInternal(task) {
|
|
16100
|
-
// Always creates/overwrites tracker
|
|
16101
|
-
this.commentChangeTracker.set(task.postId, new CommentChange(task.latestCreatedAt, task.serverCommentCount));
|
|
16102
|
-
return true;
|
|
16103
|
-
}
|
|
16104
|
-
processCreateTaskInternal(task) {
|
|
16105
|
-
const tracker = this.commentChangeTracker.get(task.postId);
|
|
16106
|
-
if (!tracker)
|
|
16107
|
-
return false; // No tracker, skip
|
|
16108
|
-
if (tracker.createdCommentIds.has(task.commentId))
|
|
16109
|
-
return false; // Deduplication
|
|
16110
|
-
if (task.createdAt <= tracker.latestCommentCreatedAt)
|
|
16111
|
-
return false; // Timestamp filtering
|
|
16112
|
-
tracker.createdCommentIds.add(task.commentId);
|
|
16113
|
-
return true;
|
|
16114
|
-
}
|
|
16115
|
-
processDeleteTaskInternal(task) {
|
|
16116
|
-
const tracker = this.commentChangeTracker.get(task.postId);
|
|
16117
|
-
if (!tracker)
|
|
16118
|
-
return false; // No tracker, skip
|
|
16119
|
-
if (tracker.deletedCommentIds.has(task.commentId))
|
|
16120
|
-
return false; // Deduplication
|
|
16121
|
-
tracker.deletedCommentIds.add(task.commentId);
|
|
16122
|
-
return true;
|
|
16123
|
-
}
|
|
16124
|
-
computeCommentCount(postId) {
|
|
16125
|
-
const tracker = this.commentChangeTracker.get(postId);
|
|
16126
|
-
if (!tracker)
|
|
16127
|
-
return 0;
|
|
16128
|
-
const count = tracker.serverCommentCount + tracker.createdCommentIds.size - tracker.deletedCommentIds.size;
|
|
16129
|
-
return Math.max(0, count);
|
|
16130
|
-
}
|
|
16131
|
-
static publishUpdate(postId, newCount) {
|
|
16132
|
-
var _a;
|
|
16133
|
-
const queryKey = ['post', 'get', postId];
|
|
16134
|
-
mergeInCache(queryKey, {
|
|
16135
|
-
localCommentCount: newCount,
|
|
16136
|
-
});
|
|
16137
|
-
const postPayload = (_a = pullFromCache(queryKey)) === null || _a === void 0 ? void 0 : _a.data;
|
|
16138
|
-
if (!postPayload)
|
|
16139
|
-
return;
|
|
16140
|
-
fireEvent('local.post.updated', {
|
|
16141
|
-
posts: [postPayload],
|
|
16142
|
-
});
|
|
16143
|
-
}
|
|
16144
|
-
}
|
|
16145
|
-
PostCommentCountEngine.BATCH_SIZE = 50;
|
|
16146
|
-
let instance;
|
|
16147
|
-
var PostCommentCountEngine$1 = {
|
|
16148
|
-
getInstance: () => {
|
|
16149
|
-
if (!instance) {
|
|
16150
|
-
instance = new PostCommentCountEngine();
|
|
16151
|
-
}
|
|
16152
|
-
return instance;
|
|
16153
|
-
},
|
|
16154
|
-
};
|
|
16155
|
-
|
|
16156
16818
|
const updateStreamReferences = (streams, streamId, postId) => {
|
|
16157
16819
|
if (!streamId)
|
|
16158
16820
|
return streams;
|
|
@@ -16172,7 +16834,7 @@ const preparePostPayload = (payload) => {
|
|
|
16172
16834
|
let mappedNewStream = [];
|
|
16173
16835
|
// feed type
|
|
16174
16836
|
const posts = postsData.map(post => {
|
|
16175
|
-
var _a, _b, _c
|
|
16837
|
+
var _a, _b, _c;
|
|
16176
16838
|
const feedType = (_a = postPayload.feeds.find(feed => feed.feedId === post.feedId)) === null || _a === void 0 ? void 0 : _a.feedType;
|
|
16177
16839
|
const childPosts = payload.postChildren.filter(children => children.parentPostId === post.postId);
|
|
16178
16840
|
if (childPosts.length > 0 && isAmityLivestreamPost(childPosts[0])) {
|
|
@@ -16191,7 +16853,11 @@ const preparePostPayload = (payload) => {
|
|
|
16191
16853
|
// Queue ResetTask for this post
|
|
16192
16854
|
PostCommentCountEngine$1.getInstance().queueCommentChangeTask(new ResetTask(post.postId, latestCreatedAt, (_c = post.commentsCount) !== null && _c !== void 0 ? _c : 0));
|
|
16193
16855
|
return Object.assign(Object.assign({}, post), { childPosts,
|
|
16194
|
-
feedType,
|
|
16856
|
+
feedType,
|
|
16857
|
+
// The ResetTask above has just seeded the engine, so this is the server figure plus the
|
|
16858
|
+
// author's own pending comments. Reading `post.commentsCount` here instead would overwrite
|
|
16859
|
+
// that +1 in the cache on every refresh, since the ingest that follows merges this object.
|
|
16860
|
+
localCommentCount: PostCommentCountEngine$1.getInstance().getLocalCommentCount(post.postId, true), pinnedProductId: post === null || post === void 0 ? void 0 : post.pinnedProductId });
|
|
16195
16861
|
});
|
|
16196
16862
|
return Object.assign(Object.assign({}, postPayload), { postChildren, videoStreamings: mappedNewStream, posts, communities: communityWithMembershipStatus, communityUsers: mappedCommunityUsers });
|
|
16197
16863
|
};
|
|
@@ -16944,62 +17610,67 @@ const onPostReactionRemoved = (callback) => {
|
|
|
16944
17610
|
return createEventSubscriber(client, 'post.removeReaction', 'post.removeReaction', filter);
|
|
16945
17611
|
};
|
|
16946
17612
|
|
|
17613
|
+
/**
|
|
17614
|
+
* `comment.created` fires while a comment is still pending, so delivery is not visibility. The
|
|
17615
|
+
* two side effects that make a comment public — the parent link that feeds the reply list and
|
|
17616
|
+
* the comment-count task — are gated here; `comment.approved` is the only reveal signal, and a
|
|
17617
|
+
* decline arrives as `comment.deleted`.
|
|
17618
|
+
*/
|
|
17619
|
+
const applyApprovalSideEffects = (event, comment, previous) => {
|
|
17620
|
+
switch (event) {
|
|
17621
|
+
case 'comment.created':
|
|
17622
|
+
if (isCommentPending(comment)) {
|
|
17623
|
+
recordPendingAuthoredComment(comment);
|
|
17624
|
+
}
|
|
17625
|
+
else {
|
|
17626
|
+
linkCommentToParent(comment);
|
|
17627
|
+
applyCommentCreatedCount(comment);
|
|
17628
|
+
}
|
|
17629
|
+
break;
|
|
17630
|
+
case 'comment.approved':
|
|
17631
|
+
linkCommentToParent(comment);
|
|
17632
|
+
applyCommentApprovedCount(comment);
|
|
17633
|
+
break;
|
|
17634
|
+
case 'comment.updated':
|
|
17635
|
+
// An effective edit in a gated community sends an approved comment back for review
|
|
17636
|
+
if (isCommentPending(comment) && previous && isCommentApproved(previous)) {
|
|
17637
|
+
unlinkCommentFromParent(comment);
|
|
17638
|
+
applyCommentReReviewCount(comment);
|
|
17639
|
+
}
|
|
17640
|
+
break;
|
|
17641
|
+
case 'comment.deleted':
|
|
17642
|
+
unlinkCommentFromParent(comment);
|
|
17643
|
+
// A pending comment was never counted, so its deletion (or decline) moves no count
|
|
17644
|
+
if (previous && isCommentPending(previous))
|
|
17645
|
+
releasePendingAuthoredComment(comment);
|
|
17646
|
+
break;
|
|
17647
|
+
}
|
|
17648
|
+
};
|
|
16947
17649
|
const createCommentEventSubscriber = (event, callback) => {
|
|
16948
17650
|
const client = getActiveClient();
|
|
16949
17651
|
const filter = (payload) => {
|
|
16950
|
-
var _a;
|
|
17652
|
+
var _a, _b;
|
|
16951
17653
|
if (!client.cache) {
|
|
16952
17654
|
// TODO: here we are missing specific properties here!
|
|
16953
17655
|
callback(LinkedObject.comment(payload.comments[0]));
|
|
16954
17656
|
}
|
|
16955
17657
|
else {
|
|
16956
|
-
const
|
|
17658
|
+
const flagged = ['comment.flagged', 'comment.unflagged'].includes(event)
|
|
16957
17659
|
? prepareCommentFromFlaggedEvent(payload)
|
|
16958
17660
|
: payload;
|
|
16959
|
-
//
|
|
16960
|
-
|
|
17661
|
+
// Resolve `approvalStatus` before the merge: an absent value means approved and has to
|
|
17662
|
+
// overwrite a cached `pending`, which a plain merge would leave in place.
|
|
17663
|
+
const processed = prepareCommentPayload(flagged);
|
|
16961
17664
|
const { comments } = processed;
|
|
16962
17665
|
if (comments.length > 0) {
|
|
16963
|
-
const
|
|
16964
|
-
|
|
16965
|
-
|
|
16966
|
-
|
|
16967
|
-
|
|
16968
|
-
|
|
16969
|
-
if (comments[0].parentId) {
|
|
16970
|
-
const parentComment = pullFromCache([
|
|
16971
|
-
'comment',
|
|
16972
|
-
'get',
|
|
16973
|
-
comments[0].parentId,
|
|
16974
|
-
]);
|
|
16975
|
-
if (parentComment === null || parentComment === void 0 ? void 0 : parentComment.data) {
|
|
16976
|
-
// Skip to update parent childComment if current comment already exists
|
|
16977
|
-
if (!parentComment.data.children.includes(comments[0].commentId)) {
|
|
16978
|
-
pushToCache(['comment', 'get', comments[0].parentId], Object.assign(Object.assign({}, parentComment.data), { childrenNumber: parentComment.data.childrenNumber + 1, children: [...new Set([...parentComment.data.children, comments[0].commentId])] }));
|
|
16979
|
-
}
|
|
16980
|
-
}
|
|
16981
|
-
}
|
|
16982
|
-
}
|
|
17666
|
+
const commentKey = ['comment', 'get', comments[0].commentId];
|
|
17667
|
+
const previous = (_a = pullFromCache(commentKey)) === null || _a === void 0 ? void 0 : _a.data;
|
|
17668
|
+
// NOTE: The event data should be merge with existing cache rather than replace it
|
|
17669
|
+
ingestInCache(processed, undefined, false);
|
|
17670
|
+
const comment = pullFromCache(commentKey);
|
|
17671
|
+
applyApprovalSideEffects(event, comment.data, previous);
|
|
16983
17672
|
if (['comment.deleted'].includes(event)) {
|
|
16984
|
-
|
|
16985
|
-
const parentComment = pullFromCache([
|
|
16986
|
-
'comment',
|
|
16987
|
-
'get',
|
|
16988
|
-
comments[0].parentId,
|
|
16989
|
-
]);
|
|
16990
|
-
if (parentComment === null || parentComment === void 0 ? void 0 : parentComment.data) {
|
|
16991
|
-
// Remove deleted comment in parent childComment if still exists
|
|
16992
|
-
if (parentComment.data.children.includes(comments[0].commentId)) {
|
|
16993
|
-
const newParentComment = Object.assign(Object.assign({}, parentComment.data), { childrenNumber: parentComment.data.childrenNumber - 1, children: [
|
|
16994
|
-
...new Set([
|
|
16995
|
-
...parentComment.data.children.filter(id => id !== comments[0].commentId),
|
|
16996
|
-
]),
|
|
16997
|
-
] });
|
|
16998
|
-
pushToCache(['comment', 'get', comments[0].parentId], newParentComment);
|
|
16999
|
-
}
|
|
17000
|
-
}
|
|
17001
|
-
}
|
|
17002
|
-
const queries = (_a = queryCache(['comment', 'query'])) === null || _a === void 0 ? void 0 : _a.filter(({ key }) => { var _a; return ((_a = key[2]) === null || _a === void 0 ? void 0 : _a.referenceId) === comment.data.referenceId; });
|
|
17673
|
+
const queries = (_b = queryCache(['comment', 'query'])) === null || _b === void 0 ? void 0 : _b.filter(({ key }) => { var _a; return ((_a = key[2]) === null || _a === void 0 ? void 0 : _a.referenceId) === comment.data.referenceId; });
|
|
17003
17674
|
queries === null || queries === void 0 ? void 0 : queries.map(({ key, data }) => upsertInCache(key, data, { cachedAt: -1 }));
|
|
17004
17675
|
}
|
|
17005
17676
|
callback(LinkedObject.comment(comment.data));
|
|
@@ -17011,13 +17682,13 @@ const createCommentEventSubscriber = (event, callback) => {
|
|
|
17011
17682
|
const createLocalCommentEventSubscriber = (event, callback) => {
|
|
17012
17683
|
const client = getActiveClient();
|
|
17013
17684
|
const filter = (payload) => {
|
|
17014
|
-
var _a, _b, _c, _d
|
|
17685
|
+
var _a, _b, _c, _d;
|
|
17015
17686
|
if (!client.cache) {
|
|
17016
17687
|
// TODO: here we are missing specific properties here!
|
|
17017
17688
|
callback(LinkedObject.comment(payload.comments[0]));
|
|
17018
17689
|
}
|
|
17019
17690
|
else {
|
|
17020
|
-
const processed = payload;
|
|
17691
|
+
const processed = prepareCommentPayload(payload);
|
|
17021
17692
|
ingestInCache(processed);
|
|
17022
17693
|
const { comments } = processed;
|
|
17023
17694
|
if (comments.length > 0) {
|
|
@@ -17026,7 +17697,9 @@ const createLocalCommentEventSubscriber = (event, callback) => {
|
|
|
17026
17697
|
'get',
|
|
17027
17698
|
comments[0].commentId,
|
|
17028
17699
|
]);
|
|
17029
|
-
|
|
17700
|
+
// A pending comment is persisted for its author but never linked into the public
|
|
17701
|
+
// surfaces (parent reply list, post comment list)
|
|
17702
|
+
if (['local.comment.created'].includes(event) && isCommentApproved(comments[0])) {
|
|
17030
17703
|
if (comments[0].parentId) {
|
|
17031
17704
|
const parentComment = pullFromCache([
|
|
17032
17705
|
'comment',
|
|
@@ -17055,11 +17728,11 @@ const createLocalCommentEventSubscriber = (event, callback) => {
|
|
|
17055
17728
|
const postCacheKey = ['post', 'get', comments[0].referenceId];
|
|
17056
17729
|
const postCache = (_a = pullFromCache(postCacheKey)) === null || _a === void 0 ? void 0 : _a.data;
|
|
17057
17730
|
if (postCache) {
|
|
17058
|
-
const updatedPostCache = Object.assign(Object.assign({}, postCache), { comments:
|
|
17731
|
+
const updatedPostCache = Object.assign(Object.assign({}, postCache), { comments: appendLatestCommentId(postCache, comments[0].commentId) });
|
|
17059
17732
|
pushToCache(postCacheKey, updatedPostCache);
|
|
17060
17733
|
}
|
|
17061
17734
|
}
|
|
17062
|
-
const queries = (
|
|
17735
|
+
const queries = (_b = queryCache(['comment', 'query'])) === null || _b === void 0 ? void 0 : _b.filter(({ key }) => { var _a; return ((_a = key[2]) === null || _a === void 0 ? void 0 : _a.referenceId) === comment.data.referenceId; });
|
|
17063
17736
|
queries === null || queries === void 0 ? void 0 : queries.map(({ key, data }) => upsertInCache(key, data, { cachedAt: -1 }));
|
|
17064
17737
|
}
|
|
17065
17738
|
if (['local.comment.deleted'].includes(event)) {
|
|
@@ -17093,13 +17766,13 @@ const createLocalCommentEventSubscriber = (event, callback) => {
|
|
|
17093
17766
|
}
|
|
17094
17767
|
else {
|
|
17095
17768
|
const postCacheKey = ['post', 'get', comments[0].referenceId];
|
|
17096
|
-
const postCache = (
|
|
17769
|
+
const postCache = (_c = pullFromCache(postCacheKey)) === null || _c === void 0 ? void 0 : _c.data;
|
|
17097
17770
|
if (postCache) {
|
|
17098
17771
|
const updatedPost = Object.assign(Object.assign({}, postCache), { comments: postCache === null || postCache === void 0 ? void 0 : postCache.comments.filter(commentId => { var _a; return commentId !== ((_a = comments[0]) === null || _a === void 0 ? void 0 : _a.commentId); }) });
|
|
17099
17772
|
pushToCache(postCacheKey, updatedPost);
|
|
17100
17773
|
}
|
|
17101
17774
|
}
|
|
17102
|
-
const queries = (
|
|
17775
|
+
const queries = (_d = queryCache(['comment', 'query'])) === null || _d === void 0 ? void 0 : _d.filter(({ key }) => { var _a; return ((_a = key[2]) === null || _a === void 0 ? void 0 : _a.referenceId) === comment.data.referenceId; });
|
|
17103
17776
|
queries === null || queries === void 0 ? void 0 : queries.map(({ key, data }) => upsertInCache(key, data, { cachedAt: -1 }));
|
|
17104
17777
|
}
|
|
17105
17778
|
callback(LinkedObject.comment(comment.data));
|
|
@@ -17160,6 +17833,23 @@ const onCommentUpdated = (callback) => createCommentEventSubscriber('comment.upd
|
|
|
17160
17833
|
*/
|
|
17161
17834
|
const onCommentDeleted = (callback) => createCommentEventSubscriber('comment.deleted', callback);
|
|
17162
17835
|
|
|
17836
|
+
/**
|
|
17837
|
+
* ```js
|
|
17838
|
+
* import { onCommentApproved } from '@amityco/ts-sdk'
|
|
17839
|
+
* const dispose = onCommentApproved(comment => {
|
|
17840
|
+
* // ...
|
|
17841
|
+
* })
|
|
17842
|
+
* ```
|
|
17843
|
+
*
|
|
17844
|
+
* Fired when a {@link Amity.InternalComment} held for review has been approved
|
|
17845
|
+
*
|
|
17846
|
+
* @param callback The function to call when the event was fired
|
|
17847
|
+
* @returns an {@link Amity.Unsubscriber} function to stop listening
|
|
17848
|
+
*
|
|
17849
|
+
* @category Comment Events
|
|
17850
|
+
*/
|
|
17851
|
+
const onCommentApproved = (callback) => createCommentEventSubscriber('comment.approved', callback);
|
|
17852
|
+
|
|
17163
17853
|
/**
|
|
17164
17854
|
* ```js
|
|
17165
17855
|
* import { onCommentFlagged } from '@amityco/ts-sdk'
|
|
@@ -17792,7 +18482,7 @@ const getReactions$1 = (params, callback, config) => {
|
|
|
17792
18482
|
};
|
|
17793
18483
|
/* end_public_function */
|
|
17794
18484
|
|
|
17795
|
-
var index$
|
|
18485
|
+
var index$p = /*#__PURE__*/Object.freeze({
|
|
17796
18486
|
__proto__: null,
|
|
17797
18487
|
addReaction: addReaction,
|
|
17798
18488
|
removeReaction: removeReaction,
|
|
@@ -17803,17 +18493,6 @@ var index$o = /*#__PURE__*/Object.freeze({
|
|
|
17803
18493
|
getReactions: getReactions$1
|
|
17804
18494
|
});
|
|
17805
18495
|
|
|
17806
|
-
function prepareCommentPayload(commentPayload) {
|
|
17807
|
-
const { comments } = commentPayload;
|
|
17808
|
-
return Object.assign(Object.assign({}, commentPayload), { comments: comments.map(comment => {
|
|
17809
|
-
if (comment.hasOwnProperty('myReactions'))
|
|
17810
|
-
return comment;
|
|
17811
|
-
// Sometimes `myReactions` field will not come with BE response because that field is empty
|
|
17812
|
-
// We need to put it with an empty array manually to make it show up in client side
|
|
17813
|
-
return Object.assign({ myReactions: [] }, comment);
|
|
17814
|
-
}) });
|
|
17815
|
-
}
|
|
17816
|
-
|
|
17817
18496
|
const createMessageReport = async ({ client, referenceId, }) => {
|
|
17818
18497
|
const { data: payload } = await client.http.post(`/api/v5/messages/${encodeURIComponent(referenceId)}/flags`);
|
|
17819
18498
|
if (client.cache) {
|
|
@@ -18277,20 +18956,20 @@ const getArchivedChannelIds = async () => {
|
|
|
18277
18956
|
|
|
18278
18957
|
/**
|
|
18279
18958
|
* ```js
|
|
18280
|
-
* import {
|
|
18281
|
-
* const dispose =
|
|
18959
|
+
* import { onMessageDeleted } from '@amityco/ts-sdk'
|
|
18960
|
+
* const dispose = onMessageDeleted(message => {
|
|
18282
18961
|
* // ...
|
|
18283
18962
|
* })
|
|
18284
18963
|
* ```
|
|
18285
18964
|
*
|
|
18286
|
-
* Fired when an {@link Amity.Message}
|
|
18965
|
+
* Fired when an {@link Amity.Message} was deleted
|
|
18287
18966
|
*
|
|
18288
18967
|
* @param callback The function to call when the event was fired
|
|
18289
18968
|
* @returns an {@link Amity.Unsubscriber} function to stop listening
|
|
18290
18969
|
*
|
|
18291
18970
|
* @category Message Events
|
|
18292
18971
|
*/
|
|
18293
|
-
const
|
|
18972
|
+
const onMessageDeleted = (callback) => {
|
|
18294
18973
|
const client = getActiveClient();
|
|
18295
18974
|
const filter = async (rawPayload) => {
|
|
18296
18975
|
const payload = await prepareMessagePayload(rawPayload);
|
|
@@ -18298,30 +18977,48 @@ const onMessageUpdated = (callback) => {
|
|
|
18298
18977
|
callback(payload.messages[0]);
|
|
18299
18978
|
};
|
|
18300
18979
|
const disposers = [
|
|
18301
|
-
createEventSubscriber(client, '
|
|
18302
|
-
createEventSubscriber(client, '
|
|
18980
|
+
createEventSubscriber(client, 'message/onMessageDeleted', 'message.deleted', filter),
|
|
18981
|
+
createEventSubscriber(client, 'message/onMessageDeleted', 'local.message.deleted', payload => callback(payload.messages[0])),
|
|
18303
18982
|
];
|
|
18304
18983
|
return () => {
|
|
18305
18984
|
disposers.forEach(fn => fn());
|
|
18306
18985
|
};
|
|
18307
18986
|
};
|
|
18308
18987
|
|
|
18988
|
+
/**
|
|
18989
|
+
* Defensive clear of `channel.pinnedMessage` when the pinned message itself is deleted.
|
|
18990
|
+
*
|
|
18991
|
+
* The server also emits `channel.messageUnpinned` in this case, but realtime events are
|
|
18992
|
+
* fire-and-forget and their order is not guaranteed. Clearing on `message.deleted`
|
|
18993
|
+
* (MQTT or local) makes the banner disappear even if the unpin event is lost; the
|
|
18994
|
+
* server's own `messageUnpinned` then becomes a no-op.
|
|
18995
|
+
*
|
|
18996
|
+
* Internal — wired into the `getChannel` live object; not exported publicly.
|
|
18997
|
+
*/
|
|
18998
|
+
const onChannelPinnedMessageDeleted = (callback) => onMessageDeleted(message => {
|
|
18999
|
+
var _a;
|
|
19000
|
+
const channel = findCachedChannelByAnyId(message.channelId);
|
|
19001
|
+
if (!channel || ((_a = channel.pinnedMessage) === null || _a === void 0 ? void 0 : _a.messageId) !== message.messageId)
|
|
19002
|
+
return;
|
|
19003
|
+
callback(updatePinnedMessageCache(channel, null));
|
|
19004
|
+
});
|
|
19005
|
+
|
|
18309
19006
|
/**
|
|
18310
19007
|
* ```js
|
|
18311
|
-
* import {
|
|
18312
|
-
* const dispose =
|
|
19008
|
+
* import { onMessageUpdated } from '@amityco/ts-sdk'
|
|
19009
|
+
* const dispose = onMessageUpdated(message => {
|
|
18313
19010
|
* // ...
|
|
18314
19011
|
* })
|
|
18315
19012
|
* ```
|
|
18316
19013
|
*
|
|
18317
|
-
* Fired when an {@link Amity.Message}
|
|
19014
|
+
* Fired when an {@link Amity.Message} has been updated
|
|
18318
19015
|
*
|
|
18319
19016
|
* @param callback The function to call when the event was fired
|
|
18320
19017
|
* @returns an {@link Amity.Unsubscriber} function to stop listening
|
|
18321
19018
|
*
|
|
18322
19019
|
* @category Message Events
|
|
18323
19020
|
*/
|
|
18324
|
-
const
|
|
19021
|
+
const onMessageUpdated = (callback) => {
|
|
18325
19022
|
const client = getActiveClient();
|
|
18326
19023
|
const filter = async (rawPayload) => {
|
|
18327
19024
|
const payload = await prepareMessagePayload(rawPayload);
|
|
@@ -18329,8 +19026,8 @@ const onMessageDeleted = (callback) => {
|
|
|
18329
19026
|
callback(payload.messages[0]);
|
|
18330
19027
|
};
|
|
18331
19028
|
const disposers = [
|
|
18332
|
-
createEventSubscriber(client, '
|
|
18333
|
-
createEventSubscriber(client, '
|
|
19029
|
+
createEventSubscriber(client, 'onMessageUpdated', 'message.updated', filter),
|
|
19030
|
+
createEventSubscriber(client, 'onMessageUpdated', 'local.message.updated', payload => callback(payload.messages[0])),
|
|
18334
19031
|
];
|
|
18335
19032
|
return () => {
|
|
18336
19033
|
disposers.forEach(fn => fn());
|
|
@@ -18911,6 +19608,132 @@ softDeleteMessage.optimistically = (messageId) => {
|
|
|
18911
19608
|
};
|
|
18912
19609
|
/* end_public_function */
|
|
18913
19610
|
|
|
19611
|
+
/**
|
|
19612
|
+
* Fire-and-forget refresh of `channelUsers[...].permissions` for the channel a
|
|
19613
|
+
* message belongs to. Used by `pinMessage` / `unpinMessage` on `403` so the next
|
|
19614
|
+
* `hasPermission(PIN_MESSAGE).channel(channelId)` reflects a revoked role
|
|
19615
|
+
* ([`pinMessage` REQ-010](../../@types/../..) / [`unpinMessage` REQ-008](../../@types/../..)).
|
|
19616
|
+
*
|
|
19617
|
+
* The API only receives a `messageId`, so the channel is resolved through the
|
|
19618
|
+
* local cache: first the message row, then any cached channel whose current pin
|
|
19619
|
+
* is that message. When nothing matches the refresh is skipped — the next
|
|
19620
|
+
* channel read picks up the fresh permissions anyway.
|
|
19621
|
+
*/
|
|
19622
|
+
const refreshChannelPermissionsForMessage = (messageId) => {
|
|
19623
|
+
var _a, _b, _c;
|
|
19624
|
+
const cachedMessage = (_a = getMessage$1.locally(messageId)) === null || _a === void 0 ? void 0 : _a.data;
|
|
19625
|
+
let channelId = cachedMessage === null || cachedMessage === void 0 ? void 0 : cachedMessage.channelId;
|
|
19626
|
+
if (!channelId) {
|
|
19627
|
+
channelId = (_c = (_b = queryCache(['channel', 'get'])) === null || _b === void 0 ? void 0 : _b.find(({ data }) => { var _a; return ((_a = data.pinnedMessage) === null || _a === void 0 ? void 0 : _a.messageId) === messageId; })) === null || _c === void 0 ? void 0 : _c.data.channelId;
|
|
19628
|
+
}
|
|
19629
|
+
if (!channelId)
|
|
19630
|
+
return;
|
|
19631
|
+
getChannel$1(channelId).catch(() => {
|
|
19632
|
+
/* silent per spec; UIKit renders no error toast */
|
|
19633
|
+
});
|
|
19634
|
+
};
|
|
19635
|
+
|
|
19636
|
+
/* begin_public_function
|
|
19637
|
+
id: message.pin
|
|
19638
|
+
*/
|
|
19639
|
+
/**
|
|
19640
|
+
* ```js
|
|
19641
|
+
* import { MessageRepository } from '@amityco/ts-sdk'
|
|
19642
|
+
* const channel = await MessageRepository.pinMessage(messageId)
|
|
19643
|
+
* console.log(channel.pinnedMessage)
|
|
19644
|
+
* ```
|
|
19645
|
+
*
|
|
19646
|
+
* Pins a {@link Amity.Message} in its livestream (`live`) channel. A channel holds at
|
|
19647
|
+
* most one pinned message: pinning a different message replaces the current pin in a
|
|
19648
|
+
* single step — no unpin is needed first. Pinning the message that is already pinned is
|
|
19649
|
+
* rejected by the server (400).
|
|
19650
|
+
*
|
|
19651
|
+
* The caller must hold the `PIN_MESSAGE` permission in the channel (or be an admin with
|
|
19652
|
+
* `ModerateChannel`). The server also rejects pinning a deleted message, a message whose
|
|
19653
|
+
* author is banned from the channel or globally banned, and pinning in any channel type
|
|
19654
|
+
* other than `live`. On any error the pin state is left unchanged.
|
|
19655
|
+
*
|
|
19656
|
+
* The response is the affected channel; it is ingested into cache and fires
|
|
19657
|
+
* `local.channel.updated`, so `ChannelRepository.getChannel` observers update without
|
|
19658
|
+
* waiting for the `channel.messagePinned` realtime event.
|
|
19659
|
+
*
|
|
19660
|
+
* @param messageId the **internal** ID of the {@link Amity.Message} to pin
|
|
19661
|
+
* @returns the updated {@link Amity.Channel}, with `pinnedMessage` set
|
|
19662
|
+
*
|
|
19663
|
+
* @category Message API
|
|
19664
|
+
* @async
|
|
19665
|
+
*/
|
|
19666
|
+
const pinMessage = async (messageId) => {
|
|
19667
|
+
const client = getActiveClient();
|
|
19668
|
+
client.log('message/pinMessage', messageId);
|
|
19669
|
+
let payload;
|
|
19670
|
+
try {
|
|
19671
|
+
({ data: payload } = await client.http.post(`/api/v5/messages/${encodeURIComponent(messageId)}/pin`));
|
|
19672
|
+
}
|
|
19673
|
+
catch (error) {
|
|
19674
|
+
if ((error === null || error === void 0 ? void 0 : error.code) === 400301 /* Amity.ServerError.PERMISSION_DENIED */) {
|
|
19675
|
+
refreshChannelPermissionsForMessage(messageId);
|
|
19676
|
+
}
|
|
19677
|
+
throw error;
|
|
19678
|
+
}
|
|
19679
|
+
const data = await prepareChannelPayload(payload);
|
|
19680
|
+
if (client.cache)
|
|
19681
|
+
ingestInCache(data);
|
|
19682
|
+
fireEvent('local.channel.updated', data);
|
|
19683
|
+
return constructChannelObject(data.channels[0]);
|
|
19684
|
+
};
|
|
19685
|
+
/* end_public_function */
|
|
19686
|
+
|
|
19687
|
+
/* begin_public_function
|
|
19688
|
+
id: message.unpin
|
|
19689
|
+
*/
|
|
19690
|
+
/**
|
|
19691
|
+
* ```js
|
|
19692
|
+
* import { MessageRepository } from '@amityco/ts-sdk'
|
|
19693
|
+
* const channel = await MessageRepository.unpinMessage(messageId)
|
|
19694
|
+
* console.log(channel.pinnedMessage) // null
|
|
19695
|
+
* ```
|
|
19696
|
+
*
|
|
19697
|
+
* Removes the pin from a {@link Amity.Message}. `messageId` must be the message that is
|
|
19698
|
+
* **currently** pinned in its channel; otherwise the server answers 400 — this is
|
|
19699
|
+
* deliberate, so a stale client cannot clear a pin that someone else has since replaced.
|
|
19700
|
+
* On that error, re-read the channel (or rely on the `channel.messagePinned` event) to
|
|
19701
|
+
* get the current pin.
|
|
19702
|
+
*
|
|
19703
|
+
* The caller must hold the `PIN_MESSAGE` permission in the channel (or be an admin with
|
|
19704
|
+
* `ModerateChannel`). Unpinning is allowed regardless of channel type and stream state.
|
|
19705
|
+
*
|
|
19706
|
+
* The response is the affected channel; it is ingested into cache and fires
|
|
19707
|
+
* `local.channel.updated`, so `ChannelRepository.getChannel` observers update without
|
|
19708
|
+
* waiting for the `channel.messageUnpinned` realtime event.
|
|
19709
|
+
*
|
|
19710
|
+
* @param messageId the **internal** ID of the currently pinned {@link Amity.Message}
|
|
19711
|
+
* @returns the updated {@link Amity.Channel}, with `pinnedMessage` cleared
|
|
19712
|
+
*
|
|
19713
|
+
* @category Message API
|
|
19714
|
+
* @async
|
|
19715
|
+
*/
|
|
19716
|
+
const unpinMessage = async (messageId) => {
|
|
19717
|
+
const client = getActiveClient();
|
|
19718
|
+
client.log('message/unpinMessage', messageId);
|
|
19719
|
+
let payload;
|
|
19720
|
+
try {
|
|
19721
|
+
({ data: payload } = await client.http.delete(`/api/v5/messages/${encodeURIComponent(messageId)}/pin`));
|
|
19722
|
+
}
|
|
19723
|
+
catch (error) {
|
|
19724
|
+
if ((error === null || error === void 0 ? void 0 : error.code) === 400301 /* Amity.ServerError.PERMISSION_DENIED */) {
|
|
19725
|
+
refreshChannelPermissionsForMessage(messageId);
|
|
19726
|
+
}
|
|
19727
|
+
throw error;
|
|
19728
|
+
}
|
|
19729
|
+
const data = await prepareChannelPayload(payload);
|
|
19730
|
+
if (client.cache)
|
|
19731
|
+
ingestInCache(data);
|
|
19732
|
+
fireEvent('local.channel.updated', data);
|
|
19733
|
+
return constructChannelObject(data.channels[0]);
|
|
19734
|
+
};
|
|
19735
|
+
/* end_public_function */
|
|
19736
|
+
|
|
18914
19737
|
/**
|
|
18915
19738
|
* ```js
|
|
18916
19739
|
* import { MessageRepository } from '@amityco/ts-sdk'
|
|
@@ -19807,13 +20630,15 @@ const searchMessage = (params, callback) => {
|
|
|
19807
20630
|
};
|
|
19808
20631
|
/* end_public_function */
|
|
19809
20632
|
|
|
19810
|
-
var index$
|
|
20633
|
+
var index$o = /*#__PURE__*/Object.freeze({
|
|
19811
20634
|
__proto__: null,
|
|
19812
20635
|
createMessage: createMessage,
|
|
19813
20636
|
updateMessage: updateMessage,
|
|
19814
20637
|
editMessage: editMessage,
|
|
19815
20638
|
deleteMessage: deleteMessage,
|
|
19816
20639
|
softDeleteMessage: softDeleteMessage,
|
|
20640
|
+
pinMessage: pinMessage,
|
|
20641
|
+
unpinMessage: unpinMessage,
|
|
19817
20642
|
markAsDelivered: markAsDelivered,
|
|
19818
20643
|
getReadUsers: getReadUsers,
|
|
19819
20644
|
getDeliveredUsers: getDeliveredUsers,
|
|
@@ -20343,7 +21168,7 @@ const stopMessageReceiptSync = (subChannelId) => {
|
|
|
20343
21168
|
};
|
|
20344
21169
|
/* end_public_function */
|
|
20345
21170
|
|
|
20346
|
-
var index$
|
|
21171
|
+
var index$n = /*#__PURE__*/Object.freeze({
|
|
20347
21172
|
__proto__: null,
|
|
20348
21173
|
getSubChannelByIds: getSubChannels$1,
|
|
20349
21174
|
createSubChannel: createSubChannel,
|
|
@@ -20451,6 +21276,9 @@ const getChannel = (channelId, callback) => {
|
|
|
20451
21276
|
onChannelMemberBanned,
|
|
20452
21277
|
onChannelMemberUnbanned,
|
|
20453
21278
|
onChannelSetMuted,
|
|
21279
|
+
onChannelMessagePinned,
|
|
21280
|
+
onChannelMessageUnpinned,
|
|
21281
|
+
onChannelPinnedMessageDeleted,
|
|
20454
21282
|
convertEventPayload(onChannelMarkerFetched, 'entityId', 'channel'),
|
|
20455
21283
|
convertEventPayload(onChannelMarkerUpdated, 'entityId', 'channel'),
|
|
20456
21284
|
convertEventPayload((callback) => {
|
|
@@ -21076,6 +21904,14 @@ class ChannelLiveCollectionController extends LiveCollectionController {
|
|
|
21076
21904
|
return;
|
|
21077
21905
|
if (messagePreviewSetting ===
|
|
21078
21906
|
"message-preview-not-include-deleted" /* Amity.MessagePreviewSetting.MESSAGE_PREVIEW_NOT_INCLUDE_DELETED */) {
|
|
21907
|
+
// The replacement preview the server sends back is an OLDER
|
|
21908
|
+
// message than the one just deleted, and
|
|
21909
|
+
// updateChannelMessagePreviewCache drops any preview that is not
|
|
21910
|
+
// newer than what is cached — so without clearing the entry
|
|
21911
|
+
// first the refetch is a no-op and the channel keeps showing the
|
|
21912
|
+
// deleted message. getChannel's own live object already does
|
|
21913
|
+
// this; the live collections did not.
|
|
21914
|
+
dropFromCache(['messagePreviewChannel', 'get', message.channelId]);
|
|
21079
21915
|
await getChannel$1(message.channelId);
|
|
21080
21916
|
}
|
|
21081
21917
|
callback(message);
|
|
@@ -21800,6 +22636,14 @@ class SearchChannelLiveCollectionController extends LiveCollectionController {
|
|
|
21800
22636
|
return;
|
|
21801
22637
|
if (messagePreviewSetting ===
|
|
21802
22638
|
"message-preview-not-include-deleted" /* Amity.MessagePreviewSetting.MESSAGE_PREVIEW_NOT_INCLUDE_DELETED */) {
|
|
22639
|
+
// The replacement preview the server sends back is an OLDER
|
|
22640
|
+
// message than the one just deleted, and
|
|
22641
|
+
// updateChannelMessagePreviewCache drops any preview that is not
|
|
22642
|
+
// newer than what is cached — so without clearing the entry
|
|
22643
|
+
// first the refetch is a no-op and the channel keeps showing the
|
|
22644
|
+
// deleted message. getChannel's own live object already does
|
|
22645
|
+
// this; the live collections did not.
|
|
22646
|
+
dropFromCache(['messagePreviewChannel', 'get', message.channelId]);
|
|
21803
22647
|
await getChannel$1(message.channelId);
|
|
21804
22648
|
}
|
|
21805
22649
|
callback(message);
|
|
@@ -22294,7 +23138,7 @@ const searchMembers$1 = (params, callback, config) => {
|
|
|
22294
23138
|
};
|
|
22295
23139
|
/* end_public_function */
|
|
22296
23140
|
|
|
22297
|
-
var index$
|
|
23141
|
+
var index$m = /*#__PURE__*/Object.freeze({
|
|
22298
23142
|
__proto__: null,
|
|
22299
23143
|
addMembers: addMembers$1,
|
|
22300
23144
|
removeMembers: removeMembers$1,
|
|
@@ -22516,7 +23360,7 @@ const unmuteMembers = async (channelId, userIds) => {
|
|
|
22516
23360
|
};
|
|
22517
23361
|
/* end_public_function */
|
|
22518
23362
|
|
|
22519
|
-
var index$
|
|
23363
|
+
var index$l = /*#__PURE__*/Object.freeze({
|
|
22520
23364
|
__proto__: null,
|
|
22521
23365
|
addRole: addRole,
|
|
22522
23366
|
removeRole: removeRole,
|
|
@@ -22526,10 +23370,10 @@ var index$k = /*#__PURE__*/Object.freeze({
|
|
|
22526
23370
|
unmuteMembers: unmuteMembers
|
|
22527
23371
|
});
|
|
22528
23372
|
|
|
22529
|
-
var index$
|
|
23373
|
+
var index$k = /*#__PURE__*/Object.freeze({
|
|
22530
23374
|
__proto__: null,
|
|
22531
|
-
Membership: index$
|
|
22532
|
-
Moderation: index$
|
|
23375
|
+
Membership: index$m,
|
|
23376
|
+
Moderation: index$l,
|
|
22533
23377
|
getChannelByIds: getChannelByIds$1,
|
|
22534
23378
|
createChannel: createChannel,
|
|
22535
23379
|
updateChannel: updateChannel,
|
|
@@ -22547,6 +23391,8 @@ var index$j = /*#__PURE__*/Object.freeze({
|
|
|
22547
23391
|
onChannelJoined: onChannelJoined,
|
|
22548
23392
|
onChannelLeft: onChannelLeft,
|
|
22549
23393
|
onChannelSetMuted: onChannelSetMuted,
|
|
23394
|
+
onChannelMessagePinned: onChannelMessagePinned,
|
|
23395
|
+
onChannelMessageUnpinned: onChannelMessageUnpinned,
|
|
22550
23396
|
onChannelMemberAdded: onChannelMemberAdded,
|
|
22551
23397
|
onChannelMemberRemoved: onChannelMemberRemoved,
|
|
22552
23398
|
onChannelMemberBanned: onChannelMemberBanned,
|
|
@@ -22564,7 +23410,11 @@ var index$j = /*#__PURE__*/Object.freeze({
|
|
|
22564
23410
|
isUnreadCountSupport: isUnreadCountSupport,
|
|
22565
23411
|
convertFromRaw: convertFromRaw,
|
|
22566
23412
|
preUpdateChannelCache: preUpdateChannelCache,
|
|
22567
|
-
prepareChannelPayload: prepareChannelPayload
|
|
23413
|
+
prepareChannelPayload: prepareChannelPayload,
|
|
23414
|
+
findCachedChannelByAnyId: findCachedChannelByAnyId,
|
|
23415
|
+
findCachedChannelForPin: findCachedChannelForPin,
|
|
23416
|
+
updatePinnedMessageCache: updatePinnedMessageCache,
|
|
23417
|
+
applyChannelRolePayload: applyChannelRolePayload
|
|
22568
23418
|
});
|
|
22569
23419
|
|
|
22570
23420
|
const saveCommunityUsers = (communities, communityUsers) => {
|
|
@@ -23958,7 +24808,7 @@ const searchMembers = (params, callback, config) => {
|
|
|
23958
24808
|
};
|
|
23959
24809
|
/* end_public_function */
|
|
23960
24810
|
|
|
23961
|
-
var index$
|
|
24811
|
+
var index$j = /*#__PURE__*/Object.freeze({
|
|
23962
24812
|
__proto__: null,
|
|
23963
24813
|
addMembers: addMembers,
|
|
23964
24814
|
removeMembers: removeMembers,
|
|
@@ -25209,7 +26059,7 @@ const unbanMembers = async (communityId, userIds) => {
|
|
|
25209
26059
|
};
|
|
25210
26060
|
/* end_public_function */
|
|
25211
26061
|
|
|
25212
|
-
var index$
|
|
26062
|
+
var index$i = /*#__PURE__*/Object.freeze({
|
|
25213
26063
|
__proto__: null,
|
|
25214
26064
|
addRoles: addRoles,
|
|
25215
26065
|
removeRoles: removeRoles,
|
|
@@ -25217,10 +26067,10 @@ var index$h = /*#__PURE__*/Object.freeze({
|
|
|
25217
26067
|
unbanMembers: unbanMembers
|
|
25218
26068
|
});
|
|
25219
26069
|
|
|
25220
|
-
var index$
|
|
26070
|
+
var index$h = /*#__PURE__*/Object.freeze({
|
|
25221
26071
|
__proto__: null,
|
|
25222
|
-
Moderation: index$
|
|
25223
|
-
Membership: index$
|
|
26072
|
+
Moderation: index$i,
|
|
26073
|
+
Membership: index$j,
|
|
25224
26074
|
getCommunityByIds: getCommunities$1,
|
|
25225
26075
|
createCommunity: createCommunity,
|
|
25226
26076
|
updateCommunity: updateCommunity,
|
|
@@ -25456,7 +26306,7 @@ const getCategories = (params, callback, config) => {
|
|
|
25456
26306
|
};
|
|
25457
26307
|
/* end_public_function */
|
|
25458
26308
|
|
|
25459
|
-
var index$
|
|
26309
|
+
var index$g = /*#__PURE__*/Object.freeze({
|
|
25460
26310
|
__proto__: null,
|
|
25461
26311
|
getCategory: getCategory,
|
|
25462
26312
|
getCategories: getCategories
|
|
@@ -25755,6 +26605,11 @@ const createCommentOptimistic = (bundle) => {
|
|
|
25755
26605
|
targetType: 'community',
|
|
25756
26606
|
dataType: 'text',
|
|
25757
26607
|
syncState: "syncing" /* Amity.SyncState.Syncing */,
|
|
26608
|
+
// In a gated community the optimistic object stays out of public collections until the
|
|
26609
|
+
// response settles the status; the author's own view still updates through the local event
|
|
26610
|
+
approvalStatus: isCommentApprovalRequired(bundle)
|
|
26611
|
+
? "pending" /* Amity.CommentApprovalStatusEnum.Pending */
|
|
26612
|
+
: "approved" /* Amity.CommentApprovalStatusEnum.Approved */,
|
|
25758
26613
|
};
|
|
25759
26614
|
const cachedAt = UNSYNCED_OBJECT_CACHED_AT_VALUE;
|
|
25760
26615
|
pushToCache(['comment', 'get', comment.commentId], comment, { cachedAt });
|
|
@@ -25771,32 +26626,57 @@ const createCommentOptimistic = (bundle) => {
|
|
|
25771
26626
|
* ```js
|
|
25772
26627
|
* import { CommentRepository } from '@amityco/ts-sdk'
|
|
25773
26628
|
* const newComment = await CommentRepository.createComment(bundle)
|
|
26629
|
+
*
|
|
26630
|
+
* // Server-confirmed only: nothing is shown until the request succeeds
|
|
26631
|
+
* const confirmed = await CommentRepository.createComment(bundle, false)
|
|
25774
26632
|
* ```
|
|
25775
26633
|
*
|
|
25776
26634
|
* Creates an {@link Amity.Comment}
|
|
25777
26635
|
*
|
|
26636
|
+
* With `isOptimistic` (the default) a local comment appears at once with `syncState: 'syncing'`,
|
|
26637
|
+
* moves to `'synced'` when the server confirms it and to `'error'` if the request fails, so the
|
|
26638
|
+
* caller can offer a retry. With `isOptimistic: false` nothing is created locally until the
|
|
26639
|
+
* server answers: on success the comment arrives already `'synced'`; on failure no comment
|
|
26640
|
+
* entity exists anywhere and the promise rejects.
|
|
26641
|
+
*
|
|
25778
26642
|
* @param bundle The data necessary to create a new {@link Amity.Comment}
|
|
26643
|
+
* @param isOptimistic Show a local comment before the server confirms it. Default `true`.
|
|
26644
|
+
* Ignored when the client cache is disabled, since there is nowhere to hold the local comment.
|
|
25779
26645
|
* @returns The newly created {@link Amity.Comment}
|
|
25780
26646
|
*
|
|
25781
26647
|
* @category Comment API
|
|
25782
26648
|
* @async
|
|
25783
26649
|
*/
|
|
25784
|
-
const createComment = async (bundle) => {
|
|
26650
|
+
const createComment = async (bundle, isOptimistic = true) => {
|
|
25785
26651
|
const client = getActiveClient();
|
|
25786
|
-
client.log('comment/createComment', bundle);
|
|
25787
|
-
|
|
26652
|
+
client.log('comment/createComment', Object.assign(Object.assign({}, bundle), { isOptimistic }));
|
|
26653
|
+
// Without a local comment the server assigns the id; with one, the same id travels through the
|
|
26654
|
+
// optimistic object, the response and every realtime event so each step recognises it.
|
|
26655
|
+
const optimisticData = isOptimistic ? createCommentOptimistic(bundle) : undefined;
|
|
25788
26656
|
const commentId = optimisticData === null || optimisticData === void 0 ? void 0 : optimisticData.commentId;
|
|
25789
26657
|
try {
|
|
25790
|
-
const { data } = await client.http.post('/api/v3/comments', Object.assign(Object.assign({}, bundle), { commentId }));
|
|
25791
|
-
const { comments } = data;
|
|
26658
|
+
const { data: payload } = await client.http.post('/api/v3/comments', Object.assign(Object.assign({}, bundle), { commentId }));
|
|
25792
26659
|
// BE always returns an array of comments If it got record 0 from BE it might have a problem on creation logic
|
|
25793
|
-
if (comments.length === 0)
|
|
26660
|
+
if (payload.comments.length === 0)
|
|
25794
26661
|
throw new Error('Comment not created');
|
|
26662
|
+
// Absent `approvalStatus` means approved; the result is the only source of the status.
|
|
26663
|
+
// The confirmed comment is written as `synced` so the cache itself tells the two states apart
|
|
26664
|
+
// (a local-event subscriber is not guaranteed to be listening).
|
|
26665
|
+
const prepared = prepareCommentPayload(payload);
|
|
26666
|
+
const data = Object.assign(Object.assign({}, prepared), { comments: prepared.comments.map(comment => comment.commentId === (commentId !== null && commentId !== void 0 ? commentId : comment.commentId)
|
|
26667
|
+
? Object.assign(Object.assign({}, comment), { syncState: "synced" /* Amity.SyncState.Synced */ }) : comment) });
|
|
26668
|
+
const { comments } = data;
|
|
25795
26669
|
const cachedAt = client.cache && Date.now();
|
|
25796
26670
|
if (client.cache)
|
|
25797
26671
|
ingestInCache(data, { cachedAt });
|
|
25798
26672
|
if (['post', 'content'].includes(bundle.referenceType)) {
|
|
25799
|
-
|
|
26673
|
+
if (isCommentPending(comments[0])) {
|
|
26674
|
+
// Not counted for anyone else until approved; the author sees their own +1
|
|
26675
|
+
recordPendingAuthoredComment(comments[0]);
|
|
26676
|
+
}
|
|
26677
|
+
else {
|
|
26678
|
+
PostCommentCountEngine$1.getInstance().queueCommentChangeTask(new CreateTask(bundle.referenceId, comments[0].commentId, comments[0].createdAt));
|
|
26679
|
+
}
|
|
25800
26680
|
}
|
|
25801
26681
|
else if (bundle.referenceType === 'story') {
|
|
25802
26682
|
const storyIndex = pullFromCache([
|
|
@@ -25817,9 +26697,9 @@ const createComment = async (bundle) => {
|
|
|
25817
26697
|
categories: [],
|
|
25818
26698
|
comments,
|
|
25819
26699
|
communities: [],
|
|
25820
|
-
communityUsers:
|
|
25821
|
-
files:
|
|
25822
|
-
users:
|
|
26700
|
+
communityUsers: payload.communityUsers,
|
|
26701
|
+
files: payload.files,
|
|
26702
|
+
users: payload.users,
|
|
25823
26703
|
});
|
|
25824
26704
|
}
|
|
25825
26705
|
}
|
|
@@ -25827,9 +26707,9 @@ const createComment = async (bundle) => {
|
|
|
25827
26707
|
fireEvent('local.comment.created', {
|
|
25828
26708
|
comments: [Object.assign(Object.assign({}, comments[0]), { syncState: "synced" /* Amity.SyncState.Synced */ })],
|
|
25829
26709
|
commentChildren: data.commentChildren,
|
|
25830
|
-
users:
|
|
25831
|
-
files:
|
|
25832
|
-
communityUsers:
|
|
26710
|
+
users: payload.users,
|
|
26711
|
+
files: payload.files,
|
|
26712
|
+
communityUsers: payload.communityUsers,
|
|
25833
26713
|
});
|
|
25834
26714
|
return {
|
|
25835
26715
|
data: LinkedObject.comment(comments[0]),
|
|
@@ -25837,9 +26717,17 @@ const createComment = async (bundle) => {
|
|
|
25837
26717
|
};
|
|
25838
26718
|
}
|
|
25839
26719
|
catch (e) {
|
|
26720
|
+
// Only a local comment has anything to mark as failed; a server-confirmed-only create leaves
|
|
26721
|
+
// no entity behind
|
|
25840
26722
|
if (optimisticData) {
|
|
26723
|
+
const failed = Object.assign(Object.assign({}, optimisticData), { syncState: "error" /* Amity.SyncState.Error */ });
|
|
26724
|
+
// Write the failure to the cache directly: the local event below only reaches pages that
|
|
26725
|
+
// observe comments, and the caller's retry UI reads the cached state
|
|
26726
|
+
pushToCache(['comment', 'get', failed.commentId], failed, {
|
|
26727
|
+
cachedAt: UNSYNCED_OBJECT_CACHED_AT_VALUE,
|
|
26728
|
+
});
|
|
25841
26729
|
fireEvent('local.comment.created', {
|
|
25842
|
-
comments: [
|
|
26730
|
+
comments: [failed],
|
|
25843
26731
|
commentChildren: [],
|
|
25844
26732
|
users: [],
|
|
25845
26733
|
files: [],
|
|
@@ -25872,16 +26760,26 @@ const createComment = async (bundle) => {
|
|
|
25872
26760
|
* @async
|
|
25873
26761
|
*/
|
|
25874
26762
|
const updateComment = async (commentId, patch) => {
|
|
26763
|
+
var _a;
|
|
25875
26764
|
const client = getActiveClient();
|
|
25876
26765
|
client.log('user/updateComment', patch);
|
|
25877
|
-
const
|
|
26766
|
+
const previous = (_a = pullFromCache(['comment', 'get', commentId])) === null || _a === void 0 ? void 0 : _a.data;
|
|
26767
|
+
const { data: payload } = await client.http.put(`/api/v3/comments/${encodeURIComponent(commentId)}`, patch);
|
|
26768
|
+
const data = prepareCommentPayload(payload);
|
|
26769
|
+
const updated = data.comments.find(comment => comment.commentId === commentId);
|
|
25878
26770
|
const cachedAt = client.cache && Date.now();
|
|
25879
26771
|
if (client.cache)
|
|
25880
26772
|
ingestInCache(data, { cachedAt });
|
|
25881
|
-
|
|
25882
|
-
|
|
26773
|
+
// An effective edit in a gated community sends the comment back for review: it leaves the
|
|
26774
|
+
// public reply list and the public count once. The `comment.updated` event below removes it
|
|
26775
|
+
// from the comment collections; the realtime echo finds it already pending and does nothing.
|
|
26776
|
+
if (isCommentPending(updated) && previous && isCommentApproved(previous)) {
|
|
26777
|
+
unlinkCommentFromParent(updated);
|
|
26778
|
+
applyCommentReReviewCount(updated);
|
|
26779
|
+
}
|
|
26780
|
+
fireEvent('comment.updated', payload);
|
|
25883
26781
|
return {
|
|
25884
|
-
data: LinkedObject.comment(
|
|
26782
|
+
data: LinkedObject.comment(updated),
|
|
25885
26783
|
cachedAt,
|
|
25886
26784
|
};
|
|
25887
26785
|
};
|
|
@@ -26021,7 +26919,13 @@ const deleteComment = async (commentId, permanent = false) => {
|
|
|
26021
26919
|
const post = (_b = pullFromCache(['post', 'get', comment.data.referenceId])) === null || _b === void 0 ? void 0 : _b.data;
|
|
26022
26920
|
if (post) {
|
|
26023
26921
|
const engine = PostCommentCountEngine$1.getInstance();
|
|
26024
|
-
|
|
26922
|
+
if (isCommentPending(comment.data)) {
|
|
26923
|
+
// Never counted for anyone else; only the author's own +1 goes away
|
|
26924
|
+
engine.removePendingAuthoredComment(post.postId, commentId);
|
|
26925
|
+
}
|
|
26926
|
+
else {
|
|
26927
|
+
engine.queueCommentChangeTask(new DeleteTask(post.postId, commentId));
|
|
26928
|
+
}
|
|
26025
26929
|
if (!deleted.parentId && ((_c = deleted.children /* c8 ignore next */) === null || _c === void 0 ? void 0 : _c.length) > 0) {
|
|
26026
26930
|
// NOTE: delete the parent comment will also remove all children comments
|
|
26027
26931
|
deleted.children.forEach((childCommentId) => {
|
|
@@ -26091,6 +26995,109 @@ const hardDeleteComment = async (commentId) => {
|
|
|
26091
26995
|
};
|
|
26092
26996
|
/* end_public_function */
|
|
26093
26997
|
|
|
26998
|
+
/* begin_public_function
|
|
26999
|
+
id: comment.approve
|
|
27000
|
+
*/
|
|
27001
|
+
/**
|
|
27002
|
+
* ```js
|
|
27003
|
+
* import { CommentRepository } from '@amityco/ts-sdk'
|
|
27004
|
+
*
|
|
27005
|
+
* const { data: comment } = await CommentRepository.approveComment('commentId')
|
|
27006
|
+
* ```
|
|
27007
|
+
*
|
|
27008
|
+
* Approves a {@link Amity.Comment} held for review, making it visible to everyone
|
|
27009
|
+
*
|
|
27010
|
+
* @param commentId The {@link Amity.Comment} ID to be approved
|
|
27011
|
+
* @return The {@link Amity.Comment} that was approved
|
|
27012
|
+
*
|
|
27013
|
+
* @category Comment API
|
|
27014
|
+
* @async
|
|
27015
|
+
*/
|
|
27016
|
+
const approveComment = async (commentId) => {
|
|
27017
|
+
const client = getActiveClient();
|
|
27018
|
+
client.log('comment/approveComment', commentId);
|
|
27019
|
+
// No request body, and nothing is revealed before the server confirms
|
|
27020
|
+
const { data: payload } = await client.http.post(`/api/v3/comments/${encodeURIComponent(commentId)}/approve`);
|
|
27021
|
+
const data = prepareCommentPayload(prepareMembershipPayload(payload, 'communityUsers'));
|
|
27022
|
+
const approved = data.comments.find(comment => comment.commentId === commentId);
|
|
27023
|
+
const cachedAt = client.cache && Date.now();
|
|
27024
|
+
if (client.cache)
|
|
27025
|
+
ingestInCache(data, { cachedAt });
|
|
27026
|
+
// The reveal path: parent link and exactly one count task. Applied here so it does not depend
|
|
27027
|
+
// on an observer being open; the event below and the realtime `comment.approved` that follows
|
|
27028
|
+
// find the work done and reconcile by comment id (collection insert, queue removal).
|
|
27029
|
+
linkCommentToParent(approved);
|
|
27030
|
+
applyCommentApprovedCount(approved);
|
|
27031
|
+
fireEvent('comment.approved', payload);
|
|
27032
|
+
return {
|
|
27033
|
+
data: LinkedObject.comment(approved),
|
|
27034
|
+
cachedAt,
|
|
27035
|
+
};
|
|
27036
|
+
};
|
|
27037
|
+
/* end_public_function */
|
|
27038
|
+
|
|
27039
|
+
// Rejected is terminal and implies deleted
|
|
27040
|
+
const markRejected = (comment) => (Object.assign(Object.assign({}, comment), { approvalStatus: "rejected" /* Amity.CommentApprovalStatusEnum.Rejected */, isDeleted: true }));
|
|
27041
|
+
/* begin_public_function
|
|
27042
|
+
id: comment.decline
|
|
27043
|
+
*/
|
|
27044
|
+
/**
|
|
27045
|
+
* ```js
|
|
27046
|
+
* import { CommentRepository } from '@amityco/ts-sdk'
|
|
27047
|
+
*
|
|
27048
|
+
* const { data: comment } = await CommentRepository.declineComment('commentId', 'Off-topic')
|
|
27049
|
+
* ```
|
|
27050
|
+
*
|
|
27051
|
+
* Declines a {@link Amity.Comment} held for review. A declined comment is also a deleted comment
|
|
27052
|
+
*
|
|
27053
|
+
* @param commentId The {@link Amity.Comment} ID to be declined
|
|
27054
|
+
* @param reason Optional reviewer's note, at most 250 characters, kept for the moderation record only
|
|
27055
|
+
* @return The {@link Amity.Comment} that was declined
|
|
27056
|
+
*
|
|
27057
|
+
* @category Comment API
|
|
27058
|
+
* @async
|
|
27059
|
+
*/
|
|
27060
|
+
const declineComment = async (commentId, reason) => {
|
|
27061
|
+
var _a, _b, _c, _d, _e, _f;
|
|
27062
|
+
const client = getActiveClient();
|
|
27063
|
+
client.log('comment/declineComment', commentId, reason);
|
|
27064
|
+
// Read before the request: the fallback when the response carries no comment
|
|
27065
|
+
const cached = (_a = pullFromCache(['comment', 'get', commentId])) === null || _a === void 0 ? void 0 : _a.data;
|
|
27066
|
+
// `reason` is surfaced to nobody; the key is absent from the body when the caller gives none
|
|
27067
|
+
const { data: payload } = await client.http.post(`/api/v3/comments/${encodeURIComponent(commentId)}/decline`, reason ? { reason } : undefined);
|
|
27068
|
+
// The BE contract (PDT-5135 §3) states the response body for approve only; for decline the
|
|
27069
|
+
// standard comment payload is assumed. Ingest whatever came back, and when the body carries no
|
|
27070
|
+
// comment fall back to the cached one so the delete path below still runs.
|
|
27071
|
+
const returned = (_b = payload === null || payload === void 0 ? void 0 : payload.comments) === null || _b === void 0 ? void 0 : _b.some(comment => comment.commentId === commentId);
|
|
27072
|
+
if (!returned && !cached)
|
|
27073
|
+
throw new Error('Comment not found after decline');
|
|
27074
|
+
const comments = returned
|
|
27075
|
+
? payload.comments.map(comment => comment.commentId === commentId ? markRejected(comment) : comment)
|
|
27076
|
+
: [markRejected(cached)];
|
|
27077
|
+
const declined = {
|
|
27078
|
+
comments,
|
|
27079
|
+
commentChildren: (_c = payload === null || payload === void 0 ? void 0 : payload.commentChildren) !== null && _c !== void 0 ? _c : [],
|
|
27080
|
+
users: (_d = payload === null || payload === void 0 ? void 0 : payload.users) !== null && _d !== void 0 ? _d : [],
|
|
27081
|
+
files: (_e = payload === null || payload === void 0 ? void 0 : payload.files) !== null && _e !== void 0 ? _e : [],
|
|
27082
|
+
communityUsers: (_f = payload === null || payload === void 0 ? void 0 : payload.communityUsers) !== null && _f !== void 0 ? _f : [],
|
|
27083
|
+
};
|
|
27084
|
+
// There is no `comment.declined` event: the existing delete path drops the comment from every
|
|
27085
|
+
// collection and the review queue, and moves no count because a pending comment was never counted.
|
|
27086
|
+
const data = prepareCommentPayload(prepareMembershipPayload(declined, 'communityUsers'));
|
|
27087
|
+
const rejected = data.comments.find(comment => comment.commentId === commentId);
|
|
27088
|
+
const cachedAt = client.cache && Date.now();
|
|
27089
|
+
if (client.cache)
|
|
27090
|
+
ingestInCache(data, { cachedAt });
|
|
27091
|
+
unlinkCommentFromParent(rejected);
|
|
27092
|
+
releasePendingAuthoredComment(rejected);
|
|
27093
|
+
fireEvent('comment.deleted', declined);
|
|
27094
|
+
return {
|
|
27095
|
+
data: LinkedObject.comment(rejected),
|
|
27096
|
+
cachedAt,
|
|
27097
|
+
};
|
|
27098
|
+
};
|
|
27099
|
+
/* end_public_function */
|
|
27100
|
+
|
|
26094
27101
|
/* begin_public_function
|
|
26095
27102
|
id: comment.flag
|
|
26096
27103
|
*/
|
|
@@ -26176,6 +27183,7 @@ const isCommentFlaggedByMe = async (commentId) => {
|
|
|
26176
27183
|
/* end_public_function */
|
|
26177
27184
|
|
|
26178
27185
|
const getComment$1 = async (commentId) => {
|
|
27186
|
+
var _a;
|
|
26179
27187
|
const client = getActiveClient();
|
|
26180
27188
|
client.log('comment/getComment', commentId);
|
|
26181
27189
|
isInTombstone('comment', commentId);
|
|
@@ -26186,7 +27194,11 @@ const getComment$1 = async (commentId) => {
|
|
|
26186
27194
|
data = response.data;
|
|
26187
27195
|
}
|
|
26188
27196
|
catch (error) {
|
|
26189
|
-
|
|
27197
|
+
// A pending comment answers 404 to anyone but its author and reviewers. That is a
|
|
27198
|
+
// visibility answer, not a deletion — never tombstone a comment known to be pending.
|
|
27199
|
+
const cached = (_a = pullFromCache(['comment', 'get', commentId])) === null || _a === void 0 ? void 0 : _a.data;
|
|
27200
|
+
const isKnownPending = !!cached && isCommentPending(cached);
|
|
27201
|
+
if (!isKnownPending && checkIfShouldGoesToTombstone(error === null || error === void 0 ? void 0 : error.code)) {
|
|
26190
27202
|
pushToTombstone('comment', commentId);
|
|
26191
27203
|
}
|
|
26192
27204
|
throw error;
|
|
@@ -26313,6 +27325,7 @@ const onLocalCommentReactionRemoved = (callback) => {
|
|
|
26313
27325
|
*/
|
|
26314
27326
|
const getComment = (commentId, callback) => {
|
|
26315
27327
|
return liveObject(commentId, callback, 'commentId', getComment$1, [
|
|
27328
|
+
onCommentApproved,
|
|
26316
27329
|
onCommentDeleteLocal,
|
|
26317
27330
|
onCommentDeleted,
|
|
26318
27331
|
onCommentFlagged,
|
|
@@ -26326,28 +27339,31 @@ const getComment = (commentId, callback) => {
|
|
|
26326
27339
|
};
|
|
26327
27340
|
/* end_public_function */
|
|
26328
27341
|
|
|
26329
|
-
|
|
26330
|
-
|
|
26331
|
-
|
|
26332
|
-
|
|
26333
|
-
|
|
26334
|
-
|
|
26335
|
-
|
|
26336
|
-
|
|
26337
|
-
|
|
26338
|
-
|
|
26339
|
-
|
|
26340
|
-
|
|
26341
|
-
|
|
26342
|
-
|
|
26343
|
-
|
|
26344
|
-
|
|
27342
|
+
/**
|
|
27343
|
+
* ```js
|
|
27344
|
+
* import { onCommentCreated } from '@amityco/ts-sdk'
|
|
27345
|
+
* const dispose = onCommentCreated(comment => {
|
|
27346
|
+
* // ...
|
|
27347
|
+
* })
|
|
27348
|
+
* ```
|
|
27349
|
+
*
|
|
27350
|
+
* Fired when a {@link Amity.InternalComment} has been created
|
|
27351
|
+
*
|
|
27352
|
+
* @param callback The function to call when the event was fired
|
|
27353
|
+
* @returns an {@link Amity.Unsubscriber} function to stop listening
|
|
27354
|
+
*
|
|
27355
|
+
* @category Comment Events
|
|
27356
|
+
*/
|
|
27357
|
+
const onCommentCreatedLocal = (callback) => {
|
|
27358
|
+
return createLocalCommentEventSubscriber('local.comment.created', callback);
|
|
27359
|
+
};
|
|
26345
27360
|
|
|
26346
27361
|
var EnumCommentActions;
|
|
26347
27362
|
(function (EnumCommentActions) {
|
|
26348
27363
|
EnumCommentActions["OnCommentCreated"] = "onCommentCreated";
|
|
26349
27364
|
EnumCommentActions["OnCommentUpdated"] = "onCommentUpdated";
|
|
26350
27365
|
EnumCommentActions["OnCommentDeleted"] = "onCommentDeleted";
|
|
27366
|
+
EnumCommentActions["OnCommentApproved"] = "onCommentApproved";
|
|
26351
27367
|
EnumCommentActions["OnCommentFlagged"] = "onCommentFlagged";
|
|
26352
27368
|
EnumCommentActions["OnCommentUnflagged"] = "onCommentUnflagged";
|
|
26353
27369
|
EnumCommentActions["OnCommentReactionAdded"] = "onCommentReactionAdded";
|
|
@@ -26370,15 +27386,17 @@ class CommentQueryStreamController extends QueryStreamController {
|
|
|
26370
27386
|
}
|
|
26371
27387
|
appendToQueryStream(response, direction, refresh = false) {
|
|
26372
27388
|
var _a, _b;
|
|
27389
|
+
// The public list is approved-only even when the server widens the read for a reviewer
|
|
27390
|
+
const commentIds = response.comments.filter(isCommentApproved).map(getResolver('comment'));
|
|
26373
27391
|
if (refresh) {
|
|
26374
27392
|
pushToCache(this.cacheKey, {
|
|
26375
|
-
data:
|
|
27393
|
+
data: commentIds,
|
|
26376
27394
|
});
|
|
26377
27395
|
}
|
|
26378
27396
|
else {
|
|
26379
27397
|
const collection = (_a = pullFromCache(this.cacheKey)) === null || _a === void 0 ? void 0 : _a.data;
|
|
26380
27398
|
const comments = (_b = collection === null || collection === void 0 ? void 0 : collection.data) !== null && _b !== void 0 ? _b : [];
|
|
26381
|
-
pushToCache(this.cacheKey, Object.assign(Object.assign({}, collection), { data: [...new Set([...comments, ...
|
|
27399
|
+
pushToCache(this.cacheKey, Object.assign(Object.assign({}, collection), { data: [...new Set([...comments, ...commentIds])] }));
|
|
26382
27400
|
}
|
|
26383
27401
|
}
|
|
26384
27402
|
reactor(action) {
|
|
@@ -26397,8 +27415,19 @@ class CommentQueryStreamController extends QueryStreamController {
|
|
|
26397
27415
|
return;
|
|
26398
27416
|
}
|
|
26399
27417
|
if (action === EnumCommentActions.OnCommentCreated) {
|
|
27418
|
+
// A pending comment reaches clients over realtime before anyone may see it: persist
|
|
27419
|
+
// only, no insert and no emit. `comment.approved` is the reveal signal.
|
|
27420
|
+
if (!isCommentApproved(comment))
|
|
27421
|
+
return;
|
|
27422
|
+
collection.data = [...new Set([comment.commentId, ...collection.data])];
|
|
27423
|
+
}
|
|
27424
|
+
if (action === EnumCommentActions.OnCommentApproved) {
|
|
26400
27425
|
collection.data = [...new Set([comment.commentId, ...collection.data])];
|
|
26401
27426
|
}
|
|
27427
|
+
// An effective edit in a gated community returns the comment to review: it leaves the list
|
|
27428
|
+
if (action === EnumCommentActions.OnCommentUpdated && isCommentPending(comment)) {
|
|
27429
|
+
collection.data = collection.data.filter(commentId => commentId !== comment.commentId);
|
|
27430
|
+
}
|
|
26402
27431
|
pushToCache(this.cacheKey, collection);
|
|
26403
27432
|
this.notifyChange({ origin: "event" /* Amity.LiveDataOrigin.EVENT */, loading: false });
|
|
26404
27433
|
};
|
|
@@ -26408,24 +27437,22 @@ class CommentQueryStreamController extends QueryStreamController {
|
|
|
26408
27437
|
}
|
|
26409
27438
|
}
|
|
26410
27439
|
|
|
26411
|
-
|
|
26412
|
-
|
|
26413
|
-
|
|
26414
|
-
|
|
26415
|
-
|
|
26416
|
-
|
|
26417
|
-
|
|
26418
|
-
|
|
26419
|
-
|
|
26420
|
-
|
|
26421
|
-
|
|
26422
|
-
|
|
26423
|
-
|
|
26424
|
-
|
|
26425
|
-
|
|
26426
|
-
|
|
26427
|
-
return createLocalCommentEventSubscriber('local.comment.created', callback);
|
|
26428
|
-
};
|
|
27440
|
+
class CommentPaginationController extends PaginationController {
|
|
27441
|
+
async getRequest(queryParams, token) {
|
|
27442
|
+
var _a;
|
|
27443
|
+
const { pageSize, limit, includeDeleted } = queryParams, params = __rest(queryParams, ["pageSize", "limit", "includeDeleted"]);
|
|
27444
|
+
const effectiveLimit = (_a = pageSize !== null && pageSize !== void 0 ? pageSize : limit) !== null && _a !== void 0 ? _a : COLLECTION_DEFAULT_PAGINATION_LIMIT;
|
|
27445
|
+
const baseOptions = {
|
|
27446
|
+
type: params.sortBy || queryParams.limit || queryParams.pageSize ? 'pagination' : undefined,
|
|
27447
|
+
};
|
|
27448
|
+
const options = token
|
|
27449
|
+
? Object.assign(Object.assign({}, baseOptions), { token }) : Object.assign(Object.assign({}, baseOptions), { pageSize: effectiveLimit, limit: effectiveLimit });
|
|
27450
|
+
const { data: queryResponse } = await this.http.get(`/api/v3/comments`, {
|
|
27451
|
+
params: Object.assign(Object.assign({}, params), { isDeleted: inferIsDeleted(includeDeleted), options }),
|
|
27452
|
+
});
|
|
27453
|
+
return queryResponse;
|
|
27454
|
+
}
|
|
27455
|
+
}
|
|
26429
27456
|
|
|
26430
27457
|
class CommentLiveCollectionController extends LiveCollectionController {
|
|
26431
27458
|
constructor(query, callback) {
|
|
@@ -26461,6 +27488,7 @@ class CommentLiveCollectionController extends LiveCollectionController {
|
|
|
26461
27488
|
{ fn: onCommentCreated, action: EnumCommentActions.OnCommentCreated },
|
|
26462
27489
|
{ fn: onCommentUpdated, action: EnumCommentActions.OnCommentUpdated },
|
|
26463
27490
|
{ fn: onCommentDeleted, action: EnumCommentActions.OnCommentDeleted },
|
|
27491
|
+
{ fn: onCommentApproved, action: EnumCommentActions.OnCommentApproved },
|
|
26464
27492
|
{ fn: onCommentFlagged, action: EnumCommentActions.OnCommentFlagged },
|
|
26465
27493
|
{ fn: onCommentUnflagged, action: EnumCommentActions.OnCommentUnflagged },
|
|
26466
27494
|
{ fn: onCommentReactionAdded, action: EnumCommentActions.OnCommentReactionAdded },
|
|
@@ -26494,7 +27522,8 @@ class CommentLiveCollectionController extends LiveCollectionController {
|
|
|
26494
27522
|
});
|
|
26495
27523
|
}
|
|
26496
27524
|
applyFilter(data) {
|
|
26497
|
-
|
|
27525
|
+
// Approved-only, for every caller including the author of a pending comment
|
|
27526
|
+
let comments = data.filter(isCommentApproved);
|
|
26498
27527
|
if (!this.query.includeDeleted) {
|
|
26499
27528
|
comments = filterByPropEquality(comments, 'isDeleted', false);
|
|
26500
27529
|
}
|
|
@@ -26582,7 +27611,202 @@ const getComments = (params, callback, config) => {
|
|
|
26582
27611
|
};
|
|
26583
27612
|
/* end_public_function */
|
|
26584
27613
|
|
|
26585
|
-
|
|
27614
|
+
class CommentReviewQueuePaginationController extends PaginationController {
|
|
27615
|
+
async getRequest(queryParams, token) {
|
|
27616
|
+
const { communityId, limit } = queryParams, params = __rest(queryParams, ["communityId", "limit"]);
|
|
27617
|
+
// The route defaults to 10, not the SDK-wide 20, and rejects anything above 100
|
|
27618
|
+
const effectiveLimit = Math.min(limit !== null && limit !== void 0 ? limit : COMMENT_REVIEW_QUEUE_DEFAULT_PAGINATION_SIZE, COMMENT_REVIEW_QUEUE_MAX_PAGINATION_SIZE);
|
|
27619
|
+
// Token paging only. The route also accepts options[skip], but offset paging over a queue that
|
|
27620
|
+
// drains from the front skips items, so the SDK never sends it.
|
|
27621
|
+
const options = token ? { token } : { limit: effectiveLimit };
|
|
27622
|
+
const { data: queryResponse } = await this.http.get(API_ENDPOINTS.commentReviewQueue(communityId), {
|
|
27623
|
+
params: Object.assign(Object.assign({}, params), { options }),
|
|
27624
|
+
});
|
|
27625
|
+
return queryResponse;
|
|
27626
|
+
}
|
|
27627
|
+
}
|
|
27628
|
+
|
|
27629
|
+
class CommentReviewQueueQueryStreamController extends QueryStreamController {
|
|
27630
|
+
constructor(query, cacheKey, notifyChange) {
|
|
27631
|
+
super(query, cacheKey);
|
|
27632
|
+
this.notifyChange = notifyChange;
|
|
27633
|
+
}
|
|
27634
|
+
async saveToMainDB(response) {
|
|
27635
|
+
const processedPayload = prepareCommentPayload(response);
|
|
27636
|
+
const client = getActiveClient();
|
|
27637
|
+
const cachedAt = client.cache && Date.now();
|
|
27638
|
+
if (client.cache) {
|
|
27639
|
+
ingestInCache(processedPayload, { cachedAt });
|
|
27640
|
+
}
|
|
27641
|
+
}
|
|
27642
|
+
appendToQueryStream(response, direction, refresh = false) {
|
|
27643
|
+
var _a, _b;
|
|
27644
|
+
// Server order is queue-entry order, oldest first. Keep it: later pages append, nothing
|
|
27645
|
+
// re-sorts by createdAt (the two diverge on re-review).
|
|
27646
|
+
const commentIds = response.comments.map(getResolver('comment'));
|
|
27647
|
+
if (refresh) {
|
|
27648
|
+
pushToCache(this.cacheKey, {
|
|
27649
|
+
data: commentIds,
|
|
27650
|
+
});
|
|
27651
|
+
}
|
|
27652
|
+
else {
|
|
27653
|
+
const collection = (_a = pullFromCache(this.cacheKey)) === null || _a === void 0 ? void 0 : _a.data;
|
|
27654
|
+
const comments = (_b = collection === null || collection === void 0 ? void 0 : collection.data) !== null && _b !== void 0 ? _b : [];
|
|
27655
|
+
pushToCache(this.cacheKey, Object.assign(Object.assign({}, collection), { data: [...new Set([...comments, ...commentIds])] }));
|
|
27656
|
+
}
|
|
27657
|
+
}
|
|
27658
|
+
matchesQuery(comment) {
|
|
27659
|
+
return (comment.targetType === 'community' &&
|
|
27660
|
+
comment.targetId === this.query.communityId &&
|
|
27661
|
+
(!this.query.postId || comment.referenceId === this.query.postId));
|
|
27662
|
+
}
|
|
27663
|
+
reactor(action) {
|
|
27664
|
+
return (comment) => {
|
|
27665
|
+
var _a;
|
|
27666
|
+
const collection = (_a = pullFromCache(this.cacheKey)) === null || _a === void 0 ? void 0 : _a.data;
|
|
27667
|
+
if (!collection || !this.matchesQuery(comment))
|
|
27668
|
+
return;
|
|
27669
|
+
const isQueued = collection.data.includes(comment.commentId);
|
|
27670
|
+
// A date-filtered queue is the server's to shape; live events only remove from it
|
|
27671
|
+
const acceptsLiveInserts = !this.query.startDate && !this.query.endDate;
|
|
27672
|
+
switch (action) {
|
|
27673
|
+
case EnumCommentActions.OnCommentCreated:
|
|
27674
|
+
case EnumCommentActions.OnCommentUpdated:
|
|
27675
|
+
if (isCommentPending(comment) && !comment.isDeleted) {
|
|
27676
|
+
if (isQueued || !acceptsLiveInserts)
|
|
27677
|
+
return;
|
|
27678
|
+
// Enters (or, after an edit, re-enters) the queue at the end
|
|
27679
|
+
collection.data = [...collection.data, comment.commentId];
|
|
27680
|
+
}
|
|
27681
|
+
else {
|
|
27682
|
+
if (!isQueued)
|
|
27683
|
+
return;
|
|
27684
|
+
collection.data = collection.data.filter(commentId => commentId !== comment.commentId);
|
|
27685
|
+
}
|
|
27686
|
+
break;
|
|
27687
|
+
case EnumCommentActions.OnCommentApproved:
|
|
27688
|
+
case EnumCommentActions.OnCommentDeleted:
|
|
27689
|
+
if (!isQueued)
|
|
27690
|
+
return;
|
|
27691
|
+
collection.data = collection.data.filter(commentId => commentId !== comment.commentId);
|
|
27692
|
+
break;
|
|
27693
|
+
default:
|
|
27694
|
+
return;
|
|
27695
|
+
}
|
|
27696
|
+
pushToCache(this.cacheKey, collection);
|
|
27697
|
+
this.notifyChange({ origin: "event" /* Amity.LiveDataOrigin.EVENT */, loading: false });
|
|
27698
|
+
};
|
|
27699
|
+
}
|
|
27700
|
+
subscribeRTE(createSubscriber) {
|
|
27701
|
+
return createSubscriber.map(subscriber => subscriber.fn(this.reactor(subscriber.action)));
|
|
27702
|
+
}
|
|
27703
|
+
}
|
|
27704
|
+
|
|
27705
|
+
class CommentReviewQueueLiveCollectionController extends LiveCollectionController {
|
|
27706
|
+
constructor(query, callback) {
|
|
27707
|
+
const queryStreamId = hash__default["default"](query);
|
|
27708
|
+
const cacheKey = ['commentReviewQueue', 'collection', queryStreamId];
|
|
27709
|
+
const paginationController = new CommentReviewQueuePaginationController(query);
|
|
27710
|
+
super(paginationController, queryStreamId, cacheKey, callback);
|
|
27711
|
+
this.query = query;
|
|
27712
|
+
this.queryStreamController = new CommentReviewQueueQueryStreamController(this.query, this.cacheKey, this.notifyChange.bind(this));
|
|
27713
|
+
this.callback = callback.bind(this);
|
|
27714
|
+
this.loadPage({ initial: true });
|
|
27715
|
+
}
|
|
27716
|
+
setup() {
|
|
27717
|
+
var _a;
|
|
27718
|
+
const collection = (_a = pullFromCache(this.cacheKey)) === null || _a === void 0 ? void 0 : _a.data;
|
|
27719
|
+
if (!collection) {
|
|
27720
|
+
pushToCache(this.cacheKey, {
|
|
27721
|
+
data: [],
|
|
27722
|
+
params: {},
|
|
27723
|
+
});
|
|
27724
|
+
}
|
|
27725
|
+
}
|
|
27726
|
+
async persistModel(queryPayload) {
|
|
27727
|
+
await this.queryStreamController.saveToMainDB(queryPayload);
|
|
27728
|
+
}
|
|
27729
|
+
persistQueryStream({ response, direction, refresh, }) {
|
|
27730
|
+
this.queryStreamController.appendToQueryStream(response, direction, refresh);
|
|
27731
|
+
}
|
|
27732
|
+
startSubscription() {
|
|
27733
|
+
// No `comment.declined` exists: a decline arrives as `comment.deleted`
|
|
27734
|
+
return this.queryStreamController.subscribeRTE([
|
|
27735
|
+
{ fn: onCommentCreated, action: EnumCommentActions.OnCommentCreated },
|
|
27736
|
+
{ fn: onCommentUpdated, action: EnumCommentActions.OnCommentUpdated },
|
|
27737
|
+
{ fn: onCommentApproved, action: EnumCommentActions.OnCommentApproved },
|
|
27738
|
+
{ fn: onCommentDeleted, action: EnumCommentActions.OnCommentDeleted },
|
|
27739
|
+
{ fn: onCommentDeleteLocal, action: EnumCommentActions.OnCommentDeleted },
|
|
27740
|
+
]);
|
|
27741
|
+
}
|
|
27742
|
+
notifyChange({ origin, loading, error }) {
|
|
27743
|
+
var _a;
|
|
27744
|
+
// A caller who lost REVIEW_COMMUNITY_COMMENT must not keep reading stale pending content
|
|
27745
|
+
if ((error === null || error === void 0 ? void 0 : error.code) === 400301 /* Amity.ServerError.PERMISSION_DENIED */) {
|
|
27746
|
+
pushToCache(this.cacheKey, { data: [], params: {} });
|
|
27747
|
+
}
|
|
27748
|
+
const collection = (_a = pullFromCache(this.cacheKey)) === null || _a === void 0 ? void 0 : _a.data;
|
|
27749
|
+
if (!collection)
|
|
27750
|
+
return;
|
|
27751
|
+
const data = collection.data
|
|
27752
|
+
.map(id => pullFromCache(['comment', 'get', id]))
|
|
27753
|
+
.filter(isNonNullable)
|
|
27754
|
+
.map(({ data }) => data)
|
|
27755
|
+
.filter(comment => isCommentPending(comment) && !comment.isDeleted)
|
|
27756
|
+
.map(LinkedObject.comment);
|
|
27757
|
+
if (!this.shouldNotify(data) && origin === 'event')
|
|
27758
|
+
return;
|
|
27759
|
+
this.callback({
|
|
27760
|
+
onNextPage: () => this.loadPage({ direction: "next" /* Amity.LiveCollectionPageDirection.NEXT */ }),
|
|
27761
|
+
data,
|
|
27762
|
+
hasNextPage: !!this.paginationController.getNextToken(),
|
|
27763
|
+
loading,
|
|
27764
|
+
error,
|
|
27765
|
+
});
|
|
27766
|
+
}
|
|
27767
|
+
}
|
|
27768
|
+
|
|
27769
|
+
/* begin_public_function
|
|
27770
|
+
id: comment.review_queue
|
|
27771
|
+
*/
|
|
27772
|
+
/**
|
|
27773
|
+
* ```js
|
|
27774
|
+
* import { CommentRepository } from '@amityco/ts-sdk'
|
|
27775
|
+
*
|
|
27776
|
+
* const unsub = CommentRepository.getCommentReviewQueue(
|
|
27777
|
+
* { communityId: 'communityId' },
|
|
27778
|
+
* ({ data: comments, hasNextPage, onNextPage }) => {
|
|
27779
|
+
* // every comment is awaiting review
|
|
27780
|
+
* },
|
|
27781
|
+
* )
|
|
27782
|
+
* ```
|
|
27783
|
+
*
|
|
27784
|
+
* Observe the {@link Amity.Comment} list awaiting moderator review in a community, oldest first
|
|
27785
|
+
*
|
|
27786
|
+
* @param params the community to read the queue of, optionally narrowed to one post and a date range
|
|
27787
|
+
* @param callback the function to call when new data are available
|
|
27788
|
+
* @returns An {@link Amity.Unsubscriber} function to run when willing to stop observing the queue
|
|
27789
|
+
*
|
|
27790
|
+
* @category Comments Live Collection
|
|
27791
|
+
*/
|
|
27792
|
+
const getCommentReviewQueue = (params, callback) => {
|
|
27793
|
+
const { log, cache } = getActiveClient();
|
|
27794
|
+
if (!cache)
|
|
27795
|
+
console.log(ENABLE_CACHE_MESSAGE);
|
|
27796
|
+
const timestamp = Date.now();
|
|
27797
|
+
log(`getCommentReviewQueue(tmpid: ${timestamp}) > listen`);
|
|
27798
|
+
const commentReviewQueueLiveCollection = new CommentReviewQueueLiveCollectionController(params, callback);
|
|
27799
|
+
const disposers = commentReviewQueueLiveCollection.startSubscription();
|
|
27800
|
+
const cacheKey = commentReviewQueueLiveCollection.getCacheKey();
|
|
27801
|
+
disposers.push(() => dropFromCache(cacheKey));
|
|
27802
|
+
return () => {
|
|
27803
|
+
log(`getCommentReviewQueue(tmpid: ${timestamp}) > dispose`);
|
|
27804
|
+
disposers.forEach(fn => fn());
|
|
27805
|
+
};
|
|
27806
|
+
};
|
|
27807
|
+
/* end_public_function */
|
|
27808
|
+
|
|
27809
|
+
var index$f = /*#__PURE__*/Object.freeze({
|
|
26586
27810
|
__proto__: null,
|
|
26587
27811
|
getCommentByIds: getCommentByIds,
|
|
26588
27812
|
createComment: createComment,
|
|
@@ -26590,18 +27814,22 @@ var index$e = /*#__PURE__*/Object.freeze({
|
|
|
26590
27814
|
deleteComment: deleteComment,
|
|
26591
27815
|
softDeleteComment: softDeleteComment,
|
|
26592
27816
|
hardDeleteComment: hardDeleteComment,
|
|
27817
|
+
approveComment: approveComment,
|
|
27818
|
+
declineComment: declineComment,
|
|
26593
27819
|
flagComment: flagComment,
|
|
26594
27820
|
unflagComment: unflagComment,
|
|
26595
27821
|
isCommentFlaggedByMe: isCommentFlaggedByMe,
|
|
26596
27822
|
onCommentCreated: onCommentCreated,
|
|
26597
27823
|
onCommentUpdated: onCommentUpdated,
|
|
26598
27824
|
onCommentDeleted: onCommentDeleted,
|
|
27825
|
+
onCommentApproved: onCommentApproved,
|
|
26599
27826
|
onCommentFlagged: onCommentFlagged,
|
|
26600
27827
|
onCommentUnflagged: onCommentUnflagged,
|
|
26601
27828
|
onCommentReactionAdded: onCommentReactionAdded,
|
|
26602
27829
|
onCommentReactionRemoved: onCommentReactionRemoved,
|
|
26603
27830
|
getComment: getComment,
|
|
26604
|
-
getComments: getComments
|
|
27831
|
+
getComments: getComments,
|
|
27832
|
+
getCommentReviewQueue: getCommentReviewQueue
|
|
26605
27833
|
});
|
|
26606
27834
|
|
|
26607
27835
|
/**
|
|
@@ -27851,7 +29079,7 @@ const getForYouFeed = (callback) => {
|
|
|
27851
29079
|
};
|
|
27852
29080
|
/* end_public_function */
|
|
27853
29081
|
|
|
27854
|
-
var index$
|
|
29082
|
+
var index$e = /*#__PURE__*/Object.freeze({
|
|
27855
29083
|
__proto__: null,
|
|
27856
29084
|
queryGlobalFeed: queryGlobalFeed,
|
|
27857
29085
|
getCustomRankingGlobalFeed: getCustomRankingGlobalFeed,
|
|
@@ -30996,7 +32224,7 @@ const getRooms = (params, callback, config) => {
|
|
|
30996
32224
|
};
|
|
30997
32225
|
/* end_public_function */
|
|
30998
32226
|
|
|
30999
|
-
var index$
|
|
32227
|
+
var index$d = /*#__PURE__*/Object.freeze({
|
|
31000
32228
|
__proto__: null,
|
|
31001
32229
|
createRoom: createRoom,
|
|
31002
32230
|
updateRoom: updateRoom,
|
|
@@ -31295,7 +32523,7 @@ const getCommunityLiveRoomPosts = (params, callback, config) => {
|
|
|
31295
32523
|
};
|
|
31296
32524
|
/* end_public_function */
|
|
31297
32525
|
|
|
31298
|
-
var index$
|
|
32526
|
+
var index$c = /*#__PURE__*/Object.freeze({
|
|
31299
32527
|
__proto__: null,
|
|
31300
32528
|
getPostByIds: getPostByIds,
|
|
31301
32529
|
createPost: createPost,
|
|
@@ -31910,7 +33138,7 @@ const getStreams = (params, callback, config) => {
|
|
|
31910
33138
|
};
|
|
31911
33139
|
};
|
|
31912
33140
|
|
|
31913
|
-
var index$
|
|
33141
|
+
var index$b = /*#__PURE__*/Object.freeze({
|
|
31914
33142
|
__proto__: null,
|
|
31915
33143
|
createStream: createStream,
|
|
31916
33144
|
updateStream: updateStream,
|
|
@@ -32213,7 +33441,7 @@ const stopHeartbeat = (roomId) => {
|
|
|
32213
33441
|
};
|
|
32214
33442
|
/* end_public_function */
|
|
32215
33443
|
|
|
32216
|
-
var index$
|
|
33444
|
+
var index$a = /*#__PURE__*/Object.freeze({
|
|
32217
33445
|
__proto__: null,
|
|
32218
33446
|
getRoomOnlineUsers: getRoomOnlineUsers,
|
|
32219
33447
|
getRoomUserCount: getRoomUserCount,
|
|
@@ -32524,7 +33752,7 @@ const getPoll = (pollId, callback) => {
|
|
|
32524
33752
|
};
|
|
32525
33753
|
/* end_public_function */
|
|
32526
33754
|
|
|
32527
|
-
var index$
|
|
33755
|
+
var index$9 = /*#__PURE__*/Object.freeze({
|
|
32528
33756
|
__proto__: null,
|
|
32529
33757
|
createPoll: createPoll,
|
|
32530
33758
|
closePoll: closePoll,
|
|
@@ -32828,7 +34056,7 @@ const getPlayer = async (parameters) => {
|
|
|
32828
34056
|
return video;
|
|
32829
34057
|
};
|
|
32830
34058
|
|
|
32831
|
-
var index$
|
|
34059
|
+
var index$8 = /*#__PURE__*/Object.freeze({
|
|
32832
34060
|
__proto__: null,
|
|
32833
34061
|
getPlayer: getPlayer
|
|
32834
34062
|
});
|
|
@@ -34001,7 +35229,7 @@ const getGlobalStoryTargets = (params, callback, config) => {
|
|
|
34001
35229
|
};
|
|
34002
35230
|
};
|
|
34003
35231
|
|
|
34004
|
-
var index$
|
|
35232
|
+
var index$7 = /*#__PURE__*/Object.freeze({
|
|
34005
35233
|
__proto__: null,
|
|
34006
35234
|
createImageStory: createImageStory,
|
|
34007
35235
|
createVideoStory: createVideoStory,
|
|
@@ -34038,7 +35266,7 @@ const getNetworkAds = async () => {
|
|
|
34038
35266
|
};
|
|
34039
35267
|
};
|
|
34040
35268
|
|
|
34041
|
-
var index$
|
|
35269
|
+
var index$6 = /*#__PURE__*/Object.freeze({
|
|
34042
35270
|
__proto__: null,
|
|
34043
35271
|
getNetworkAds: getNetworkAds
|
|
34044
35272
|
});
|
|
@@ -34429,7 +35657,7 @@ const markTraySeen = async (lastSeenAt) => {
|
|
|
34429
35657
|
};
|
|
34430
35658
|
/* end_public_function */
|
|
34431
35659
|
|
|
34432
|
-
var index$
|
|
35660
|
+
var index$5 = /*#__PURE__*/Object.freeze({
|
|
34433
35661
|
__proto__: null,
|
|
34434
35662
|
getNotificationTraySeen: getNotificationTraySeen,
|
|
34435
35663
|
getNotificationTrayItems: getNotificationTrayItems,
|
|
@@ -34731,7 +35959,7 @@ const getInvitations = (params, callback) => {
|
|
|
34731
35959
|
};
|
|
34732
35960
|
};
|
|
34733
35961
|
|
|
34734
|
-
var index$
|
|
35962
|
+
var index$4 = /*#__PURE__*/Object.freeze({
|
|
34735
35963
|
__proto__: null,
|
|
34736
35964
|
cancelInvitation: cancelInvitation,
|
|
34737
35965
|
onLocalInvitationCreated: onLocalInvitationCreated,
|
|
@@ -34880,7 +36108,7 @@ const getReactions = (postId, callback) => {
|
|
|
34880
36108
|
};
|
|
34881
36109
|
};
|
|
34882
36110
|
|
|
34883
|
-
var index$
|
|
36111
|
+
var index$3 = /*#__PURE__*/Object.freeze({
|
|
34884
36112
|
__proto__: null,
|
|
34885
36113
|
createReaction: createReaction,
|
|
34886
36114
|
onLiveReactionCreated: onLiveReactionCreated,
|
|
@@ -35363,7 +36591,7 @@ const getMyEvents = (params, callback, config) => {
|
|
|
35363
36591
|
};
|
|
35364
36592
|
};
|
|
35365
36593
|
|
|
35366
|
-
var index$
|
|
36594
|
+
var index$2 = /*#__PURE__*/Object.freeze({
|
|
35367
36595
|
__proto__: null,
|
|
35368
36596
|
createEvent: createEvent,
|
|
35369
36597
|
updateEvent: updateEvent,
|
|
@@ -35590,12 +36818,36 @@ const searchProducts = (params, callback, config) => {
|
|
|
35590
36818
|
};
|
|
35591
36819
|
/* end_public_function */
|
|
35592
36820
|
|
|
35593
|
-
var index = /*#__PURE__*/Object.freeze({
|
|
36821
|
+
var index$1 = /*#__PURE__*/Object.freeze({
|
|
35594
36822
|
__proto__: null,
|
|
35595
36823
|
getProduct: getProduct,
|
|
35596
36824
|
searchProducts: searchProducts
|
|
35597
36825
|
});
|
|
35598
36826
|
|
|
36827
|
+
const getPool = async (topicId, limit) => {
|
|
36828
|
+
const client = getActiveClient();
|
|
36829
|
+
if (!topicId)
|
|
36830
|
+
throw new ASCError('topicId must not be empty', 800110 /* Amity.ClientError.INVALID_PARAMETERS */, "error" /* Amity.ErrorLevel.ERROR */);
|
|
36831
|
+
if (limit !== undefined && (limit < 1 || limit > 100))
|
|
36832
|
+
throw new ASCError('limit must be between 1 and 100', 800110 /* Amity.ClientError.INVALID_PARAMETERS */, "error" /* Amity.ErrorLevel.ERROR */);
|
|
36833
|
+
const { data } = await client.http.get('/api/v5/curated-content/pool', { params: { topicId, limit } });
|
|
36834
|
+
const { topic } = data, payload = __rest(data, ["topic"]);
|
|
36835
|
+
const processedPayload = preparePostPayload(payload);
|
|
36836
|
+
const cachedAt = client.cache && Date.now();
|
|
36837
|
+
if (client.cache) {
|
|
36838
|
+
ingestInCache(processedPayload, { cachedAt });
|
|
36839
|
+
}
|
|
36840
|
+
return {
|
|
36841
|
+
topic: LinkedObject.curatedContentTopic(topic),
|
|
36842
|
+
posts: processedPayload.posts.map(LinkedObject.post),
|
|
36843
|
+
};
|
|
36844
|
+
};
|
|
36845
|
+
|
|
36846
|
+
var index = /*#__PURE__*/Object.freeze({
|
|
36847
|
+
__proto__: null,
|
|
36848
|
+
getPool: getPool
|
|
36849
|
+
});
|
|
36850
|
+
|
|
35599
36851
|
/**
|
|
35600
36852
|
* Helper class for managing product tags per media attachment.
|
|
35601
36853
|
*
|
|
@@ -35644,39 +36896,40 @@ class AmityAttachmentProductTags {
|
|
|
35644
36896
|
}
|
|
35645
36897
|
|
|
35646
36898
|
exports.API_REGIONS = API_REGIONS;
|
|
35647
|
-
exports.AdRepository = index$
|
|
36899
|
+
exports.AdRepository = index$6;
|
|
35648
36900
|
exports.AmityAttachmentProductTags = AmityAttachmentProductTags;
|
|
35649
|
-
exports.CategoryRepository = index$
|
|
35650
|
-
exports.ChannelRepository = index$
|
|
35651
|
-
exports.Client = index$
|
|
35652
|
-
exports.CommentRepository = index$
|
|
36901
|
+
exports.CategoryRepository = index$g;
|
|
36902
|
+
exports.ChannelRepository = index$k;
|
|
36903
|
+
exports.Client = index$t;
|
|
36904
|
+
exports.CommentRepository = index$f;
|
|
35653
36905
|
exports.CommunityPostSettingMaps = CommunityPostSettingMaps;
|
|
35654
36906
|
exports.CommunityPostSettings = CommunityPostSettings;
|
|
35655
|
-
exports.CommunityRepository = index$
|
|
36907
|
+
exports.CommunityRepository = index$h;
|
|
35656
36908
|
exports.ContentFeedType = ContentFeedType;
|
|
36909
|
+
exports.CuratedContentRepository = index;
|
|
35657
36910
|
exports.DefaultCommunityPostSetting = DefaultCommunityPostSetting;
|
|
35658
|
-
exports.EventRepository = index$
|
|
35659
|
-
exports.FeedRepository = index$
|
|
35660
|
-
exports.FileRepository = index$
|
|
36911
|
+
exports.EventRepository = index$2;
|
|
36912
|
+
exports.FeedRepository = index$e;
|
|
36913
|
+
exports.FileRepository = index$q;
|
|
35661
36914
|
exports.FileType = FileType;
|
|
35662
36915
|
exports.GET_WATCHER_URLS = GET_WATCHER_URLS;
|
|
35663
|
-
exports.InvitationRepository = index$
|
|
35664
|
-
exports.LiveReactionRepository = index$
|
|
35665
|
-
exports.LiveStreamPlayer = index$
|
|
36916
|
+
exports.InvitationRepository = index$4;
|
|
36917
|
+
exports.LiveReactionRepository = index$3;
|
|
36918
|
+
exports.LiveStreamPlayer = index$8;
|
|
35666
36919
|
exports.MessageContentType = MessageContentType;
|
|
35667
|
-
exports.MessageRepository = index$
|
|
35668
|
-
exports.PollRepository = index$
|
|
36920
|
+
exports.MessageRepository = index$o;
|
|
36921
|
+
exports.PollRepository = index$9;
|
|
35669
36922
|
exports.PostContentType = PostContentType;
|
|
35670
|
-
exports.PostRepository = index$
|
|
36923
|
+
exports.PostRepository = index$c;
|
|
35671
36924
|
exports.PostStructureType = PostStructureType;
|
|
35672
|
-
exports.ProductRepository = index;
|
|
35673
|
-
exports.ReactionRepository = index$
|
|
35674
|
-
exports.RoomPresenceRepository = index$
|
|
35675
|
-
exports.RoomRepository = index$
|
|
35676
|
-
exports.StoryRepository = index$
|
|
35677
|
-
exports.StreamRepository = index$
|
|
35678
|
-
exports.SubChannelRepository = index$
|
|
35679
|
-
exports.UserRepository = index$
|
|
36925
|
+
exports.ProductRepository = index$1;
|
|
36926
|
+
exports.ReactionRepository = index$p;
|
|
36927
|
+
exports.RoomPresenceRepository = index$a;
|
|
36928
|
+
exports.RoomRepository = index$d;
|
|
36929
|
+
exports.StoryRepository = index$7;
|
|
36930
|
+
exports.StreamRepository = index$b;
|
|
36931
|
+
exports.SubChannelRepository = index$n;
|
|
36932
|
+
exports.UserRepository = index$r;
|
|
35680
36933
|
exports.VERSION = VERSION;
|
|
35681
36934
|
exports.VideoResolution = VideoResolution;
|
|
35682
36935
|
exports.VideoSize = VideoSize;
|
|
@@ -35738,7 +36991,7 @@ exports.isPaged = isPaged;
|
|
|
35738
36991
|
exports.isReportedByMe = isReportedByMe;
|
|
35739
36992
|
exports.isSkip = isSkip;
|
|
35740
36993
|
exports.mergeInCache = mergeInCache;
|
|
35741
|
-
exports.notificationTray = index$
|
|
36994
|
+
exports.notificationTray = index$5;
|
|
35742
36995
|
exports.onChannelMarkerFetched = onChannelMarkerFetched;
|
|
35743
36996
|
exports.onFeedMarkerFetched = onFeedMarkerFetched;
|
|
35744
36997
|
exports.onFeedMarkerUpdated = onFeedMarkerUpdated;
|