@amityco/ts-sdk-react-native 7.27.1 → 7.28.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/api/createChannel.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 +1743 -478
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.esm.js +1718 -454
- package/dist/index.umd.js +1 -1
- 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.esm.js
CHANGED
|
@@ -3,9 +3,10 @@ import mitt from 'mitt';
|
|
|
3
3
|
import debug from 'debug';
|
|
4
4
|
import axios from 'axios';
|
|
5
5
|
import HttpAgent, { HttpsAgent } from 'agentkeepalive';
|
|
6
|
+
import uuid$1 from 'react-native-uuid';
|
|
6
7
|
import mqtt from 'mqtt';
|
|
8
|
+
import { UAParser } from 'ua-parser-js';
|
|
7
9
|
import AsyncStorage from '@react-native-async-storage/async-storage';
|
|
8
|
-
import uuid$1 from 'react-native-uuid';
|
|
9
10
|
import jwtDecode from 'jwt-decode';
|
|
10
11
|
import { Platform } from 'react-native';
|
|
11
12
|
import hash from 'object-hash';
|
|
@@ -317,8 +318,8 @@ var AmityLiveViewerCountMode;
|
|
|
317
318
|
|
|
318
319
|
function getVersion() {
|
|
319
320
|
try {
|
|
320
|
-
// the string ''v7.
|
|
321
|
-
return 'v7.
|
|
321
|
+
// the string ''v7.28.0-esm'' should be replaced by actual value by @rollup/plugin-replace
|
|
322
|
+
return 'v7.28.0-esm';
|
|
322
323
|
}
|
|
323
324
|
catch (error) {
|
|
324
325
|
return '__dev__';
|
|
@@ -327,6 +328,7 @@ function getVersion() {
|
|
|
327
328
|
const VERSION = getVersion();
|
|
328
329
|
|
|
329
330
|
const COLLECTION_DEFAULT_PAGINATION_LIMIT = 5;
|
|
331
|
+
const LATEST_COMMENTS_LIMIT = 5;
|
|
330
332
|
const COLLECTION_DEFAULT_PAGINATION_SIZE = 20;
|
|
331
333
|
const COLLECTION_DEFAULT_CACHING_POLICY = 'cache_then_server';
|
|
332
334
|
const ENABLE_CACHE_MESSAGE = 'For using Live Collection feature you need to enable Cache!';
|
|
@@ -342,7 +344,11 @@ const YEAR = 365 * DAY;
|
|
|
342
344
|
const ACCESS_TOKEN_WATCHER_INTERVAL = 10 * MINUTE;
|
|
343
345
|
const API_ENDPOINTS = {
|
|
344
346
|
forYouFeed: '/api/v1/feeds/for-you',
|
|
347
|
+
commentReviewQueue: (communityId) => `/api/v3/communities/${encodeURIComponent(communityId)}/comments/review-queue`,
|
|
345
348
|
};
|
|
349
|
+
// The review-queue route defaults to 10, not the SDK-wide page size, and caps at 100
|
|
350
|
+
const COMMENT_REVIEW_QUEUE_DEFAULT_PAGINATION_SIZE = 10;
|
|
351
|
+
const COMMENT_REVIEW_QUEUE_MAX_PAGINATION_SIZE = 100;
|
|
346
352
|
|
|
347
353
|
// cache constants
|
|
348
354
|
const CACHE_KEY_GET = 'get';
|
|
@@ -1951,6 +1957,8 @@ function computeUrl(type, region) {
|
|
|
1951
1957
|
return URLS[type].replace('{region}', region);
|
|
1952
1958
|
}
|
|
1953
1959
|
|
|
1960
|
+
const uuid = () => uuid$1.v4().toString();
|
|
1961
|
+
|
|
1954
1962
|
/**
|
|
1955
1963
|
* Unwraps v3 server payload (for error handling and type extraction)
|
|
1956
1964
|
*
|
|
@@ -1975,6 +1983,24 @@ const unwrapPayload = (response) => {
|
|
|
1975
1983
|
// unjust, but helps force uncast "T | undefined" to allow deconstruction without warnings
|
|
1976
1984
|
return undefined;
|
|
1977
1985
|
};
|
|
1986
|
+
/**
|
|
1987
|
+
* Builds a hex string of `bytes` length from the SDK's uuid helper (a v4 UUID is
|
|
1988
|
+
* 16 bytes / 32 hex chars once hyphens are removed) — avoids a new crypto dependency.
|
|
1989
|
+
*/
|
|
1990
|
+
const randomHex = (bytes) => {
|
|
1991
|
+
let hex = '';
|
|
1992
|
+
while (hex.length < bytes * 2)
|
|
1993
|
+
hex += uuid().replace(/-/g, '');
|
|
1994
|
+
return hex.slice(0, bytes * 2);
|
|
1995
|
+
};
|
|
1996
|
+
/**
|
|
1997
|
+
* W3C Trace Context `traceparent`: `version-<16-byte trace-id>-<8-byte span-id>-<flags>`.
|
|
1998
|
+
* The SDK is the trace originator, so it mints a fresh trace + span id per request; flags `01` = sampled.
|
|
1999
|
+
*
|
|
2000
|
+
* @category Transport
|
|
2001
|
+
* @hidden
|
|
2002
|
+
*/
|
|
2003
|
+
const generateTraceparent = () => `00-${randomHex(16)}-${randomHex(8)}-01`;
|
|
1978
2004
|
|
|
1979
2005
|
class NetworkActivitiesWatcher {
|
|
1980
2006
|
constructor() {
|
|
@@ -2099,6 +2125,10 @@ const createHttpTransport = (endpoint) => {
|
|
|
2099
2125
|
});
|
|
2100
2126
|
instance.defaults.withCredentials = false;
|
|
2101
2127
|
instance.interceptors.request.use(config => {
|
|
2128
|
+
// Request tracing — set on every outbound request (login included), never persisted.
|
|
2129
|
+
// Must run before the session-url early-return below so /api/v5/sessions carries them too.
|
|
2130
|
+
config.headers.set('x-request-id', uuid());
|
|
2131
|
+
config.headers.set('traceparent', generateTraceparent());
|
|
2102
2132
|
// do not check expiration for token creation url
|
|
2103
2133
|
if (config.url === '/api/v5/sessions') {
|
|
2104
2134
|
return config;
|
|
@@ -2142,20 +2172,28 @@ const createHttpTransport = (endpoint) => {
|
|
|
2142
2172
|
});
|
|
2143
2173
|
return response;
|
|
2144
2174
|
}, error => {
|
|
2145
|
-
var _a, _b, _c;
|
|
2175
|
+
var _a, _b, _c, _d;
|
|
2146
2176
|
const { response } = error;
|
|
2147
2177
|
// handle unauthorized request
|
|
2148
2178
|
if ((response === null || response === void 0 ? void 0 : response.data.code) === 400100 /* Amity.ServerError.UNAUTHORIZED */) {
|
|
2149
2179
|
fireEvent('tokenTerminated', "terminated" /* Amity.SessionStates.TERMINATED */);
|
|
2150
2180
|
}
|
|
2181
|
+
// handle globally banned user. The realtime `user.didGlobalBan` event can be missed
|
|
2182
|
+
// (e.g. MQTT dropped before delivery), so mirror the 400100 handling above and fire
|
|
2183
|
+
// the same virtual event the login subscriptions already listen to. That terminates
|
|
2184
|
+
// the session with `TokenTerminationReason.GLOBAL_BAN` and notifies `onClientBanned`
|
|
2185
|
+
// consumers, instead of leaving the session `established` with a revoked token.
|
|
2186
|
+
if (((_a = response === null || response === void 0 ? void 0 : response.data) === null || _a === void 0 ? void 0 : _a.code) === 400312 /* Amity.ServerError.GLOBAL_BAN */) {
|
|
2187
|
+
fireEvent('user.didGlobalBan', { users: [], files: [] });
|
|
2188
|
+
}
|
|
2151
2189
|
// handle visitor daily usage limit exceeded
|
|
2152
|
-
if (((
|
|
2190
|
+
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 */) {
|
|
2153
2191
|
throttledFireVisitorUsageLimit();
|
|
2154
2192
|
throw new ASCError('Visitor usage limit exceeded', 400323 /* Amity.ServerError.VISITOR_USAGE_LIMIT_EXCEEDED */, "error" /* Amity.ErrorLevel.ERROR */);
|
|
2155
2193
|
}
|
|
2156
2194
|
// if it's an error with status in the response payload,
|
|
2157
2195
|
// then it's an expected error.
|
|
2158
|
-
if ((
|
|
2196
|
+
if ((_c = response === null || response === void 0 ? void 0 : response.data) === null || _c === void 0 ? void 0 : _c.status) {
|
|
2159
2197
|
unwrapPayload(response === null || response === void 0 ? void 0 : response.data);
|
|
2160
2198
|
}
|
|
2161
2199
|
// as on request cancellation error is returned
|
|
@@ -2163,7 +2201,7 @@ const createHttpTransport = (endpoint) => {
|
|
|
2163
2201
|
throw error;
|
|
2164
2202
|
}
|
|
2165
2203
|
// unexpected error.
|
|
2166
|
-
throw new Error((
|
|
2204
|
+
throw new Error((_d = response === null || response === void 0 ? void 0 : response.data) !== null && _d !== void 0 ? _d : error);
|
|
2167
2205
|
});
|
|
2168
2206
|
instance.defaults.paramsSerializer = {
|
|
2169
2207
|
encode: params => encodeURIComponent(params),
|
|
@@ -2369,8 +2407,6 @@ const getItem = async (key) => {
|
|
|
2369
2407
|
});
|
|
2370
2408
|
};
|
|
2371
2409
|
|
|
2372
|
-
const uuid = () => uuid$1.v4().toString();
|
|
2373
|
-
|
|
2374
2410
|
// TODO: find a way to uniquely identify the device
|
|
2375
2411
|
let tabIndex = 0;
|
|
2376
2412
|
// This logic is running on browser only
|
|
@@ -2430,22 +2466,60 @@ const getMQTTClientId = async (userId) => {
|
|
|
2430
2466
|
};
|
|
2431
2467
|
/** @hidden */
|
|
2432
2468
|
const getDeviceModel = () => {
|
|
2433
|
-
var _a
|
|
2469
|
+
var _a;
|
|
2434
2470
|
if ((_a = safeProcess.versions) === null || _a === void 0 ? void 0 : _a.node)
|
|
2435
2471
|
return safeProcess.versions.node;
|
|
2436
|
-
|
|
2437
|
-
|
|
2438
|
-
|
|
2472
|
+
return undefined;
|
|
2473
|
+
};
|
|
2474
|
+
const hasNavigator = () => typeof navigator !== 'undefined' && !!navigator;
|
|
2475
|
+
const getLocale = () => (hasNavigator() ? navigator.language : undefined);
|
|
2476
|
+
const getTimezone = () => {
|
|
2477
|
+
try {
|
|
2478
|
+
return Intl.DateTimeFormat().resolvedOptions().timeZone;
|
|
2479
|
+
}
|
|
2480
|
+
catch (_a) {
|
|
2481
|
+
return undefined;
|
|
2482
|
+
}
|
|
2483
|
+
};
|
|
2484
|
+
const getNetworkType = () => {
|
|
2485
|
+
var _a;
|
|
2486
|
+
if (!hasNavigator())
|
|
2487
|
+
return undefined;
|
|
2488
|
+
return (_a = navigator.connection) === null || _a === void 0 ? void 0 : _a.effectiveType;
|
|
2489
|
+
};
|
|
2490
|
+
const isNode = () => { var _a; return !!((_a = safeProcess.versions) === null || _a === void 0 ? void 0 : _a.node); };
|
|
2491
|
+
const parseUserAgent = () => {
|
|
2492
|
+
if (!hasNavigator() || !navigator.userAgent)
|
|
2493
|
+
return {};
|
|
2494
|
+
const { os, browser, device } = new UAParser(navigator.userAgent).getResult();
|
|
2495
|
+
const result = {};
|
|
2496
|
+
if (os.name)
|
|
2497
|
+
result.osName = os.name;
|
|
2498
|
+
if (os.version)
|
|
2499
|
+
result.osVersion = os.version;
|
|
2500
|
+
if (browser.name)
|
|
2501
|
+
result.browserName = browser.name;
|
|
2502
|
+
if (browser.version)
|
|
2503
|
+
result.browserVersion = browser.version;
|
|
2504
|
+
if (device.type === 'tablet')
|
|
2505
|
+
result.deviceType = 'tablet';
|
|
2506
|
+
else if (device.type === 'mobile')
|
|
2507
|
+
result.deviceType = 'mobile';
|
|
2508
|
+
else
|
|
2509
|
+
result.deviceType = 'desktop';
|
|
2510
|
+
return result;
|
|
2439
2511
|
};
|
|
2440
2512
|
/** @hidden */
|
|
2441
2513
|
const getDeviceInfo = () => {
|
|
2442
|
-
|
|
2443
|
-
|
|
2444
|
-
|
|
2445
|
-
|
|
2446
|
-
|
|
2447
|
-
|
|
2448
|
-
|
|
2514
|
+
var _a;
|
|
2515
|
+
let client;
|
|
2516
|
+
try {
|
|
2517
|
+
client = getActiveClient();
|
|
2518
|
+
}
|
|
2519
|
+
catch (_b) {
|
|
2520
|
+
client = undefined;
|
|
2521
|
+
}
|
|
2522
|
+
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());
|
|
2449
2523
|
};
|
|
2450
2524
|
|
|
2451
2525
|
/* eslint-disable no-console */
|
|
@@ -3902,6 +3976,95 @@ const prepareChannelPayload = async (rawPayload, options = { isMessagePreviewUpd
|
|
|
3902
3976
|
channelUsers });
|
|
3903
3977
|
};
|
|
3904
3978
|
|
|
3979
|
+
const channelCacheKey = (channel) => [
|
|
3980
|
+
'channel',
|
|
3981
|
+
'get',
|
|
3982
|
+
getResolver('channel')(channel),
|
|
3983
|
+
];
|
|
3984
|
+
/**
|
|
3985
|
+
* Find a cached channel by any of its ids (internal, public, or `channelId`).
|
|
3986
|
+
*
|
|
3987
|
+
* The channel cache is keyed by the channel internal id (see `idResolvers.channel`), but
|
|
3988
|
+
* realtime payloads reference channels by different ids: pin events carry the **public**
|
|
3989
|
+
* id, messages carry `channelId`. Try the cheap direct lookup first, then scan.
|
|
3990
|
+
*/
|
|
3991
|
+
const findCachedChannelByAnyId = (id) => {
|
|
3992
|
+
var _a, _b, _c;
|
|
3993
|
+
if (!id)
|
|
3994
|
+
return undefined;
|
|
3995
|
+
const direct = (_a = pullFromCache(['channel', 'get', id])) === null || _a === void 0 ? void 0 : _a.data;
|
|
3996
|
+
if (direct)
|
|
3997
|
+
return direct;
|
|
3998
|
+
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;
|
|
3999
|
+
};
|
|
4000
|
+
/**
|
|
4001
|
+
* Resolve the cached channel a `channel.messagePinned` / `channel.messageUnpinned` event
|
|
4002
|
+
* refers to. `data.channelId` is the channel public id; a pinned message body (present on
|
|
4003
|
+
* `messagePinned` only) also carries the internal id, which is the direct cache key.
|
|
4004
|
+
*/
|
|
4005
|
+
const findCachedChannelForPin = (payload) => {
|
|
4006
|
+
var _a, _b;
|
|
4007
|
+
return (_b = findCachedChannelByAnyId((_a = payload.pinnedMessage) === null || _a === void 0 ? void 0 : _a.channelId)) !== null && _b !== void 0 ? _b : findCachedChannelByAnyId(payload.channelId);
|
|
4008
|
+
};
|
|
4009
|
+
/**
|
|
4010
|
+
* Write a new pin snapshot (or `null` to clear) on a cached channel and ingest any
|
|
4011
|
+
* users delivered with it (the pin author and the message author), so the banner can
|
|
4012
|
+
* render a byline without a second fetch.
|
|
4013
|
+
*
|
|
4014
|
+
* Every `messagePinned` payload is a full snapshot — "this is the pin now" — so the last
|
|
4015
|
+
* one received always wins; there is no merging with the previous pin.
|
|
4016
|
+
*/
|
|
4017
|
+
const updatePinnedMessageCache = (channel, pinnedMessage, users) => {
|
|
4018
|
+
if (users && users.length > 0) {
|
|
4019
|
+
ingestInCache({ users: users.map(convertRawUserToInternalUser) });
|
|
4020
|
+
}
|
|
4021
|
+
const updated = Object.assign(Object.assign({}, channel), { pinnedMessage });
|
|
4022
|
+
pushToCache(channelCacheKey(channel), updated);
|
|
4023
|
+
return updated;
|
|
4024
|
+
};
|
|
4025
|
+
|
|
4026
|
+
/**
|
|
4027
|
+
* Applies a `channel.roleAdded` / `channel.roleRemoved` realtime payload to the cache.
|
|
4028
|
+
*
|
|
4029
|
+
* The event names every member the role request affected together with the
|
|
4030
|
+
* roles and channel-scoped permissions each of them is left holding. That is a
|
|
4031
|
+
* full state, not a delta, so it is written straight over the cached membership.
|
|
4032
|
+
*
|
|
4033
|
+
* Members the SDK has not fetched yet are skipped: the payload does not carry
|
|
4034
|
+
* enough to build a full {@link Amity.Membership} and the live collections only
|
|
4035
|
+
* emit rows that already exist in cache.
|
|
4036
|
+
*
|
|
4037
|
+
* @param payload the `data` of the realtime event
|
|
4038
|
+
* @returns the refreshed channel (when resolvable) and the updated cached memberships
|
|
4039
|
+
*
|
|
4040
|
+
* @hidden
|
|
4041
|
+
*/
|
|
4042
|
+
const applyChannelRolePayload = (payload) => {
|
|
4043
|
+
var _a, _b, _c;
|
|
4044
|
+
const { channelId, users = [], channels = [] } = payload;
|
|
4045
|
+
const rawChannel = (_a = channels.find(channel => channel.channelId === channelId)) !== null && _a !== void 0 ? _a : channels[0];
|
|
4046
|
+
let channel;
|
|
4047
|
+
if (rawChannel) {
|
|
4048
|
+
const channelKey = ['channel', 'get', getResolver('channel')(rawChannel)];
|
|
4049
|
+
// the role event does not touch message previews, keep whatever preview is cached
|
|
4050
|
+
const converted = convertFromRaw(rawChannel, { isMessagePreviewUpdated: false });
|
|
4051
|
+
upsertInCache(channelKey, converted);
|
|
4052
|
+
channel = (_c = (_b = pullFromCache(channelKey)) === null || _b === void 0 ? void 0 : _b.data) !== null && _c !== void 0 ? _c : converted;
|
|
4053
|
+
}
|
|
4054
|
+
const members = [];
|
|
4055
|
+
users.forEach(({ userId, roles, permissions }) => {
|
|
4056
|
+
var _a, _b, _c;
|
|
4057
|
+
const memberKey = ['channelUsers', 'get', getResolver('channelUsers')({ channelId, userId })];
|
|
4058
|
+
const cached = (_a = pullFromCache(memberKey)) === null || _a === void 0 ? void 0 : _a.data;
|
|
4059
|
+
if (!cached)
|
|
4060
|
+
return;
|
|
4061
|
+
const updated = Object.assign(Object.assign({}, cached), { roles, permissions });
|
|
4062
|
+
pushToCache(memberKey, updated);
|
|
4063
|
+
members.push((_c = (_b = pullFromCache(memberKey)) === null || _b === void 0 ? void 0 : _b.data) !== null && _c !== void 0 ? _c : updated);
|
|
4064
|
+
});
|
|
4065
|
+
return { channel, members };
|
|
4066
|
+
};
|
|
4067
|
+
|
|
3905
4068
|
/**
|
|
3906
4069
|
* ```js
|
|
3907
4070
|
* import { getSubChannelMarkers } from '@amityco/ts-sdk-react-native'
|
|
@@ -4087,32 +4250,6 @@ const channelMemberLinkedObject = (channelMember) => {
|
|
|
4087
4250
|
} });
|
|
4088
4251
|
};
|
|
4089
4252
|
|
|
4090
|
-
/**
|
|
4091
|
-
*
|
|
4092
|
-
* get current user's membership data
|
|
4093
|
-
*
|
|
4094
|
-
* @returns the {@link Amity.Membership<'channel'>} objects
|
|
4095
|
-
*
|
|
4096
|
-
* @category Channel API
|
|
4097
|
-
* @async
|
|
4098
|
-
*/
|
|
4099
|
-
const getMyMembership$1 = (channelId) => {
|
|
4100
|
-
const client = getActiveClient();
|
|
4101
|
-
client.log('channel/getMyMembership.locally');
|
|
4102
|
-
const cacheChannelUser = pullFromCache([
|
|
4103
|
-
'channelUsers',
|
|
4104
|
-
'get',
|
|
4105
|
-
`${channelId}#${client.userId}`,
|
|
4106
|
-
]);
|
|
4107
|
-
if (!cacheChannelUser) {
|
|
4108
|
-
throw new ASCApiError('Item not found!', 400400 /* Amity.ServerError.ITEM_NOT_FOUND */, "error" /* Amity.ErrorLevel.ERROR */);
|
|
4109
|
-
}
|
|
4110
|
-
return {
|
|
4111
|
-
data: cacheChannelUser.data,
|
|
4112
|
-
cachedAt: cacheChannelUser.cachedAt,
|
|
4113
|
-
};
|
|
4114
|
-
};
|
|
4115
|
-
|
|
4116
4253
|
/**
|
|
4117
4254
|
* ```js
|
|
4118
4255
|
* import { isEqual } from '~/utils/isEqual'
|
|
@@ -4183,55 +4320,81 @@ function isEqual(x, y) {
|
|
|
4183
4320
|
}));
|
|
4184
4321
|
}
|
|
4185
4322
|
|
|
4186
|
-
|
|
4323
|
+
/**
|
|
4324
|
+
*
|
|
4325
|
+
* get current user's membership data
|
|
4326
|
+
*
|
|
4327
|
+
* @returns the {@link Amity.Membership<'channel'>} objects
|
|
4328
|
+
*
|
|
4329
|
+
* @category Channel API
|
|
4330
|
+
* @async
|
|
4331
|
+
*/
|
|
4332
|
+
const getMyMembership$1 = (channelId) => {
|
|
4333
|
+
const client = getActiveClient();
|
|
4334
|
+
client.log('channel/getMyMembership.locally');
|
|
4335
|
+
const cacheChannelUser = pullFromCache([
|
|
4336
|
+
'channelUsers',
|
|
4337
|
+
'get',
|
|
4338
|
+
`${channelId}#${client.userId}`,
|
|
4339
|
+
]);
|
|
4340
|
+
if (!cacheChannelUser) {
|
|
4341
|
+
throw new ASCApiError('Item not found!', 400400 /* Amity.ServerError.ITEM_NOT_FOUND */, "error" /* Amity.ErrorLevel.ERROR */);
|
|
4342
|
+
}
|
|
4343
|
+
return {
|
|
4344
|
+
data: cacheChannelUser.data,
|
|
4345
|
+
cachedAt: cacheChannelUser.cachedAt,
|
|
4346
|
+
};
|
|
4347
|
+
};
|
|
4348
|
+
|
|
4349
|
+
const callbacks$e = [];
|
|
4187
4350
|
let mainDisposer$b = null;
|
|
4188
|
-
const dispose$
|
|
4189
|
-
const index = callbacks$
|
|
4351
|
+
const dispose$e = (cb) => {
|
|
4352
|
+
const index = callbacks$e.indexOf(cb);
|
|
4190
4353
|
if (index > -1) {
|
|
4191
|
-
callbacks$
|
|
4354
|
+
callbacks$e.splice(index, 1);
|
|
4192
4355
|
}
|
|
4193
|
-
if (callbacks$
|
|
4356
|
+
if (callbacks$e.length === 0) {
|
|
4194
4357
|
mainDisposer$b === null || mainDisposer$b === void 0 ? void 0 : mainDisposer$b();
|
|
4195
4358
|
}
|
|
4196
4359
|
};
|
|
4197
4360
|
const onChannelCreated = (callback) => {
|
|
4198
|
-
if (callbacks$
|
|
4361
|
+
if (callbacks$e.length === 0) {
|
|
4199
4362
|
const client = getActiveClient();
|
|
4200
4363
|
const filter = async (payload) => {
|
|
4201
4364
|
const data = await prepareChannelPayload(payload);
|
|
4202
4365
|
ingestInCache(data);
|
|
4203
|
-
callbacks$
|
|
4366
|
+
callbacks$e.forEach(cb => cb(data.channels[0]));
|
|
4204
4367
|
};
|
|
4205
4368
|
mainDisposer$b = createEventSubscriber(client, 'onChannelCreated', 'channel.created', filter);
|
|
4206
4369
|
}
|
|
4207
|
-
callbacks$
|
|
4208
|
-
return () => dispose$
|
|
4370
|
+
callbacks$e.push(callback);
|
|
4371
|
+
return () => dispose$e(callback);
|
|
4209
4372
|
};
|
|
4210
4373
|
|
|
4211
|
-
const callbacks$
|
|
4212
|
-
const mainDisposers = [];
|
|
4213
|
-
const dispose$
|
|
4214
|
-
const index = callbacks$
|
|
4374
|
+
const callbacks$d = [];
|
|
4375
|
+
const mainDisposers$2 = [];
|
|
4376
|
+
const dispose$d = (cb) => {
|
|
4377
|
+
const index = callbacks$d.indexOf(cb);
|
|
4215
4378
|
if (index > -1) {
|
|
4216
|
-
callbacks$
|
|
4379
|
+
callbacks$d.splice(index, 1);
|
|
4217
4380
|
}
|
|
4218
|
-
if (callbacks$
|
|
4219
|
-
mainDisposers.forEach(fn => fn());
|
|
4381
|
+
if (callbacks$d.length === 0) {
|
|
4382
|
+
mainDisposers$2.forEach(fn => fn());
|
|
4220
4383
|
}
|
|
4221
4384
|
};
|
|
4222
4385
|
const onChannelUpdated = (callback) => {
|
|
4223
4386
|
const client = getActiveClient();
|
|
4224
|
-
if (callbacks$
|
|
4387
|
+
if (callbacks$d.length === 0) {
|
|
4225
4388
|
const filter = async (payload) => {
|
|
4226
4389
|
const data = await prepareChannelPayload(payload);
|
|
4227
4390
|
ingestInCache(data);
|
|
4228
|
-
callbacks$
|
|
4391
|
+
callbacks$d.forEach(cb => cb(data.channels[0]));
|
|
4229
4392
|
};
|
|
4230
|
-
mainDisposers.push(createEventSubscriber(client, 'onChannelUpdated', 'channel.updated', filter));
|
|
4231
|
-
mainDisposers.push(createEventSubscriber(client, 'onChannelUpdated', 'local.channel.updated', payload => callbacks$
|
|
4393
|
+
mainDisposers$2.push(createEventSubscriber(client, 'onChannelUpdated', 'channel.updated', filter));
|
|
4394
|
+
mainDisposers$2.push(createEventSubscriber(client, 'onChannelUpdated', 'local.channel.updated', payload => callbacks$d.forEach(cb => cb(payload.channels[0]))));
|
|
4232
4395
|
}
|
|
4233
|
-
callbacks$
|
|
4234
|
-
return () => dispose$
|
|
4396
|
+
callbacks$d.push(callback);
|
|
4397
|
+
return () => dispose$d(callback);
|
|
4235
4398
|
};
|
|
4236
4399
|
|
|
4237
4400
|
const addFlagIsDeletedSubChannelUnreadByChannelId = (channelId) => {
|
|
@@ -4254,19 +4417,19 @@ const deleteChannelUnreadByChannelId = (channelId) => {
|
|
|
4254
4417
|
}
|
|
4255
4418
|
};
|
|
4256
4419
|
|
|
4257
|
-
const callbacks$
|
|
4420
|
+
const callbacks$c = [];
|
|
4258
4421
|
let mainDisposer$a = null;
|
|
4259
|
-
const dispose$
|
|
4260
|
-
const index = callbacks$
|
|
4422
|
+
const dispose$c = (cb) => {
|
|
4423
|
+
const index = callbacks$c.indexOf(cb);
|
|
4261
4424
|
if (index > -1) {
|
|
4262
|
-
callbacks$
|
|
4425
|
+
callbacks$c.splice(index, 1);
|
|
4263
4426
|
}
|
|
4264
|
-
if (callbacks$
|
|
4427
|
+
if (callbacks$c.length === 0) {
|
|
4265
4428
|
mainDisposer$a === null || mainDisposer$a === void 0 ? void 0 : mainDisposer$a();
|
|
4266
4429
|
}
|
|
4267
4430
|
};
|
|
4268
4431
|
const onChannelDeleted = (callback) => {
|
|
4269
|
-
if (callbacks$
|
|
4432
|
+
if (callbacks$c.length === 0) {
|
|
4270
4433
|
const client = getActiveClient();
|
|
4271
4434
|
const filter = async (payload) => {
|
|
4272
4435
|
const data = await prepareChannelPayload(payload);
|
|
@@ -4286,53 +4449,53 @@ const onChannelDeleted = (callback) => {
|
|
|
4286
4449
|
}
|
|
4287
4450
|
});
|
|
4288
4451
|
ingestInCache(data);
|
|
4289
|
-
callbacks$
|
|
4452
|
+
callbacks$c.forEach(cb => cb(data.channels[0]));
|
|
4290
4453
|
};
|
|
4291
4454
|
mainDisposer$a = createEventSubscriber(client, 'onChannelDeleted', 'channel.deleted', filter);
|
|
4292
4455
|
}
|
|
4293
|
-
callbacks$
|
|
4294
|
-
return () => dispose$
|
|
4456
|
+
callbacks$c.push(callback);
|
|
4457
|
+
return () => dispose$c(callback);
|
|
4295
4458
|
};
|
|
4296
4459
|
|
|
4297
|
-
const callbacks$
|
|
4460
|
+
const callbacks$b = [];
|
|
4298
4461
|
let mainDisposer$9 = null;
|
|
4299
|
-
const dispose$
|
|
4300
|
-
const index = callbacks$
|
|
4462
|
+
const dispose$b = (cb) => {
|
|
4463
|
+
const index = callbacks$b.indexOf(cb);
|
|
4301
4464
|
if (index > -1) {
|
|
4302
|
-
callbacks$
|
|
4465
|
+
callbacks$b.splice(index, 1);
|
|
4303
4466
|
}
|
|
4304
|
-
if (callbacks$
|
|
4467
|
+
if (callbacks$b.length === 0) {
|
|
4305
4468
|
mainDisposer$9 === null || mainDisposer$9 === void 0 ? void 0 : mainDisposer$9();
|
|
4306
4469
|
}
|
|
4307
4470
|
};
|
|
4308
4471
|
const onChannelJoined = (callback) => {
|
|
4309
|
-
if (callbacks$
|
|
4472
|
+
if (callbacks$b.length === 0) {
|
|
4310
4473
|
const client = getActiveClient();
|
|
4311
4474
|
const filter = async (payload) => {
|
|
4312
4475
|
const preparedPayload = await prepareChannelPayload(payload);
|
|
4313
4476
|
const { channels, channelUsers } = preparedPayload;
|
|
4314
4477
|
ingestInCache(preparedPayload);
|
|
4315
|
-
callbacks$
|
|
4478
|
+
callbacks$b.forEach(cb => cb(channels[0], channelUsers[0]));
|
|
4316
4479
|
};
|
|
4317
4480
|
mainDisposer$9 = createEventSubscriber(client, 'onChannelJoined', 'channel.joined', filter);
|
|
4318
4481
|
}
|
|
4319
|
-
callbacks$
|
|
4320
|
-
return () => dispose$
|
|
4482
|
+
callbacks$b.push(callback);
|
|
4483
|
+
return () => dispose$b(callback);
|
|
4321
4484
|
};
|
|
4322
4485
|
|
|
4323
|
-
const callbacks$
|
|
4486
|
+
const callbacks$a = [];
|
|
4324
4487
|
let mainDisposer$8 = null;
|
|
4325
|
-
const dispose$
|
|
4326
|
-
const index = callbacks$
|
|
4488
|
+
const dispose$a = (cb) => {
|
|
4489
|
+
const index = callbacks$a.indexOf(cb);
|
|
4327
4490
|
if (index > -1) {
|
|
4328
|
-
callbacks$
|
|
4491
|
+
callbacks$a.splice(index, 1);
|
|
4329
4492
|
}
|
|
4330
|
-
if (callbacks$
|
|
4493
|
+
if (callbacks$a.length === 0) {
|
|
4331
4494
|
mainDisposer$8 === null || mainDisposer$8 === void 0 ? void 0 : mainDisposer$8();
|
|
4332
4495
|
}
|
|
4333
4496
|
};
|
|
4334
4497
|
const onChannelLeft = (callback) => {
|
|
4335
|
-
if (callbacks$
|
|
4498
|
+
if (callbacks$a.length === 0) {
|
|
4336
4499
|
const client = getActiveClient();
|
|
4337
4500
|
const filter = async (payload) => {
|
|
4338
4501
|
const { userId } = getActiveClient();
|
|
@@ -4356,27 +4519,27 @@ const onChannelLeft = (callback) => {
|
|
|
4356
4519
|
}
|
|
4357
4520
|
const { channels, channelUsers } = preparedPayload;
|
|
4358
4521
|
ingestInCache(preparedPayload);
|
|
4359
|
-
callbacks$
|
|
4522
|
+
callbacks$a.forEach(cb => cb(channels[0], channelUsers[0]));
|
|
4360
4523
|
};
|
|
4361
4524
|
mainDisposer$8 = createEventSubscriber(client, 'onChannelLeft', 'channel.left', filter);
|
|
4362
4525
|
}
|
|
4363
|
-
callbacks$
|
|
4364
|
-
return () => dispose$
|
|
4526
|
+
callbacks$a.push(callback);
|
|
4527
|
+
return () => dispose$a(callback);
|
|
4365
4528
|
};
|
|
4366
4529
|
|
|
4367
|
-
const callbacks$
|
|
4530
|
+
const callbacks$9 = [];
|
|
4368
4531
|
let mainDisposer$7 = null;
|
|
4369
|
-
const dispose$
|
|
4370
|
-
const index = callbacks$
|
|
4532
|
+
const dispose$9 = (cb) => {
|
|
4533
|
+
const index = callbacks$9.indexOf(cb);
|
|
4371
4534
|
if (index > -1) {
|
|
4372
|
-
callbacks$
|
|
4535
|
+
callbacks$9.splice(index, 1);
|
|
4373
4536
|
}
|
|
4374
|
-
if (callbacks$
|
|
4537
|
+
if (callbacks$9.length === 0) {
|
|
4375
4538
|
mainDisposer$7 === null || mainDisposer$7 === void 0 ? void 0 : mainDisposer$7();
|
|
4376
4539
|
}
|
|
4377
4540
|
};
|
|
4378
4541
|
const onChannelSetMuted = (callback) => {
|
|
4379
|
-
if (callbacks$
|
|
4542
|
+
if (callbacks$9.length === 0) {
|
|
4380
4543
|
const client = getActiveClient();
|
|
4381
4544
|
const filter = async (payload) => {
|
|
4382
4545
|
var _a;
|
|
@@ -4391,24 +4554,124 @@ const onChannelSetMuted = (callback) => {
|
|
|
4391
4554
|
payload.channelId,
|
|
4392
4555
|
])) === null || _a === void 0 ? void 0 : _a.data;
|
|
4393
4556
|
if (channel) {
|
|
4394
|
-
callbacks$
|
|
4557
|
+
callbacks$9.forEach(cb => cb(channel));
|
|
4395
4558
|
}
|
|
4396
4559
|
};
|
|
4397
4560
|
mainDisposer$7 = createEventSubscriber(client, 'onChannelMute', 'channel.setMuted', filter);
|
|
4398
4561
|
}
|
|
4562
|
+
callbacks$9.push(callback);
|
|
4563
|
+
return () => dispose$9(callback);
|
|
4564
|
+
};
|
|
4565
|
+
|
|
4566
|
+
const callbacks$8 = [];
|
|
4567
|
+
let mainDisposer$6 = null;
|
|
4568
|
+
const dispose$8 = (cb) => {
|
|
4569
|
+
const index = callbacks$8.indexOf(cb);
|
|
4570
|
+
if (index > -1) {
|
|
4571
|
+
callbacks$8.splice(index, 1);
|
|
4572
|
+
}
|
|
4573
|
+
if (callbacks$8.length === 0) {
|
|
4574
|
+
mainDisposer$6 === null || mainDisposer$6 === void 0 ? void 0 : mainDisposer$6();
|
|
4575
|
+
}
|
|
4576
|
+
};
|
|
4577
|
+
/* begin_public_function
|
|
4578
|
+
id: channel.event.message_pinned
|
|
4579
|
+
*/
|
|
4580
|
+
/**
|
|
4581
|
+
* ```js
|
|
4582
|
+
* import { onChannelMessagePinned } from '@amityco/ts-sdk'
|
|
4583
|
+
* const dispose = onChannelMessagePinned(channel => {
|
|
4584
|
+
* // channel.pinnedMessage is the new pin
|
|
4585
|
+
* })
|
|
4586
|
+
* ```
|
|
4587
|
+
*
|
|
4588
|
+
* Fired when a message is pinned in a channel (the `channel.messagePinned` realtime
|
|
4589
|
+
* event). Pinning a different message while one is already pinned emits a single
|
|
4590
|
+
* `messagePinned` carrying the replacement — treat every payload as a full snapshot.
|
|
4591
|
+
*
|
|
4592
|
+
* The updated channel is written to cache before the callback runs, so
|
|
4593
|
+
* `ChannelRepository.getChannel` observers see `channel.pinnedMessage` change.
|
|
4594
|
+
*
|
|
4595
|
+
* @param callback The function to call when the event was fired
|
|
4596
|
+
* @returns an {@link Amity.Unsubscriber} function to run when willing to stop listening
|
|
4597
|
+
*
|
|
4598
|
+
* @category Channel Events
|
|
4599
|
+
*/
|
|
4600
|
+
const onChannelMessagePinned = (callback) => {
|
|
4601
|
+
if (callbacks$8.length === 0) {
|
|
4602
|
+
const client = getActiveClient();
|
|
4603
|
+
const filter = (payload) => {
|
|
4604
|
+
var _a;
|
|
4605
|
+
const channel = findCachedChannelForPin(payload);
|
|
4606
|
+
if (!channel)
|
|
4607
|
+
return;
|
|
4608
|
+
const updated = updatePinnedMessageCache(channel, (_a = payload.pinnedMessage) !== null && _a !== void 0 ? _a : null, payload.users);
|
|
4609
|
+
callbacks$8.forEach(cb => cb(updated));
|
|
4610
|
+
};
|
|
4611
|
+
mainDisposer$6 = createEventSubscriber(client, 'onChannelMessagePinned', 'channel.messagePinned', filter);
|
|
4612
|
+
}
|
|
4613
|
+
callbacks$8.push(callback);
|
|
4614
|
+
return () => dispose$8(callback);
|
|
4615
|
+
};
|
|
4616
|
+
/* end_public_function */
|
|
4617
|
+
|
|
4618
|
+
const callbacks$7 = [];
|
|
4619
|
+
let mainDisposer$5 = null;
|
|
4620
|
+
const dispose$7 = (cb) => {
|
|
4621
|
+
const index = callbacks$7.indexOf(cb);
|
|
4622
|
+
if (index > -1) {
|
|
4623
|
+
callbacks$7.splice(index, 1);
|
|
4624
|
+
}
|
|
4625
|
+
if (callbacks$7.length === 0) {
|
|
4626
|
+
mainDisposer$5 === null || mainDisposer$5 === void 0 ? void 0 : mainDisposer$5();
|
|
4627
|
+
}
|
|
4628
|
+
};
|
|
4629
|
+
/* begin_public_function
|
|
4630
|
+
id: channel.event.message_unpinned
|
|
4631
|
+
*/
|
|
4632
|
+
/**
|
|
4633
|
+
* ```js
|
|
4634
|
+
* import { onChannelMessageUnpinned } from '@amityco/ts-sdk'
|
|
4635
|
+
* const dispose = onChannelMessageUnpinned(channel => {
|
|
4636
|
+
* // channel.pinnedMessage is now null
|
|
4637
|
+
* })
|
|
4638
|
+
* ```
|
|
4639
|
+
*
|
|
4640
|
+
* Fired when a channel's pinned message is removed (the `channel.messageUnpinned`
|
|
4641
|
+
* realtime event) — either by an explicit unpin or automatically by the server when the
|
|
4642
|
+
* pinned message is deleted or its author is banned from the channel / globally.
|
|
4643
|
+
*
|
|
4644
|
+
* @param callback The function to call when the event was fired
|
|
4645
|
+
* @returns an {@link Amity.Unsubscriber} function to run when willing to stop listening
|
|
4646
|
+
*
|
|
4647
|
+
* @category Channel Events
|
|
4648
|
+
*/
|
|
4649
|
+
const onChannelMessageUnpinned = (callback) => {
|
|
4650
|
+
if (callbacks$7.length === 0) {
|
|
4651
|
+
const client = getActiveClient();
|
|
4652
|
+
const filter = (payload) => {
|
|
4653
|
+
const channel = findCachedChannelForPin(payload);
|
|
4654
|
+
if (!channel)
|
|
4655
|
+
return;
|
|
4656
|
+
const updated = updatePinnedMessageCache(channel, null);
|
|
4657
|
+
callbacks$7.forEach(cb => cb(updated));
|
|
4658
|
+
};
|
|
4659
|
+
mainDisposer$5 = createEventSubscriber(client, 'onChannelMessageUnpinned', 'channel.messageUnpinned', filter);
|
|
4660
|
+
}
|
|
4399
4661
|
callbacks$7.push(callback);
|
|
4400
4662
|
return () => dispose$7(callback);
|
|
4401
4663
|
};
|
|
4664
|
+
/* end_public_function */
|
|
4402
4665
|
|
|
4403
4666
|
const callbacks$6 = [];
|
|
4404
|
-
let mainDisposer$
|
|
4667
|
+
let mainDisposer$4 = null;
|
|
4405
4668
|
const dispose$6 = (cb) => {
|
|
4406
4669
|
const index = callbacks$6.indexOf(cb);
|
|
4407
4670
|
if (index > -1) {
|
|
4408
4671
|
callbacks$6.splice(index, 1);
|
|
4409
4672
|
}
|
|
4410
4673
|
if (callbacks$6.length === 0) {
|
|
4411
|
-
mainDisposer$
|
|
4674
|
+
mainDisposer$4 === null || mainDisposer$4 === void 0 ? void 0 : mainDisposer$4();
|
|
4412
4675
|
}
|
|
4413
4676
|
};
|
|
4414
4677
|
const onChannelMemberAdded = (callback) => {
|
|
@@ -4420,21 +4683,21 @@ const onChannelMemberAdded = (callback) => {
|
|
|
4420
4683
|
ingestInCache(preparedPayload);
|
|
4421
4684
|
callbacks$6.forEach(cb => cb(channels[0], channelUsers.find(cu => cu.membership === 'member')));
|
|
4422
4685
|
};
|
|
4423
|
-
mainDisposer$
|
|
4686
|
+
mainDisposer$4 = createEventSubscriber(client, 'onChannelMemberAdded', 'channel.membersAdded', filter);
|
|
4424
4687
|
}
|
|
4425
4688
|
callbacks$6.push(callback);
|
|
4426
4689
|
return () => dispose$6(callback);
|
|
4427
4690
|
};
|
|
4428
4691
|
|
|
4429
4692
|
const callbacks$5 = [];
|
|
4430
|
-
let mainDisposer$
|
|
4693
|
+
let mainDisposer$3 = null;
|
|
4431
4694
|
const dispose$5 = (cb) => {
|
|
4432
4695
|
const index = callbacks$5.indexOf(cb);
|
|
4433
4696
|
if (index > -1) {
|
|
4434
4697
|
callbacks$5.splice(index, 1);
|
|
4435
4698
|
}
|
|
4436
4699
|
if (callbacks$5.length === 0) {
|
|
4437
|
-
mainDisposer$
|
|
4700
|
+
mainDisposer$3 === null || mainDisposer$3 === void 0 ? void 0 : mainDisposer$3();
|
|
4438
4701
|
}
|
|
4439
4702
|
};
|
|
4440
4703
|
const onChannelMemberRemoved = (callback) => {
|
|
@@ -4446,21 +4709,21 @@ const onChannelMemberRemoved = (callback) => {
|
|
|
4446
4709
|
ingestInCache(preparedPayload);
|
|
4447
4710
|
callbacks$5.forEach(cb => cb(channels[0], channelUsers[0]));
|
|
4448
4711
|
};
|
|
4449
|
-
mainDisposer$
|
|
4712
|
+
mainDisposer$3 = createEventSubscriber(client, 'onChannelMemberRemoved', 'channel.membersRemoved', filter);
|
|
4450
4713
|
}
|
|
4451
4714
|
callbacks$5.push(callback);
|
|
4452
4715
|
return () => dispose$5(callback);
|
|
4453
4716
|
};
|
|
4454
4717
|
|
|
4455
4718
|
const callbacks$4 = [];
|
|
4456
|
-
let mainDisposer$
|
|
4719
|
+
let mainDisposer$2 = null;
|
|
4457
4720
|
const dispose$4 = (cb) => {
|
|
4458
4721
|
const index = callbacks$4.indexOf(cb);
|
|
4459
4722
|
if (index > -1) {
|
|
4460
4723
|
callbacks$4.splice(index, 1);
|
|
4461
4724
|
}
|
|
4462
4725
|
if (callbacks$4.length === 0) {
|
|
4463
|
-
mainDisposer$
|
|
4726
|
+
mainDisposer$2 === null || mainDisposer$2 === void 0 ? void 0 : mainDisposer$2();
|
|
4464
4727
|
}
|
|
4465
4728
|
};
|
|
4466
4729
|
const onChannelMemberBanned = (callback) => {
|
|
@@ -4480,20 +4743,20 @@ const onChannelMemberBanned = (callback) => {
|
|
|
4480
4743
|
ingestInCache(preparedPayload);
|
|
4481
4744
|
callbacks$4.forEach(cb => cb(channels[0], channelUsers.find(cu => cu.membership === 'banned')));
|
|
4482
4745
|
};
|
|
4483
|
-
mainDisposer$
|
|
4746
|
+
mainDisposer$2 = createEventSubscriber(client, 'onChannelMemberBanned', 'channel.banned', filter);
|
|
4484
4747
|
callbacks$4.push(callback);
|
|
4485
4748
|
return () => dispose$4(callback);
|
|
4486
4749
|
};
|
|
4487
4750
|
|
|
4488
4751
|
const callbacks$3 = [];
|
|
4489
|
-
let mainDisposer$
|
|
4752
|
+
let mainDisposer$1 = null;
|
|
4490
4753
|
const dispose$3 = (cb) => {
|
|
4491
4754
|
const index = callbacks$3.indexOf(cb);
|
|
4492
4755
|
if (index > -1) {
|
|
4493
4756
|
callbacks$3.splice(index, 1);
|
|
4494
4757
|
}
|
|
4495
4758
|
if (callbacks$3.length === 0) {
|
|
4496
|
-
mainDisposer$
|
|
4759
|
+
mainDisposer$1 === null || mainDisposer$1 === void 0 ? void 0 : mainDisposer$1();
|
|
4497
4760
|
}
|
|
4498
4761
|
};
|
|
4499
4762
|
const onChannelMemberUnbanned = (callback) => {
|
|
@@ -4505,59 +4768,127 @@ const onChannelMemberUnbanned = (callback) => {
|
|
|
4505
4768
|
ingestInCache(preparedPayload);
|
|
4506
4769
|
callbacks$3.forEach(cb => cb(channels[0], channelUsers.find(cu => cu.membership === 'none')));
|
|
4507
4770
|
};
|
|
4508
|
-
mainDisposer$
|
|
4771
|
+
mainDisposer$1 = createEventSubscriber(client, 'onChannelMemberUnbanned', 'channel.unbanned', filter);
|
|
4509
4772
|
}
|
|
4510
4773
|
callbacks$3.push(callback);
|
|
4511
4774
|
return () => dispose$3(callback);
|
|
4512
4775
|
};
|
|
4513
4776
|
|
|
4514
4777
|
const callbacks$2 = [];
|
|
4515
|
-
|
|
4778
|
+
const mainDisposers$1 = [];
|
|
4516
4779
|
const dispose$2 = (cb) => {
|
|
4517
4780
|
const index = callbacks$2.indexOf(cb);
|
|
4518
4781
|
if (index > -1) {
|
|
4519
4782
|
callbacks$2.splice(index, 1);
|
|
4520
4783
|
}
|
|
4521
4784
|
if (callbacks$2.length === 0) {
|
|
4522
|
-
|
|
4785
|
+
mainDisposers$1.forEach(fn => fn());
|
|
4786
|
+
mainDisposers$1.length = 0;
|
|
4523
4787
|
}
|
|
4524
4788
|
};
|
|
4789
|
+
/* begin_public_function
|
|
4790
|
+
id: channel.event.member_role_added
|
|
4791
|
+
*/
|
|
4792
|
+
/**
|
|
4793
|
+
* ```js
|
|
4794
|
+
* import { onChannelMemberRoleAdded } from '@amityco/ts-sdk'
|
|
4795
|
+
* const dispose = onChannelMemberRoleAdded((channel, member) => {
|
|
4796
|
+
* // member.roles and member.permissions are the member's resulting state
|
|
4797
|
+
* })
|
|
4798
|
+
* ```
|
|
4799
|
+
*
|
|
4800
|
+
* Fired when a role is added to a member of a {@link Amity.Channel}, either by the
|
|
4801
|
+
* local `ChannelRepository.Moderation.addRole` call or by the `channel.roleAdded` realtime
|
|
4802
|
+
* event coming from any client or the admin console.
|
|
4803
|
+
*
|
|
4804
|
+
* The realtime event reaches every subscriber of the channel topic (see `getChannelTopic`),
|
|
4805
|
+
* not only the actor or the affected members. It carries the affected members' resulting
|
|
4806
|
+
* channel roles and channel-scoped permissions, which are written to cache before the
|
|
4807
|
+
* callback runs. The callback is invoked once per affected member already held in cache.
|
|
4808
|
+
*
|
|
4809
|
+
* @param callback The function to call when the event was fired
|
|
4810
|
+
* @returns an {@link Amity.Unsubscriber} function to run when willing to stop listening
|
|
4811
|
+
*
|
|
4812
|
+
* @category Channel Events
|
|
4813
|
+
*/
|
|
4525
4814
|
const onChannelMemberRoleAdded = (callback) => {
|
|
4526
4815
|
if (callbacks$2.length === 0) {
|
|
4527
4816
|
const client = getActiveClient();
|
|
4528
|
-
const
|
|
4817
|
+
const onLocal = async (payload) => {
|
|
4529
4818
|
const { channels, channelUsers } = payload;
|
|
4530
4819
|
callbacks$2.forEach(cb => cb(channels[0], channelUsers.find(channelUser => channelUser.membership === 'member')));
|
|
4531
4820
|
};
|
|
4532
|
-
|
|
4821
|
+
const onRealtime = (payload) => {
|
|
4822
|
+
const { channel, members } = applyChannelRolePayload(payload);
|
|
4823
|
+
if (!channel)
|
|
4824
|
+
return;
|
|
4825
|
+
members.forEach(member => callbacks$2.forEach(cb => cb(channel, member)));
|
|
4826
|
+
};
|
|
4827
|
+
mainDisposers$1.push(createEventSubscriber(client, 'onChannelMemberRoleAdded', 'local.channel-moderator.role-added', onLocal));
|
|
4828
|
+
mainDisposers$1.push(createEventSubscriber(client, 'onChannelMemberRoleAdded', 'channel.roleAdded', onRealtime));
|
|
4533
4829
|
}
|
|
4534
4830
|
callbacks$2.push(callback);
|
|
4535
4831
|
return () => dispose$2(callback);
|
|
4536
4832
|
};
|
|
4833
|
+
/* end_public_function */
|
|
4537
4834
|
|
|
4538
4835
|
const callbacks$1 = [];
|
|
4539
|
-
|
|
4836
|
+
const mainDisposers = [];
|
|
4540
4837
|
const dispose$1 = (cb) => {
|
|
4541
4838
|
const index = callbacks$1.indexOf(cb);
|
|
4542
4839
|
if (index > -1) {
|
|
4543
4840
|
callbacks$1.splice(index, 1);
|
|
4544
4841
|
}
|
|
4545
4842
|
if (callbacks$1.length === 0) {
|
|
4546
|
-
|
|
4843
|
+
mainDisposers.forEach(fn => fn());
|
|
4844
|
+
mainDisposers.length = 0;
|
|
4547
4845
|
}
|
|
4548
4846
|
};
|
|
4847
|
+
/* begin_public_function
|
|
4848
|
+
id: channel.event.member_role_removed
|
|
4849
|
+
*/
|
|
4850
|
+
/**
|
|
4851
|
+
* ```js
|
|
4852
|
+
* import { onChannelMemberRoleRemoved } from '@amityco/ts-sdk'
|
|
4853
|
+
* const dispose = onChannelMemberRoleRemoved((channel, member) => {
|
|
4854
|
+
* // member.roles and member.permissions are the member's resulting state
|
|
4855
|
+
* })
|
|
4856
|
+
* ```
|
|
4857
|
+
*
|
|
4858
|
+
* Fired when a role is removed from a member of a {@link Amity.Channel}, either by the
|
|
4859
|
+
* local `ChannelRepository.Moderation.removeRole` call or by the `channel.roleRemoved` realtime
|
|
4860
|
+
* event coming from any client or the admin console.
|
|
4861
|
+
*
|
|
4862
|
+
* The realtime event reaches every subscriber of the channel topic (see `getChannelTopic`),
|
|
4863
|
+
* not only the actor or the affected members. It carries the affected members' resulting
|
|
4864
|
+
* channel roles and channel-scoped permissions, which are written to cache before the
|
|
4865
|
+
* callback runs. The callback is invoked once per affected member already held in cache.
|
|
4866
|
+
*
|
|
4867
|
+
* @param callback The function to call when the event was fired
|
|
4868
|
+
* @returns an {@link Amity.Unsubscriber} function to run when willing to stop listening
|
|
4869
|
+
*
|
|
4870
|
+
* @category Channel Events
|
|
4871
|
+
*/
|
|
4549
4872
|
const onChannelMemberRoleRemoved = (callback) => {
|
|
4550
4873
|
if (callbacks$1.length === 0) {
|
|
4551
4874
|
const client = getActiveClient();
|
|
4552
|
-
const
|
|
4875
|
+
const onLocal = async (payload) => {
|
|
4553
4876
|
const { channels, channelUsers } = payload;
|
|
4554
4877
|
callbacks$1.forEach(cb => cb(channels[0], channelUsers.find(channelUser => channelUser.membership === 'member')));
|
|
4555
4878
|
};
|
|
4556
|
-
|
|
4879
|
+
const onRealtime = (payload) => {
|
|
4880
|
+
const { channel, members } = applyChannelRolePayload(payload);
|
|
4881
|
+
if (!channel)
|
|
4882
|
+
return;
|
|
4883
|
+
members.forEach(member => callbacks$1.forEach(cb => cb(channel, member)));
|
|
4884
|
+
};
|
|
4885
|
+
mainDisposers.push(createEventSubscriber(client, 'onChannelMemberRoleRemoved', 'local.channel-moderator.role-removed', onLocal));
|
|
4886
|
+
mainDisposers.push(createEventSubscriber(client, 'onChannelMemberRoleRemoved', 'channel.roleRemoved', onRealtime));
|
|
4557
4887
|
}
|
|
4558
4888
|
callbacks$1.push(callback);
|
|
4559
4889
|
return () => dispose$1(callback);
|
|
4560
4890
|
};
|
|
4891
|
+
/* end_public_function */
|
|
4561
4892
|
|
|
4562
4893
|
/**
|
|
4563
4894
|
* Fired when a {@link Amity.Channel} has been archived by the active user.
|
|
@@ -4681,6 +5012,8 @@ const getMyMembership = (channelId, callback) => {
|
|
|
4681
5012
|
disposers.push(onChannelMemberBanned(realtimeRouter));
|
|
4682
5013
|
disposers.push(onChannelMemberUnbanned(realtimeRouter));
|
|
4683
5014
|
disposers.push(onChannelSetUserMuted(realtimeRouter));
|
|
5015
|
+
disposers.push(onChannelMemberRoleAdded(realtimeRouter));
|
|
5016
|
+
disposers.push(onChannelMemberRoleRemoved(realtimeRouter));
|
|
4684
5017
|
onFetch();
|
|
4685
5018
|
return () => {
|
|
4686
5019
|
disposers.forEach(fn => fn());
|
|
@@ -5074,7 +5407,9 @@ const initializeMessagePreviewSetting = async () => {
|
|
|
5074
5407
|
const getSocialSettings = async () => {
|
|
5075
5408
|
const client = getActiveClient();
|
|
5076
5409
|
const { data } = await client.http.get(`/api/v3/network-settings/social`);
|
|
5077
|
-
return data.socialNetworkSetting
|
|
5410
|
+
return Object.assign(Object.assign({}, data.socialNetworkSetting), {
|
|
5411
|
+
// Networks that never set the comment edit switch allow the edit
|
|
5412
|
+
isAllowEditCommentWhenReviewingEnabled: data.socialNetworkSetting.isAllowEditCommentWhenReviewingEnabled });
|
|
5078
5413
|
};
|
|
5079
5414
|
|
|
5080
5415
|
/**
|
|
@@ -5760,6 +6095,32 @@ class AnalyticsEventCapturer {
|
|
|
5760
6095
|
activityType: "view" /* Amity.AnalyticEventActivityType.View */,
|
|
5761
6096
|
});
|
|
5762
6097
|
}
|
|
6098
|
+
markCuratedContentWidgetAsViewed(topicId) {
|
|
6099
|
+
this.markAs({
|
|
6100
|
+
uniqueId: `curatedContentWidget.${topicId}`,
|
|
6101
|
+
contentId: topicId,
|
|
6102
|
+
contentType: "curated_content_widget" /* Amity.AnalyticEventContentType.CuratedContentWidget */,
|
|
6103
|
+
activityType: "view" /* Amity.AnalyticEventActivityType.View */,
|
|
6104
|
+
});
|
|
6105
|
+
}
|
|
6106
|
+
markCuratedContentPostAsViewed(postId, topicId) {
|
|
6107
|
+
this.markAs({
|
|
6108
|
+
uniqueId: `curatedContentPost.${postId}.view`,
|
|
6109
|
+
contentId: postId,
|
|
6110
|
+
contentType: "curated_content_post" /* Amity.AnalyticEventContentType.CuratedContentPost */,
|
|
6111
|
+
activityType: "view" /* Amity.AnalyticEventActivityType.View */,
|
|
6112
|
+
metadata: { topicId },
|
|
6113
|
+
});
|
|
6114
|
+
}
|
|
6115
|
+
markCuratedContentPostAsClicked(postId, topicId) {
|
|
6116
|
+
this.markAs({
|
|
6117
|
+
uniqueId: `curatedContentPost.${postId}.click`,
|
|
6118
|
+
contentId: postId,
|
|
6119
|
+
contentType: "curated_content_post" /* Amity.AnalyticEventContentType.CuratedContentPost */,
|
|
6120
|
+
activityType: "linkClicked" /* Amity.AnalyticEventActivityType.Click */,
|
|
6121
|
+
metadata: { topicId },
|
|
6122
|
+
});
|
|
6123
|
+
}
|
|
5763
6124
|
markPostAsMeaningfullyViewed(postId, feedRenderPosition) {
|
|
5764
6125
|
var _a;
|
|
5765
6126
|
const cached = (_a = pullFromCache(['feedMetadata', 'get', postId])) === null || _a === void 0 ? void 0 : _a.data;
|
|
@@ -5923,6 +6284,24 @@ class AnalyticsEngine {
|
|
|
5923
6284
|
this._eventCapturer.markPostAsViewed(postId);
|
|
5924
6285
|
}
|
|
5925
6286
|
}
|
|
6287
|
+
markCuratedContentWidgetAsViewed(topicId) {
|
|
6288
|
+
if (this._client.sessionState === "established" /* Amity.SessionStates.ESTABLISHED */ ||
|
|
6289
|
+
this._client.sessionState === "tokenExpired" /* Amity.SessionStates.TOKEN_EXPIRED */) {
|
|
6290
|
+
this._eventCapturer.markCuratedContentWidgetAsViewed(topicId);
|
|
6291
|
+
}
|
|
6292
|
+
}
|
|
6293
|
+
markCuratedContentPostAsViewed(postId, topicId) {
|
|
6294
|
+
if (this._client.sessionState === "established" /* Amity.SessionStates.ESTABLISHED */ ||
|
|
6295
|
+
this._client.sessionState === "tokenExpired" /* Amity.SessionStates.TOKEN_EXPIRED */) {
|
|
6296
|
+
this._eventCapturer.markCuratedContentPostAsViewed(postId, topicId);
|
|
6297
|
+
}
|
|
6298
|
+
}
|
|
6299
|
+
markCuratedContentPostAsClicked(postId, topicId) {
|
|
6300
|
+
if (this._client.sessionState === "established" /* Amity.SessionStates.ESTABLISHED */ ||
|
|
6301
|
+
this._client.sessionState === "tokenExpired" /* Amity.SessionStates.TOKEN_EXPIRED */) {
|
|
6302
|
+
this._eventCapturer.markCuratedContentPostAsClicked(postId, topicId);
|
|
6303
|
+
}
|
|
6304
|
+
}
|
|
5926
6305
|
markPostAsMeaningfullyViewed(postId, feedRenderPosition) {
|
|
5927
6306
|
if (this._client.sessionState === "established" /* Amity.SessionStates.ESTABLISHED */ ||
|
|
5928
6307
|
this._client.sessionState === "tokenExpired" /* Amity.SessionStates.TOKEN_EXPIRED */) {
|
|
@@ -7349,6 +7728,265 @@ class CursorController {
|
|
|
7349
7728
|
}
|
|
7350
7729
|
}
|
|
7351
7730
|
|
|
7731
|
+
class ResetTask {
|
|
7732
|
+
constructor(postId, latestCreatedAt, serverCommentCount) {
|
|
7733
|
+
this.postId = postId;
|
|
7734
|
+
this.latestCreatedAt = latestCreatedAt;
|
|
7735
|
+
this.serverCommentCount = serverCommentCount;
|
|
7736
|
+
}
|
|
7737
|
+
}
|
|
7738
|
+
|
|
7739
|
+
// Task to track comment creation
|
|
7740
|
+
class CreateTask {
|
|
7741
|
+
constructor(postId, commentId, createdAt) {
|
|
7742
|
+
this.postId = postId;
|
|
7743
|
+
this.commentId = commentId;
|
|
7744
|
+
this.createdAt = createdAt;
|
|
7745
|
+
}
|
|
7746
|
+
}
|
|
7747
|
+
|
|
7748
|
+
/**
|
|
7749
|
+
* A pending comment was approved and now counts publicly. Unlike `CreateTask` it carries no
|
|
7750
|
+
* `createdAt` and bypasses the age guard on purpose: the comment was written before the last post
|
|
7751
|
+
* payload (so its `createdAt` is old) but entered the server count only now. Same rule as iOS.
|
|
7752
|
+
*
|
|
7753
|
+
* Accepted trade-off (plan 40 §9): if a `ResetTask` that already includes this comment lands
|
|
7754
|
+
* between the approve response and the late `comment.approved` event, the count reads +1 until
|
|
7755
|
+
* the next server sync — the same self-correcting drift accepted for stale deletes.
|
|
7756
|
+
*/
|
|
7757
|
+
class ApproveTask {
|
|
7758
|
+
constructor(postId, commentId) {
|
|
7759
|
+
this.postId = postId;
|
|
7760
|
+
this.commentId = commentId;
|
|
7761
|
+
}
|
|
7762
|
+
}
|
|
7763
|
+
|
|
7764
|
+
// Task to track comment deletion
|
|
7765
|
+
class DeleteTask {
|
|
7766
|
+
constructor(postId, commentId) {
|
|
7767
|
+
this.postId = postId;
|
|
7768
|
+
this.commentId = commentId;
|
|
7769
|
+
}
|
|
7770
|
+
}
|
|
7771
|
+
|
|
7772
|
+
class CommentChange {
|
|
7773
|
+
constructor(latestCreatedAt, serverCommentCount) {
|
|
7774
|
+
this.latestCommentCreatedAt = latestCreatedAt;
|
|
7775
|
+
this.serverCommentCount = serverCommentCount;
|
|
7776
|
+
this.createdCommentIds = new Set();
|
|
7777
|
+
this.deletedCommentIds = new Set();
|
|
7778
|
+
}
|
|
7779
|
+
}
|
|
7780
|
+
|
|
7781
|
+
class PostCommentCountEngine {
|
|
7782
|
+
constructor() {
|
|
7783
|
+
this.isProcessing = false;
|
|
7784
|
+
this.tasks = [];
|
|
7785
|
+
this.commentChangeTracker = new Map();
|
|
7786
|
+
// Ids of the LOGGED-IN USER's own pending comments, per post. Survives ResetTask, so the
|
|
7787
|
+
// author's +1 does not vanish on the next post refresh; emptied only when the comment leaves
|
|
7788
|
+
// the pending state (approval hands it to createdCommentIds, decline/delete drops it).
|
|
7789
|
+
this.pendingAuthoredCommentIds = new Map();
|
|
7790
|
+
}
|
|
7791
|
+
queueCommentChangeTask(task) {
|
|
7792
|
+
this.tasks.push(task);
|
|
7793
|
+
if (!this.isProcessing) {
|
|
7794
|
+
this.processCommentChangeTask();
|
|
7795
|
+
}
|
|
7796
|
+
}
|
|
7797
|
+
addPendingAuthoredComment(postId, commentId, { publish = true } = {}) {
|
|
7798
|
+
var _a;
|
|
7799
|
+
const ids = (_a = this.pendingAuthoredCommentIds.get(postId)) !== null && _a !== void 0 ? _a : new Set();
|
|
7800
|
+
if (ids.has(commentId))
|
|
7801
|
+
return;
|
|
7802
|
+
ids.add(commentId);
|
|
7803
|
+
this.pendingAuthoredCommentIds.set(postId, ids);
|
|
7804
|
+
if (publish)
|
|
7805
|
+
this.publishIfTracked(postId);
|
|
7806
|
+
}
|
|
7807
|
+
removePendingAuthoredComment(postId, commentId, { publish = true } = {}) {
|
|
7808
|
+
const ids = this.pendingAuthoredCommentIds.get(postId);
|
|
7809
|
+
if (!(ids === null || ids === void 0 ? void 0 : ids.delete(commentId)))
|
|
7810
|
+
return false;
|
|
7811
|
+
if (ids.size === 0)
|
|
7812
|
+
this.pendingAuthoredCommentIds.delete(postId);
|
|
7813
|
+
if (publish)
|
|
7814
|
+
this.publishIfTracked(postId);
|
|
7815
|
+
return true;
|
|
7816
|
+
}
|
|
7817
|
+
/** Whether a post payload has seeded this post; without one every count is `0`. */
|
|
7818
|
+
hasTracker(postId) {
|
|
7819
|
+
return this.commentChangeTracker.has(postId);
|
|
7820
|
+
}
|
|
7821
|
+
isPendingAuthoredComment(postId, commentId) {
|
|
7822
|
+
var _a, _b;
|
|
7823
|
+
return (_b = (_a = this.pendingAuthoredCommentIds.get(postId)) === null || _a === void 0 ? void 0 : _a.has(commentId)) !== null && _b !== void 0 ? _b : false;
|
|
7824
|
+
}
|
|
7825
|
+
// Drops every per-post state. Called on logout / user switch.
|
|
7826
|
+
reset() {
|
|
7827
|
+
this.tasks = [];
|
|
7828
|
+
this.commentChangeTracker.clear();
|
|
7829
|
+
this.pendingAuthoredCommentIds.clear();
|
|
7830
|
+
}
|
|
7831
|
+
publishIfTracked(postId) {
|
|
7832
|
+
// Without a tracker there is no server figure to add to; the next ResetTask picks it up.
|
|
7833
|
+
if (!this.commentChangeTracker.has(postId))
|
|
7834
|
+
return;
|
|
7835
|
+
PostCommentCountEngine.publishUpdate(postId, this.getLocalCommentCount(postId, true));
|
|
7836
|
+
}
|
|
7837
|
+
processCommentChangeTask() {
|
|
7838
|
+
if (this.isProcessing) {
|
|
7839
|
+
return;
|
|
7840
|
+
}
|
|
7841
|
+
this.isProcessing = true;
|
|
7842
|
+
if (this.tasks.length === 0) {
|
|
7843
|
+
this.isProcessing = false;
|
|
7844
|
+
return;
|
|
7845
|
+
}
|
|
7846
|
+
// Process in capped batches, coalescing updates
|
|
7847
|
+
const batch = this.tasks.splice(0, PostCommentCountEngine.BATCH_SIZE);
|
|
7848
|
+
const modifiedPostIds = new Set();
|
|
7849
|
+
batch.forEach(task => {
|
|
7850
|
+
let modified = false;
|
|
7851
|
+
if (task instanceof ResetTask) {
|
|
7852
|
+
modified = this.processResetTaskInternal(task);
|
|
7853
|
+
}
|
|
7854
|
+
else if (task instanceof CreateTask) {
|
|
7855
|
+
modified = this.processCreateTaskInternal(task);
|
|
7856
|
+
}
|
|
7857
|
+
else if (task instanceof ApproveTask) {
|
|
7858
|
+
modified = this.processApproveTaskInternal(task);
|
|
7859
|
+
}
|
|
7860
|
+
else if (task instanceof DeleteTask) {
|
|
7861
|
+
modified = this.processDeleteTaskInternal(task);
|
|
7862
|
+
}
|
|
7863
|
+
if (modified) {
|
|
7864
|
+
modifiedPostIds.add(task.postId);
|
|
7865
|
+
}
|
|
7866
|
+
});
|
|
7867
|
+
// Publish one update per modified post
|
|
7868
|
+
modifiedPostIds.forEach(postId => {
|
|
7869
|
+
PostCommentCountEngine.publishUpdate(postId, this.getLocalCommentCount(postId, true));
|
|
7870
|
+
});
|
|
7871
|
+
this.isProcessing = false;
|
|
7872
|
+
// Recurse if more tasks remain
|
|
7873
|
+
if (this.tasks.length > 0) {
|
|
7874
|
+
this.processCommentChangeTask();
|
|
7875
|
+
}
|
|
7876
|
+
}
|
|
7877
|
+
processResetTaskInternal(task) {
|
|
7878
|
+
// Always creates/overwrites tracker
|
|
7879
|
+
this.commentChangeTracker.set(task.postId, new CommentChange(task.latestCreatedAt, task.serverCommentCount));
|
|
7880
|
+
return true;
|
|
7881
|
+
}
|
|
7882
|
+
processCreateTaskInternal(task) {
|
|
7883
|
+
// The comment is public now: the author-local +1 hands over to the normal path, so the
|
|
7884
|
+
// count stays put instead of moving twice.
|
|
7885
|
+
const wasPendingAuthored = this.removePendingAuthoredComment(task.postId, task.commentId, {
|
|
7886
|
+
publish: false,
|
|
7887
|
+
});
|
|
7888
|
+
const tracker = this.commentChangeTracker.get(task.postId);
|
|
7889
|
+
if (!tracker)
|
|
7890
|
+
return false; // No tracker, skip
|
|
7891
|
+
if (tracker.deletedCommentIds.delete(task.commentId))
|
|
7892
|
+
return true; // Re-approval cancels the earlier removal
|
|
7893
|
+
if (tracker.createdCommentIds.has(task.commentId))
|
|
7894
|
+
return wasPendingAuthored; // Deduplication
|
|
7895
|
+
if (task.createdAt <= tracker.latestCommentCreatedAt)
|
|
7896
|
+
return wasPendingAuthored; // Timestamp filtering
|
|
7897
|
+
tracker.createdCommentIds.add(task.commentId);
|
|
7898
|
+
return true;
|
|
7899
|
+
}
|
|
7900
|
+
processApproveTaskInternal(task) {
|
|
7901
|
+
// The comment is public now: the author-local +1 hands over to the normal path, so the
|
|
7902
|
+
// count stays put instead of moving twice.
|
|
7903
|
+
const wasPendingAuthored = this.removePendingAuthoredComment(task.postId, task.commentId, {
|
|
7904
|
+
publish: false,
|
|
7905
|
+
});
|
|
7906
|
+
const tracker = this.commentChangeTracker.get(task.postId);
|
|
7907
|
+
if (!tracker)
|
|
7908
|
+
return false; // No tracker, skip
|
|
7909
|
+
if (tracker.deletedCommentIds.delete(task.commentId))
|
|
7910
|
+
return true; // Re-approval cancels the earlier re-review removal
|
|
7911
|
+
if (tracker.createdCommentIds.has(task.commentId))
|
|
7912
|
+
return wasPendingAuthored; // Approve response and comment.approved event dedupe by id
|
|
7913
|
+
// No timestamp filtering: approval is the moment the comment enters the count, not createdAt
|
|
7914
|
+
tracker.createdCommentIds.add(task.commentId);
|
|
7915
|
+
return true;
|
|
7916
|
+
}
|
|
7917
|
+
processDeleteTaskInternal(task) {
|
|
7918
|
+
const tracker = this.commentChangeTracker.get(task.postId);
|
|
7919
|
+
if (!tracker)
|
|
7920
|
+
return false; // No tracker, skip
|
|
7921
|
+
if (tracker.deletedCommentIds.has(task.commentId))
|
|
7922
|
+
return false; // Deduplication
|
|
7923
|
+
tracker.deletedCommentIds.add(task.commentId);
|
|
7924
|
+
return true;
|
|
7925
|
+
}
|
|
7926
|
+
/**
|
|
7927
|
+
* The count as this session sees it: the last server figure plus the local delta.
|
|
7928
|
+
*
|
|
7929
|
+
* `includePending` adds the logged-in user's own pending comments — the author's view. A
|
|
7930
|
+
* pending id is added only while the public delta does not already count it, so a comment
|
|
7931
|
+
* present in both sets counts once: a `comment.created` that arrives pending after the
|
|
7932
|
+
* `comment.approved` hand-over adds nothing, while an approved comment sent back to review
|
|
7933
|
+
* (created, deleted and pending all hold its id) keeps the author's +1.
|
|
7934
|
+
*
|
|
7935
|
+
* `0` for a post no payload has seeded yet; callers fall back to the post's own figure.
|
|
7936
|
+
*/
|
|
7937
|
+
getLocalCommentCount(postId, includePending = false) {
|
|
7938
|
+
var _a;
|
|
7939
|
+
const tracker = this.commentChangeTracker.get(postId);
|
|
7940
|
+
if (!tracker)
|
|
7941
|
+
return 0;
|
|
7942
|
+
const publicDelta = tracker.createdCommentIds.size - tracker.deletedCommentIds.size;
|
|
7943
|
+
if (!includePending)
|
|
7944
|
+
return Math.max(0, tracker.serverCommentCount + publicDelta);
|
|
7945
|
+
let pendingExtra = 0;
|
|
7946
|
+
(_a = this.pendingAuthoredCommentIds.get(postId)) === null || _a === void 0 ? void 0 : _a.forEach(commentId => {
|
|
7947
|
+
const countedPublicly = tracker.createdCommentIds.has(commentId) && !tracker.deletedCommentIds.has(commentId);
|
|
7948
|
+
if (!countedPublicly)
|
|
7949
|
+
pendingExtra += 1;
|
|
7950
|
+
});
|
|
7951
|
+
return Math.max(0, tracker.serverCommentCount + publicDelta + pendingExtra);
|
|
7952
|
+
}
|
|
7953
|
+
static publishUpdate(postId, newCount) {
|
|
7954
|
+
var _a;
|
|
7955
|
+
const queryKey = ['post', 'get', postId];
|
|
7956
|
+
mergeInCache(queryKey, {
|
|
7957
|
+
localCommentCount: newCount,
|
|
7958
|
+
});
|
|
7959
|
+
const postPayload = (_a = pullFromCache(queryKey)) === null || _a === void 0 ? void 0 : _a.data;
|
|
7960
|
+
if (!postPayload)
|
|
7961
|
+
return;
|
|
7962
|
+
fireEvent('local.post.updated', {
|
|
7963
|
+
posts: [postPayload],
|
|
7964
|
+
});
|
|
7965
|
+
}
|
|
7966
|
+
}
|
|
7967
|
+
PostCommentCountEngine.BATCH_SIZE = 50;
|
|
7968
|
+
let instance$1;
|
|
7969
|
+
var PostCommentCountEngine$1 = {
|
|
7970
|
+
getInstance: () => {
|
|
7971
|
+
if (!instance$1) {
|
|
7972
|
+
instance$1 = new PostCommentCountEngine();
|
|
7973
|
+
}
|
|
7974
|
+
return instance$1;
|
|
7975
|
+
},
|
|
7976
|
+
};
|
|
7977
|
+
|
|
7978
|
+
/**
|
|
7979
|
+
* Comment-count state is per user — in particular the ids of the logged-in user's own pending
|
|
7980
|
+
* comments — so it must not survive a logout or a user switch.
|
|
7981
|
+
*
|
|
7982
|
+
* @category private
|
|
7983
|
+
*/
|
|
7984
|
+
const postCommentCountEngineOnLoginHandler = () => onSessionStateChange(state => {
|
|
7985
|
+
if (state === "notLoggedIn" /* Amity.SessionStates.NOT_LOGGED_IN */ || state === "terminated" /* Amity.SessionStates.TERMINATED */) {
|
|
7986
|
+
PostCommentCountEngine$1.getInstance().reset();
|
|
7987
|
+
}
|
|
7988
|
+
});
|
|
7989
|
+
|
|
7352
7990
|
const EVENTS = [
|
|
7353
7991
|
'disconnected',
|
|
7354
7992
|
'error',
|
|
@@ -7538,7 +8176,7 @@ const setupLoginSubscriptions = (unsubWatcher) => {
|
|
|
7538
8176
|
// NOTE: This is a temporary solution to handle the channel marker when the user is forced to leave
|
|
7539
8177
|
// the channel because currently backend can't handle this, so every time a user is banned from
|
|
7540
8178
|
// a channel or the channel is deleted the channel's unread count will not be reset to zero
|
|
7541
|
-
onChannelDeleted(removeChannelMarkerCache), onChannelMemberBanned(removeChannelMarkerCache), markReadEngineOnLoginHandler(), analyticsEngineOnLoginHandler(), objectResolverEngineOnLoginHandler(), reactionSyncEngineOnLoginHandler(), blockedUserSyncEngineOnLoginHandler(), blockingUserSyncEngineOnLoginHandler(), blockRealtimeOnLoginHandler(), resetAutoSubscriptionsOnLogout(), CursorController.clearOnLogout());
|
|
8179
|
+
onChannelDeleted(removeChannelMarkerCache), onChannelMemberBanned(removeChannelMarkerCache), markReadEngineOnLoginHandler(), analyticsEngineOnLoginHandler(), objectResolverEngineOnLoginHandler(), reactionSyncEngineOnLoginHandler(), blockedUserSyncEngineOnLoginHandler(), blockingUserSyncEngineOnLoginHandler(), blockRealtimeOnLoginHandler(), resetAutoSubscriptionsOnLogout(), CursorController.clearOnLogout(), postCommentCountEngineOnLoginHandler());
|
|
7542
8180
|
if (client.useLegacyUnreadCount) {
|
|
7543
8181
|
subscriptions.push(readReceiptSyncEngineOnLoginHandler());
|
|
7544
8182
|
}
|
|
@@ -8594,7 +9232,7 @@ const DEFAULT_DEBUG_SESSION = 'amity';
|
|
|
8594
9232
|
*
|
|
8595
9233
|
* @category Client API
|
|
8596
9234
|
* */
|
|
8597
|
-
const createClient = (apiKey, apiRegion = API_REGIONS.SG, { debugSession = DEFAULT_DEBUG_SESSION, apiEndpoint, prefixDeviceIdKey, rteEnabled = true, } = {}) => {
|
|
9235
|
+
const createClient = (apiKey, apiRegion = API_REGIONS.SG, { debugSession = DEFAULT_DEBUG_SESSION, apiEndpoint, prefixDeviceIdKey, rteEnabled = true, product, uikitVersion, appId, appVersion, } = {}) => {
|
|
8598
9236
|
var _a, _b, _c;
|
|
8599
9237
|
const log = createLogger(debugSession);
|
|
8600
9238
|
log('client/api/createClient', {
|
|
@@ -8623,6 +9261,10 @@ const createClient = (apiKey, apiRegion = API_REGIONS.SG, { debugSession = DEFAU
|
|
|
8623
9261
|
const useLegacyUnreadCount = true;
|
|
8624
9262
|
const client = {
|
|
8625
9263
|
version: `${VERSION}`,
|
|
9264
|
+
product,
|
|
9265
|
+
uikitVersion,
|
|
9266
|
+
appId,
|
|
9267
|
+
appVersion,
|
|
8626
9268
|
apiKey,
|
|
8627
9269
|
/*
|
|
8628
9270
|
* SDK Components
|
|
@@ -8884,13 +9526,13 @@ class GlobalFileAccessType {
|
|
|
8884
9526
|
}
|
|
8885
9527
|
}
|
|
8886
9528
|
_GlobalFileAccessType_fileAccessType = new WeakMap();
|
|
8887
|
-
let instance
|
|
9529
|
+
let instance;
|
|
8888
9530
|
var GlobalFileAccessType$1 = {
|
|
8889
9531
|
getInstance: () => {
|
|
8890
|
-
if (!instance
|
|
8891
|
-
instance
|
|
9532
|
+
if (!instance) {
|
|
9533
|
+
instance = new GlobalFileAccessType();
|
|
8892
9534
|
}
|
|
8893
|
-
return instance
|
|
9535
|
+
return instance;
|
|
8894
9536
|
},
|
|
8895
9537
|
};
|
|
8896
9538
|
|
|
@@ -9749,7 +10391,7 @@ const getUserUnread = (callback) => {
|
|
|
9749
10391
|
};
|
|
9750
10392
|
};
|
|
9751
10393
|
|
|
9752
|
-
var index$
|
|
10394
|
+
var index$t = /*#__PURE__*/Object.freeze({
|
|
9753
10395
|
__proto__: null,
|
|
9754
10396
|
getActiveClient: getActiveClient,
|
|
9755
10397
|
getActiveUser: getActiveUser,
|
|
@@ -10978,7 +11620,7 @@ const getMyFollowInfo = (callback) => {
|
|
|
10978
11620
|
};
|
|
10979
11621
|
/* end_public_function */
|
|
10980
11622
|
|
|
10981
|
-
var index$
|
|
11623
|
+
var index$s = /*#__PURE__*/Object.freeze({
|
|
10982
11624
|
__proto__: null,
|
|
10983
11625
|
blockUser: blockUser,
|
|
10984
11626
|
unBlockUser: unBlockUser,
|
|
@@ -12319,6 +12961,16 @@ const createChannel = async (bundle) => {
|
|
|
12319
12961
|
/* c8 ignore next */
|
|
12320
12962
|
isPublic: (bundle === null || bundle === void 0 ? void 0 : bundle.type) === 'community' ? isPublic : undefined }));
|
|
12321
12963
|
}
|
|
12964
|
+
// Fire the event locally, the same way createCommunity and createPost do.
|
|
12965
|
+
// Without it a running getChannels collection never inserts the new channel:
|
|
12966
|
+
// its query stream controller inserts an id only on OnCreate / OnJoin /
|
|
12967
|
+
// OnResolveChannel / OnUnarchived, and the first sent message arrives as an
|
|
12968
|
+
// OnUpdate, which only re-notifies. Reusing the MQTT event name means the
|
|
12969
|
+
// already-wired onChannelCreated -> OnCreate path does the insert, so the
|
|
12970
|
+
// list updates without a re-query. onChannelCreated re-runs
|
|
12971
|
+
// prepareChannelPayload + ingestInCache itself, so this is idempotent with
|
|
12972
|
+
// the ingest below.
|
|
12973
|
+
fireEvent('channel.created', payload.data);
|
|
12322
12974
|
const data = await prepareChannelPayload(payload.data);
|
|
12323
12975
|
const cachedAt = client.cache && Date.now();
|
|
12324
12976
|
if (client.cache)
|
|
@@ -12490,8 +13142,32 @@ const streamLinkedObject = (stream) => {
|
|
|
12490
13142
|
} });
|
|
12491
13143
|
};
|
|
12492
13144
|
|
|
13145
|
+
const KNOWN_APPROVAL_STATUSES = [
|
|
13146
|
+
"pending" /* Amity.CommentApprovalStatusEnum.Pending */,
|
|
13147
|
+
"approved" /* Amity.CommentApprovalStatusEnum.Approved */,
|
|
13148
|
+
"rejected" /* Amity.CommentApprovalStatusEnum.Rejected */,
|
|
13149
|
+
];
|
|
13150
|
+
/**
|
|
13151
|
+
* The server sends `approvalStatus` only while a comment is held for review or after it was
|
|
13152
|
+
* rejected. Absent, `null`, or an unrecognised value all resolve to `approved` — never to
|
|
13153
|
+
* `pending`, which would mark every comment written before the feature as unpublished.
|
|
13154
|
+
*/
|
|
13155
|
+
const resolveCommentApprovalStatus = (approvalStatus) => {
|
|
13156
|
+
if (approvalStatus && KNOWN_APPROVAL_STATUSES.includes(approvalStatus)) {
|
|
13157
|
+
return approvalStatus;
|
|
13158
|
+
}
|
|
13159
|
+
return "approved" /* Amity.CommentApprovalStatusEnum.Approved */;
|
|
13160
|
+
};
|
|
13161
|
+
const prepareComment = (comment) => (Object.assign(Object.assign(Object.assign({}, (comment.hasOwnProperty('myReactions') ? {} : { myReactions: [] })), comment), { approvalStatus: resolveCommentApprovalStatus(comment.approvalStatus) }));
|
|
13162
|
+
function prepareCommentPayload(commentPayload) {
|
|
13163
|
+
const { comments, commentChildren } = commentPayload;
|
|
13164
|
+
return Object.assign(Object.assign(Object.assign({}, commentPayload), { comments: comments.map(prepareComment) }), (commentChildren ? { commentChildren: commentChildren.map(prepareComment) } : {}));
|
|
13165
|
+
}
|
|
13166
|
+
|
|
12493
13167
|
const commentLinkedObject = (comment) => {
|
|
12494
|
-
return Object.assign(Object.assign({}, comment), {
|
|
13168
|
+
return Object.assign(Object.assign({}, comment), {
|
|
13169
|
+
// Non-optional on the public model: absent on the wire means approved
|
|
13170
|
+
approvalStatus: resolveCommentApprovalStatus(comment.approvalStatus), get target() {
|
|
12495
13171
|
const commentTypes = {
|
|
12496
13172
|
type: comment.targetType,
|
|
12497
13173
|
};
|
|
@@ -13142,6 +13818,122 @@ const fileLinkedObject = (file) => {
|
|
|
13142
13818
|
return file;
|
|
13143
13819
|
};
|
|
13144
13820
|
|
|
13821
|
+
const isCommentPending = (comment) => resolveCommentApprovalStatus(comment.approvalStatus) === "pending" /* Amity.CommentApprovalStatusEnum.Pending */;
|
|
13822
|
+
const isCommentApproved = (comment) => resolveCommentApprovalStatus(comment.approvalStatus) === "approved" /* Amity.CommentApprovalStatusEnum.Approved */;
|
|
13823
|
+
// Only post and content references feed PostCommentCountEngine; story counts live on the story.
|
|
13824
|
+
const isCountedReference = (comment) => ['post', 'content'].includes(comment.referenceType);
|
|
13825
|
+
const isAuthoredByCurrentUser = (comment) => comment.userId === getActiveClient().userId;
|
|
13826
|
+
/**
|
|
13827
|
+
* Whether a comment on this reference would be held for review, read from the cached post's
|
|
13828
|
+
* community. `true` when that cannot be known — the post or its community is not cached yet.
|
|
13829
|
+
* A pending guess that turns out approved is corrected by the response and the comment then
|
|
13830
|
+
* enters the list; an approved guess that turns out pending has already been shown in a public
|
|
13831
|
+
* list with nothing to take it back out. Only shapes the optimistic object — the server
|
|
13832
|
+
* response is the authority on the actual status.
|
|
13833
|
+
*/
|
|
13834
|
+
const isCommentApprovalRequired = (bundle) => {
|
|
13835
|
+
var _a, _b;
|
|
13836
|
+
// Only comments on community posts are gated; every other reference is known-off
|
|
13837
|
+
if (bundle.referenceType !== 'post')
|
|
13838
|
+
return false;
|
|
13839
|
+
const post = (_a = pullFromCache(['post', 'get', bundle.referenceId])) === null || _a === void 0 ? void 0 : _a.data;
|
|
13840
|
+
if (!post)
|
|
13841
|
+
return true;
|
|
13842
|
+
// A user-feed post is known-off
|
|
13843
|
+
if (post.targetType !== 'community')
|
|
13844
|
+
return false;
|
|
13845
|
+
const community = (_b = pullFromCache([
|
|
13846
|
+
'community',
|
|
13847
|
+
'get',
|
|
13848
|
+
post.targetId,
|
|
13849
|
+
])) === null || _b === void 0 ? void 0 : _b.data;
|
|
13850
|
+
if (!community)
|
|
13851
|
+
return true;
|
|
13852
|
+
return community.needApprovalOnCommentCreation === true;
|
|
13853
|
+
};
|
|
13854
|
+
/**
|
|
13855
|
+
* An approved comment arrived over realtime: one `CreateTask` carrying its own `createdAt`, so
|
|
13856
|
+
* the timestamp filter skips anything the last post payload already counted. The author's own
|
|
13857
|
+
* comment reaches here as an echo too; the engine de-duplicates it by id against the task the
|
|
13858
|
+
* create response queued.
|
|
13859
|
+
*/
|
|
13860
|
+
const applyCommentCreatedCount = (comment) => {
|
|
13861
|
+
if (!isCountedReference(comment))
|
|
13862
|
+
return;
|
|
13863
|
+
PostCommentCountEngine$1.getInstance().queueCommentChangeTask(new CreateTask(comment.referenceId, comment.commentId, comment.createdAt));
|
|
13864
|
+
};
|
|
13865
|
+
/**
|
|
13866
|
+
* The author's own pending comment counts in their view only. Recorded as separate engine state
|
|
13867
|
+
* so it survives a post refresh (`ResetTask`).
|
|
13868
|
+
*/
|
|
13869
|
+
const recordPendingAuthoredComment = (comment, options) => {
|
|
13870
|
+
if (!isCountedReference(comment) || !isAuthoredByCurrentUser(comment))
|
|
13871
|
+
return;
|
|
13872
|
+
PostCommentCountEngine$1.getInstance().addPendingAuthoredComment(comment.referenceId, comment.commentId, options);
|
|
13873
|
+
};
|
|
13874
|
+
/**
|
|
13875
|
+
* A pending comment was declined or deleted: it was never in the server count, so no
|
|
13876
|
+
* `DeleteTask` — only the author-local +1 goes away.
|
|
13877
|
+
*/
|
|
13878
|
+
const releasePendingAuthoredComment = (comment) => {
|
|
13879
|
+
if (!isCountedReference(comment))
|
|
13880
|
+
return;
|
|
13881
|
+
PostCommentCountEngine$1.getInstance().removePendingAuthoredComment(comment.referenceId, comment.commentId);
|
|
13882
|
+
};
|
|
13883
|
+
/**
|
|
13884
|
+
* Reveal: exactly one `ApproveTask`. The engine de-duplicates by comment id, so the approve
|
|
13885
|
+
* response and the `comment.approved` event may both call this. `ApproveTask` bypasses the age
|
|
13886
|
+
* guard on purpose — the comment was written before the last server sync but enters the public
|
|
13887
|
+
* count now — matching the iOS `ApproveTask` (plan 40 §9, guard off for approve).
|
|
13888
|
+
*/
|
|
13889
|
+
const applyCommentApprovedCount = (comment) => {
|
|
13890
|
+
if (!isCountedReference(comment))
|
|
13891
|
+
return;
|
|
13892
|
+
PostCommentCountEngine$1.getInstance().queueCommentChangeTask(new ApproveTask(comment.referenceId, comment.commentId));
|
|
13893
|
+
};
|
|
13894
|
+
/**
|
|
13895
|
+
* Re-review: an approved comment edited back to pending leaves the public count once. The
|
|
13896
|
+
* author keeps their own +1 through the pending set, so their count does not move.
|
|
13897
|
+
*/
|
|
13898
|
+
const applyCommentReReviewCount = (comment) => {
|
|
13899
|
+
if (!isCountedReference(comment))
|
|
13900
|
+
return;
|
|
13901
|
+
recordPendingAuthoredComment(comment, { publish: false });
|
|
13902
|
+
PostCommentCountEngine$1.getInstance().queueCommentChangeTask(new DeleteTask(comment.referenceId, comment.commentId));
|
|
13903
|
+
};
|
|
13904
|
+
/** Adds a reply to its cached parent's `children` (and count) once. */
|
|
13905
|
+
const linkCommentToParent = (comment) => {
|
|
13906
|
+
var _a;
|
|
13907
|
+
if (!comment.parentId)
|
|
13908
|
+
return;
|
|
13909
|
+
const parentKey = ['comment', 'get', comment.parentId];
|
|
13910
|
+
const parent = (_a = pullFromCache(parentKey)) === null || _a === void 0 ? void 0 : _a.data;
|
|
13911
|
+
if (!parent || parent.children.includes(comment.commentId))
|
|
13912
|
+
return;
|
|
13913
|
+
pushToCache(parentKey, Object.assign(Object.assign({}, parent), { childrenNumber: parent.childrenNumber + 1, children: [...new Set([...parent.children, comment.commentId])] }));
|
|
13914
|
+
};
|
|
13915
|
+
/** Removes a reply from its cached parent's `children` (and count) once. */
|
|
13916
|
+
const unlinkCommentFromParent = (comment) => {
|
|
13917
|
+
var _a;
|
|
13918
|
+
if (!comment.parentId)
|
|
13919
|
+
return;
|
|
13920
|
+
const parentKey = ['comment', 'get', comment.parentId];
|
|
13921
|
+
const parent = (_a = pullFromCache(parentKey)) === null || _a === void 0 ? void 0 : _a.data;
|
|
13922
|
+
if (!parent || !parent.children.includes(comment.commentId))
|
|
13923
|
+
return;
|
|
13924
|
+
pushToCache(parentKey, Object.assign(Object.assign({}, parent), { childrenNumber: parent.childrenNumber - 1, children: parent.children.filter(id => id !== comment.commentId) }));
|
|
13925
|
+
};
|
|
13926
|
+
|
|
13927
|
+
/**
|
|
13928
|
+
* The server's list is oldest → newest, so the newest ids are the last ones. Kept unique so the
|
|
13929
|
+
* create response, the local event and the realtime echo cannot each add the same comment.
|
|
13930
|
+
*/
|
|
13931
|
+
const capLatestCommentIds = (commentIds) => [...new Set(commentIds)].slice(-LATEST_COMMENTS_LIMIT);
|
|
13932
|
+
/** A comment belongs in the post preview only while it is cached, not deleted and public. */
|
|
13933
|
+
const isPreviewableComment = (comment) => comment !== undefined && !comment.isDeleted && isCommentApproved(comment);
|
|
13934
|
+
/** The post's preview list after one of the user's own top-level comments is created. */
|
|
13935
|
+
const appendLatestCommentId = (post, commentId) => { var _a; return capLatestCommentIds([...((_a = post.comments) !== null && _a !== void 0 ? _a : []), commentId]); };
|
|
13936
|
+
|
|
13145
13937
|
const postLinkedObject = (post) => {
|
|
13146
13938
|
return shallowClone(post, {
|
|
13147
13939
|
childrenPosts: post.children
|
|
@@ -13165,19 +13957,13 @@ const postLinkedObject = (post) => {
|
|
|
13165
13957
|
get latestComments() {
|
|
13166
13958
|
if (!post.comments)
|
|
13167
13959
|
return [];
|
|
13168
|
-
|
|
13169
|
-
|
|
13170
|
-
|
|
13171
|
-
|
|
13172
|
-
|
|
13173
|
-
|
|
13174
|
-
|
|
13175
|
-
])) === null || _a === void 0 ? void 0 : _a.data;
|
|
13176
|
-
if (!commentCached)
|
|
13177
|
-
return null;
|
|
13178
|
-
return commentLinkedObject(commentCached);
|
|
13179
|
-
})
|
|
13180
|
-
.filter(Boolean) || []);
|
|
13960
|
+
// Same rule as the server's own list and as iOS: deleted and non-public comments are
|
|
13961
|
+
// dropped first, then the newest LATEST_COMMENTS_LIMIT remain
|
|
13962
|
+
return post.comments
|
|
13963
|
+
.map(commentId => { var _a; return (_a = pullFromCache(['comment', 'get', commentId])) === null || _a === void 0 ? void 0 : _a.data; })
|
|
13964
|
+
.filter(isPreviewableComment)
|
|
13965
|
+
.slice(-LATEST_COMMENTS_LIMIT)
|
|
13966
|
+
.map(commentLinkedObject);
|
|
13181
13967
|
},
|
|
13182
13968
|
get creator() {
|
|
13183
13969
|
// The id is checked for a value, not just for presence: a payload can
|
|
@@ -13190,6 +13976,15 @@ const postLinkedObject = (post) => {
|
|
|
13190
13976
|
return undefined;
|
|
13191
13977
|
return userLinkedObject(cacheData.data);
|
|
13192
13978
|
},
|
|
13979
|
+
getLocalCommentCount(includePending = false) {
|
|
13980
|
+
var _a;
|
|
13981
|
+
const engine = PostCommentCountEngine$1.getInstance();
|
|
13982
|
+
// Before any payload has seeded the engine for this post there is no tracker; the
|
|
13983
|
+
// post's own figure is the best answer then.
|
|
13984
|
+
return engine.hasTracker(post.postId)
|
|
13985
|
+
? engine.getLocalCommentCount(post.postId, includePending)
|
|
13986
|
+
: (_a = post.localCommentCount) !== null && _a !== void 0 ? _a : post.commentsCount;
|
|
13987
|
+
},
|
|
13193
13988
|
get targetCommunity() {
|
|
13194
13989
|
var _a;
|
|
13195
13990
|
if (!post.targetId)
|
|
@@ -13554,7 +14349,8 @@ const messageLinkedObject = (message) => {
|
|
|
13554
14349
|
},
|
|
13555
14350
|
get creator() {
|
|
13556
14351
|
var _a;
|
|
13557
|
-
|
|
14352
|
+
const creator = (_a = pullFromCache(['user', 'get', message.creatorId])) === null || _a === void 0 ? void 0 : _a.data;
|
|
14353
|
+
return creator ? userLinkedObject(creator) : undefined;
|
|
13558
14354
|
}, markRead: () => markReadMessage(message), addReaction: (reactionName) => addReactionToMessage(reactionName, message), removeReaction: (reactionName) => removeReactionToMessage(reactionName, message) });
|
|
13559
14355
|
};
|
|
13560
14356
|
|
|
@@ -14215,6 +15011,22 @@ const eventLinkedObject = (event) => {
|
|
|
14215
15011
|
} });
|
|
14216
15012
|
};
|
|
14217
15013
|
|
|
15014
|
+
const curatedContentTopicLinkedObject = (topic) => {
|
|
15015
|
+
return shallowClone(topic, {
|
|
15016
|
+
analytics: {
|
|
15017
|
+
markAsViewed: () => {
|
|
15018
|
+
AnalyticsEngine$1.getInstance().markCuratedContentWidgetAsViewed(topic.topicId);
|
|
15019
|
+
},
|
|
15020
|
+
markPostAsViewed: (postId) => {
|
|
15021
|
+
AnalyticsEngine$1.getInstance().markCuratedContentPostAsViewed(postId, topic.topicId);
|
|
15022
|
+
},
|
|
15023
|
+
markPostClick: (postId) => {
|
|
15024
|
+
AnalyticsEngine$1.getInstance().markCuratedContentPostAsClicked(postId, topic.topicId);
|
|
15025
|
+
},
|
|
15026
|
+
},
|
|
15027
|
+
});
|
|
15028
|
+
};
|
|
15029
|
+
|
|
14218
15030
|
const LinkedObject = {
|
|
14219
15031
|
file: fileLinkedObject,
|
|
14220
15032
|
ad: adLinkedObject,
|
|
@@ -14239,6 +15051,7 @@ const LinkedObject = {
|
|
|
14239
15051
|
eventResponse: eventResponseLinkedObject,
|
|
14240
15052
|
product: productLinkedObject,
|
|
14241
15053
|
poll: pollLinkedObject,
|
|
15054
|
+
curatedContentTopic: curatedContentTopicLinkedObject,
|
|
14242
15055
|
};
|
|
14243
15056
|
|
|
14244
15057
|
/* begin_public_function
|
|
@@ -15561,9 +16374,9 @@ var AmityUserSearchMatchType;
|
|
|
15561
16374
|
AmityUserSearchMatchType["PARTIAL"] = "partial";
|
|
15562
16375
|
})(AmityUserSearchMatchType || (AmityUserSearchMatchType = {}));
|
|
15563
16376
|
|
|
15564
|
-
var index$
|
|
16377
|
+
var index$r = /*#__PURE__*/Object.freeze({
|
|
15565
16378
|
__proto__: null,
|
|
15566
|
-
Relationship: index$
|
|
16379
|
+
Relationship: index$s,
|
|
15567
16380
|
getUserByIds: getUserByIds,
|
|
15568
16381
|
updateUser: updateUser,
|
|
15569
16382
|
flagUser: flagUser,
|
|
@@ -15971,7 +16784,7 @@ const uploadAudio = async (formData, onProgress) => {
|
|
|
15971
16784
|
};
|
|
15972
16785
|
/* end_public_function */
|
|
15973
16786
|
|
|
15974
|
-
var index$
|
|
16787
|
+
var index$q = /*#__PURE__*/Object.freeze({
|
|
15975
16788
|
__proto__: null,
|
|
15976
16789
|
getFile: getFile,
|
|
15977
16790
|
uploadFile: uploadFile,
|
|
@@ -16164,147 +16977,6 @@ getMessage$1.locally = (messageId) => {
|
|
|
16164
16977
|
};
|
|
16165
16978
|
};
|
|
16166
16979
|
|
|
16167
|
-
class ResetTask {
|
|
16168
|
-
constructor(postId, latestCreatedAt, serverCommentCount) {
|
|
16169
|
-
this.postId = postId;
|
|
16170
|
-
this.latestCreatedAt = latestCreatedAt;
|
|
16171
|
-
this.serverCommentCount = serverCommentCount;
|
|
16172
|
-
}
|
|
16173
|
-
}
|
|
16174
|
-
|
|
16175
|
-
// Task to track comment creation
|
|
16176
|
-
class CreateTask {
|
|
16177
|
-
constructor(postId, commentId, createdAt) {
|
|
16178
|
-
this.postId = postId;
|
|
16179
|
-
this.commentId = commentId;
|
|
16180
|
-
this.createdAt = createdAt;
|
|
16181
|
-
}
|
|
16182
|
-
}
|
|
16183
|
-
|
|
16184
|
-
// Task to track comment deletion
|
|
16185
|
-
class DeleteTask {
|
|
16186
|
-
constructor(postId, commentId) {
|
|
16187
|
-
this.postId = postId;
|
|
16188
|
-
this.commentId = commentId;
|
|
16189
|
-
}
|
|
16190
|
-
}
|
|
16191
|
-
|
|
16192
|
-
class CommentChange {
|
|
16193
|
-
constructor(latestCreatedAt, serverCommentCount) {
|
|
16194
|
-
this.latestCommentCreatedAt = latestCreatedAt;
|
|
16195
|
-
this.serverCommentCount = serverCommentCount;
|
|
16196
|
-
this.createdCommentIds = new Set();
|
|
16197
|
-
this.deletedCommentIds = new Set();
|
|
16198
|
-
}
|
|
16199
|
-
}
|
|
16200
|
-
|
|
16201
|
-
class PostCommentCountEngine {
|
|
16202
|
-
constructor() {
|
|
16203
|
-
this.isProcessing = false;
|
|
16204
|
-
this.tasks = [];
|
|
16205
|
-
this.commentChangeTracker = new Map();
|
|
16206
|
-
}
|
|
16207
|
-
queueCommentChangeTask(task) {
|
|
16208
|
-
this.tasks.push(task);
|
|
16209
|
-
if (!this.isProcessing) {
|
|
16210
|
-
this.processCommentChangeTask();
|
|
16211
|
-
}
|
|
16212
|
-
}
|
|
16213
|
-
processCommentChangeTask() {
|
|
16214
|
-
if (this.isProcessing) {
|
|
16215
|
-
return;
|
|
16216
|
-
}
|
|
16217
|
-
this.isProcessing = true;
|
|
16218
|
-
if (this.tasks.length === 0) {
|
|
16219
|
-
this.isProcessing = false;
|
|
16220
|
-
return;
|
|
16221
|
-
}
|
|
16222
|
-
// Process in capped batches, coalescing updates
|
|
16223
|
-
const batch = this.tasks.splice(0, PostCommentCountEngine.BATCH_SIZE);
|
|
16224
|
-
const modifiedPostIds = new Set();
|
|
16225
|
-
batch.forEach(task => {
|
|
16226
|
-
let modified = false;
|
|
16227
|
-
if (task instanceof ResetTask) {
|
|
16228
|
-
modified = this.processResetTaskInternal(task);
|
|
16229
|
-
}
|
|
16230
|
-
else if (task instanceof CreateTask) {
|
|
16231
|
-
modified = this.processCreateTaskInternal(task);
|
|
16232
|
-
}
|
|
16233
|
-
else if (task instanceof DeleteTask) {
|
|
16234
|
-
modified = this.processDeleteTaskInternal(task);
|
|
16235
|
-
}
|
|
16236
|
-
if (modified) {
|
|
16237
|
-
modifiedPostIds.add(task.postId);
|
|
16238
|
-
}
|
|
16239
|
-
});
|
|
16240
|
-
// Publish one update per modified post
|
|
16241
|
-
modifiedPostIds.forEach(postId => {
|
|
16242
|
-
const count = this.computeCommentCount(postId);
|
|
16243
|
-
PostCommentCountEngine.publishUpdate(postId, count);
|
|
16244
|
-
});
|
|
16245
|
-
this.isProcessing = false;
|
|
16246
|
-
// Recurse if more tasks remain
|
|
16247
|
-
if (this.tasks.length > 0) {
|
|
16248
|
-
this.processCommentChangeTask();
|
|
16249
|
-
}
|
|
16250
|
-
}
|
|
16251
|
-
processResetTaskInternal(task) {
|
|
16252
|
-
// Always creates/overwrites tracker
|
|
16253
|
-
this.commentChangeTracker.set(task.postId, new CommentChange(task.latestCreatedAt, task.serverCommentCount));
|
|
16254
|
-
return true;
|
|
16255
|
-
}
|
|
16256
|
-
processCreateTaskInternal(task) {
|
|
16257
|
-
const tracker = this.commentChangeTracker.get(task.postId);
|
|
16258
|
-
if (!tracker)
|
|
16259
|
-
return false; // No tracker, skip
|
|
16260
|
-
if (tracker.createdCommentIds.has(task.commentId))
|
|
16261
|
-
return false; // Deduplication
|
|
16262
|
-
if (task.createdAt <= tracker.latestCommentCreatedAt)
|
|
16263
|
-
return false; // Timestamp filtering
|
|
16264
|
-
tracker.createdCommentIds.add(task.commentId);
|
|
16265
|
-
return true;
|
|
16266
|
-
}
|
|
16267
|
-
processDeleteTaskInternal(task) {
|
|
16268
|
-
const tracker = this.commentChangeTracker.get(task.postId);
|
|
16269
|
-
if (!tracker)
|
|
16270
|
-
return false; // No tracker, skip
|
|
16271
|
-
if (tracker.deletedCommentIds.has(task.commentId))
|
|
16272
|
-
return false; // Deduplication
|
|
16273
|
-
tracker.deletedCommentIds.add(task.commentId);
|
|
16274
|
-
return true;
|
|
16275
|
-
}
|
|
16276
|
-
computeCommentCount(postId) {
|
|
16277
|
-
const tracker = this.commentChangeTracker.get(postId);
|
|
16278
|
-
if (!tracker)
|
|
16279
|
-
return 0;
|
|
16280
|
-
const count = tracker.serverCommentCount + tracker.createdCommentIds.size - tracker.deletedCommentIds.size;
|
|
16281
|
-
return Math.max(0, count);
|
|
16282
|
-
}
|
|
16283
|
-
static publishUpdate(postId, newCount) {
|
|
16284
|
-
var _a;
|
|
16285
|
-
const queryKey = ['post', 'get', postId];
|
|
16286
|
-
mergeInCache(queryKey, {
|
|
16287
|
-
localCommentCount: newCount,
|
|
16288
|
-
});
|
|
16289
|
-
const postPayload = (_a = pullFromCache(queryKey)) === null || _a === void 0 ? void 0 : _a.data;
|
|
16290
|
-
if (!postPayload)
|
|
16291
|
-
return;
|
|
16292
|
-
fireEvent('local.post.updated', {
|
|
16293
|
-
posts: [postPayload],
|
|
16294
|
-
});
|
|
16295
|
-
}
|
|
16296
|
-
}
|
|
16297
|
-
PostCommentCountEngine.BATCH_SIZE = 50;
|
|
16298
|
-
let instance;
|
|
16299
|
-
var PostCommentCountEngine$1 = {
|
|
16300
|
-
getInstance: () => {
|
|
16301
|
-
if (!instance) {
|
|
16302
|
-
instance = new PostCommentCountEngine();
|
|
16303
|
-
}
|
|
16304
|
-
return instance;
|
|
16305
|
-
},
|
|
16306
|
-
};
|
|
16307
|
-
|
|
16308
16980
|
const updateStreamReferences = (streams, streamId, postId) => {
|
|
16309
16981
|
if (!streamId)
|
|
16310
16982
|
return streams;
|
|
@@ -16324,7 +16996,7 @@ const preparePostPayload = (payload) => {
|
|
|
16324
16996
|
let mappedNewStream = [];
|
|
16325
16997
|
// feed type
|
|
16326
16998
|
const posts = postsData.map(post => {
|
|
16327
|
-
var _a, _b, _c
|
|
16999
|
+
var _a, _b, _c;
|
|
16328
17000
|
const feedType = (_a = postPayload.feeds.find(feed => feed.feedId === post.feedId)) === null || _a === void 0 ? void 0 : _a.feedType;
|
|
16329
17001
|
const childPosts = payload.postChildren.filter(children => children.parentPostId === post.postId);
|
|
16330
17002
|
if (childPosts.length > 0 && isAmityLivestreamPost(childPosts[0])) {
|
|
@@ -16343,7 +17015,11 @@ const preparePostPayload = (payload) => {
|
|
|
16343
17015
|
// Queue ResetTask for this post
|
|
16344
17016
|
PostCommentCountEngine$1.getInstance().queueCommentChangeTask(new ResetTask(post.postId, latestCreatedAt, (_c = post.commentsCount) !== null && _c !== void 0 ? _c : 0));
|
|
16345
17017
|
return Object.assign(Object.assign({}, post), { childPosts,
|
|
16346
|
-
feedType,
|
|
17018
|
+
feedType,
|
|
17019
|
+
// The ResetTask above has just seeded the engine, so this is the server figure plus the
|
|
17020
|
+
// author's own pending comments. Reading `post.commentsCount` here instead would overwrite
|
|
17021
|
+
// that +1 in the cache on every refresh, since the ingest that follows merges this object.
|
|
17022
|
+
localCommentCount: PostCommentCountEngine$1.getInstance().getLocalCommentCount(post.postId, true), pinnedProductId: post === null || post === void 0 ? void 0 : post.pinnedProductId });
|
|
16347
17023
|
});
|
|
16348
17024
|
return Object.assign(Object.assign({}, postPayload), { postChildren, videoStreamings: mappedNewStream, posts, communities: communityWithMembershipStatus, communityUsers: mappedCommunityUsers });
|
|
16349
17025
|
};
|
|
@@ -17096,62 +17772,67 @@ const onPostReactionRemoved = (callback) => {
|
|
|
17096
17772
|
return createEventSubscriber(client, 'post.removeReaction', 'post.removeReaction', filter);
|
|
17097
17773
|
};
|
|
17098
17774
|
|
|
17775
|
+
/**
|
|
17776
|
+
* `comment.created` fires while a comment is still pending, so delivery is not visibility. The
|
|
17777
|
+
* two side effects that make a comment public — the parent link that feeds the reply list and
|
|
17778
|
+
* the comment-count task — are gated here; `comment.approved` is the only reveal signal, and a
|
|
17779
|
+
* decline arrives as `comment.deleted`.
|
|
17780
|
+
*/
|
|
17781
|
+
const applyApprovalSideEffects = (event, comment, previous) => {
|
|
17782
|
+
switch (event) {
|
|
17783
|
+
case 'comment.created':
|
|
17784
|
+
if (isCommentPending(comment)) {
|
|
17785
|
+
recordPendingAuthoredComment(comment);
|
|
17786
|
+
}
|
|
17787
|
+
else {
|
|
17788
|
+
linkCommentToParent(comment);
|
|
17789
|
+
applyCommentCreatedCount(comment);
|
|
17790
|
+
}
|
|
17791
|
+
break;
|
|
17792
|
+
case 'comment.approved':
|
|
17793
|
+
linkCommentToParent(comment);
|
|
17794
|
+
applyCommentApprovedCount(comment);
|
|
17795
|
+
break;
|
|
17796
|
+
case 'comment.updated':
|
|
17797
|
+
// An effective edit in a gated community sends an approved comment back for review
|
|
17798
|
+
if (isCommentPending(comment) && previous && isCommentApproved(previous)) {
|
|
17799
|
+
unlinkCommentFromParent(comment);
|
|
17800
|
+
applyCommentReReviewCount(comment);
|
|
17801
|
+
}
|
|
17802
|
+
break;
|
|
17803
|
+
case 'comment.deleted':
|
|
17804
|
+
unlinkCommentFromParent(comment);
|
|
17805
|
+
// A pending comment was never counted, so its deletion (or decline) moves no count
|
|
17806
|
+
if (previous && isCommentPending(previous))
|
|
17807
|
+
releasePendingAuthoredComment(comment);
|
|
17808
|
+
break;
|
|
17809
|
+
}
|
|
17810
|
+
};
|
|
17099
17811
|
const createCommentEventSubscriber = (event, callback) => {
|
|
17100
17812
|
const client = getActiveClient();
|
|
17101
17813
|
const filter = (payload) => {
|
|
17102
|
-
var _a;
|
|
17814
|
+
var _a, _b;
|
|
17103
17815
|
if (!client.cache) {
|
|
17104
17816
|
// TODO: here we are missing specific properties here!
|
|
17105
17817
|
callback(LinkedObject.comment(payload.comments[0]));
|
|
17106
17818
|
}
|
|
17107
17819
|
else {
|
|
17108
|
-
const
|
|
17820
|
+
const flagged = ['comment.flagged', 'comment.unflagged'].includes(event)
|
|
17109
17821
|
? prepareCommentFromFlaggedEvent(payload)
|
|
17110
17822
|
: payload;
|
|
17111
|
-
//
|
|
17112
|
-
|
|
17823
|
+
// Resolve `approvalStatus` before the merge: an absent value means approved and has to
|
|
17824
|
+
// overwrite a cached `pending`, which a plain merge would leave in place.
|
|
17825
|
+
const processed = prepareCommentPayload(flagged);
|
|
17113
17826
|
const { comments } = processed;
|
|
17114
17827
|
if (comments.length > 0) {
|
|
17115
|
-
const
|
|
17116
|
-
|
|
17117
|
-
|
|
17118
|
-
|
|
17119
|
-
|
|
17120
|
-
|
|
17121
|
-
if (comments[0].parentId) {
|
|
17122
|
-
const parentComment = pullFromCache([
|
|
17123
|
-
'comment',
|
|
17124
|
-
'get',
|
|
17125
|
-
comments[0].parentId,
|
|
17126
|
-
]);
|
|
17127
|
-
if (parentComment === null || parentComment === void 0 ? void 0 : parentComment.data) {
|
|
17128
|
-
// Skip to update parent childComment if current comment already exists
|
|
17129
|
-
if (!parentComment.data.children.includes(comments[0].commentId)) {
|
|
17130
|
-
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])] }));
|
|
17131
|
-
}
|
|
17132
|
-
}
|
|
17133
|
-
}
|
|
17134
|
-
}
|
|
17828
|
+
const commentKey = ['comment', 'get', comments[0].commentId];
|
|
17829
|
+
const previous = (_a = pullFromCache(commentKey)) === null || _a === void 0 ? void 0 : _a.data;
|
|
17830
|
+
// NOTE: The event data should be merge with existing cache rather than replace it
|
|
17831
|
+
ingestInCache(processed, undefined, false);
|
|
17832
|
+
const comment = pullFromCache(commentKey);
|
|
17833
|
+
applyApprovalSideEffects(event, comment.data, previous);
|
|
17135
17834
|
if (['comment.deleted'].includes(event)) {
|
|
17136
|
-
|
|
17137
|
-
const parentComment = pullFromCache([
|
|
17138
|
-
'comment',
|
|
17139
|
-
'get',
|
|
17140
|
-
comments[0].parentId,
|
|
17141
|
-
]);
|
|
17142
|
-
if (parentComment === null || parentComment === void 0 ? void 0 : parentComment.data) {
|
|
17143
|
-
// Remove deleted comment in parent childComment if still exists
|
|
17144
|
-
if (parentComment.data.children.includes(comments[0].commentId)) {
|
|
17145
|
-
const newParentComment = Object.assign(Object.assign({}, parentComment.data), { childrenNumber: parentComment.data.childrenNumber - 1, children: [
|
|
17146
|
-
...new Set([
|
|
17147
|
-
...parentComment.data.children.filter(id => id !== comments[0].commentId),
|
|
17148
|
-
]),
|
|
17149
|
-
] });
|
|
17150
|
-
pushToCache(['comment', 'get', comments[0].parentId], newParentComment);
|
|
17151
|
-
}
|
|
17152
|
-
}
|
|
17153
|
-
}
|
|
17154
|
-
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; });
|
|
17835
|
+
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; });
|
|
17155
17836
|
queries === null || queries === void 0 ? void 0 : queries.map(({ key, data }) => upsertInCache(key, data, { cachedAt: -1 }));
|
|
17156
17837
|
}
|
|
17157
17838
|
callback(LinkedObject.comment(comment.data));
|
|
@@ -17163,13 +17844,13 @@ const createCommentEventSubscriber = (event, callback) => {
|
|
|
17163
17844
|
const createLocalCommentEventSubscriber = (event, callback) => {
|
|
17164
17845
|
const client = getActiveClient();
|
|
17165
17846
|
const filter = (payload) => {
|
|
17166
|
-
var _a, _b, _c, _d
|
|
17847
|
+
var _a, _b, _c, _d;
|
|
17167
17848
|
if (!client.cache) {
|
|
17168
17849
|
// TODO: here we are missing specific properties here!
|
|
17169
17850
|
callback(LinkedObject.comment(payload.comments[0]));
|
|
17170
17851
|
}
|
|
17171
17852
|
else {
|
|
17172
|
-
const processed = payload;
|
|
17853
|
+
const processed = prepareCommentPayload(payload);
|
|
17173
17854
|
ingestInCache(processed);
|
|
17174
17855
|
const { comments } = processed;
|
|
17175
17856
|
if (comments.length > 0) {
|
|
@@ -17178,7 +17859,9 @@ const createLocalCommentEventSubscriber = (event, callback) => {
|
|
|
17178
17859
|
'get',
|
|
17179
17860
|
comments[0].commentId,
|
|
17180
17861
|
]);
|
|
17181
|
-
|
|
17862
|
+
// A pending comment is persisted for its author but never linked into the public
|
|
17863
|
+
// surfaces (parent reply list, post comment list)
|
|
17864
|
+
if (['local.comment.created'].includes(event) && isCommentApproved(comments[0])) {
|
|
17182
17865
|
if (comments[0].parentId) {
|
|
17183
17866
|
const parentComment = pullFromCache([
|
|
17184
17867
|
'comment',
|
|
@@ -17207,11 +17890,11 @@ const createLocalCommentEventSubscriber = (event, callback) => {
|
|
|
17207
17890
|
const postCacheKey = ['post', 'get', comments[0].referenceId];
|
|
17208
17891
|
const postCache = (_a = pullFromCache(postCacheKey)) === null || _a === void 0 ? void 0 : _a.data;
|
|
17209
17892
|
if (postCache) {
|
|
17210
|
-
const updatedPostCache = Object.assign(Object.assign({}, postCache), { comments:
|
|
17893
|
+
const updatedPostCache = Object.assign(Object.assign({}, postCache), { comments: appendLatestCommentId(postCache, comments[0].commentId) });
|
|
17211
17894
|
pushToCache(postCacheKey, updatedPostCache);
|
|
17212
17895
|
}
|
|
17213
17896
|
}
|
|
17214
|
-
const queries = (
|
|
17897
|
+
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; });
|
|
17215
17898
|
queries === null || queries === void 0 ? void 0 : queries.map(({ key, data }) => upsertInCache(key, data, { cachedAt: -1 }));
|
|
17216
17899
|
}
|
|
17217
17900
|
if (['local.comment.deleted'].includes(event)) {
|
|
@@ -17245,13 +17928,13 @@ const createLocalCommentEventSubscriber = (event, callback) => {
|
|
|
17245
17928
|
}
|
|
17246
17929
|
else {
|
|
17247
17930
|
const postCacheKey = ['post', 'get', comments[0].referenceId];
|
|
17248
|
-
const postCache = (
|
|
17931
|
+
const postCache = (_c = pullFromCache(postCacheKey)) === null || _c === void 0 ? void 0 : _c.data;
|
|
17249
17932
|
if (postCache) {
|
|
17250
17933
|
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); }) });
|
|
17251
17934
|
pushToCache(postCacheKey, updatedPost);
|
|
17252
17935
|
}
|
|
17253
17936
|
}
|
|
17254
|
-
const queries = (
|
|
17937
|
+
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; });
|
|
17255
17938
|
queries === null || queries === void 0 ? void 0 : queries.map(({ key, data }) => upsertInCache(key, data, { cachedAt: -1 }));
|
|
17256
17939
|
}
|
|
17257
17940
|
callback(LinkedObject.comment(comment.data));
|
|
@@ -17312,6 +17995,23 @@ const onCommentUpdated = (callback) => createCommentEventSubscriber('comment.upd
|
|
|
17312
17995
|
*/
|
|
17313
17996
|
const onCommentDeleted = (callback) => createCommentEventSubscriber('comment.deleted', callback);
|
|
17314
17997
|
|
|
17998
|
+
/**
|
|
17999
|
+
* ```js
|
|
18000
|
+
* import { onCommentApproved } from '@amityco/ts-sdk'
|
|
18001
|
+
* const dispose = onCommentApproved(comment => {
|
|
18002
|
+
* // ...
|
|
18003
|
+
* })
|
|
18004
|
+
* ```
|
|
18005
|
+
*
|
|
18006
|
+
* Fired when a {@link Amity.InternalComment} held for review has been approved
|
|
18007
|
+
*
|
|
18008
|
+
* @param callback The function to call when the event was fired
|
|
18009
|
+
* @returns an {@link Amity.Unsubscriber} function to stop listening
|
|
18010
|
+
*
|
|
18011
|
+
* @category Comment Events
|
|
18012
|
+
*/
|
|
18013
|
+
const onCommentApproved = (callback) => createCommentEventSubscriber('comment.approved', callback);
|
|
18014
|
+
|
|
17315
18015
|
/**
|
|
17316
18016
|
* ```js
|
|
17317
18017
|
* import { onCommentFlagged } from '@amityco/ts-sdk-react-native'
|
|
@@ -17944,7 +18644,7 @@ const getReactions$1 = (params, callback, config) => {
|
|
|
17944
18644
|
};
|
|
17945
18645
|
/* end_public_function */
|
|
17946
18646
|
|
|
17947
|
-
var index$
|
|
18647
|
+
var index$p = /*#__PURE__*/Object.freeze({
|
|
17948
18648
|
__proto__: null,
|
|
17949
18649
|
addReaction: addReaction,
|
|
17950
18650
|
removeReaction: removeReaction,
|
|
@@ -17955,17 +18655,6 @@ var index$o = /*#__PURE__*/Object.freeze({
|
|
|
17955
18655
|
getReactions: getReactions$1
|
|
17956
18656
|
});
|
|
17957
18657
|
|
|
17958
|
-
function prepareCommentPayload(commentPayload) {
|
|
17959
|
-
const { comments } = commentPayload;
|
|
17960
|
-
return Object.assign(Object.assign({}, commentPayload), { comments: comments.map(comment => {
|
|
17961
|
-
if (comment.hasOwnProperty('myReactions'))
|
|
17962
|
-
return comment;
|
|
17963
|
-
// Sometimes `myReactions` field will not come with BE response because that field is empty
|
|
17964
|
-
// We need to put it with an empty array manually to make it show up in client side
|
|
17965
|
-
return Object.assign({ myReactions: [] }, comment);
|
|
17966
|
-
}) });
|
|
17967
|
-
}
|
|
17968
|
-
|
|
17969
18658
|
const createMessageReport = async ({ client, referenceId, }) => {
|
|
17970
18659
|
const { data: payload } = await client.http.post(`/api/v5/messages/${encodeURIComponent(referenceId)}/flags`);
|
|
17971
18660
|
if (client.cache) {
|
|
@@ -18429,20 +19118,20 @@ const getArchivedChannelIds = async () => {
|
|
|
18429
19118
|
|
|
18430
19119
|
/**
|
|
18431
19120
|
* ```js
|
|
18432
|
-
* import {
|
|
18433
|
-
* const dispose =
|
|
19121
|
+
* import { onMessageDeleted } from '@amityco/ts-sdk-react-native'
|
|
19122
|
+
* const dispose = onMessageDeleted(message => {
|
|
18434
19123
|
* // ...
|
|
18435
19124
|
* })
|
|
18436
19125
|
* ```
|
|
18437
19126
|
*
|
|
18438
|
-
* Fired when an {@link Amity.Message}
|
|
19127
|
+
* Fired when an {@link Amity.Message} was deleted
|
|
18439
19128
|
*
|
|
18440
19129
|
* @param callback The function to call when the event was fired
|
|
18441
19130
|
* @returns an {@link Amity.Unsubscriber} function to stop listening
|
|
18442
19131
|
*
|
|
18443
19132
|
* @category Message Events
|
|
18444
19133
|
*/
|
|
18445
|
-
const
|
|
19134
|
+
const onMessageDeleted = (callback) => {
|
|
18446
19135
|
const client = getActiveClient();
|
|
18447
19136
|
const filter = async (rawPayload) => {
|
|
18448
19137
|
const payload = await prepareMessagePayload(rawPayload);
|
|
@@ -18450,30 +19139,48 @@ const onMessageUpdated = (callback) => {
|
|
|
18450
19139
|
callback(payload.messages[0]);
|
|
18451
19140
|
};
|
|
18452
19141
|
const disposers = [
|
|
18453
|
-
createEventSubscriber(client, '
|
|
18454
|
-
createEventSubscriber(client, '
|
|
19142
|
+
createEventSubscriber(client, 'message/onMessageDeleted', 'message.deleted', filter),
|
|
19143
|
+
createEventSubscriber(client, 'message/onMessageDeleted', 'local.message.deleted', payload => callback(payload.messages[0])),
|
|
18455
19144
|
];
|
|
18456
19145
|
return () => {
|
|
18457
19146
|
disposers.forEach(fn => fn());
|
|
18458
19147
|
};
|
|
18459
19148
|
};
|
|
18460
19149
|
|
|
19150
|
+
/**
|
|
19151
|
+
* Defensive clear of `channel.pinnedMessage` when the pinned message itself is deleted.
|
|
19152
|
+
*
|
|
19153
|
+
* The server also emits `channel.messageUnpinned` in this case, but realtime events are
|
|
19154
|
+
* fire-and-forget and their order is not guaranteed. Clearing on `message.deleted`
|
|
19155
|
+
* (MQTT or local) makes the banner disappear even if the unpin event is lost; the
|
|
19156
|
+
* server's own `messageUnpinned` then becomes a no-op.
|
|
19157
|
+
*
|
|
19158
|
+
* Internal — wired into the `getChannel` live object; not exported publicly.
|
|
19159
|
+
*/
|
|
19160
|
+
const onChannelPinnedMessageDeleted = (callback) => onMessageDeleted(message => {
|
|
19161
|
+
var _a;
|
|
19162
|
+
const channel = findCachedChannelByAnyId(message.channelId);
|
|
19163
|
+
if (!channel || ((_a = channel.pinnedMessage) === null || _a === void 0 ? void 0 : _a.messageId) !== message.messageId)
|
|
19164
|
+
return;
|
|
19165
|
+
callback(updatePinnedMessageCache(channel, null));
|
|
19166
|
+
});
|
|
19167
|
+
|
|
18461
19168
|
/**
|
|
18462
19169
|
* ```js
|
|
18463
|
-
* import {
|
|
18464
|
-
* const dispose =
|
|
19170
|
+
* import { onMessageUpdated } from '@amityco/ts-sdk-react-native'
|
|
19171
|
+
* const dispose = onMessageUpdated(message => {
|
|
18465
19172
|
* // ...
|
|
18466
19173
|
* })
|
|
18467
19174
|
* ```
|
|
18468
19175
|
*
|
|
18469
|
-
* Fired when an {@link Amity.Message}
|
|
19176
|
+
* Fired when an {@link Amity.Message} has been updated
|
|
18470
19177
|
*
|
|
18471
19178
|
* @param callback The function to call when the event was fired
|
|
18472
19179
|
* @returns an {@link Amity.Unsubscriber} function to stop listening
|
|
18473
19180
|
*
|
|
18474
19181
|
* @category Message Events
|
|
18475
19182
|
*/
|
|
18476
|
-
const
|
|
19183
|
+
const onMessageUpdated = (callback) => {
|
|
18477
19184
|
const client = getActiveClient();
|
|
18478
19185
|
const filter = async (rawPayload) => {
|
|
18479
19186
|
const payload = await prepareMessagePayload(rawPayload);
|
|
@@ -18481,8 +19188,8 @@ const onMessageDeleted = (callback) => {
|
|
|
18481
19188
|
callback(payload.messages[0]);
|
|
18482
19189
|
};
|
|
18483
19190
|
const disposers = [
|
|
18484
|
-
createEventSubscriber(client, '
|
|
18485
|
-
createEventSubscriber(client, '
|
|
19191
|
+
createEventSubscriber(client, 'onMessageUpdated', 'message.updated', filter),
|
|
19192
|
+
createEventSubscriber(client, 'onMessageUpdated', 'local.message.updated', payload => callback(payload.messages[0])),
|
|
18486
19193
|
];
|
|
18487
19194
|
return () => {
|
|
18488
19195
|
disposers.forEach(fn => fn());
|
|
@@ -19063,6 +19770,132 @@ softDeleteMessage.optimistically = (messageId) => {
|
|
|
19063
19770
|
};
|
|
19064
19771
|
/* end_public_function */
|
|
19065
19772
|
|
|
19773
|
+
/**
|
|
19774
|
+
* Fire-and-forget refresh of `channelUsers[...].permissions` for the channel a
|
|
19775
|
+
* message belongs to. Used by `pinMessage` / `unpinMessage` on `403` so the next
|
|
19776
|
+
* `hasPermission(PIN_MESSAGE).channel(channelId)` reflects a revoked role
|
|
19777
|
+
* ([`pinMessage` REQ-010](../../@types/../..) / [`unpinMessage` REQ-008](../../@types/../..)).
|
|
19778
|
+
*
|
|
19779
|
+
* The API only receives a `messageId`, so the channel is resolved through the
|
|
19780
|
+
* local cache: first the message row, then any cached channel whose current pin
|
|
19781
|
+
* is that message. When nothing matches the refresh is skipped — the next
|
|
19782
|
+
* channel read picks up the fresh permissions anyway.
|
|
19783
|
+
*/
|
|
19784
|
+
const refreshChannelPermissionsForMessage = (messageId) => {
|
|
19785
|
+
var _a, _b, _c;
|
|
19786
|
+
const cachedMessage = (_a = getMessage$1.locally(messageId)) === null || _a === void 0 ? void 0 : _a.data;
|
|
19787
|
+
let channelId = cachedMessage === null || cachedMessage === void 0 ? void 0 : cachedMessage.channelId;
|
|
19788
|
+
if (!channelId) {
|
|
19789
|
+
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;
|
|
19790
|
+
}
|
|
19791
|
+
if (!channelId)
|
|
19792
|
+
return;
|
|
19793
|
+
getChannel$1(channelId).catch(() => {
|
|
19794
|
+
/* silent per spec; UIKit renders no error toast */
|
|
19795
|
+
});
|
|
19796
|
+
};
|
|
19797
|
+
|
|
19798
|
+
/* begin_public_function
|
|
19799
|
+
id: message.pin
|
|
19800
|
+
*/
|
|
19801
|
+
/**
|
|
19802
|
+
* ```js
|
|
19803
|
+
* import { MessageRepository } from '@amityco/ts-sdk'
|
|
19804
|
+
* const channel = await MessageRepository.pinMessage(messageId)
|
|
19805
|
+
* console.log(channel.pinnedMessage)
|
|
19806
|
+
* ```
|
|
19807
|
+
*
|
|
19808
|
+
* Pins a {@link Amity.Message} in its livestream (`live`) channel. A channel holds at
|
|
19809
|
+
* most one pinned message: pinning a different message replaces the current pin in a
|
|
19810
|
+
* single step — no unpin is needed first. Pinning the message that is already pinned is
|
|
19811
|
+
* rejected by the server (400).
|
|
19812
|
+
*
|
|
19813
|
+
* The caller must hold the `PIN_MESSAGE` permission in the channel (or be an admin with
|
|
19814
|
+
* `ModerateChannel`). The server also rejects pinning a deleted message, a message whose
|
|
19815
|
+
* author is banned from the channel or globally banned, and pinning in any channel type
|
|
19816
|
+
* other than `live`. On any error the pin state is left unchanged.
|
|
19817
|
+
*
|
|
19818
|
+
* The response is the affected channel; it is ingested into cache and fires
|
|
19819
|
+
* `local.channel.updated`, so `ChannelRepository.getChannel` observers update without
|
|
19820
|
+
* waiting for the `channel.messagePinned` realtime event.
|
|
19821
|
+
*
|
|
19822
|
+
* @param messageId the **internal** ID of the {@link Amity.Message} to pin
|
|
19823
|
+
* @returns the updated {@link Amity.Channel}, with `pinnedMessage` set
|
|
19824
|
+
*
|
|
19825
|
+
* @category Message API
|
|
19826
|
+
* @async
|
|
19827
|
+
*/
|
|
19828
|
+
const pinMessage = async (messageId) => {
|
|
19829
|
+
const client = getActiveClient();
|
|
19830
|
+
client.log('message/pinMessage', messageId);
|
|
19831
|
+
let payload;
|
|
19832
|
+
try {
|
|
19833
|
+
({ data: payload } = await client.http.post(`/api/v5/messages/${encodeURIComponent(messageId)}/pin`));
|
|
19834
|
+
}
|
|
19835
|
+
catch (error) {
|
|
19836
|
+
if ((error === null || error === void 0 ? void 0 : error.code) === 400301 /* Amity.ServerError.PERMISSION_DENIED */) {
|
|
19837
|
+
refreshChannelPermissionsForMessage(messageId);
|
|
19838
|
+
}
|
|
19839
|
+
throw error;
|
|
19840
|
+
}
|
|
19841
|
+
const data = await prepareChannelPayload(payload);
|
|
19842
|
+
if (client.cache)
|
|
19843
|
+
ingestInCache(data);
|
|
19844
|
+
fireEvent('local.channel.updated', data);
|
|
19845
|
+
return constructChannelObject(data.channels[0]);
|
|
19846
|
+
};
|
|
19847
|
+
/* end_public_function */
|
|
19848
|
+
|
|
19849
|
+
/* begin_public_function
|
|
19850
|
+
id: message.unpin
|
|
19851
|
+
*/
|
|
19852
|
+
/**
|
|
19853
|
+
* ```js
|
|
19854
|
+
* import { MessageRepository } from '@amityco/ts-sdk'
|
|
19855
|
+
* const channel = await MessageRepository.unpinMessage(messageId)
|
|
19856
|
+
* console.log(channel.pinnedMessage) // null
|
|
19857
|
+
* ```
|
|
19858
|
+
*
|
|
19859
|
+
* Removes the pin from a {@link Amity.Message}. `messageId` must be the message that is
|
|
19860
|
+
* **currently** pinned in its channel; otherwise the server answers 400 — this is
|
|
19861
|
+
* deliberate, so a stale client cannot clear a pin that someone else has since replaced.
|
|
19862
|
+
* On that error, re-read the channel (or rely on the `channel.messagePinned` event) to
|
|
19863
|
+
* get the current pin.
|
|
19864
|
+
*
|
|
19865
|
+
* The caller must hold the `PIN_MESSAGE` permission in the channel (or be an admin with
|
|
19866
|
+
* `ModerateChannel`). Unpinning is allowed regardless of channel type and stream state.
|
|
19867
|
+
*
|
|
19868
|
+
* The response is the affected channel; it is ingested into cache and fires
|
|
19869
|
+
* `local.channel.updated`, so `ChannelRepository.getChannel` observers update without
|
|
19870
|
+
* waiting for the `channel.messageUnpinned` realtime event.
|
|
19871
|
+
*
|
|
19872
|
+
* @param messageId the **internal** ID of the currently pinned {@link Amity.Message}
|
|
19873
|
+
* @returns the updated {@link Amity.Channel}, with `pinnedMessage` cleared
|
|
19874
|
+
*
|
|
19875
|
+
* @category Message API
|
|
19876
|
+
* @async
|
|
19877
|
+
*/
|
|
19878
|
+
const unpinMessage = async (messageId) => {
|
|
19879
|
+
const client = getActiveClient();
|
|
19880
|
+
client.log('message/unpinMessage', messageId);
|
|
19881
|
+
let payload;
|
|
19882
|
+
try {
|
|
19883
|
+
({ data: payload } = await client.http.delete(`/api/v5/messages/${encodeURIComponent(messageId)}/pin`));
|
|
19884
|
+
}
|
|
19885
|
+
catch (error) {
|
|
19886
|
+
if ((error === null || error === void 0 ? void 0 : error.code) === 400301 /* Amity.ServerError.PERMISSION_DENIED */) {
|
|
19887
|
+
refreshChannelPermissionsForMessage(messageId);
|
|
19888
|
+
}
|
|
19889
|
+
throw error;
|
|
19890
|
+
}
|
|
19891
|
+
const data = await prepareChannelPayload(payload);
|
|
19892
|
+
if (client.cache)
|
|
19893
|
+
ingestInCache(data);
|
|
19894
|
+
fireEvent('local.channel.updated', data);
|
|
19895
|
+
return constructChannelObject(data.channels[0]);
|
|
19896
|
+
};
|
|
19897
|
+
/* end_public_function */
|
|
19898
|
+
|
|
19066
19899
|
/**
|
|
19067
19900
|
* ```js
|
|
19068
19901
|
* import { MessageRepository } from '@amityco/ts-sdk-react-native'
|
|
@@ -19959,13 +20792,15 @@ const searchMessage = (params, callback) => {
|
|
|
19959
20792
|
};
|
|
19960
20793
|
/* end_public_function */
|
|
19961
20794
|
|
|
19962
|
-
var index$
|
|
20795
|
+
var index$o = /*#__PURE__*/Object.freeze({
|
|
19963
20796
|
__proto__: null,
|
|
19964
20797
|
createMessage: createMessage,
|
|
19965
20798
|
updateMessage: updateMessage,
|
|
19966
20799
|
editMessage: editMessage,
|
|
19967
20800
|
deleteMessage: deleteMessage,
|
|
19968
20801
|
softDeleteMessage: softDeleteMessage,
|
|
20802
|
+
pinMessage: pinMessage,
|
|
20803
|
+
unpinMessage: unpinMessage,
|
|
19969
20804
|
markAsDelivered: markAsDelivered,
|
|
19970
20805
|
getReadUsers: getReadUsers,
|
|
19971
20806
|
getDeliveredUsers: getDeliveredUsers,
|
|
@@ -20495,7 +21330,7 @@ const stopMessageReceiptSync = (subChannelId) => {
|
|
|
20495
21330
|
};
|
|
20496
21331
|
/* end_public_function */
|
|
20497
21332
|
|
|
20498
|
-
var index$
|
|
21333
|
+
var index$n = /*#__PURE__*/Object.freeze({
|
|
20499
21334
|
__proto__: null,
|
|
20500
21335
|
getSubChannelByIds: getSubChannels$1,
|
|
20501
21336
|
createSubChannel: createSubChannel,
|
|
@@ -20602,7 +21437,12 @@ const getChannel = (channelId, callback) => {
|
|
|
20602
21437
|
onChannelMemberRemoved,
|
|
20603
21438
|
onChannelMemberBanned,
|
|
20604
21439
|
onChannelMemberUnbanned,
|
|
21440
|
+
onChannelMemberRoleAdded,
|
|
21441
|
+
onChannelMemberRoleRemoved,
|
|
20605
21442
|
onChannelSetMuted,
|
|
21443
|
+
onChannelMessagePinned,
|
|
21444
|
+
onChannelMessageUnpinned,
|
|
21445
|
+
onChannelPinnedMessageDeleted,
|
|
20606
21446
|
convertEventPayload(onChannelMarkerFetched, 'entityId', 'channel'),
|
|
20607
21447
|
convertEventPayload(onChannelMarkerUpdated, 'entityId', 'channel'),
|
|
20608
21448
|
convertEventPayload((callback) => {
|
|
@@ -21228,6 +22068,14 @@ class ChannelLiveCollectionController extends LiveCollectionController {
|
|
|
21228
22068
|
return;
|
|
21229
22069
|
if (messagePreviewSetting ===
|
|
21230
22070
|
"message-preview-not-include-deleted" /* Amity.MessagePreviewSetting.MESSAGE_PREVIEW_NOT_INCLUDE_DELETED */) {
|
|
22071
|
+
// The replacement preview the server sends back is an OLDER
|
|
22072
|
+
// message than the one just deleted, and
|
|
22073
|
+
// updateChannelMessagePreviewCache drops any preview that is not
|
|
22074
|
+
// newer than what is cached — so without clearing the entry
|
|
22075
|
+
// first the refetch is a no-op and the channel keeps showing the
|
|
22076
|
+
// deleted message. getChannel's own live object already does
|
|
22077
|
+
// this; the live collections did not.
|
|
22078
|
+
dropFromCache(['messagePreviewChannel', 'get', message.channelId]);
|
|
21231
22079
|
await getChannel$1(message.channelId);
|
|
21232
22080
|
}
|
|
21233
22081
|
callback(message);
|
|
@@ -21952,6 +22800,14 @@ class SearchChannelLiveCollectionController extends LiveCollectionController {
|
|
|
21952
22800
|
return;
|
|
21953
22801
|
if (messagePreviewSetting ===
|
|
21954
22802
|
"message-preview-not-include-deleted" /* Amity.MessagePreviewSetting.MESSAGE_PREVIEW_NOT_INCLUDE_DELETED */) {
|
|
22803
|
+
// The replacement preview the server sends back is an OLDER
|
|
22804
|
+
// message than the one just deleted, and
|
|
22805
|
+
// updateChannelMessagePreviewCache drops any preview that is not
|
|
22806
|
+
// newer than what is cached — so without clearing the entry
|
|
22807
|
+
// first the refetch is a no-op and the channel keeps showing the
|
|
22808
|
+
// deleted message. getChannel's own live object already does
|
|
22809
|
+
// this; the live collections did not.
|
|
22810
|
+
dropFromCache(['messagePreviewChannel', 'get', message.channelId]);
|
|
21955
22811
|
await getChannel$1(message.channelId);
|
|
21956
22812
|
}
|
|
21957
22813
|
callback(message);
|
|
@@ -22446,7 +23302,7 @@ const searchMembers$1 = (params, callback, config) => {
|
|
|
22446
23302
|
};
|
|
22447
23303
|
/* end_public_function */
|
|
22448
23304
|
|
|
22449
|
-
var index$
|
|
23305
|
+
var index$m = /*#__PURE__*/Object.freeze({
|
|
22450
23306
|
__proto__: null,
|
|
22451
23307
|
addMembers: addMembers$1,
|
|
22452
23308
|
removeMembers: removeMembers$1,
|
|
@@ -22668,7 +23524,7 @@ const unmuteMembers = async (channelId, userIds) => {
|
|
|
22668
23524
|
};
|
|
22669
23525
|
/* end_public_function */
|
|
22670
23526
|
|
|
22671
|
-
var index$
|
|
23527
|
+
var index$l = /*#__PURE__*/Object.freeze({
|
|
22672
23528
|
__proto__: null,
|
|
22673
23529
|
addRole: addRole,
|
|
22674
23530
|
removeRole: removeRole,
|
|
@@ -22678,10 +23534,10 @@ var index$k = /*#__PURE__*/Object.freeze({
|
|
|
22678
23534
|
unmuteMembers: unmuteMembers
|
|
22679
23535
|
});
|
|
22680
23536
|
|
|
22681
|
-
var index$
|
|
23537
|
+
var index$k = /*#__PURE__*/Object.freeze({
|
|
22682
23538
|
__proto__: null,
|
|
22683
|
-
Membership: index$
|
|
22684
|
-
Moderation: index$
|
|
23539
|
+
Membership: index$m,
|
|
23540
|
+
Moderation: index$l,
|
|
22685
23541
|
getChannelByIds: getChannelByIds$1,
|
|
22686
23542
|
createChannel: createChannel,
|
|
22687
23543
|
updateChannel: updateChannel,
|
|
@@ -22699,6 +23555,8 @@ var index$j = /*#__PURE__*/Object.freeze({
|
|
|
22699
23555
|
onChannelJoined: onChannelJoined,
|
|
22700
23556
|
onChannelLeft: onChannelLeft,
|
|
22701
23557
|
onChannelSetMuted: onChannelSetMuted,
|
|
23558
|
+
onChannelMessagePinned: onChannelMessagePinned,
|
|
23559
|
+
onChannelMessageUnpinned: onChannelMessageUnpinned,
|
|
22702
23560
|
onChannelMemberAdded: onChannelMemberAdded,
|
|
22703
23561
|
onChannelMemberRemoved: onChannelMemberRemoved,
|
|
22704
23562
|
onChannelMemberBanned: onChannelMemberBanned,
|
|
@@ -22716,7 +23574,11 @@ var index$j = /*#__PURE__*/Object.freeze({
|
|
|
22716
23574
|
isUnreadCountSupport: isUnreadCountSupport,
|
|
22717
23575
|
convertFromRaw: convertFromRaw,
|
|
22718
23576
|
preUpdateChannelCache: preUpdateChannelCache,
|
|
22719
|
-
prepareChannelPayload: prepareChannelPayload
|
|
23577
|
+
prepareChannelPayload: prepareChannelPayload,
|
|
23578
|
+
findCachedChannelByAnyId: findCachedChannelByAnyId,
|
|
23579
|
+
findCachedChannelForPin: findCachedChannelForPin,
|
|
23580
|
+
updatePinnedMessageCache: updatePinnedMessageCache,
|
|
23581
|
+
applyChannelRolePayload: applyChannelRolePayload
|
|
22720
23582
|
});
|
|
22721
23583
|
|
|
22722
23584
|
const saveCommunityUsers = (communities, communityUsers) => {
|
|
@@ -24110,7 +24972,7 @@ const searchMembers = (params, callback, config) => {
|
|
|
24110
24972
|
};
|
|
24111
24973
|
/* end_public_function */
|
|
24112
24974
|
|
|
24113
|
-
var index$
|
|
24975
|
+
var index$j = /*#__PURE__*/Object.freeze({
|
|
24114
24976
|
__proto__: null,
|
|
24115
24977
|
addMembers: addMembers,
|
|
24116
24978
|
removeMembers: removeMembers,
|
|
@@ -25361,7 +26223,7 @@ const unbanMembers = async (communityId, userIds) => {
|
|
|
25361
26223
|
};
|
|
25362
26224
|
/* end_public_function */
|
|
25363
26225
|
|
|
25364
|
-
var index$
|
|
26226
|
+
var index$i = /*#__PURE__*/Object.freeze({
|
|
25365
26227
|
__proto__: null,
|
|
25366
26228
|
addRoles: addRoles,
|
|
25367
26229
|
removeRoles: removeRoles,
|
|
@@ -25369,10 +26231,10 @@ var index$h = /*#__PURE__*/Object.freeze({
|
|
|
25369
26231
|
unbanMembers: unbanMembers
|
|
25370
26232
|
});
|
|
25371
26233
|
|
|
25372
|
-
var index$
|
|
26234
|
+
var index$h = /*#__PURE__*/Object.freeze({
|
|
25373
26235
|
__proto__: null,
|
|
25374
|
-
Moderation: index$
|
|
25375
|
-
Membership: index$
|
|
26236
|
+
Moderation: index$i,
|
|
26237
|
+
Membership: index$j,
|
|
25376
26238
|
getCommunityByIds: getCommunities$1,
|
|
25377
26239
|
createCommunity: createCommunity,
|
|
25378
26240
|
updateCommunity: updateCommunity,
|
|
@@ -25609,7 +26471,7 @@ const getCategories = (params, callback, config) => {
|
|
|
25609
26471
|
};
|
|
25610
26472
|
/* end_public_function */
|
|
25611
26473
|
|
|
25612
|
-
var index$
|
|
26474
|
+
var index$g = /*#__PURE__*/Object.freeze({
|
|
25613
26475
|
__proto__: null,
|
|
25614
26476
|
getCategory: getCategory,
|
|
25615
26477
|
getCategories: getCategories
|
|
@@ -25908,6 +26770,11 @@ const createCommentOptimistic = (bundle) => {
|
|
|
25908
26770
|
targetType: 'community',
|
|
25909
26771
|
dataType: 'text',
|
|
25910
26772
|
syncState: "syncing" /* Amity.SyncState.Syncing */,
|
|
26773
|
+
// In a gated community the optimistic object stays out of public collections until the
|
|
26774
|
+
// response settles the status; the author's own view still updates through the local event
|
|
26775
|
+
approvalStatus: isCommentApprovalRequired(bundle)
|
|
26776
|
+
? "pending" /* Amity.CommentApprovalStatusEnum.Pending */
|
|
26777
|
+
: "approved" /* Amity.CommentApprovalStatusEnum.Approved */,
|
|
25911
26778
|
};
|
|
25912
26779
|
const cachedAt = UNSYNCED_OBJECT_CACHED_AT_VALUE;
|
|
25913
26780
|
pushToCache(['comment', 'get', comment.commentId], comment, { cachedAt });
|
|
@@ -25924,32 +26791,57 @@ const createCommentOptimistic = (bundle) => {
|
|
|
25924
26791
|
* ```js
|
|
25925
26792
|
* import { CommentRepository } from '@amityco/ts-sdk-react-native'
|
|
25926
26793
|
* const newComment = await CommentRepository.createComment(bundle)
|
|
26794
|
+
*
|
|
26795
|
+
* // Server-confirmed only: nothing is shown until the request succeeds
|
|
26796
|
+
* const confirmed = await CommentRepository.createComment(bundle, false)
|
|
25927
26797
|
* ```
|
|
25928
26798
|
*
|
|
25929
26799
|
* Creates an {@link Amity.Comment}
|
|
25930
26800
|
*
|
|
26801
|
+
* With `isOptimistic` (the default) a local comment appears at once with `syncState: 'syncing'`,
|
|
26802
|
+
* moves to `'synced'` when the server confirms it and to `'error'` if the request fails, so the
|
|
26803
|
+
* caller can offer a retry. With `isOptimistic: false` nothing is created locally until the
|
|
26804
|
+
* server answers: on success the comment arrives already `'synced'`; on failure no comment
|
|
26805
|
+
* entity exists anywhere and the promise rejects.
|
|
26806
|
+
*
|
|
25931
26807
|
* @param bundle The data necessary to create a new {@link Amity.Comment}
|
|
26808
|
+
* @param isOptimistic Show a local comment before the server confirms it. Default `true`.
|
|
26809
|
+
* Ignored when the client cache is disabled, since there is nowhere to hold the local comment.
|
|
25932
26810
|
* @returns The newly created {@link Amity.Comment}
|
|
25933
26811
|
*
|
|
25934
26812
|
* @category Comment API
|
|
25935
26813
|
* @async
|
|
25936
26814
|
*/
|
|
25937
|
-
const createComment = async (bundle) => {
|
|
26815
|
+
const createComment = async (bundle, isOptimistic = true) => {
|
|
25938
26816
|
const client = getActiveClient();
|
|
25939
|
-
client.log('comment/createComment', bundle);
|
|
25940
|
-
|
|
26817
|
+
client.log('comment/createComment', Object.assign(Object.assign({}, bundle), { isOptimistic }));
|
|
26818
|
+
// Without a local comment the server assigns the id; with one, the same id travels through the
|
|
26819
|
+
// optimistic object, the response and every realtime event so each step recognises it.
|
|
26820
|
+
const optimisticData = isOptimistic ? createCommentOptimistic(bundle) : undefined;
|
|
25941
26821
|
const commentId = optimisticData === null || optimisticData === void 0 ? void 0 : optimisticData.commentId;
|
|
25942
26822
|
try {
|
|
25943
|
-
const { data } = await client.http.post('/api/v3/comments', Object.assign(Object.assign({}, bundle), { commentId }));
|
|
25944
|
-
const { comments } = data;
|
|
26823
|
+
const { data: payload } = await client.http.post('/api/v3/comments', Object.assign(Object.assign({}, bundle), { commentId }));
|
|
25945
26824
|
// BE always returns an array of comments If it got record 0 from BE it might have a problem on creation logic
|
|
25946
|
-
if (comments.length === 0)
|
|
26825
|
+
if (payload.comments.length === 0)
|
|
25947
26826
|
throw new Error('Comment not created');
|
|
26827
|
+
// Absent `approvalStatus` means approved; the result is the only source of the status.
|
|
26828
|
+
// The confirmed comment is written as `synced` so the cache itself tells the two states apart
|
|
26829
|
+
// (a local-event subscriber is not guaranteed to be listening).
|
|
26830
|
+
const prepared = prepareCommentPayload(payload);
|
|
26831
|
+
const data = Object.assign(Object.assign({}, prepared), { comments: prepared.comments.map(comment => comment.commentId === (commentId !== null && commentId !== void 0 ? commentId : comment.commentId)
|
|
26832
|
+
? Object.assign(Object.assign({}, comment), { syncState: "synced" /* Amity.SyncState.Synced */ }) : comment) });
|
|
26833
|
+
const { comments } = data;
|
|
25948
26834
|
const cachedAt = client.cache && Date.now();
|
|
25949
26835
|
if (client.cache)
|
|
25950
26836
|
ingestInCache(data, { cachedAt });
|
|
25951
26837
|
if (['post', 'content'].includes(bundle.referenceType)) {
|
|
25952
|
-
|
|
26838
|
+
if (isCommentPending(comments[0])) {
|
|
26839
|
+
// Not counted for anyone else until approved; the author sees their own +1
|
|
26840
|
+
recordPendingAuthoredComment(comments[0]);
|
|
26841
|
+
}
|
|
26842
|
+
else {
|
|
26843
|
+
PostCommentCountEngine$1.getInstance().queueCommentChangeTask(new CreateTask(bundle.referenceId, comments[0].commentId, comments[0].createdAt));
|
|
26844
|
+
}
|
|
25953
26845
|
}
|
|
25954
26846
|
else if (bundle.referenceType === 'story') {
|
|
25955
26847
|
const storyIndex = pullFromCache([
|
|
@@ -25970,9 +26862,9 @@ const createComment = async (bundle) => {
|
|
|
25970
26862
|
categories: [],
|
|
25971
26863
|
comments,
|
|
25972
26864
|
communities: [],
|
|
25973
|
-
communityUsers:
|
|
25974
|
-
files:
|
|
25975
|
-
users:
|
|
26865
|
+
communityUsers: payload.communityUsers,
|
|
26866
|
+
files: payload.files,
|
|
26867
|
+
users: payload.users,
|
|
25976
26868
|
});
|
|
25977
26869
|
}
|
|
25978
26870
|
}
|
|
@@ -25980,9 +26872,9 @@ const createComment = async (bundle) => {
|
|
|
25980
26872
|
fireEvent('local.comment.created', {
|
|
25981
26873
|
comments: [Object.assign(Object.assign({}, comments[0]), { syncState: "synced" /* Amity.SyncState.Synced */ })],
|
|
25982
26874
|
commentChildren: data.commentChildren,
|
|
25983
|
-
users:
|
|
25984
|
-
files:
|
|
25985
|
-
communityUsers:
|
|
26875
|
+
users: payload.users,
|
|
26876
|
+
files: payload.files,
|
|
26877
|
+
communityUsers: payload.communityUsers,
|
|
25986
26878
|
});
|
|
25987
26879
|
return {
|
|
25988
26880
|
data: LinkedObject.comment(comments[0]),
|
|
@@ -25990,9 +26882,17 @@ const createComment = async (bundle) => {
|
|
|
25990
26882
|
};
|
|
25991
26883
|
}
|
|
25992
26884
|
catch (e) {
|
|
26885
|
+
// Only a local comment has anything to mark as failed; a server-confirmed-only create leaves
|
|
26886
|
+
// no entity behind
|
|
25993
26887
|
if (optimisticData) {
|
|
26888
|
+
const failed = Object.assign(Object.assign({}, optimisticData), { syncState: "error" /* Amity.SyncState.Error */ });
|
|
26889
|
+
// Write the failure to the cache directly: the local event below only reaches pages that
|
|
26890
|
+
// observe comments, and the caller's retry UI reads the cached state
|
|
26891
|
+
pushToCache(['comment', 'get', failed.commentId], failed, {
|
|
26892
|
+
cachedAt: UNSYNCED_OBJECT_CACHED_AT_VALUE,
|
|
26893
|
+
});
|
|
25994
26894
|
fireEvent('local.comment.created', {
|
|
25995
|
-
comments: [
|
|
26895
|
+
comments: [failed],
|
|
25996
26896
|
commentChildren: [],
|
|
25997
26897
|
users: [],
|
|
25998
26898
|
files: [],
|
|
@@ -26025,16 +26925,26 @@ const createComment = async (bundle) => {
|
|
|
26025
26925
|
* @async
|
|
26026
26926
|
*/
|
|
26027
26927
|
const updateComment = async (commentId, patch) => {
|
|
26928
|
+
var _a;
|
|
26028
26929
|
const client = getActiveClient();
|
|
26029
26930
|
client.log('user/updateComment', patch);
|
|
26030
|
-
const
|
|
26931
|
+
const previous = (_a = pullFromCache(['comment', 'get', commentId])) === null || _a === void 0 ? void 0 : _a.data;
|
|
26932
|
+
const { data: payload } = await client.http.put(`/api/v3/comments/${encodeURIComponent(commentId)}`, patch);
|
|
26933
|
+
const data = prepareCommentPayload(payload);
|
|
26934
|
+
const updated = data.comments.find(comment => comment.commentId === commentId);
|
|
26031
26935
|
const cachedAt = client.cache && Date.now();
|
|
26032
26936
|
if (client.cache)
|
|
26033
26937
|
ingestInCache(data, { cachedAt });
|
|
26034
|
-
|
|
26035
|
-
|
|
26938
|
+
// An effective edit in a gated community sends the comment back for review: it leaves the
|
|
26939
|
+
// public reply list and the public count once. The `comment.updated` event below removes it
|
|
26940
|
+
// from the comment collections; the realtime echo finds it already pending and does nothing.
|
|
26941
|
+
if (isCommentPending(updated) && previous && isCommentApproved(previous)) {
|
|
26942
|
+
unlinkCommentFromParent(updated);
|
|
26943
|
+
applyCommentReReviewCount(updated);
|
|
26944
|
+
}
|
|
26945
|
+
fireEvent('comment.updated', payload);
|
|
26036
26946
|
return {
|
|
26037
|
-
data: LinkedObject.comment(
|
|
26947
|
+
data: LinkedObject.comment(updated),
|
|
26038
26948
|
cachedAt,
|
|
26039
26949
|
};
|
|
26040
26950
|
};
|
|
@@ -26174,7 +27084,13 @@ const deleteComment = async (commentId, permanent = false) => {
|
|
|
26174
27084
|
const post = (_b = pullFromCache(['post', 'get', comment.data.referenceId])) === null || _b === void 0 ? void 0 : _b.data;
|
|
26175
27085
|
if (post) {
|
|
26176
27086
|
const engine = PostCommentCountEngine$1.getInstance();
|
|
26177
|
-
|
|
27087
|
+
if (isCommentPending(comment.data)) {
|
|
27088
|
+
// Never counted for anyone else; only the author's own +1 goes away
|
|
27089
|
+
engine.removePendingAuthoredComment(post.postId, commentId);
|
|
27090
|
+
}
|
|
27091
|
+
else {
|
|
27092
|
+
engine.queueCommentChangeTask(new DeleteTask(post.postId, commentId));
|
|
27093
|
+
}
|
|
26178
27094
|
if (!deleted.parentId && ((_c = deleted.children /* c8 ignore next */) === null || _c === void 0 ? void 0 : _c.length) > 0) {
|
|
26179
27095
|
// NOTE: delete the parent comment will also remove all children comments
|
|
26180
27096
|
deleted.children.forEach((childCommentId) => {
|
|
@@ -26244,6 +27160,109 @@ const hardDeleteComment = async (commentId) => {
|
|
|
26244
27160
|
};
|
|
26245
27161
|
/* end_public_function */
|
|
26246
27162
|
|
|
27163
|
+
/* begin_public_function
|
|
27164
|
+
id: comment.approve
|
|
27165
|
+
*/
|
|
27166
|
+
/**
|
|
27167
|
+
* ```js
|
|
27168
|
+
* import { CommentRepository } from '@amityco/ts-sdk'
|
|
27169
|
+
*
|
|
27170
|
+
* const { data: comment } = await CommentRepository.approveComment('commentId')
|
|
27171
|
+
* ```
|
|
27172
|
+
*
|
|
27173
|
+
* Approves a {@link Amity.Comment} held for review, making it visible to everyone
|
|
27174
|
+
*
|
|
27175
|
+
* @param commentId The {@link Amity.Comment} ID to be approved
|
|
27176
|
+
* @return The {@link Amity.Comment} that was approved
|
|
27177
|
+
*
|
|
27178
|
+
* @category Comment API
|
|
27179
|
+
* @async
|
|
27180
|
+
*/
|
|
27181
|
+
const approveComment = async (commentId) => {
|
|
27182
|
+
const client = getActiveClient();
|
|
27183
|
+
client.log('comment/approveComment', commentId);
|
|
27184
|
+
// No request body, and nothing is revealed before the server confirms
|
|
27185
|
+
const { data: payload } = await client.http.post(`/api/v3/comments/${encodeURIComponent(commentId)}/approve`);
|
|
27186
|
+
const data = prepareCommentPayload(prepareMembershipPayload(payload, 'communityUsers'));
|
|
27187
|
+
const approved = data.comments.find(comment => comment.commentId === commentId);
|
|
27188
|
+
const cachedAt = client.cache && Date.now();
|
|
27189
|
+
if (client.cache)
|
|
27190
|
+
ingestInCache(data, { cachedAt });
|
|
27191
|
+
// The reveal path: parent link and exactly one count task. Applied here so it does not depend
|
|
27192
|
+
// on an observer being open; the event below and the realtime `comment.approved` that follows
|
|
27193
|
+
// find the work done and reconcile by comment id (collection insert, queue removal).
|
|
27194
|
+
linkCommentToParent(approved);
|
|
27195
|
+
applyCommentApprovedCount(approved);
|
|
27196
|
+
fireEvent('comment.approved', payload);
|
|
27197
|
+
return {
|
|
27198
|
+
data: LinkedObject.comment(approved),
|
|
27199
|
+
cachedAt,
|
|
27200
|
+
};
|
|
27201
|
+
};
|
|
27202
|
+
/* end_public_function */
|
|
27203
|
+
|
|
27204
|
+
// Rejected is terminal and implies deleted
|
|
27205
|
+
const markRejected = (comment) => (Object.assign(Object.assign({}, comment), { approvalStatus: "rejected" /* Amity.CommentApprovalStatusEnum.Rejected */, isDeleted: true }));
|
|
27206
|
+
/* begin_public_function
|
|
27207
|
+
id: comment.decline
|
|
27208
|
+
*/
|
|
27209
|
+
/**
|
|
27210
|
+
* ```js
|
|
27211
|
+
* import { CommentRepository } from '@amityco/ts-sdk'
|
|
27212
|
+
*
|
|
27213
|
+
* const { data: comment } = await CommentRepository.declineComment('commentId', 'Off-topic')
|
|
27214
|
+
* ```
|
|
27215
|
+
*
|
|
27216
|
+
* Declines a {@link Amity.Comment} held for review. A declined comment is also a deleted comment
|
|
27217
|
+
*
|
|
27218
|
+
* @param commentId The {@link Amity.Comment} ID to be declined
|
|
27219
|
+
* @param reason Optional reviewer's note, at most 250 characters, kept for the moderation record only
|
|
27220
|
+
* @return The {@link Amity.Comment} that was declined
|
|
27221
|
+
*
|
|
27222
|
+
* @category Comment API
|
|
27223
|
+
* @async
|
|
27224
|
+
*/
|
|
27225
|
+
const declineComment = async (commentId, reason) => {
|
|
27226
|
+
var _a, _b, _c, _d, _e, _f;
|
|
27227
|
+
const client = getActiveClient();
|
|
27228
|
+
client.log('comment/declineComment', commentId, reason);
|
|
27229
|
+
// Read before the request: the fallback when the response carries no comment
|
|
27230
|
+
const cached = (_a = pullFromCache(['comment', 'get', commentId])) === null || _a === void 0 ? void 0 : _a.data;
|
|
27231
|
+
// `reason` is surfaced to nobody; the key is absent from the body when the caller gives none
|
|
27232
|
+
const { data: payload } = await client.http.post(`/api/v3/comments/${encodeURIComponent(commentId)}/decline`, reason ? { reason } : undefined);
|
|
27233
|
+
// The BE contract (PDT-5135 §3) states the response body for approve only; for decline the
|
|
27234
|
+
// standard comment payload is assumed. Ingest whatever came back, and when the body carries no
|
|
27235
|
+
// comment fall back to the cached one so the delete path below still runs.
|
|
27236
|
+
const returned = (_b = payload === null || payload === void 0 ? void 0 : payload.comments) === null || _b === void 0 ? void 0 : _b.some(comment => comment.commentId === commentId);
|
|
27237
|
+
if (!returned && !cached)
|
|
27238
|
+
throw new Error('Comment not found after decline');
|
|
27239
|
+
const comments = returned
|
|
27240
|
+
? payload.comments.map(comment => comment.commentId === commentId ? markRejected(comment) : comment)
|
|
27241
|
+
: [markRejected(cached)];
|
|
27242
|
+
const declined = {
|
|
27243
|
+
comments,
|
|
27244
|
+
commentChildren: (_c = payload === null || payload === void 0 ? void 0 : payload.commentChildren) !== null && _c !== void 0 ? _c : [],
|
|
27245
|
+
users: (_d = payload === null || payload === void 0 ? void 0 : payload.users) !== null && _d !== void 0 ? _d : [],
|
|
27246
|
+
files: (_e = payload === null || payload === void 0 ? void 0 : payload.files) !== null && _e !== void 0 ? _e : [],
|
|
27247
|
+
communityUsers: (_f = payload === null || payload === void 0 ? void 0 : payload.communityUsers) !== null && _f !== void 0 ? _f : [],
|
|
27248
|
+
};
|
|
27249
|
+
// There is no `comment.declined` event: the existing delete path drops the comment from every
|
|
27250
|
+
// collection and the review queue, and moves no count because a pending comment was never counted.
|
|
27251
|
+
const data = prepareCommentPayload(prepareMembershipPayload(declined, 'communityUsers'));
|
|
27252
|
+
const rejected = data.comments.find(comment => comment.commentId === commentId);
|
|
27253
|
+
const cachedAt = client.cache && Date.now();
|
|
27254
|
+
if (client.cache)
|
|
27255
|
+
ingestInCache(data, { cachedAt });
|
|
27256
|
+
unlinkCommentFromParent(rejected);
|
|
27257
|
+
releasePendingAuthoredComment(rejected);
|
|
27258
|
+
fireEvent('comment.deleted', declined);
|
|
27259
|
+
return {
|
|
27260
|
+
data: LinkedObject.comment(rejected),
|
|
27261
|
+
cachedAt,
|
|
27262
|
+
};
|
|
27263
|
+
};
|
|
27264
|
+
/* end_public_function */
|
|
27265
|
+
|
|
26247
27266
|
/* begin_public_function
|
|
26248
27267
|
id: comment.flag
|
|
26249
27268
|
*/
|
|
@@ -26329,6 +27348,7 @@ const isCommentFlaggedByMe = async (commentId) => {
|
|
|
26329
27348
|
/* end_public_function */
|
|
26330
27349
|
|
|
26331
27350
|
const getComment$1 = async (commentId) => {
|
|
27351
|
+
var _a;
|
|
26332
27352
|
const client = getActiveClient();
|
|
26333
27353
|
client.log('comment/getComment', commentId);
|
|
26334
27354
|
isInTombstone('comment', commentId);
|
|
@@ -26339,7 +27359,11 @@ const getComment$1 = async (commentId) => {
|
|
|
26339
27359
|
data = response.data;
|
|
26340
27360
|
}
|
|
26341
27361
|
catch (error) {
|
|
26342
|
-
|
|
27362
|
+
// A pending comment answers 404 to anyone but its author and reviewers. That is a
|
|
27363
|
+
// visibility answer, not a deletion — never tombstone a comment known to be pending.
|
|
27364
|
+
const cached = (_a = pullFromCache(['comment', 'get', commentId])) === null || _a === void 0 ? void 0 : _a.data;
|
|
27365
|
+
const isKnownPending = !!cached && isCommentPending(cached);
|
|
27366
|
+
if (!isKnownPending && checkIfShouldGoesToTombstone(error === null || error === void 0 ? void 0 : error.code)) {
|
|
26343
27367
|
pushToTombstone('comment', commentId);
|
|
26344
27368
|
}
|
|
26345
27369
|
throw error;
|
|
@@ -26466,6 +27490,7 @@ const onLocalCommentReactionRemoved = (callback) => {
|
|
|
26466
27490
|
*/
|
|
26467
27491
|
const getComment = (commentId, callback) => {
|
|
26468
27492
|
return liveObject(commentId, callback, 'commentId', getComment$1, [
|
|
27493
|
+
onCommentApproved,
|
|
26469
27494
|
onCommentDeleteLocal,
|
|
26470
27495
|
onCommentDeleted,
|
|
26471
27496
|
onCommentFlagged,
|
|
@@ -26479,28 +27504,31 @@ const getComment = (commentId, callback) => {
|
|
|
26479
27504
|
};
|
|
26480
27505
|
/* end_public_function */
|
|
26481
27506
|
|
|
26482
|
-
|
|
26483
|
-
|
|
26484
|
-
|
|
26485
|
-
|
|
26486
|
-
|
|
26487
|
-
|
|
26488
|
-
|
|
26489
|
-
|
|
26490
|
-
|
|
26491
|
-
|
|
26492
|
-
|
|
26493
|
-
|
|
26494
|
-
|
|
26495
|
-
|
|
26496
|
-
|
|
26497
|
-
|
|
27507
|
+
/**
|
|
27508
|
+
* ```js
|
|
27509
|
+
* import { onCommentCreated } from '@amityco/ts-sdk-react-native'
|
|
27510
|
+
* const dispose = onCommentCreated(comment => {
|
|
27511
|
+
* // ...
|
|
27512
|
+
* })
|
|
27513
|
+
* ```
|
|
27514
|
+
*
|
|
27515
|
+
* Fired when a {@link Amity.InternalComment} has been created
|
|
27516
|
+
*
|
|
27517
|
+
* @param callback The function to call when the event was fired
|
|
27518
|
+
* @returns an {@link Amity.Unsubscriber} function to stop listening
|
|
27519
|
+
*
|
|
27520
|
+
* @category Comment Events
|
|
27521
|
+
*/
|
|
27522
|
+
const onCommentCreatedLocal = (callback) => {
|
|
27523
|
+
return createLocalCommentEventSubscriber('local.comment.created', callback);
|
|
27524
|
+
};
|
|
26498
27525
|
|
|
26499
27526
|
var EnumCommentActions;
|
|
26500
27527
|
(function (EnumCommentActions) {
|
|
26501
27528
|
EnumCommentActions["OnCommentCreated"] = "onCommentCreated";
|
|
26502
27529
|
EnumCommentActions["OnCommentUpdated"] = "onCommentUpdated";
|
|
26503
27530
|
EnumCommentActions["OnCommentDeleted"] = "onCommentDeleted";
|
|
27531
|
+
EnumCommentActions["OnCommentApproved"] = "onCommentApproved";
|
|
26504
27532
|
EnumCommentActions["OnCommentFlagged"] = "onCommentFlagged";
|
|
26505
27533
|
EnumCommentActions["OnCommentUnflagged"] = "onCommentUnflagged";
|
|
26506
27534
|
EnumCommentActions["OnCommentReactionAdded"] = "onCommentReactionAdded";
|
|
@@ -26523,15 +27551,17 @@ class CommentQueryStreamController extends QueryStreamController {
|
|
|
26523
27551
|
}
|
|
26524
27552
|
appendToQueryStream(response, direction, refresh = false) {
|
|
26525
27553
|
var _a, _b;
|
|
27554
|
+
// The public list is approved-only even when the server widens the read for a reviewer
|
|
27555
|
+
const commentIds = response.comments.filter(isCommentApproved).map(getResolver('comment'));
|
|
26526
27556
|
if (refresh) {
|
|
26527
27557
|
pushToCache(this.cacheKey, {
|
|
26528
|
-
data:
|
|
27558
|
+
data: commentIds,
|
|
26529
27559
|
});
|
|
26530
27560
|
}
|
|
26531
27561
|
else {
|
|
26532
27562
|
const collection = (_a = pullFromCache(this.cacheKey)) === null || _a === void 0 ? void 0 : _a.data;
|
|
26533
27563
|
const comments = (_b = collection === null || collection === void 0 ? void 0 : collection.data) !== null && _b !== void 0 ? _b : [];
|
|
26534
|
-
pushToCache(this.cacheKey, Object.assign(Object.assign({}, collection), { data: [...new Set([...comments, ...
|
|
27564
|
+
pushToCache(this.cacheKey, Object.assign(Object.assign({}, collection), { data: [...new Set([...comments, ...commentIds])] }));
|
|
26535
27565
|
}
|
|
26536
27566
|
}
|
|
26537
27567
|
reactor(action) {
|
|
@@ -26550,8 +27580,19 @@ class CommentQueryStreamController extends QueryStreamController {
|
|
|
26550
27580
|
return;
|
|
26551
27581
|
}
|
|
26552
27582
|
if (action === EnumCommentActions.OnCommentCreated) {
|
|
27583
|
+
// A pending comment reaches clients over realtime before anyone may see it: persist
|
|
27584
|
+
// only, no insert and no emit. `comment.approved` is the reveal signal.
|
|
27585
|
+
if (!isCommentApproved(comment))
|
|
27586
|
+
return;
|
|
26553
27587
|
collection.data = [...new Set([comment.commentId, ...collection.data])];
|
|
26554
27588
|
}
|
|
27589
|
+
if (action === EnumCommentActions.OnCommentApproved) {
|
|
27590
|
+
collection.data = [...new Set([comment.commentId, ...collection.data])];
|
|
27591
|
+
}
|
|
27592
|
+
// An effective edit in a gated community returns the comment to review: it leaves the list
|
|
27593
|
+
if (action === EnumCommentActions.OnCommentUpdated && isCommentPending(comment)) {
|
|
27594
|
+
collection.data = collection.data.filter(commentId => commentId !== comment.commentId);
|
|
27595
|
+
}
|
|
26555
27596
|
pushToCache(this.cacheKey, collection);
|
|
26556
27597
|
this.notifyChange({ origin: "event" /* Amity.LiveDataOrigin.EVENT */, loading: false });
|
|
26557
27598
|
};
|
|
@@ -26561,24 +27602,22 @@ class CommentQueryStreamController extends QueryStreamController {
|
|
|
26561
27602
|
}
|
|
26562
27603
|
}
|
|
26563
27604
|
|
|
26564
|
-
|
|
26565
|
-
|
|
26566
|
-
|
|
26567
|
-
|
|
26568
|
-
|
|
26569
|
-
|
|
26570
|
-
|
|
26571
|
-
|
|
26572
|
-
|
|
26573
|
-
|
|
26574
|
-
|
|
26575
|
-
|
|
26576
|
-
|
|
26577
|
-
|
|
26578
|
-
|
|
26579
|
-
|
|
26580
|
-
return createLocalCommentEventSubscriber('local.comment.created', callback);
|
|
26581
|
-
};
|
|
27605
|
+
class CommentPaginationController extends PaginationController {
|
|
27606
|
+
async getRequest(queryParams, token) {
|
|
27607
|
+
var _a;
|
|
27608
|
+
const { pageSize, limit, includeDeleted } = queryParams, params = __rest(queryParams, ["pageSize", "limit", "includeDeleted"]);
|
|
27609
|
+
const effectiveLimit = (_a = pageSize !== null && pageSize !== void 0 ? pageSize : limit) !== null && _a !== void 0 ? _a : COLLECTION_DEFAULT_PAGINATION_LIMIT;
|
|
27610
|
+
const baseOptions = {
|
|
27611
|
+
type: params.sortBy || queryParams.limit || queryParams.pageSize ? 'pagination' : undefined,
|
|
27612
|
+
};
|
|
27613
|
+
const options = token
|
|
27614
|
+
? Object.assign(Object.assign({}, baseOptions), { token }) : Object.assign(Object.assign({}, baseOptions), { pageSize: effectiveLimit, limit: effectiveLimit });
|
|
27615
|
+
const { data: queryResponse } = await this.http.get(`/api/v3/comments`, {
|
|
27616
|
+
params: Object.assign(Object.assign({}, params), { isDeleted: inferIsDeleted(includeDeleted), options }),
|
|
27617
|
+
});
|
|
27618
|
+
return queryResponse;
|
|
27619
|
+
}
|
|
27620
|
+
}
|
|
26582
27621
|
|
|
26583
27622
|
class CommentLiveCollectionController extends LiveCollectionController {
|
|
26584
27623
|
constructor(query, callback) {
|
|
@@ -26614,6 +27653,7 @@ class CommentLiveCollectionController extends LiveCollectionController {
|
|
|
26614
27653
|
{ fn: onCommentCreated, action: EnumCommentActions.OnCommentCreated },
|
|
26615
27654
|
{ fn: onCommentUpdated, action: EnumCommentActions.OnCommentUpdated },
|
|
26616
27655
|
{ fn: onCommentDeleted, action: EnumCommentActions.OnCommentDeleted },
|
|
27656
|
+
{ fn: onCommentApproved, action: EnumCommentActions.OnCommentApproved },
|
|
26617
27657
|
{ fn: onCommentFlagged, action: EnumCommentActions.OnCommentFlagged },
|
|
26618
27658
|
{ fn: onCommentUnflagged, action: EnumCommentActions.OnCommentUnflagged },
|
|
26619
27659
|
{ fn: onCommentReactionAdded, action: EnumCommentActions.OnCommentReactionAdded },
|
|
@@ -26647,7 +27687,8 @@ class CommentLiveCollectionController extends LiveCollectionController {
|
|
|
26647
27687
|
});
|
|
26648
27688
|
}
|
|
26649
27689
|
applyFilter(data) {
|
|
26650
|
-
|
|
27690
|
+
// Approved-only, for every caller including the author of a pending comment
|
|
27691
|
+
let comments = data.filter(isCommentApproved);
|
|
26651
27692
|
if (!this.query.includeDeleted) {
|
|
26652
27693
|
comments = filterByPropEquality(comments, 'isDeleted', false);
|
|
26653
27694
|
}
|
|
@@ -26735,7 +27776,202 @@ const getComments = (params, callback, config) => {
|
|
|
26735
27776
|
};
|
|
26736
27777
|
/* end_public_function */
|
|
26737
27778
|
|
|
26738
|
-
|
|
27779
|
+
class CommentReviewQueuePaginationController extends PaginationController {
|
|
27780
|
+
async getRequest(queryParams, token) {
|
|
27781
|
+
const { communityId, limit } = queryParams, params = __rest(queryParams, ["communityId", "limit"]);
|
|
27782
|
+
// The route defaults to 10, not the SDK-wide 20, and rejects anything above 100
|
|
27783
|
+
const effectiveLimit = Math.min(limit !== null && limit !== void 0 ? limit : COMMENT_REVIEW_QUEUE_DEFAULT_PAGINATION_SIZE, COMMENT_REVIEW_QUEUE_MAX_PAGINATION_SIZE);
|
|
27784
|
+
// Token paging only. The route also accepts options[skip], but offset paging over a queue that
|
|
27785
|
+
// drains from the front skips items, so the SDK never sends it.
|
|
27786
|
+
const options = token ? { token } : { limit: effectiveLimit };
|
|
27787
|
+
const { data: queryResponse } = await this.http.get(API_ENDPOINTS.commentReviewQueue(communityId), {
|
|
27788
|
+
params: Object.assign(Object.assign({}, params), { options }),
|
|
27789
|
+
});
|
|
27790
|
+
return queryResponse;
|
|
27791
|
+
}
|
|
27792
|
+
}
|
|
27793
|
+
|
|
27794
|
+
class CommentReviewQueueQueryStreamController extends QueryStreamController {
|
|
27795
|
+
constructor(query, cacheKey, notifyChange) {
|
|
27796
|
+
super(query, cacheKey);
|
|
27797
|
+
this.notifyChange = notifyChange;
|
|
27798
|
+
}
|
|
27799
|
+
async saveToMainDB(response) {
|
|
27800
|
+
const processedPayload = prepareCommentPayload(response);
|
|
27801
|
+
const client = getActiveClient();
|
|
27802
|
+
const cachedAt = client.cache && Date.now();
|
|
27803
|
+
if (client.cache) {
|
|
27804
|
+
ingestInCache(processedPayload, { cachedAt });
|
|
27805
|
+
}
|
|
27806
|
+
}
|
|
27807
|
+
appendToQueryStream(response, direction, refresh = false) {
|
|
27808
|
+
var _a, _b;
|
|
27809
|
+
// Server order is queue-entry order, oldest first. Keep it: later pages append, nothing
|
|
27810
|
+
// re-sorts by createdAt (the two diverge on re-review).
|
|
27811
|
+
const commentIds = response.comments.map(getResolver('comment'));
|
|
27812
|
+
if (refresh) {
|
|
27813
|
+
pushToCache(this.cacheKey, {
|
|
27814
|
+
data: commentIds,
|
|
27815
|
+
});
|
|
27816
|
+
}
|
|
27817
|
+
else {
|
|
27818
|
+
const collection = (_a = pullFromCache(this.cacheKey)) === null || _a === void 0 ? void 0 : _a.data;
|
|
27819
|
+
const comments = (_b = collection === null || collection === void 0 ? void 0 : collection.data) !== null && _b !== void 0 ? _b : [];
|
|
27820
|
+
pushToCache(this.cacheKey, Object.assign(Object.assign({}, collection), { data: [...new Set([...comments, ...commentIds])] }));
|
|
27821
|
+
}
|
|
27822
|
+
}
|
|
27823
|
+
matchesQuery(comment) {
|
|
27824
|
+
return (comment.targetType === 'community' &&
|
|
27825
|
+
comment.targetId === this.query.communityId &&
|
|
27826
|
+
(!this.query.postId || comment.referenceId === this.query.postId));
|
|
27827
|
+
}
|
|
27828
|
+
reactor(action) {
|
|
27829
|
+
return (comment) => {
|
|
27830
|
+
var _a;
|
|
27831
|
+
const collection = (_a = pullFromCache(this.cacheKey)) === null || _a === void 0 ? void 0 : _a.data;
|
|
27832
|
+
if (!collection || !this.matchesQuery(comment))
|
|
27833
|
+
return;
|
|
27834
|
+
const isQueued = collection.data.includes(comment.commentId);
|
|
27835
|
+
// A date-filtered queue is the server's to shape; live events only remove from it
|
|
27836
|
+
const acceptsLiveInserts = !this.query.startDate && !this.query.endDate;
|
|
27837
|
+
switch (action) {
|
|
27838
|
+
case EnumCommentActions.OnCommentCreated:
|
|
27839
|
+
case EnumCommentActions.OnCommentUpdated:
|
|
27840
|
+
if (isCommentPending(comment) && !comment.isDeleted) {
|
|
27841
|
+
if (isQueued || !acceptsLiveInserts)
|
|
27842
|
+
return;
|
|
27843
|
+
// Enters (or, after an edit, re-enters) the queue at the end
|
|
27844
|
+
collection.data = [...collection.data, comment.commentId];
|
|
27845
|
+
}
|
|
27846
|
+
else {
|
|
27847
|
+
if (!isQueued)
|
|
27848
|
+
return;
|
|
27849
|
+
collection.data = collection.data.filter(commentId => commentId !== comment.commentId);
|
|
27850
|
+
}
|
|
27851
|
+
break;
|
|
27852
|
+
case EnumCommentActions.OnCommentApproved:
|
|
27853
|
+
case EnumCommentActions.OnCommentDeleted:
|
|
27854
|
+
if (!isQueued)
|
|
27855
|
+
return;
|
|
27856
|
+
collection.data = collection.data.filter(commentId => commentId !== comment.commentId);
|
|
27857
|
+
break;
|
|
27858
|
+
default:
|
|
27859
|
+
return;
|
|
27860
|
+
}
|
|
27861
|
+
pushToCache(this.cacheKey, collection);
|
|
27862
|
+
this.notifyChange({ origin: "event" /* Amity.LiveDataOrigin.EVENT */, loading: false });
|
|
27863
|
+
};
|
|
27864
|
+
}
|
|
27865
|
+
subscribeRTE(createSubscriber) {
|
|
27866
|
+
return createSubscriber.map(subscriber => subscriber.fn(this.reactor(subscriber.action)));
|
|
27867
|
+
}
|
|
27868
|
+
}
|
|
27869
|
+
|
|
27870
|
+
class CommentReviewQueueLiveCollectionController extends LiveCollectionController {
|
|
27871
|
+
constructor(query, callback) {
|
|
27872
|
+
const queryStreamId = hash(query);
|
|
27873
|
+
const cacheKey = ['commentReviewQueue', 'collection', queryStreamId];
|
|
27874
|
+
const paginationController = new CommentReviewQueuePaginationController(query);
|
|
27875
|
+
super(paginationController, queryStreamId, cacheKey, callback);
|
|
27876
|
+
this.query = query;
|
|
27877
|
+
this.queryStreamController = new CommentReviewQueueQueryStreamController(this.query, this.cacheKey, this.notifyChange.bind(this));
|
|
27878
|
+
this.callback = callback.bind(this);
|
|
27879
|
+
this.loadPage({ initial: true });
|
|
27880
|
+
}
|
|
27881
|
+
setup() {
|
|
27882
|
+
var _a;
|
|
27883
|
+
const collection = (_a = pullFromCache(this.cacheKey)) === null || _a === void 0 ? void 0 : _a.data;
|
|
27884
|
+
if (!collection) {
|
|
27885
|
+
pushToCache(this.cacheKey, {
|
|
27886
|
+
data: [],
|
|
27887
|
+
params: {},
|
|
27888
|
+
});
|
|
27889
|
+
}
|
|
27890
|
+
}
|
|
27891
|
+
async persistModel(queryPayload) {
|
|
27892
|
+
await this.queryStreamController.saveToMainDB(queryPayload);
|
|
27893
|
+
}
|
|
27894
|
+
persistQueryStream({ response, direction, refresh, }) {
|
|
27895
|
+
this.queryStreamController.appendToQueryStream(response, direction, refresh);
|
|
27896
|
+
}
|
|
27897
|
+
startSubscription() {
|
|
27898
|
+
// No `comment.declined` exists: a decline arrives as `comment.deleted`
|
|
27899
|
+
return this.queryStreamController.subscribeRTE([
|
|
27900
|
+
{ fn: onCommentCreated, action: EnumCommentActions.OnCommentCreated },
|
|
27901
|
+
{ fn: onCommentUpdated, action: EnumCommentActions.OnCommentUpdated },
|
|
27902
|
+
{ fn: onCommentApproved, action: EnumCommentActions.OnCommentApproved },
|
|
27903
|
+
{ fn: onCommentDeleted, action: EnumCommentActions.OnCommentDeleted },
|
|
27904
|
+
{ fn: onCommentDeleteLocal, action: EnumCommentActions.OnCommentDeleted },
|
|
27905
|
+
]);
|
|
27906
|
+
}
|
|
27907
|
+
notifyChange({ origin, loading, error }) {
|
|
27908
|
+
var _a;
|
|
27909
|
+
// A caller who lost REVIEW_COMMUNITY_COMMENT must not keep reading stale pending content
|
|
27910
|
+
if ((error === null || error === void 0 ? void 0 : error.code) === 400301 /* Amity.ServerError.PERMISSION_DENIED */) {
|
|
27911
|
+
pushToCache(this.cacheKey, { data: [], params: {} });
|
|
27912
|
+
}
|
|
27913
|
+
const collection = (_a = pullFromCache(this.cacheKey)) === null || _a === void 0 ? void 0 : _a.data;
|
|
27914
|
+
if (!collection)
|
|
27915
|
+
return;
|
|
27916
|
+
const data = collection.data
|
|
27917
|
+
.map(id => pullFromCache(['comment', 'get', id]))
|
|
27918
|
+
.filter(isNonNullable)
|
|
27919
|
+
.map(({ data }) => data)
|
|
27920
|
+
.filter(comment => isCommentPending(comment) && !comment.isDeleted)
|
|
27921
|
+
.map(LinkedObject.comment);
|
|
27922
|
+
if (!this.shouldNotify(data) && origin === 'event')
|
|
27923
|
+
return;
|
|
27924
|
+
this.callback({
|
|
27925
|
+
onNextPage: () => this.loadPage({ direction: "next" /* Amity.LiveCollectionPageDirection.NEXT */ }),
|
|
27926
|
+
data,
|
|
27927
|
+
hasNextPage: !!this.paginationController.getNextToken(),
|
|
27928
|
+
loading,
|
|
27929
|
+
error,
|
|
27930
|
+
});
|
|
27931
|
+
}
|
|
27932
|
+
}
|
|
27933
|
+
|
|
27934
|
+
/* begin_public_function
|
|
27935
|
+
id: comment.review_queue
|
|
27936
|
+
*/
|
|
27937
|
+
/**
|
|
27938
|
+
* ```js
|
|
27939
|
+
* import { CommentRepository } from '@amityco/ts-sdk'
|
|
27940
|
+
*
|
|
27941
|
+
* const unsub = CommentRepository.getCommentReviewQueue(
|
|
27942
|
+
* { communityId: 'communityId' },
|
|
27943
|
+
* ({ data: comments, hasNextPage, onNextPage }) => {
|
|
27944
|
+
* // every comment is awaiting review
|
|
27945
|
+
* },
|
|
27946
|
+
* )
|
|
27947
|
+
* ```
|
|
27948
|
+
*
|
|
27949
|
+
* Observe the {@link Amity.Comment} list awaiting moderator review in a community, oldest first
|
|
27950
|
+
*
|
|
27951
|
+
* @param params the community to read the queue of, optionally narrowed to one post and a date range
|
|
27952
|
+
* @param callback the function to call when new data are available
|
|
27953
|
+
* @returns An {@link Amity.Unsubscriber} function to run when willing to stop observing the queue
|
|
27954
|
+
*
|
|
27955
|
+
* @category Comments Live Collection
|
|
27956
|
+
*/
|
|
27957
|
+
const getCommentReviewQueue = (params, callback) => {
|
|
27958
|
+
const { log, cache } = getActiveClient();
|
|
27959
|
+
if (!cache)
|
|
27960
|
+
console.log(ENABLE_CACHE_MESSAGE);
|
|
27961
|
+
const timestamp = Date.now();
|
|
27962
|
+
log(`getCommentReviewQueue(tmpid: ${timestamp}) > listen`);
|
|
27963
|
+
const commentReviewQueueLiveCollection = new CommentReviewQueueLiveCollectionController(params, callback);
|
|
27964
|
+
const disposers = commentReviewQueueLiveCollection.startSubscription();
|
|
27965
|
+
const cacheKey = commentReviewQueueLiveCollection.getCacheKey();
|
|
27966
|
+
disposers.push(() => dropFromCache(cacheKey));
|
|
27967
|
+
return () => {
|
|
27968
|
+
log(`getCommentReviewQueue(tmpid: ${timestamp}) > dispose`);
|
|
27969
|
+
disposers.forEach(fn => fn());
|
|
27970
|
+
};
|
|
27971
|
+
};
|
|
27972
|
+
/* end_public_function */
|
|
27973
|
+
|
|
27974
|
+
var index$f = /*#__PURE__*/Object.freeze({
|
|
26739
27975
|
__proto__: null,
|
|
26740
27976
|
getCommentByIds: getCommentByIds,
|
|
26741
27977
|
createComment: createComment,
|
|
@@ -26743,18 +27979,22 @@ var index$e = /*#__PURE__*/Object.freeze({
|
|
|
26743
27979
|
deleteComment: deleteComment,
|
|
26744
27980
|
softDeleteComment: softDeleteComment,
|
|
26745
27981
|
hardDeleteComment: hardDeleteComment,
|
|
27982
|
+
approveComment: approveComment,
|
|
27983
|
+
declineComment: declineComment,
|
|
26746
27984
|
flagComment: flagComment,
|
|
26747
27985
|
unflagComment: unflagComment,
|
|
26748
27986
|
isCommentFlaggedByMe: isCommentFlaggedByMe,
|
|
26749
27987
|
onCommentCreated: onCommentCreated,
|
|
26750
27988
|
onCommentUpdated: onCommentUpdated,
|
|
26751
27989
|
onCommentDeleted: onCommentDeleted,
|
|
27990
|
+
onCommentApproved: onCommentApproved,
|
|
26752
27991
|
onCommentFlagged: onCommentFlagged,
|
|
26753
27992
|
onCommentUnflagged: onCommentUnflagged,
|
|
26754
27993
|
onCommentReactionAdded: onCommentReactionAdded,
|
|
26755
27994
|
onCommentReactionRemoved: onCommentReactionRemoved,
|
|
26756
27995
|
getComment: getComment,
|
|
26757
|
-
getComments: getComments
|
|
27996
|
+
getComments: getComments,
|
|
27997
|
+
getCommentReviewQueue: getCommentReviewQueue
|
|
26758
27998
|
});
|
|
26759
27999
|
|
|
26760
28000
|
/**
|
|
@@ -28004,7 +29244,7 @@ const getForYouFeed = (callback) => {
|
|
|
28004
29244
|
};
|
|
28005
29245
|
/* end_public_function */
|
|
28006
29246
|
|
|
28007
|
-
var index$
|
|
29247
|
+
var index$e = /*#__PURE__*/Object.freeze({
|
|
28008
29248
|
__proto__: null,
|
|
28009
29249
|
queryGlobalFeed: queryGlobalFeed,
|
|
28010
29250
|
getCustomRankingGlobalFeed: getCustomRankingGlobalFeed,
|
|
@@ -31149,7 +32389,7 @@ const getRooms = (params, callback, config) => {
|
|
|
31149
32389
|
};
|
|
31150
32390
|
/* end_public_function */
|
|
31151
32391
|
|
|
31152
|
-
var index$
|
|
32392
|
+
var index$d = /*#__PURE__*/Object.freeze({
|
|
31153
32393
|
__proto__: null,
|
|
31154
32394
|
createRoom: createRoom,
|
|
31155
32395
|
updateRoom: updateRoom,
|
|
@@ -31448,7 +32688,7 @@ const getCommunityLiveRoomPosts = (params, callback, config) => {
|
|
|
31448
32688
|
};
|
|
31449
32689
|
/* end_public_function */
|
|
31450
32690
|
|
|
31451
|
-
var index$
|
|
32691
|
+
var index$c = /*#__PURE__*/Object.freeze({
|
|
31452
32692
|
__proto__: null,
|
|
31453
32693
|
getPostByIds: getPostByIds,
|
|
31454
32694
|
createPost: createPost,
|
|
@@ -32056,7 +33296,7 @@ const getStreams = (params, callback, config) => {
|
|
|
32056
33296
|
};
|
|
32057
33297
|
/* end_public_function */
|
|
32058
33298
|
|
|
32059
|
-
var index$
|
|
33299
|
+
var index$b = /*#__PURE__*/Object.freeze({
|
|
32060
33300
|
__proto__: null,
|
|
32061
33301
|
createStream: createStream,
|
|
32062
33302
|
updateStream: updateStream,
|
|
@@ -32359,7 +33599,7 @@ const stopHeartbeat = (roomId) => {
|
|
|
32359
33599
|
};
|
|
32360
33600
|
/* end_public_function */
|
|
32361
33601
|
|
|
32362
|
-
var index$
|
|
33602
|
+
var index$a = /*#__PURE__*/Object.freeze({
|
|
32363
33603
|
__proto__: null,
|
|
32364
33604
|
getRoomOnlineUsers: getRoomOnlineUsers,
|
|
32365
33605
|
getRoomUserCount: getRoomUserCount,
|
|
@@ -32670,7 +33910,7 @@ const getPoll = (pollId, callback) => {
|
|
|
32670
33910
|
};
|
|
32671
33911
|
/* end_public_function */
|
|
32672
33912
|
|
|
32673
|
-
var index$
|
|
33913
|
+
var index$9 = /*#__PURE__*/Object.freeze({
|
|
32674
33914
|
__proto__: null,
|
|
32675
33915
|
createPoll: createPoll,
|
|
32676
33916
|
closePoll: closePoll,
|
|
@@ -32974,7 +34214,7 @@ const getPlayer = async (parameters) => {
|
|
|
32974
34214
|
return video;
|
|
32975
34215
|
};
|
|
32976
34216
|
|
|
32977
|
-
var index$
|
|
34217
|
+
var index$8 = /*#__PURE__*/Object.freeze({
|
|
32978
34218
|
__proto__: null,
|
|
32979
34219
|
getPlayer: getPlayer
|
|
32980
34220
|
});
|
|
@@ -34146,7 +35386,7 @@ const getGlobalStoryTargets = (params, callback, config) => {
|
|
|
34146
35386
|
};
|
|
34147
35387
|
};
|
|
34148
35388
|
|
|
34149
|
-
var index$
|
|
35389
|
+
var index$7 = /*#__PURE__*/Object.freeze({
|
|
34150
35390
|
__proto__: null,
|
|
34151
35391
|
createImageStory: createImageStory,
|
|
34152
35392
|
createVideoStory: createVideoStory,
|
|
@@ -34183,7 +35423,7 @@ const getNetworkAds = async () => {
|
|
|
34183
35423
|
};
|
|
34184
35424
|
};
|
|
34185
35425
|
|
|
34186
|
-
var index$
|
|
35426
|
+
var index$6 = /*#__PURE__*/Object.freeze({
|
|
34187
35427
|
__proto__: null,
|
|
34188
35428
|
getNetworkAds: getNetworkAds
|
|
34189
35429
|
});
|
|
@@ -34574,7 +35814,7 @@ const markTraySeen = async (lastSeenAt) => {
|
|
|
34574
35814
|
};
|
|
34575
35815
|
/* end_public_function */
|
|
34576
35816
|
|
|
34577
|
-
var index$
|
|
35817
|
+
var index$5 = /*#__PURE__*/Object.freeze({
|
|
34578
35818
|
__proto__: null,
|
|
34579
35819
|
getNotificationTraySeen: getNotificationTraySeen,
|
|
34580
35820
|
getNotificationTrayItems: getNotificationTrayItems,
|
|
@@ -34876,7 +36116,7 @@ const getInvitations = (params, callback) => {
|
|
|
34876
36116
|
};
|
|
34877
36117
|
};
|
|
34878
36118
|
|
|
34879
|
-
var index$
|
|
36119
|
+
var index$4 = /*#__PURE__*/Object.freeze({
|
|
34880
36120
|
__proto__: null,
|
|
34881
36121
|
cancelInvitation: cancelInvitation,
|
|
34882
36122
|
onLocalInvitationCreated: onLocalInvitationCreated,
|
|
@@ -35025,7 +36265,7 @@ const getReactions = (postId, callback) => {
|
|
|
35025
36265
|
};
|
|
35026
36266
|
};
|
|
35027
36267
|
|
|
35028
|
-
var index$
|
|
36268
|
+
var index$3 = /*#__PURE__*/Object.freeze({
|
|
35029
36269
|
__proto__: null,
|
|
35030
36270
|
createReaction: createReaction,
|
|
35031
36271
|
onLiveReactionCreated: onLiveReactionCreated,
|
|
@@ -35508,7 +36748,7 @@ const getMyEvents = (params, callback, config) => {
|
|
|
35508
36748
|
};
|
|
35509
36749
|
};
|
|
35510
36750
|
|
|
35511
|
-
var index$
|
|
36751
|
+
var index$2 = /*#__PURE__*/Object.freeze({
|
|
35512
36752
|
__proto__: null,
|
|
35513
36753
|
createEvent: createEvent,
|
|
35514
36754
|
updateEvent: updateEvent,
|
|
@@ -35735,12 +36975,36 @@ const searchProducts = (params, callback, config) => {
|
|
|
35735
36975
|
};
|
|
35736
36976
|
/* end_public_function */
|
|
35737
36977
|
|
|
35738
|
-
var index = /*#__PURE__*/Object.freeze({
|
|
36978
|
+
var index$1 = /*#__PURE__*/Object.freeze({
|
|
35739
36979
|
__proto__: null,
|
|
35740
36980
|
getProduct: getProduct,
|
|
35741
36981
|
searchProducts: searchProducts
|
|
35742
36982
|
});
|
|
35743
36983
|
|
|
36984
|
+
const getPool = async (topicId, limit) => {
|
|
36985
|
+
const client = getActiveClient();
|
|
36986
|
+
if (!topicId)
|
|
36987
|
+
throw new ASCError('topicId must not be empty', 800110 /* Amity.ClientError.INVALID_PARAMETERS */, "error" /* Amity.ErrorLevel.ERROR */);
|
|
36988
|
+
if (limit !== undefined && (limit < 1 || limit > 100))
|
|
36989
|
+
throw new ASCError('limit must be between 1 and 100', 800110 /* Amity.ClientError.INVALID_PARAMETERS */, "error" /* Amity.ErrorLevel.ERROR */);
|
|
36990
|
+
const { data } = await client.http.get('/api/v5/curated-content/pool', { params: { topicId, limit } });
|
|
36991
|
+
const { topic } = data, payload = __rest(data, ["topic"]);
|
|
36992
|
+
const processedPayload = preparePostPayload(payload);
|
|
36993
|
+
const cachedAt = client.cache && Date.now();
|
|
36994
|
+
if (client.cache) {
|
|
36995
|
+
ingestInCache(processedPayload, { cachedAt });
|
|
36996
|
+
}
|
|
36997
|
+
return {
|
|
36998
|
+
topic: LinkedObject.curatedContentTopic(topic),
|
|
36999
|
+
posts: processedPayload.posts.map(LinkedObject.post),
|
|
37000
|
+
};
|
|
37001
|
+
};
|
|
37002
|
+
|
|
37003
|
+
var index = /*#__PURE__*/Object.freeze({
|
|
37004
|
+
__proto__: null,
|
|
37005
|
+
getPool: getPool
|
|
37006
|
+
});
|
|
37007
|
+
|
|
35744
37008
|
/**
|
|
35745
37009
|
* Helper class for managing product tags per media attachment.
|
|
35746
37010
|
*
|
|
@@ -35788,4 +37052,4 @@ class AmityAttachmentProductTags {
|
|
|
35788
37052
|
}
|
|
35789
37053
|
}
|
|
35790
37054
|
|
|
35791
|
-
export { API_REGIONS, index$
|
|
37055
|
+
export { API_REGIONS, index$6 as AdRepository, AmityAttachmentProductTags, AmityAutoSubscription, AmityChannelNotificationModeEnum, AmityCommunityType, AmityEventOrderOption, AmityEventOriginType, AmityEventResponseStatus, AmityEventSortOption, AmityEventStatus, AmityEventType, AmityLiveViewerCountMode, AmitySharableContentType, AnalyticsSourceTypeEnum, index$g as CategoryRepository, index$k as ChannelRepository, index$t as Client, index$f as CommentRepository, CommunityNotificationEventNameEnum, CommunityPostSettingMaps, CommunityPostSettings, index$h as CommunityRepository, ContentFeedType, ContentFlagReasonEnum, index as CuratedContentRepository, DefaultCommunityPostSetting, index$2 as EventRepository, FeedDataTypeEnum, index$e as FeedRepository, FeedSortByEnum, FeedSourceEnum, FeedTypeEnum, FileAccessTypeEnum, index$q as FileRepository, FileType, GET_WATCHER_URLS, index$4 as InvitationRepository, InvitationSortByEnum, InvitationStatusEnum, InvitationTargetTypeEnum, InvitationTypeEnum, JoinRequestStatusEnum, JoinResultStatusEnum, index$3 as LiveReactionRepository, index$8 as LiveStreamPlayer, MembershipAcceptanceTypeEnum, MessageContentType, index$o as MessageRepository, NotificationRolesFilterTypeEnum, NotificationSettingsLevelEnum, index$9 as PollRepository, PostContentType, index$c as PostRepository, PostStructureType, index$1 as ProductRepository, index$p as ReactionRepository, index$a as RoomPresenceRepository, index$d as RoomRepository, SearchUsersByEnum, index$7 as StoryRepository, index$b as StreamRepository, index$n as SubChannelRepository, SubscriptionLevels, UserNotificationModuleNameEnum, UserReportTypeEnum, index$r as UserRepository, UserTypeEnum, VERSION, VideoResolution, VideoSize, VideoTranscodingStatus, backupCache, createQuery, createReport, createUserToken, deleteReport, disableCache, dropFromCache, enableCache, exceedsUntilAtBoundary, filterByChannelMembership, filterByCommunityMembership, filterByFeedType, filterByPostDataTypes, filterByPropEquality, filterByPropInclusion, filterByPropIntersection, filterBySearchTerm, filterByStringComparePartially, filterByUntilAt, filterCommentsByBlockUsers, filterPostsByBlockUsers, getBlockUsersId, getChannelTopic, getCommentTopic, getCommunityStoriesTopic, getCommunityTopic, getLiveReactionTopic, getLiveStreamTopic, getMarkedMessageTopic, getMarkerUserFeedTopic, getMessageTopic, getMyFollowersTopic, getMyFollowingsTopic, getNetworkId, getNetworkTopic, getPostTopic, getRole, getRoomStreamerTopic, getRoomWatcherTopic, getSmartFeedChannelTopic, getSmartFeedMessageTopic, getSmartFeedSubChannelTopic, getStoryTopic, getSubChannelTopic, getUserTopic, isAfterBefore, isAfterBeforeRaw, isCachable, isFetcher, isFresh, isLocal, isMutator, isOffline, isPaged, isReportedByMe, isSkip, mergeInCache, index$5 as notificationTray, onChannelMarkerFetched, onFeedMarkerFetched, onFeedMarkerUpdated, onMessageMarked, onMessageMarkerFetched, onSubChannelMarkerFetched, onSubChannelMarkerUpdated, onUserMarkerFetched, onUserMarkerFetchedLegacy, pullFromCache, pushToCache, queryCache, queryOptions, queryRoles, restoreCache, runQuery, sortByChannelSegment, sortByDisplayName, sortByFirstCreated, sortByFirstUpdated, sortByLastActivity, sortByLastCreated, sortByLastUpdated, sortByLocalSortingDate, sortByName, sortBySegmentNumber, subscribeTopic, toPage, toPageRaw, toToken, upsertInCache, validateUntilAt, wipeCache };
|