@amityco/ts-sdk-react-native 7.23.1-c573a00.0 → 7.24.1-c018455.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/domains/room.d.ts +1 -1
- package/dist/@types/domains/room.d.ts.map +1 -1
- package/dist/index.cjs.js +1714 -1714
- package/dist/index.esm.js +1714 -1714
- package/dist/index.umd.js +2 -2
- package/dist/utils/linkedObject/storyLinkedObject.d.ts.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs.js
CHANGED
|
@@ -334,8 +334,8 @@ exports.NotificationRolesFilterTypeEnum = void 0;
|
|
|
334
334
|
|
|
335
335
|
function getVersion() {
|
|
336
336
|
try {
|
|
337
|
-
// the string ''v7.
|
|
338
|
-
return 'v7.
|
|
337
|
+
// the string ''v7.24.0-cjs'' should be replaced by actual value by @rollup/plugin-replace
|
|
338
|
+
return 'v7.24.0-cjs';
|
|
339
339
|
}
|
|
340
340
|
catch (error) {
|
|
341
341
|
return '__dev__';
|
|
@@ -13491,562 +13491,571 @@ var index$r = /*#__PURE__*/Object.freeze({
|
|
|
13491
13491
|
getMyFollowInfo: getMyFollowInfo
|
|
13492
13492
|
});
|
|
13493
13493
|
|
|
13494
|
-
|
|
13495
|
-
|
|
13496
|
-
|
|
13497
|
-
|
|
13498
|
-
|
|
13499
|
-
|
|
13500
|
-
|
|
13501
|
-
|
|
13502
|
-
|
|
13503
|
-
|
|
13504
|
-
|
|
13505
|
-
|
|
13506
|
-
|
|
13507
|
-
|
|
13508
|
-
|
|
13509
|
-
|
|
13510
|
-
|
|
13511
|
-
|
|
13512
|
-
|
|
13513
|
-
|
|
13514
|
-
|
|
13515
|
-
|
|
13516
|
-
|
|
13517
|
-
|
|
13518
|
-
|
|
13519
|
-
|
|
13520
|
-
? new Date((_b = this.cacheStoryExpireTime) === null || _b === void 0 ? void 0 : _b.data).getTime()
|
|
13521
|
-
: 0;
|
|
13522
|
-
}
|
|
13523
|
-
get localLastStorySeenExpiresAt() {
|
|
13524
|
-
var _a, _b;
|
|
13525
|
-
return ((_a = this.cacheStoreSeenTime) === null || _a === void 0 ? void 0 : _a.data) ? new Date((_b = this.cacheStoreSeenTime) === null || _b === void 0 ? void 0 : _b.data).getTime() : 0;
|
|
13526
|
-
}
|
|
13527
|
-
get isContainUnSyncedStory() {
|
|
13528
|
-
const currentSyncingState = pullFromCache([
|
|
13529
|
-
"story-sync-state" /* STORY_KEY_CACHE.SYNC_STATE */,
|
|
13530
|
-
this._targetId,
|
|
13531
|
-
]);
|
|
13532
|
-
if (!(currentSyncingState === null || currentSyncingState === void 0 ? void 0 : currentSyncingState.data))
|
|
13533
|
-
return false;
|
|
13534
|
-
return ["syncing" /* Amity.SyncState.Syncing */, "error" /* Amity.SyncState.Error */].includes(currentSyncingState.data);
|
|
13535
|
-
}
|
|
13536
|
-
getLocalLastSortingDate() {
|
|
13537
|
-
if (this.isContainUnSyncedStory) {
|
|
13538
|
-
return this.localLastStoryExpires;
|
|
13539
|
-
}
|
|
13540
|
-
return this.lastStoryExpiresAt;
|
|
13541
|
-
}
|
|
13542
|
-
getHasUnseenFlag() {
|
|
13543
|
-
const now = new Date().getTime();
|
|
13544
|
-
const highestSeen = Math.max(this.lastStorySeenExpiresAt, this.localLastStorySeenExpiresAt);
|
|
13545
|
-
pullFromCache([
|
|
13546
|
-
"story-sync-state" /* STORY_KEY_CACHE.SYNC_STATE */,
|
|
13547
|
-
this._targetId,
|
|
13494
|
+
/*
|
|
13495
|
+
* verifies membership status
|
|
13496
|
+
*/
|
|
13497
|
+
function isMember(membership) {
|
|
13498
|
+
return membership !== 'none';
|
|
13499
|
+
}
|
|
13500
|
+
/*
|
|
13501
|
+
* checks if currently logged in user is part of the community
|
|
13502
|
+
*/
|
|
13503
|
+
function isCurrentUserPartOfCommunity(c, m) {
|
|
13504
|
+
const { userId } = getActiveUser();
|
|
13505
|
+
return c.communityId === m.communityId && m.userId === userId;
|
|
13506
|
+
}
|
|
13507
|
+
/*
|
|
13508
|
+
* For mqtt events server will not send user specific data as it's broadcasted
|
|
13509
|
+
* to multiple users and it also does not include communityUser
|
|
13510
|
+
*
|
|
13511
|
+
* Client SDK needs to check for the existing isJoined field in cache data before calculating.
|
|
13512
|
+
* Althought this can be calculated, it's not scalable.
|
|
13513
|
+
*/
|
|
13514
|
+
function updateMembershipStatus(communities, communityUsers) {
|
|
13515
|
+
return communities.map(c => {
|
|
13516
|
+
const cachedCommunity = pullFromCache([
|
|
13517
|
+
'community',
|
|
13518
|
+
'get',
|
|
13519
|
+
c.communityId,
|
|
13548
13520
|
]);
|
|
13549
|
-
if (
|
|
13550
|
-
return
|
|
13551
|
-
}
|
|
13552
|
-
return this.lastStoryExpiresAt > now && this.lastStoryExpiresAt > highestSeen;
|
|
13553
|
-
}
|
|
13554
|
-
getTotalStoryByStatus() {
|
|
13555
|
-
const stories = queryCache(["story" /* STORY_KEY_CACHE.STORY */, 'get']);
|
|
13556
|
-
if (!stories) {
|
|
13557
|
-
this._errorStoriesCount = 0;
|
|
13558
|
-
this._syncingStoriesCount = 0;
|
|
13559
|
-
return;
|
|
13521
|
+
if ((cachedCommunity === null || cachedCommunity === void 0 ? void 0 : cachedCommunity.data) && (cachedCommunity === null || cachedCommunity === void 0 ? void 0 : cachedCommunity.data.hasOwnProperty('isJoined'))) {
|
|
13522
|
+
return Object.assign(Object.assign({}, cachedCommunity.data), c);
|
|
13560
13523
|
}
|
|
13561
|
-
const
|
|
13562
|
-
|
|
13563
|
-
|
|
13564
|
-
|
|
13565
|
-
|
|
13566
|
-
|
|
13567
|
-
|
|
13568
|
-
|
|
13569
|
-
|
|
13570
|
-
|
|
13524
|
+
const isJoined = c.isJoined !== undefined
|
|
13525
|
+
? c.isJoined
|
|
13526
|
+
: communityUsers.some(m => isCurrentUserPartOfCommunity(c, m) && isMember(m.communityMembership));
|
|
13527
|
+
return Object.assign(Object.assign({}, c), { isJoined });
|
|
13528
|
+
});
|
|
13529
|
+
}
|
|
13530
|
+
|
|
13531
|
+
const getMatchPostSetting = (value) => {
|
|
13532
|
+
var _a;
|
|
13533
|
+
return (_a = Object.keys(CommunityPostSettingMaps).find(key => value.needApprovalOnPostCreation ===
|
|
13534
|
+
CommunityPostSettingMaps[key].needApprovalOnPostCreation &&
|
|
13535
|
+
value.onlyAdminCanPost === CommunityPostSettingMaps[key].onlyAdminCanPost)) !== null && _a !== void 0 ? _a : DefaultCommunityPostSetting;
|
|
13536
|
+
};
|
|
13537
|
+
function addPostSetting({ communities }) {
|
|
13538
|
+
return communities.map((_a) => {
|
|
13539
|
+
var { needApprovalOnPostCreation, onlyAdminCanPost } = _a, restCommunityPayload = __rest(_a, ["needApprovalOnPostCreation", "onlyAdminCanPost"]);
|
|
13540
|
+
return (Object.assign({ postSetting: getMatchPostSetting({
|
|
13541
|
+
needApprovalOnPostCreation,
|
|
13542
|
+
onlyAdminCanPost,
|
|
13543
|
+
}) }, restCommunityPayload));
|
|
13544
|
+
});
|
|
13545
|
+
}
|
|
13546
|
+
const prepareCommunityPayload = (rawPayload) => {
|
|
13547
|
+
const communitiesWithPostSetting = addPostSetting({ communities: rawPayload.communities });
|
|
13548
|
+
// Convert users to internal format
|
|
13549
|
+
const internalUsers = rawPayload.users.map(convertRawUserToInternalUser);
|
|
13550
|
+
// map users with community
|
|
13551
|
+
const mappedCommunityUsers = rawPayload.communityUsers.map(communityUser => {
|
|
13552
|
+
const user = internalUsers.find(user => user.userId === communityUser.userId);
|
|
13553
|
+
return Object.assign(Object.assign({}, communityUser), { user });
|
|
13554
|
+
});
|
|
13555
|
+
const communityWithMembershipStatus = updateMembershipStatus(communitiesWithPostSetting, mappedCommunityUsers);
|
|
13556
|
+
return Object.assign(Object.assign({}, rawPayload), { users: rawPayload.users.map(convertRawUserToInternalUser), communities: communityWithMembershipStatus, communityUsers: mappedCommunityUsers });
|
|
13557
|
+
};
|
|
13558
|
+
const prepareCommunityJoinRequestPayload = (rawPayload) => {
|
|
13559
|
+
const mappedJoinRequests = rawPayload.joinRequests.map(joinRequest => {
|
|
13560
|
+
return Object.assign(Object.assign({}, joinRequest), { joinRequestId: joinRequest._id });
|
|
13561
|
+
});
|
|
13562
|
+
const users = rawPayload.users.map(convertRawUserToInternalUser);
|
|
13563
|
+
return Object.assign(Object.assign({}, rawPayload), { joinRequests: mappedJoinRequests, users });
|
|
13564
|
+
};
|
|
13565
|
+
const prepareCommunityMembershipPayload = (rawPayload) => {
|
|
13566
|
+
const communitiesWithPostSetting = addPostSetting({ communities: rawPayload.communities });
|
|
13567
|
+
// map users with community
|
|
13568
|
+
const mappedCommunityUsers = rawPayload.communityUsers.map(communityUser => {
|
|
13569
|
+
const user = rawPayload.users.find(user => user.userId === communityUser.userId);
|
|
13570
|
+
return Object.assign(Object.assign({}, communityUser), { user });
|
|
13571
|
+
});
|
|
13572
|
+
const communityWithMembershipStatus = updateMembershipStatus(communitiesWithPostSetting, mappedCommunityUsers);
|
|
13573
|
+
return Object.assign(Object.assign({}, rawPayload), { communities: communityWithMembershipStatus, communityUsers: mappedCommunityUsers });
|
|
13574
|
+
};
|
|
13575
|
+
const prepareCommunityRequest = (params) => {
|
|
13576
|
+
const { postSetting = undefined, storySetting } = params, restParam = __rest(params, ["postSetting", "storySetting"]);
|
|
13577
|
+
return Object.assign(Object.assign(Object.assign({}, restParam), (postSetting ? CommunityPostSettingMaps[postSetting] : undefined)), {
|
|
13578
|
+
// Convert story setting to the actual value. (Allow by default)
|
|
13579
|
+
allowCommentInStory: typeof (storySetting === null || storySetting === void 0 ? void 0 : storySetting.enableComment) === 'boolean' ? storySetting.enableComment : true });
|
|
13580
|
+
};
|
|
13581
|
+
const prepareSemanticSearchCommunityPayload = (_a) => {
|
|
13582
|
+
var communityPayload = __rest(_a, ["searchResult"]);
|
|
13583
|
+
const processedCommunityPayload = prepareCommunityPayload(communityPayload);
|
|
13584
|
+
return Object.assign({}, processedCommunityPayload);
|
|
13585
|
+
};
|
|
13586
|
+
|
|
13587
|
+
/* begin_public_function
|
|
13588
|
+
id: joinRequest.approve
|
|
13589
|
+
*/
|
|
13590
|
+
/**
|
|
13591
|
+
* ```js
|
|
13592
|
+
* import { joinRequest } from '@amityco/ts-sdk-react-native'
|
|
13593
|
+
* const isAccepted = await joinRequest.approve()
|
|
13594
|
+
* ```
|
|
13595
|
+
*
|
|
13596
|
+
* Accepts a {@link Amity.JoinRequest} object
|
|
13597
|
+
*
|
|
13598
|
+
* @param joinRequest the {@link Amity.JoinRequest} to accept
|
|
13599
|
+
* @returns A success boolean if the {@link Amity.JoinRequest} was accepted
|
|
13600
|
+
*
|
|
13601
|
+
* @category Join Request API
|
|
13602
|
+
* @async
|
|
13603
|
+
*/
|
|
13604
|
+
const approveJoinRequest = async (joinRequest) => {
|
|
13605
|
+
var _a;
|
|
13606
|
+
const client = getActiveClient();
|
|
13607
|
+
client.log('joinRequest/approveJoinRequest', joinRequest.joinRequestId);
|
|
13608
|
+
const { data } = await client.http.post(`/api/v4/communities/${joinRequest.targetId}/join/approve`, {
|
|
13609
|
+
userId: joinRequest.requestorInternalId,
|
|
13610
|
+
});
|
|
13611
|
+
const joinRequestCache = (_a = pullFromCache([
|
|
13612
|
+
'joinRequest',
|
|
13613
|
+
'get',
|
|
13614
|
+
joinRequest.joinRequestId,
|
|
13615
|
+
])) === null || _a === void 0 ? void 0 : _a.data;
|
|
13616
|
+
if (joinRequestCache) {
|
|
13617
|
+
upsertInCache(['joinRequest', 'get', joinRequest.joinRequestId], {
|
|
13618
|
+
status: "approved" /* JoinRequestStatusEnum.Approved */,
|
|
13571
13619
|
});
|
|
13572
|
-
|
|
13573
|
-
this._syncingStoriesCount = groupByType.syncing;
|
|
13574
|
-
}
|
|
13575
|
-
get syncingStoriesCount() {
|
|
13576
|
-
return this._syncingStoriesCount;
|
|
13577
|
-
}
|
|
13578
|
-
get failedStoriesCount() {
|
|
13579
|
-
return this._errorStoriesCount;
|
|
13620
|
+
fireEvent('local.joinRequest.updated', [joinRequestCache]);
|
|
13580
13621
|
}
|
|
13581
|
-
|
|
13622
|
+
return data.success;
|
|
13623
|
+
};
|
|
13624
|
+
/* end_public_function */
|
|
13582
13625
|
|
|
13583
|
-
|
|
13584
|
-
|
|
13585
|
-
|
|
13586
|
-
|
|
13587
|
-
|
|
13588
|
-
|
|
13589
|
-
|
|
13590
|
-
|
|
13591
|
-
|
|
13592
|
-
|
|
13593
|
-
|
|
13594
|
-
|
|
13595
|
-
|
|
13596
|
-
|
|
13597
|
-
|
|
13598
|
-
|
|
13599
|
-
|
|
13626
|
+
/* begin_public_function
|
|
13627
|
+
id: joinRequest.cancel
|
|
13628
|
+
*/
|
|
13629
|
+
/**
|
|
13630
|
+
* ```js
|
|
13631
|
+
* import { joinRequest } from '@amityco/ts-sdk-react-native'
|
|
13632
|
+
* const isCanceled = await joinRequest.cancel()
|
|
13633
|
+
* ```
|
|
13634
|
+
*
|
|
13635
|
+
* Cancels a {@link Amity.JoinRequest} object
|
|
13636
|
+
*
|
|
13637
|
+
* @param joinRequest the {@link Amity.JoinRequest} to cancel
|
|
13638
|
+
* @returns A success boolean if the {@link Amity.JoinRequest} was canceled
|
|
13639
|
+
*
|
|
13640
|
+
* @category Join Request API
|
|
13641
|
+
* @async
|
|
13642
|
+
*/
|
|
13643
|
+
const cancelJoinRequest = async (joinRequest) => {
|
|
13644
|
+
var _a;
|
|
13645
|
+
const client = getActiveClient();
|
|
13646
|
+
client.log('joinRequest/cancelJoinRequest', joinRequest.joinRequestId);
|
|
13647
|
+
const { data } = await client.http.delete(`/api/v4/communities/${joinRequest.targetId}/join`);
|
|
13648
|
+
const joinRequestCache = (_a = pullFromCache([
|
|
13649
|
+
'joinRequest',
|
|
13650
|
+
'get',
|
|
13651
|
+
joinRequest.joinRequestId,
|
|
13652
|
+
])) === null || _a === void 0 ? void 0 : _a.data;
|
|
13653
|
+
if (joinRequestCache) {
|
|
13654
|
+
upsertInCache(['joinRequest', 'get', joinRequest.joinRequestId], {
|
|
13655
|
+
status: "cancelled" /* JoinRequestStatusEnum.Cancelled */,
|
|
13656
|
+
});
|
|
13657
|
+
fireEvent('local.joinRequest.deleted', [joinRequestCache]);
|
|
13658
|
+
}
|
|
13659
|
+
return data.success;
|
|
13600
13660
|
};
|
|
13661
|
+
/* end_public_function */
|
|
13601
13662
|
|
|
13602
|
-
|
|
13603
|
-
|
|
13604
|
-
|
|
13605
|
-
|
|
13663
|
+
/* begin_public_function
|
|
13664
|
+
id: joinRequest.reject
|
|
13665
|
+
*/
|
|
13666
|
+
/**
|
|
13667
|
+
* ```js
|
|
13668
|
+
* import { joinRequest } from '@amityco/ts-sdk-react-native'
|
|
13669
|
+
* const isRejected = await joinRequest.reject()
|
|
13670
|
+
* ```
|
|
13671
|
+
*
|
|
13672
|
+
* Rejects a {@link Amity.JoinRequest} object
|
|
13673
|
+
*
|
|
13674
|
+
* @param joinRequest the {@link Amity.JoinRequest} to reject
|
|
13675
|
+
* @returns A success boolean if the {@link Amity.JoinRequest} was rejected
|
|
13676
|
+
*
|
|
13677
|
+
* @category Join Request API
|
|
13678
|
+
* @async
|
|
13679
|
+
*/
|
|
13680
|
+
const rejectJoinRequest = async (joinRequest) => {
|
|
13681
|
+
var _a;
|
|
13682
|
+
const client = getActiveClient();
|
|
13683
|
+
client.log('joinRequest/rejectJoinRequest', joinRequest.joinRequestId);
|
|
13684
|
+
const { data } = await client.http.post(`/api/v4/communities/${joinRequest.targetId}/join/reject`, {
|
|
13685
|
+
userId: joinRequest.requestorInternalId,
|
|
13686
|
+
});
|
|
13687
|
+
const joinRequestCache = (_a = pullFromCache([
|
|
13688
|
+
'joinRequest',
|
|
13606
13689
|
'get',
|
|
13607
|
-
|
|
13608
|
-
]);
|
|
13609
|
-
|
|
13610
|
-
|
|
13611
|
-
|
|
13612
|
-
|
|
13613
|
-
|
|
13614
|
-
|
|
13615
|
-
|
|
13616
|
-
|
|
13617
|
-
|
|
13618
|
-
|
|
13619
|
-
|
|
13620
|
-
|
|
13621
|
-
|
|
13622
|
-
|
|
13623
|
-
|
|
13624
|
-
|
|
13625
|
-
|
|
13626
|
-
|
|
13627
|
-
|
|
13628
|
-
'file',
|
|
13629
|
-
'get',
|
|
13630
|
-
(_b = (_a = story.data) === null || _a === void 0 ? void 0 : _a.videoFileId) === null || _b === void 0 ? void 0 : _b.original,
|
|
13631
|
-
]);
|
|
13632
|
-
if (!cache)
|
|
13633
|
-
return undefined;
|
|
13634
|
-
const { data } = cache;
|
|
13635
|
-
return data || undefined;
|
|
13636
|
-
},
|
|
13637
|
-
get imageData() {
|
|
13638
|
-
var _a, _b;
|
|
13639
|
-
if (!((_a = story.data) === null || _a === void 0 ? void 0 : _a.fileId))
|
|
13640
|
-
return undefined;
|
|
13641
|
-
const cache = pullFromCache(['file', 'get', (_b = story.data) === null || _b === void 0 ? void 0 : _b.fileId]);
|
|
13642
|
-
if (!cache)
|
|
13643
|
-
return undefined;
|
|
13644
|
-
const { data } = cache;
|
|
13645
|
-
if (!data)
|
|
13646
|
-
return undefined;
|
|
13647
|
-
return Object.assign(Object.assign({}, data), { fileUrl: `${data.fileUrl}?size=full` });
|
|
13648
|
-
},
|
|
13649
|
-
get community() {
|
|
13650
|
-
if (story.targetType !== 'community')
|
|
13651
|
-
return undefined;
|
|
13652
|
-
if (!communityCacheData)
|
|
13653
|
-
return undefined;
|
|
13654
|
-
return (communityCacheData === null || communityCacheData === void 0 ? void 0 : communityCacheData.data) || undefined;
|
|
13655
|
-
},
|
|
13656
|
-
get communityCategories() {
|
|
13657
|
-
if (story.targetType !== 'community')
|
|
13658
|
-
return undefined;
|
|
13659
|
-
if (!communityCacheData)
|
|
13660
|
-
return undefined;
|
|
13661
|
-
const { data: { categoryIds }, } = communityCacheData;
|
|
13662
|
-
if (categoryIds.length === 0)
|
|
13690
|
+
joinRequest.joinRequestId,
|
|
13691
|
+
])) === null || _a === void 0 ? void 0 : _a.data;
|
|
13692
|
+
if (joinRequestCache) {
|
|
13693
|
+
upsertInCache(['joinRequest', 'get', joinRequest.joinRequestId], {
|
|
13694
|
+
status: "rejected" /* JoinRequestStatusEnum.Rejected */,
|
|
13695
|
+
});
|
|
13696
|
+
fireEvent('local.joinRequest.updated', [joinRequestCache]);
|
|
13697
|
+
}
|
|
13698
|
+
return data.success;
|
|
13699
|
+
};
|
|
13700
|
+
/* end_public_function */
|
|
13701
|
+
|
|
13702
|
+
const joinRequestLinkedObject = (joinRequest) => {
|
|
13703
|
+
return Object.assign(Object.assign({}, joinRequest), { get user() {
|
|
13704
|
+
var _a;
|
|
13705
|
+
const user = (_a = pullFromCache([
|
|
13706
|
+
'user',
|
|
13707
|
+
'get',
|
|
13708
|
+
joinRequest.requestorPublicId,
|
|
13709
|
+
])) === null || _a === void 0 ? void 0 : _a.data;
|
|
13710
|
+
if (!user)
|
|
13663
13711
|
return undefined;
|
|
13664
|
-
return
|
|
13665
|
-
|
|
13666
|
-
|
|
13667
|
-
|
|
13668
|
-
|
|
13669
|
-
|
|
13670
|
-
|
|
13671
|
-
get creator() {
|
|
13672
|
-
const cacheData = pullFromCache(['user', 'get', story.creatorPublicId]);
|
|
13673
|
-
if (!(cacheData === null || cacheData === void 0 ? void 0 : cacheData.data))
|
|
13674
|
-
return;
|
|
13675
|
-
return userLinkedObject(cacheData.data);
|
|
13676
|
-
},
|
|
13677
|
-
get storyTarget() {
|
|
13678
|
-
if (!(storyTargetCache === null || storyTargetCache === void 0 ? void 0 : storyTargetCache.data))
|
|
13679
|
-
return;
|
|
13680
|
-
return storyTargetLinkedObject(storyTargetCache.data);
|
|
13681
|
-
},
|
|
13682
|
-
get isSeen() {
|
|
13683
|
-
const cacheData = pullFromCache(["story-last-seen" /* STORY_KEY_CACHE.LAST_SEEN */, story.targetId]);
|
|
13684
|
-
if (!(storyTargetCache === null || storyTargetCache === void 0 ? void 0 : storyTargetCache.data))
|
|
13685
|
-
return false;
|
|
13686
|
-
const localLastSeen = (cacheData === null || cacheData === void 0 ? void 0 : cacheData.data) ? new Date(cacheData.data).getTime() : 0;
|
|
13687
|
-
const serverLastSeen = new Date(storyTargetCache === null || storyTargetCache === void 0 ? void 0 : storyTargetCache.data.lastStorySeenExpiresAt).getTime() || 0;
|
|
13688
|
-
const expiresAt = new Date(story.expiresAt).getTime();
|
|
13689
|
-
return Math.max(localLastSeen, serverLastSeen) >= expiresAt;
|
|
13712
|
+
return userLinkedObject(user);
|
|
13713
|
+
}, cancel: async () => {
|
|
13714
|
+
await cancelJoinRequest(joinRequest);
|
|
13715
|
+
}, approve: async () => {
|
|
13716
|
+
await approveJoinRequest(joinRequest);
|
|
13717
|
+
}, reject: async () => {
|
|
13718
|
+
await rejectJoinRequest(joinRequest);
|
|
13690
13719
|
} });
|
|
13691
13720
|
};
|
|
13692
13721
|
|
|
13693
13722
|
/* begin_public_function
|
|
13694
|
-
id:
|
|
13723
|
+
id: community.getMyJoinRequest
|
|
13695
13724
|
*/
|
|
13696
13725
|
/**
|
|
13697
13726
|
* ```js
|
|
13698
|
-
* import {
|
|
13699
|
-
* const
|
|
13727
|
+
* import { community } from '@amityco/ts-sdk-react-native'
|
|
13728
|
+
* const isJoined = await community.getMyJoinRequest('foobar')
|
|
13700
13729
|
* ```
|
|
13701
13730
|
*
|
|
13702
|
-
*
|
|
13731
|
+
* Joins a {@link Amity.Community} object
|
|
13703
13732
|
*
|
|
13704
|
-
* @param
|
|
13705
|
-
* @returns
|
|
13733
|
+
* @param communityId the {@link Amity.Community} to join
|
|
13734
|
+
* @returns A success boolean if the {@link Amity.Community} was joined
|
|
13706
13735
|
*
|
|
13707
|
-
* @category
|
|
13736
|
+
* @category Community API
|
|
13708
13737
|
* @async
|
|
13709
13738
|
*/
|
|
13710
|
-
const
|
|
13739
|
+
const getMyJoinRequest = async (communityId) => {
|
|
13711
13740
|
const client = getActiveClient();
|
|
13712
|
-
client.log('
|
|
13713
|
-
|
|
13714
|
-
|
|
13715
|
-
if ((bundle === null || bundle === void 0 ? void 0 : bundle.type) === 'conversation') {
|
|
13716
|
-
payload = await client.http.post('/api/v3/channels/conversation', Object.assign(Object.assign({}, bundle), { isDistinct: true }));
|
|
13717
|
-
}
|
|
13718
|
-
else {
|
|
13719
|
-
const { isPublic } = bundle, restParams = __rest(bundle, ["isPublic"]);
|
|
13720
|
-
payload = await client.http.post('/api/v3/channels', Object.assign(Object.assign({}, restParams), {
|
|
13721
|
-
/* c8 ignore next */
|
|
13722
|
-
isPublic: (bundle === null || bundle === void 0 ? void 0 : bundle.type) === 'community' ? isPublic : undefined }));
|
|
13723
|
-
}
|
|
13724
|
-
const data = await prepareChannelPayload(payload.data);
|
|
13741
|
+
client.log('community/myJoinRequest', communityId);
|
|
13742
|
+
const { data: payload } = await client.http.get(`/api/v4/communities/${communityId}/join/me`);
|
|
13743
|
+
const data = prepareCommunityJoinRequestPayload(payload);
|
|
13725
13744
|
const cachedAt = client.cache && Date.now();
|
|
13726
13745
|
if (client.cache)
|
|
13727
13746
|
ingestInCache(data, { cachedAt });
|
|
13728
|
-
const { channels } = data;
|
|
13729
13747
|
return {
|
|
13730
|
-
data:
|
|
13748
|
+
data: data.joinRequests[0] ? joinRequestLinkedObject(data.joinRequests[0]) : undefined,
|
|
13731
13749
|
cachedAt,
|
|
13732
13750
|
};
|
|
13733
13751
|
};
|
|
13734
13752
|
/* end_public_function */
|
|
13735
13753
|
|
|
13754
|
+
/* begin_public_function
|
|
13755
|
+
id: community.join
|
|
13756
|
+
*/
|
|
13736
13757
|
/**
|
|
13737
13758
|
* ```js
|
|
13738
|
-
* import {
|
|
13739
|
-
* const
|
|
13759
|
+
* import { community } from '@amityco/ts-sdk-react-native'
|
|
13760
|
+
* const isJoined = await community.join('foobar')
|
|
13740
13761
|
* ```
|
|
13741
13762
|
*
|
|
13742
|
-
*
|
|
13763
|
+
* Joins a {@link Amity.Community} object
|
|
13743
13764
|
*
|
|
13744
|
-
* @param
|
|
13745
|
-
* @returns
|
|
13765
|
+
* @param communityId the {@link Amity.Community} to join
|
|
13766
|
+
* @returns A status join result
|
|
13746
13767
|
*
|
|
13747
|
-
* @category
|
|
13768
|
+
* @category Community API
|
|
13748
13769
|
* @async
|
|
13749
13770
|
*/
|
|
13750
|
-
const
|
|
13771
|
+
const joinRequest = async (communityId) => {
|
|
13772
|
+
var _a;
|
|
13751
13773
|
const client = getActiveClient();
|
|
13752
|
-
client.log('
|
|
13753
|
-
|
|
13754
|
-
|
|
13755
|
-
|
|
13756
|
-
|
|
13757
|
-
data
|
|
13758
|
-
|
|
13759
|
-
|
|
13774
|
+
client.log('community/joinRequest', communityId);
|
|
13775
|
+
const { data: payload } = await client.http.post(`/api/v4/communities/${communityId}/join`);
|
|
13776
|
+
const data = prepareCommunityJoinRequestPayload(payload);
|
|
13777
|
+
const cachedAt = client.cache && Date.now();
|
|
13778
|
+
if (client.cache)
|
|
13779
|
+
ingestInCache(data, { cachedAt });
|
|
13780
|
+
const status = data.joinRequests[0].status === "approved" /* JoinRequestStatusEnum.Approved */
|
|
13781
|
+
? "success" /* JoinResultStatusEnum.Success */
|
|
13782
|
+
: "pending" /* JoinResultStatusEnum.Pending */;
|
|
13783
|
+
if (status === "success" /* JoinResultStatusEnum.Success */ && client.cache) {
|
|
13784
|
+
const community = (_a = pullFromCache(['community', 'get', communityId])) === null || _a === void 0 ? void 0 : _a.data;
|
|
13785
|
+
if (community) {
|
|
13786
|
+
const updatedCommunity = Object.assign(Object.assign({}, community), { isJoined: true });
|
|
13787
|
+
upsertInCache(['community', 'get', communityId], updatedCommunity);
|
|
13760
13788
|
}
|
|
13761
13789
|
}
|
|
13762
|
-
|
|
13763
|
-
|
|
13764
|
-
|
|
13765
|
-
|
|
13790
|
+
fireEvent('v4.local.community.joined', data.joinRequests);
|
|
13791
|
+
return status === "success" /* JoinResultStatusEnum.Success */
|
|
13792
|
+
? { status }
|
|
13793
|
+
: { status, request: joinRequestLinkedObject(data.joinRequests[0]) };
|
|
13794
|
+
};
|
|
13795
|
+
/* end_public_function */
|
|
13796
|
+
|
|
13797
|
+
/**
|
|
13798
|
+
* TODO: handle cache receive cache option, and cache policy
|
|
13799
|
+
* TODO: check if querybyIds is supported
|
|
13800
|
+
*/
|
|
13801
|
+
class JoinRequestsPaginationController extends PaginationController {
|
|
13802
|
+
async getRequest(queryParams, token) {
|
|
13803
|
+
const { limit = 20, communityId } = queryParams, params = __rest(queryParams, ["limit", "communityId"]);
|
|
13804
|
+
const options = token ? { token } : { limit };
|
|
13805
|
+
const { data: queryResponse } = await this.http.get(`/api/v4/communities/${communityId}/join`, {
|
|
13806
|
+
params: Object.assign(Object.assign({}, params), { options }),
|
|
13807
|
+
});
|
|
13808
|
+
return queryResponse;
|
|
13809
|
+
}
|
|
13810
|
+
}
|
|
13811
|
+
|
|
13812
|
+
var EnumJoinRequestAction$1;
|
|
13813
|
+
(function (EnumJoinRequestAction) {
|
|
13814
|
+
EnumJoinRequestAction["OnLocalJoinRequestCreated"] = "OnLocalJoinRequestCreated";
|
|
13815
|
+
EnumJoinRequestAction["OnLocalJoinRequestUpdated"] = "OnLocalJoinRequestUpdated";
|
|
13816
|
+
EnumJoinRequestAction["OnLocalJoinRequestDeleted"] = "OnLocalJoinRequestDeleted";
|
|
13817
|
+
})(EnumJoinRequestAction$1 || (EnumJoinRequestAction$1 = {}));
|
|
13818
|
+
|
|
13819
|
+
class JoinRequestsQueryStreamController extends QueryStreamController {
|
|
13820
|
+
constructor(query, cacheKey, notifyChange, preparePayload) {
|
|
13821
|
+
super(query, cacheKey);
|
|
13822
|
+
this.notifyChange = notifyChange;
|
|
13823
|
+
this.preparePayload = preparePayload;
|
|
13824
|
+
}
|
|
13825
|
+
async saveToMainDB(response) {
|
|
13826
|
+
const processedPayload = await this.preparePayload(response);
|
|
13827
|
+
const client = getActiveClient();
|
|
13828
|
+
const cachedAt = client.cache && Date.now();
|
|
13829
|
+
if (client.cache) {
|
|
13830
|
+
ingestInCache(processedPayload, { cachedAt });
|
|
13766
13831
|
}
|
|
13767
|
-
throw error;
|
|
13768
13832
|
}
|
|
13769
|
-
|
|
13770
|
-
|
|
13771
|
-
|
|
13772
|
-
|
|
13773
|
-
|
|
13774
|
-
|
|
13775
|
-
|
|
13833
|
+
appendToQueryStream(response, direction, refresh = false) {
|
|
13834
|
+
var _a, _b;
|
|
13835
|
+
if (refresh) {
|
|
13836
|
+
pushToCache(this.cacheKey, {
|
|
13837
|
+
data: response.joinRequests.map(joinRequest => getResolver('joinRequest')({ joinRequestId: joinRequest._id })),
|
|
13838
|
+
});
|
|
13839
|
+
}
|
|
13840
|
+
else {
|
|
13841
|
+
const collection = (_a = pullFromCache(this.cacheKey)) === null || _a === void 0 ? void 0 : _a.data;
|
|
13842
|
+
const joinRequests = (_b = collection === null || collection === void 0 ? void 0 : collection.data) !== null && _b !== void 0 ? _b : [];
|
|
13843
|
+
pushToCache(this.cacheKey, Object.assign(Object.assign({}, collection), { data: [
|
|
13844
|
+
...new Set([
|
|
13845
|
+
...joinRequests,
|
|
13846
|
+
...response.joinRequests.map(joinRequest => getResolver('joinRequest')({ joinRequestId: joinRequest._id })),
|
|
13847
|
+
]),
|
|
13848
|
+
] }));
|
|
13849
|
+
}
|
|
13850
|
+
}
|
|
13851
|
+
reactor(action) {
|
|
13852
|
+
return (joinRequest) => {
|
|
13853
|
+
var _a;
|
|
13854
|
+
const collection = (_a = pullFromCache(this.cacheKey)) === null || _a === void 0 ? void 0 : _a.data;
|
|
13855
|
+
if (!collection)
|
|
13856
|
+
return;
|
|
13857
|
+
if (action === EnumJoinRequestAction$1.OnLocalJoinRequestUpdated) {
|
|
13858
|
+
const isExist = collection.data.find(id => id === joinRequest[0].joinRequestId);
|
|
13859
|
+
if (!isExist)
|
|
13860
|
+
return;
|
|
13861
|
+
}
|
|
13862
|
+
if (action === EnumJoinRequestAction$1.OnLocalJoinRequestCreated) {
|
|
13863
|
+
collection.data = [
|
|
13864
|
+
...new Set([
|
|
13865
|
+
...joinRequest.map(joinRequest => joinRequest.joinRequestId),
|
|
13866
|
+
...collection.data,
|
|
13867
|
+
]),
|
|
13868
|
+
];
|
|
13869
|
+
}
|
|
13870
|
+
if (action === EnumJoinRequestAction$1.OnLocalJoinRequestDeleted) {
|
|
13871
|
+
collection.data = collection.data.filter(id => id !== joinRequest[0].joinRequestId);
|
|
13872
|
+
}
|
|
13873
|
+
pushToCache(this.cacheKey, collection);
|
|
13874
|
+
this.notifyChange({ origin: "event" /* Amity.LiveDataOrigin.EVENT */, loading: false });
|
|
13875
|
+
};
|
|
13876
|
+
}
|
|
13877
|
+
subscribeRTE(createSubscriber) {
|
|
13878
|
+
return createSubscriber.map(subscriber => subscriber.fn(this.reactor(subscriber.action)));
|
|
13879
|
+
}
|
|
13880
|
+
}
|
|
13881
|
+
|
|
13882
|
+
/**
|
|
13883
|
+
* ```js
|
|
13884
|
+
* import { onJoinRequestCreated } from '@amityco/ts-sdk-react-native'
|
|
13885
|
+
* const dispose = onJoinRequestCreated(data => {
|
|
13886
|
+
* // ...
|
|
13887
|
+
* })
|
|
13888
|
+
* ```
|
|
13889
|
+
*
|
|
13890
|
+
* Fired when an {@link Amity.CommunityJoinRequestPayload} has been created
|
|
13891
|
+
*
|
|
13892
|
+
* @param callback The function to call when the event was fired
|
|
13893
|
+
* @returns an {@link Amity.Unsubscriber} function to stop listening
|
|
13894
|
+
*
|
|
13895
|
+
* @category JoinRequest Events
|
|
13896
|
+
*/
|
|
13897
|
+
const onJoinRequestCreated = (callback) => {
|
|
13898
|
+
const client = getActiveClient();
|
|
13899
|
+
const disposers = [
|
|
13900
|
+
createEventSubscriber(client, 'onJoinRequestCreated', 'local.joinRequest.created', payload => callback(payload)),
|
|
13901
|
+
];
|
|
13902
|
+
return () => {
|
|
13903
|
+
disposers.forEach(fn => fn());
|
|
13776
13904
|
};
|
|
13777
13905
|
};
|
|
13906
|
+
|
|
13778
13907
|
/**
|
|
13779
|
-
* ```js
|
|
13780
|
-
* import {
|
|
13781
|
-
* const
|
|
13908
|
+
* ```js
|
|
13909
|
+
* import { onJoinRequestUpdated } from '@amityco/ts-sdk-react-native'
|
|
13910
|
+
* const dispose = onJoinRequestUpdated(data => {
|
|
13911
|
+
* // ...
|
|
13912
|
+
* })
|
|
13782
13913
|
* ```
|
|
13783
13914
|
*
|
|
13784
|
-
*
|
|
13915
|
+
* Fired when an {@link Amity.CommunityJoinRequestPayload} has been created
|
|
13785
13916
|
*
|
|
13786
|
-
* @param
|
|
13787
|
-
* @returns
|
|
13917
|
+
* @param callback The function to call when the event was fired
|
|
13918
|
+
* @returns an {@link Amity.Unsubscriber} function to stop listening
|
|
13788
13919
|
*
|
|
13789
|
-
* @category
|
|
13920
|
+
* @category JoinRequest Events
|
|
13790
13921
|
*/
|
|
13791
|
-
|
|
13792
|
-
var _a;
|
|
13922
|
+
const onJoinRequestUpdated = (callback) => {
|
|
13793
13923
|
const client = getActiveClient();
|
|
13794
|
-
|
|
13795
|
-
|
|
13796
|
-
|
|
13797
|
-
|
|
13798
|
-
|
|
13799
|
-
return data.channelPublicId === channelId;
|
|
13800
|
-
});
|
|
13801
|
-
if (!cached || (cached === null || cached === void 0 ? void 0 : cached.length) === 0)
|
|
13802
|
-
return;
|
|
13803
|
-
return {
|
|
13804
|
-
data: cached[0].data,
|
|
13805
|
-
cachedAt: cached[0].cachedAt,
|
|
13924
|
+
const disposers = [
|
|
13925
|
+
createEventSubscriber(client, 'onJoinRequestUpdated', 'local.joinRequest.updated', payload => callback(payload)),
|
|
13926
|
+
];
|
|
13927
|
+
return () => {
|
|
13928
|
+
disposers.forEach(fn => fn());
|
|
13806
13929
|
};
|
|
13807
13930
|
};
|
|
13808
13931
|
|
|
13809
13932
|
/**
|
|
13810
13933
|
* ```js
|
|
13811
|
-
* import {
|
|
13812
|
-
* const
|
|
13934
|
+
* import { onJoinRequestDeleted } from '@amityco/ts-sdk-react-native'
|
|
13935
|
+
* const dispose = onJoinRequestDeleted(data => {
|
|
13936
|
+
* // ...
|
|
13937
|
+
* })
|
|
13813
13938
|
* ```
|
|
13814
13939
|
*
|
|
13815
|
-
*
|
|
13940
|
+
* Fired when an {@link Amity.CommunityJoinRequestPayload} has been created
|
|
13816
13941
|
*
|
|
13817
|
-
* @param
|
|
13818
|
-
* @returns
|
|
13942
|
+
* @param callback The function to call when the event was fired
|
|
13943
|
+
* @returns an {@link Amity.Unsubscriber} function to stop listening
|
|
13819
13944
|
*
|
|
13820
|
-
* @category
|
|
13821
|
-
* @async
|
|
13945
|
+
* @category JoinRequest Events
|
|
13822
13946
|
*/
|
|
13823
|
-
const
|
|
13824
|
-
var _a;
|
|
13947
|
+
const onJoinRequestDeleted = (callback) => {
|
|
13825
13948
|
const client = getActiveClient();
|
|
13826
|
-
|
|
13827
|
-
|
|
13828
|
-
|
|
13829
|
-
|
|
13830
|
-
|
|
13831
|
-
|
|
13832
|
-
])) === null || _a === void 0 ? void 0 : _a.data;
|
|
13833
|
-
if (channel)
|
|
13834
|
-
return channelLinkedObject(constructChannelObject(channel));
|
|
13835
|
-
const { data } = await getChannel$1(stream.channelId);
|
|
13836
|
-
return channelLinkedObject(constructChannelObject(data));
|
|
13837
|
-
}
|
|
13838
|
-
// No Channel ID
|
|
13839
|
-
// streamer: create a new live channel
|
|
13840
|
-
if (stream.userId === client.userId) {
|
|
13841
|
-
const { data: channel } = await createChannel({
|
|
13842
|
-
type: 'live',
|
|
13843
|
-
postId: stream.postId,
|
|
13844
|
-
videoStreamId: stream.streamId,
|
|
13845
|
-
});
|
|
13846
|
-
// Update channelId to stream object in cache
|
|
13847
|
-
mergeInCache(['stream', 'get', stream.streamId], {
|
|
13848
|
-
channelId: channel.channelId,
|
|
13849
|
-
});
|
|
13850
|
-
return channel;
|
|
13851
|
-
}
|
|
13852
|
-
// watcher: return undefined
|
|
13853
|
-
return undefined;
|
|
13854
|
-
};
|
|
13855
|
-
|
|
13856
|
-
const GET_WATCHER_URLS = Symbol('getWatcherUrls');
|
|
13857
|
-
const streamLinkedObject = (stream) => {
|
|
13858
|
-
return Object.assign(Object.assign({}, stream), { get moderation() {
|
|
13859
|
-
var _a;
|
|
13860
|
-
return (_a = pullFromCache(['streamModeration', 'get', stream.streamId])) === null || _a === void 0 ? void 0 : _a.data;
|
|
13861
|
-
},
|
|
13862
|
-
get post() {
|
|
13863
|
-
var _a;
|
|
13864
|
-
if (stream.referenceType !== 'post')
|
|
13865
|
-
return;
|
|
13866
|
-
return (_a = pullFromCache(['post', 'get', stream.referenceId])) === null || _a === void 0 ? void 0 : _a.data;
|
|
13867
|
-
},
|
|
13868
|
-
get community() {
|
|
13869
|
-
var _a;
|
|
13870
|
-
if (stream.targetType !== 'community')
|
|
13871
|
-
return;
|
|
13872
|
-
return (_a = pullFromCache(['community', 'get', stream.targetId])) === null || _a === void 0 ? void 0 : _a.data;
|
|
13873
|
-
},
|
|
13874
|
-
get user() {
|
|
13875
|
-
var _a;
|
|
13876
|
-
return (_a = pullFromCache(['user', 'get', stream.userId])) === null || _a === void 0 ? void 0 : _a.data;
|
|
13877
|
-
},
|
|
13878
|
-
get childStreams() {
|
|
13879
|
-
if (!stream.childStreamIds || stream.childStreamIds.length === 0)
|
|
13880
|
-
return [];
|
|
13881
|
-
return stream.childStreamIds
|
|
13882
|
-
.map(id => {
|
|
13883
|
-
var _a;
|
|
13884
|
-
const streamCache = (_a = pullFromCache(['stream', 'get', id])) === null || _a === void 0 ? void 0 : _a.data;
|
|
13885
|
-
if (!streamCache)
|
|
13886
|
-
return undefined;
|
|
13887
|
-
return streamLinkedObject(streamCache);
|
|
13888
|
-
})
|
|
13889
|
-
.filter(isNonNullable);
|
|
13890
|
-
}, getLiveChat: () => getLiveChat$1(stream), isBanned: !stream.watcherUrl, watcherUrl: null, get [GET_WATCHER_URLS]() {
|
|
13891
|
-
return stream.watcherUrl;
|
|
13892
|
-
} });
|
|
13893
|
-
};
|
|
13894
|
-
|
|
13895
|
-
const categoryLinkedObject = (category) => {
|
|
13896
|
-
return Object.assign(Object.assign({}, category), { get avatar() {
|
|
13897
|
-
var _a;
|
|
13898
|
-
if (!category.avatarFileId)
|
|
13899
|
-
return undefined;
|
|
13900
|
-
const avatar = (_a = pullFromCache([
|
|
13901
|
-
'file',
|
|
13902
|
-
'get',
|
|
13903
|
-
`${category.avatarFileId}`,
|
|
13904
|
-
])) === null || _a === void 0 ? void 0 : _a.data;
|
|
13905
|
-
return avatar;
|
|
13906
|
-
} });
|
|
13907
|
-
};
|
|
13908
|
-
|
|
13909
|
-
const commentLinkedObject = (comment) => {
|
|
13910
|
-
return Object.assign(Object.assign({}, comment), { get target() {
|
|
13911
|
-
const commentTypes = {
|
|
13912
|
-
type: comment.targetType,
|
|
13913
|
-
};
|
|
13914
|
-
if (comment.targetType === 'user') {
|
|
13915
|
-
return Object.assign(Object.assign({}, commentTypes), { userId: comment.targetId });
|
|
13916
|
-
}
|
|
13917
|
-
if (commentTypes.type === 'content') {
|
|
13918
|
-
return Object.assign(Object.assign({}, commentTypes), { contentId: comment.targetId });
|
|
13919
|
-
}
|
|
13920
|
-
if (commentTypes.type === 'community') {
|
|
13921
|
-
const cacheData = pullFromCache([
|
|
13922
|
-
'communityUsers',
|
|
13923
|
-
'get',
|
|
13924
|
-
`${comment.targetId}#${comment.userId}`,
|
|
13925
|
-
]);
|
|
13926
|
-
return Object.assign(Object.assign({}, commentTypes), { communityId: comment.targetId, creatorMember: cacheData === null || cacheData === void 0 ? void 0 : cacheData.data });
|
|
13927
|
-
}
|
|
13928
|
-
return {
|
|
13929
|
-
type: 'unknown',
|
|
13930
|
-
};
|
|
13931
|
-
},
|
|
13932
|
-
get creator() {
|
|
13933
|
-
const cacheData = pullFromCache(['user', 'get', comment.userId]);
|
|
13934
|
-
if (cacheData === null || cacheData === void 0 ? void 0 : cacheData.data)
|
|
13935
|
-
return userLinkedObject(cacheData.data);
|
|
13936
|
-
return undefined;
|
|
13937
|
-
},
|
|
13938
|
-
get childrenComment() {
|
|
13939
|
-
return comment.children
|
|
13940
|
-
.map(childCommentId => {
|
|
13941
|
-
const commentCache = pullFromCache([
|
|
13942
|
-
'comment',
|
|
13943
|
-
'get',
|
|
13944
|
-
childCommentId,
|
|
13945
|
-
]);
|
|
13946
|
-
if (!(commentCache === null || commentCache === void 0 ? void 0 : commentCache.data))
|
|
13947
|
-
return;
|
|
13948
|
-
return commentCache === null || commentCache === void 0 ? void 0 : commentCache.data;
|
|
13949
|
-
})
|
|
13950
|
-
.filter(isNonNullable)
|
|
13951
|
-
.map(item => commentLinkedObject(item));
|
|
13952
|
-
} });
|
|
13949
|
+
const disposers = [
|
|
13950
|
+
createEventSubscriber(client, 'onJoinRequestDeleted', 'local.joinRequest.deleted', payload => callback(payload)),
|
|
13951
|
+
];
|
|
13952
|
+
return () => {
|
|
13953
|
+
disposers.forEach(fn => fn());
|
|
13954
|
+
};
|
|
13953
13955
|
};
|
|
13954
13956
|
|
|
13955
|
-
|
|
13956
|
-
|
|
13957
|
-
|
|
13958
|
-
'
|
|
13959
|
-
|
|
13960
|
-
|
|
13961
|
-
|
|
13962
|
-
|
|
13963
|
-
|
|
13964
|
-
|
|
13965
|
-
|
|
13966
|
-
|
|
13967
|
-
|
|
13968
|
-
|
|
13969
|
-
|
|
13970
|
-
|
|
13971
|
-
|
|
13972
|
-
|
|
13973
|
-
}
|
|
13974
|
-
|
|
13975
|
-
|
|
13976
|
-
|
|
13977
|
-
|
|
13978
|
-
|
|
13979
|
-
}
|
|
13980
|
-
|
|
13981
|
-
|
|
13982
|
-
|
|
13983
|
-
|
|
13984
|
-
|
|
13985
|
-
}
|
|
13986
|
-
|
|
13987
|
-
|
|
13988
|
-
|
|
13989
|
-
|
|
13990
|
-
|
|
13991
|
-
|
|
13992
|
-
|
|
13993
|
-
|
|
13994
|
-
|
|
13995
|
-
|
|
13996
|
-
|
|
13997
|
-
|
|
13998
|
-
|
|
13999
|
-
|
|
14000
|
-
|
|
14001
|
-
|
|
14002
|
-
|
|
13957
|
+
class JoinRequestsLiveCollectionController extends LiveCollectionController {
|
|
13958
|
+
constructor(query, callback) {
|
|
13959
|
+
const queryStreamId = hash__default["default"](query);
|
|
13960
|
+
const cacheKey = ['joinRequest', 'collection', queryStreamId];
|
|
13961
|
+
const paginationController = new JoinRequestsPaginationController(query);
|
|
13962
|
+
super(paginationController, queryStreamId, cacheKey, callback);
|
|
13963
|
+
this.query = query;
|
|
13964
|
+
this.queryStreamController = new JoinRequestsQueryStreamController(this.query, this.cacheKey, this.notifyChange.bind(this), prepareCommunityJoinRequestPayload);
|
|
13965
|
+
this.callback = callback.bind(this);
|
|
13966
|
+
this.loadPage({ initial: true });
|
|
13967
|
+
}
|
|
13968
|
+
setup() {
|
|
13969
|
+
var _a;
|
|
13970
|
+
const collection = (_a = pullFromCache(this.cacheKey)) === null || _a === void 0 ? void 0 : _a.data;
|
|
13971
|
+
if (!collection) {
|
|
13972
|
+
pushToCache(this.cacheKey, {
|
|
13973
|
+
data: [],
|
|
13974
|
+
params: this.query,
|
|
13975
|
+
});
|
|
13976
|
+
}
|
|
13977
|
+
}
|
|
13978
|
+
async persistModel(queryPayload) {
|
|
13979
|
+
await this.queryStreamController.saveToMainDB(queryPayload);
|
|
13980
|
+
}
|
|
13981
|
+
persistQueryStream({ response, direction, refresh, }) {
|
|
13982
|
+
const joinRequestResponse = response;
|
|
13983
|
+
this.queryStreamController.appendToQueryStream(joinRequestResponse, direction, refresh);
|
|
13984
|
+
}
|
|
13985
|
+
startSubscription() {
|
|
13986
|
+
return this.queryStreamController.subscribeRTE([
|
|
13987
|
+
{ fn: onJoinRequestCreated, action: EnumJoinRequestAction$1.OnLocalJoinRequestCreated },
|
|
13988
|
+
{ fn: onJoinRequestUpdated, action: EnumJoinRequestAction$1.OnLocalJoinRequestUpdated },
|
|
13989
|
+
{ fn: onJoinRequestDeleted, action: EnumJoinRequestAction$1.OnLocalJoinRequestDeleted },
|
|
13990
|
+
]);
|
|
13991
|
+
}
|
|
13992
|
+
notifyChange({ origin, loading, error }) {
|
|
13993
|
+
var _a;
|
|
13994
|
+
const collection = (_a = pullFromCache(this.cacheKey)) === null || _a === void 0 ? void 0 : _a.data;
|
|
13995
|
+
if (!collection)
|
|
13996
|
+
return;
|
|
13997
|
+
const data = this.applyFilter(collection.data
|
|
13998
|
+
.map(id => pullFromCache(['joinRequest', 'get', id]))
|
|
13999
|
+
.filter(isNonNullable)
|
|
14000
|
+
.map(({ data }) => data)
|
|
14001
|
+
.map(joinRequestLinkedObject));
|
|
14002
|
+
if (!this.shouldNotify(data) && origin === 'event')
|
|
14003
|
+
return;
|
|
14004
|
+
this.callback({
|
|
14005
|
+
onNextPage: () => this.loadPage({ direction: "next" /* Amity.LiveCollectionPageDirection.NEXT */ }),
|
|
14006
|
+
data,
|
|
14007
|
+
hasNextPage: !!this.paginationController.getNextToken(),
|
|
14008
|
+
loading,
|
|
14009
|
+
error,
|
|
14010
|
+
});
|
|
14011
|
+
}
|
|
14012
|
+
applyFilter(data) {
|
|
14013
|
+
let joinRequest = data;
|
|
14014
|
+
if (this.query.status) {
|
|
14015
|
+
joinRequest = joinRequest.filter(joinRequest => joinRequest.status === this.query.status);
|
|
14016
|
+
}
|
|
14017
|
+
const sortFn = (() => {
|
|
14018
|
+
switch (this.query.sortBy) {
|
|
14019
|
+
case 'firstCreated':
|
|
14020
|
+
return sortByFirstCreated;
|
|
14021
|
+
case 'lastCreated':
|
|
14022
|
+
return sortByLastCreated;
|
|
14023
|
+
default:
|
|
14024
|
+
return sortByLastCreated;
|
|
14025
|
+
}
|
|
14026
|
+
})();
|
|
14027
|
+
joinRequest = joinRequest.sort(sortFn);
|
|
14028
|
+
return joinRequest;
|
|
14029
|
+
}
|
|
14003
14030
|
}
|
|
14004
14031
|
|
|
14005
14032
|
/**
|
|
14006
|
-
*
|
|
14007
|
-
* import { RoomRepository } from '@amityco/ts-sdk-react-native'
|
|
14008
|
-
* const stream = await getStream('foobar')
|
|
14009
|
-
* ```
|
|
14033
|
+
* Get Join Requests
|
|
14010
14034
|
*
|
|
14011
|
-
*
|
|
14035
|
+
* @param params the query parameters
|
|
14036
|
+
* @param callback the callback to be called when the join request are updated
|
|
14037
|
+
* @returns joinRequests
|
|
14012
14038
|
*
|
|
14013
|
-
* @
|
|
14014
|
-
* @returns the associated {@link Amity.Channel<'live'>} object
|
|
14039
|
+
* @category joinRequest Live Collection
|
|
14015
14040
|
*
|
|
14016
|
-
* @category Stream API
|
|
14017
|
-
* @async
|
|
14018
14041
|
*/
|
|
14019
|
-
const
|
|
14020
|
-
|
|
14021
|
-
|
|
14022
|
-
|
|
14023
|
-
if (room.liveChannelId) {
|
|
14024
|
-
const channel = (_a = pullFromCache([
|
|
14025
|
-
'channel',
|
|
14026
|
-
'get',
|
|
14027
|
-
room.liveChannelId,
|
|
14028
|
-
])) === null || _a === void 0 ? void 0 : _a.data;
|
|
14029
|
-
if (channel)
|
|
14030
|
-
return channelLinkedObject(constructChannelObject(channel));
|
|
14031
|
-
const { data } = await getChannel$1(room.liveChannelId);
|
|
14032
|
-
return channelLinkedObject(constructChannelObject(data));
|
|
14033
|
-
}
|
|
14034
|
-
// No Channel ID
|
|
14035
|
-
// streamer: create a new live channel
|
|
14036
|
-
if (room.createdBy === client.userId) {
|
|
14037
|
-
const { data: channel } = await createChannel({
|
|
14038
|
-
type: 'live',
|
|
14039
|
-
postId: room.referenceId,
|
|
14040
|
-
roomId: room.roomId,
|
|
14041
|
-
});
|
|
14042
|
-
// Update channelId to stream object in cache
|
|
14043
|
-
mergeInCache(['room', 'get', room.roomId], {
|
|
14044
|
-
liveChannelId: channel.channelId,
|
|
14045
|
-
});
|
|
14046
|
-
return channel;
|
|
14042
|
+
const getJoinRequests = (params, callback, config) => {
|
|
14043
|
+
const { log, cache } = getActiveClient();
|
|
14044
|
+
if (!cache) {
|
|
14045
|
+
console.log(ENABLE_CACHE_MESSAGE);
|
|
14047
14046
|
}
|
|
14048
|
-
|
|
14049
|
-
|
|
14047
|
+
const timestamp = Date.now();
|
|
14048
|
+
log(`getJoinRequests: (tmpid: ${timestamp}) > listen`);
|
|
14049
|
+
const joinRequestLiveCollection = new JoinRequestsLiveCollectionController(params, callback);
|
|
14050
|
+
const disposers = joinRequestLiveCollection.startSubscription();
|
|
14051
|
+
const cacheKey = joinRequestLiveCollection.getCacheKey();
|
|
14052
|
+
disposers.push(() => {
|
|
14053
|
+
dropFromCache(cacheKey);
|
|
14054
|
+
});
|
|
14055
|
+
return () => {
|
|
14056
|
+
log(`getJoinRequests (tmpid: ${timestamp}) > dispose`);
|
|
14057
|
+
disposers.forEach(fn => fn());
|
|
14058
|
+
};
|
|
14050
14059
|
};
|
|
14051
14060
|
|
|
14052
14061
|
const convertRawInvitationToInternalInvitation = (rawInvitation) => {
|
|
@@ -14201,1391 +14210,1382 @@ const invitationLinkedObject = (invitation) => {
|
|
|
14201
14210
|
} });
|
|
14202
14211
|
};
|
|
14203
14212
|
|
|
14204
|
-
/* begin_public_function
|
|
14205
|
-
id: invitation.get
|
|
14206
|
-
*/
|
|
14213
|
+
/* begin_public_function
|
|
14214
|
+
id: invitation.get
|
|
14215
|
+
*/
|
|
14216
|
+
/**
|
|
14217
|
+
* ```js
|
|
14218
|
+
* import { getInvitation } from '@amityco/ts-sdk-react-native'
|
|
14219
|
+
* const { invitation } = await getInvitation(targetType, targetId)
|
|
14220
|
+
* ```
|
|
14221
|
+
*
|
|
14222
|
+
* Get a {@link Amity.Invitation} object
|
|
14223
|
+
*
|
|
14224
|
+
* @param targetType The type of the target of the {@link Amity.Invitation}
|
|
14225
|
+
* @param targetId The ID of the target of the {@link Amity.Invitation}
|
|
14226
|
+
* @returns A {@link Amity.Invitation} object
|
|
14227
|
+
*
|
|
14228
|
+
* @category Invitation API
|
|
14229
|
+
* @async
|
|
14230
|
+
*/
|
|
14231
|
+
const getInvitation = async (params) => {
|
|
14232
|
+
const client = getActiveClient();
|
|
14233
|
+
client.log('invitation/getInvitation', params.targetType, params.targetId, params.type);
|
|
14234
|
+
const { data: payload } = await client.http.get(`/api/v1/invitations/me`, { params });
|
|
14235
|
+
const data = prepareMyInvitationsPayload(payload);
|
|
14236
|
+
const cachedAt = client.cache && Date.now();
|
|
14237
|
+
if (client.cache)
|
|
14238
|
+
ingestInCache(data, { cachedAt });
|
|
14239
|
+
return {
|
|
14240
|
+
data: data.invitations[0] ? invitationLinkedObject(data.invitations[0]) : undefined,
|
|
14241
|
+
cachedAt,
|
|
14242
|
+
};
|
|
14243
|
+
};
|
|
14244
|
+
/* end_public_function */
|
|
14245
|
+
|
|
14246
|
+
var InvitationActionsEnum;
|
|
14247
|
+
(function (InvitationActionsEnum) {
|
|
14248
|
+
InvitationActionsEnum["OnLocalInvitationCreated"] = "onLocalInvitationCreated";
|
|
14249
|
+
InvitationActionsEnum["OnLocalInvitationUpdated"] = "onLocalInvitationUpdated";
|
|
14250
|
+
InvitationActionsEnum["OnLocalInvitationCanceled"] = "onLocalInvitationCanceled";
|
|
14251
|
+
})(InvitationActionsEnum || (InvitationActionsEnum = {}));
|
|
14252
|
+
|
|
14253
|
+
class InvitationsPaginationController extends PaginationController {
|
|
14254
|
+
async getRequest(queryParams, token) {
|
|
14255
|
+
const { limit = COLLECTION_DEFAULT_PAGINATION_LIMIT } = queryParams, params = __rest(queryParams, ["limit"]);
|
|
14256
|
+
const options = token ? { token } : { limit };
|
|
14257
|
+
const { data } = await this.http.get('/api/v1/invitations', { params: Object.assign(Object.assign({}, params), { options }) });
|
|
14258
|
+
return data;
|
|
14259
|
+
}
|
|
14260
|
+
}
|
|
14261
|
+
|
|
14262
|
+
class InvitationsQueryStreamController extends QueryStreamController {
|
|
14263
|
+
constructor(query, cacheKey, notifyChange, preparePayload) {
|
|
14264
|
+
super(query, cacheKey);
|
|
14265
|
+
this.notifyChange = notifyChange;
|
|
14266
|
+
this.preparePayload = preparePayload;
|
|
14267
|
+
}
|
|
14268
|
+
async saveToMainDB(response) {
|
|
14269
|
+
const processedPayload = await this.preparePayload(response);
|
|
14270
|
+
const client = getActiveClient();
|
|
14271
|
+
const cachedAt = client.cache && Date.now();
|
|
14272
|
+
if (client.cache) {
|
|
14273
|
+
ingestInCache(processedPayload, { cachedAt });
|
|
14274
|
+
}
|
|
14275
|
+
}
|
|
14276
|
+
appendToQueryStream(response, direction, refresh = false) {
|
|
14277
|
+
var _a, _b;
|
|
14278
|
+
if (refresh) {
|
|
14279
|
+
pushToCache(this.cacheKey, {
|
|
14280
|
+
data: response.invitations.map(getResolver('invitation')),
|
|
14281
|
+
});
|
|
14282
|
+
}
|
|
14283
|
+
else {
|
|
14284
|
+
const collection = (_a = pullFromCache(this.cacheKey)) === null || _a === void 0 ? void 0 : _a.data;
|
|
14285
|
+
const invitations = (_b = collection === null || collection === void 0 ? void 0 : collection.data) !== null && _b !== void 0 ? _b : [];
|
|
14286
|
+
pushToCache(this.cacheKey, Object.assign(Object.assign({}, collection), { data: [
|
|
14287
|
+
...new Set([...invitations, ...response.invitations.map(getResolver('invitation'))]),
|
|
14288
|
+
] }));
|
|
14289
|
+
}
|
|
14290
|
+
}
|
|
14291
|
+
reactor(action) {
|
|
14292
|
+
return (invitations) => {
|
|
14293
|
+
var _a;
|
|
14294
|
+
const collection = (_a = pullFromCache(this.cacheKey)) === null || _a === void 0 ? void 0 : _a.data;
|
|
14295
|
+
if (!collection)
|
|
14296
|
+
return;
|
|
14297
|
+
if (action === InvitationActionsEnum.OnLocalInvitationUpdated) {
|
|
14298
|
+
const isExist = collection.data.find(id => id === invitations[0].invitationId);
|
|
14299
|
+
if (!isExist)
|
|
14300
|
+
return;
|
|
14301
|
+
}
|
|
14302
|
+
if (action === InvitationActionsEnum.OnLocalInvitationCreated) {
|
|
14303
|
+
collection.data = [
|
|
14304
|
+
...new Set([
|
|
14305
|
+
...invitations.map(invitation => invitation.invitationId),
|
|
14306
|
+
...collection.data,
|
|
14307
|
+
]),
|
|
14308
|
+
];
|
|
14309
|
+
}
|
|
14310
|
+
if (action === InvitationActionsEnum.OnLocalInvitationDeleted) {
|
|
14311
|
+
collection.data = collection.data.filter(id => id !== invitations[0].invitationId);
|
|
14312
|
+
}
|
|
14313
|
+
pushToCache(this.cacheKey, collection);
|
|
14314
|
+
this.notifyChange({ origin: "event" /* Amity.LiveDataOrigin.EVENT */, loading: false });
|
|
14315
|
+
};
|
|
14316
|
+
}
|
|
14317
|
+
subscribeRTE(createSubscriber) {
|
|
14318
|
+
return createSubscriber.map(subscriber => subscriber.fn(this.reactor(subscriber.action)));
|
|
14319
|
+
}
|
|
14320
|
+
}
|
|
14321
|
+
|
|
14322
|
+
/**
|
|
14323
|
+
* ```js
|
|
14324
|
+
* import { onLocalInvitationCreated } from '@amityco/ts-sdk-react-native'
|
|
14325
|
+
* const dispose = onLocalInvitationCreated(data => {
|
|
14326
|
+
* // ...
|
|
14327
|
+
* })
|
|
14328
|
+
* ```
|
|
14329
|
+
*
|
|
14330
|
+
* Fired when an {@link Amity.InvitationPayload} has been created
|
|
14331
|
+
*
|
|
14332
|
+
* @param callback The function to call when the event was fired
|
|
14333
|
+
* @returns an {@link Amity.Unsubscriber} function to stop listening
|
|
14334
|
+
*
|
|
14335
|
+
* @category Invitation Events
|
|
14336
|
+
*/
|
|
14337
|
+
const onLocalInvitationCreated = (callback) => {
|
|
14338
|
+
const client = getActiveClient();
|
|
14339
|
+
const disposers = [
|
|
14340
|
+
createEventSubscriber(client, 'onLocalInvitationCreated', 'local.invitation.created', payload => callback(payload)),
|
|
14341
|
+
];
|
|
14342
|
+
return () => {
|
|
14343
|
+
disposers.forEach(fn => fn());
|
|
14344
|
+
};
|
|
14345
|
+
};
|
|
14346
|
+
|
|
14347
|
+
/**
|
|
14348
|
+
* ```js
|
|
14349
|
+
* import { onLocalInvitationUpdated } from '@amityco/ts-sdk-react-native'
|
|
14350
|
+
* const dispose = onLocalInvitationUpdated(data => {
|
|
14351
|
+
* // ...
|
|
14352
|
+
* })
|
|
14353
|
+
* ```
|
|
14354
|
+
*
|
|
14355
|
+
* Fired when an {@link Amity.InvitationPayload} has been updated
|
|
14356
|
+
*
|
|
14357
|
+
* @param callback The function to call when the event was fired
|
|
14358
|
+
* @returns an {@link Amity.Unsubscriber} function to stop listening
|
|
14359
|
+
*
|
|
14360
|
+
* @category Invitation Events
|
|
14361
|
+
*/
|
|
14362
|
+
const onLocalInvitationUpdated = (callback) => {
|
|
14363
|
+
const client = getActiveClient();
|
|
14364
|
+
const disposers = [
|
|
14365
|
+
createEventSubscriber(client, 'onLocalInvitationUpdated', 'local.invitation.updated', payload => callback(payload)),
|
|
14366
|
+
];
|
|
14367
|
+
return () => {
|
|
14368
|
+
disposers.forEach(fn => fn());
|
|
14369
|
+
};
|
|
14370
|
+
};
|
|
14371
|
+
|
|
14207
14372
|
/**
|
|
14208
14373
|
* ```js
|
|
14209
|
-
* import {
|
|
14210
|
-
* const
|
|
14374
|
+
* import { onLocalInvitationCanceled } from '@amityco/ts-sdk-react-native'
|
|
14375
|
+
* const dispose = onLocalInvitationCanceled(data => {
|
|
14376
|
+
* // ...
|
|
14377
|
+
* })
|
|
14211
14378
|
* ```
|
|
14212
14379
|
*
|
|
14213
|
-
*
|
|
14380
|
+
* Fired when an {@link Amity.InvitationPayload} has been deleted
|
|
14214
14381
|
*
|
|
14215
|
-
* @param
|
|
14216
|
-
* @
|
|
14217
|
-
* @returns A {@link Amity.Invitation} object
|
|
14382
|
+
* @param callback The function to call when the event was fired
|
|
14383
|
+
* @returns an {@link Amity.Unsubscriber} function to stop listening
|
|
14218
14384
|
*
|
|
14219
|
-
* @category Invitation
|
|
14220
|
-
* @async
|
|
14385
|
+
* @category Invitation Events
|
|
14221
14386
|
*/
|
|
14222
|
-
const
|
|
14387
|
+
const onLocalInvitationCanceled = (callback) => {
|
|
14223
14388
|
const client = getActiveClient();
|
|
14224
|
-
|
|
14225
|
-
|
|
14226
|
-
|
|
14227
|
-
|
|
14228
|
-
|
|
14229
|
-
ingestInCache(data, { cachedAt });
|
|
14230
|
-
return {
|
|
14231
|
-
data: data.invitations[0] ? invitationLinkedObject(data.invitations[0]) : undefined,
|
|
14232
|
-
cachedAt,
|
|
14389
|
+
const disposers = [
|
|
14390
|
+
createEventSubscriber(client, 'onLocalInvitationCanceled', 'local.invitation.canceled', payload => callback(payload)),
|
|
14391
|
+
];
|
|
14392
|
+
return () => {
|
|
14393
|
+
disposers.forEach(fn => fn());
|
|
14233
14394
|
};
|
|
14234
14395
|
};
|
|
14235
|
-
/* end_public_function */
|
|
14236
14396
|
|
|
14237
|
-
|
|
14238
|
-
|
|
14239
|
-
|
|
14240
|
-
|
|
14241
|
-
|
|
14242
|
-
|
|
14243
|
-
this.
|
|
14244
|
-
|
|
14245
|
-
|
|
14246
|
-
|
|
14247
|
-
*/
|
|
14248
|
-
addSession(session) {
|
|
14249
|
-
this.sessions.set(session.sessionId, session);
|
|
14250
|
-
}
|
|
14251
|
-
/**
|
|
14252
|
-
* Get a watch session by sessionId
|
|
14253
|
-
*/
|
|
14254
|
-
getSession(sessionId) {
|
|
14255
|
-
return this.sessions.get(sessionId);
|
|
14397
|
+
class InvitationsLiveCollectionController extends LiveCollectionController {
|
|
14398
|
+
constructor(query, callback) {
|
|
14399
|
+
const queryStreamId = hash__default["default"](query);
|
|
14400
|
+
const cacheKey = ['invitation', 'collection', queryStreamId];
|
|
14401
|
+
const paginationController = new InvitationsPaginationController(query);
|
|
14402
|
+
super(paginationController, queryStreamId, cacheKey, callback);
|
|
14403
|
+
this.query = query;
|
|
14404
|
+
this.queryStreamController = new InvitationsQueryStreamController(this.query, this.cacheKey, this.notifyChange.bind(this), prepareInvitationPayload);
|
|
14405
|
+
this.callback = callback.bind(this);
|
|
14406
|
+
this.loadPage({ initial: true });
|
|
14256
14407
|
}
|
|
14257
|
-
|
|
14258
|
-
|
|
14259
|
-
|
|
14260
|
-
|
|
14261
|
-
|
|
14262
|
-
|
|
14263
|
-
|
|
14408
|
+
setup() {
|
|
14409
|
+
var _a;
|
|
14410
|
+
const collection = (_a = pullFromCache(this.cacheKey)) === null || _a === void 0 ? void 0 : _a.data;
|
|
14411
|
+
if (!collection) {
|
|
14412
|
+
pushToCache(this.cacheKey, {
|
|
14413
|
+
data: [],
|
|
14414
|
+
params: this.query,
|
|
14415
|
+
});
|
|
14264
14416
|
}
|
|
14265
14417
|
}
|
|
14266
|
-
|
|
14267
|
-
|
|
14268
|
-
*/
|
|
14269
|
-
getSessionsByState(state) {
|
|
14270
|
-
return Array.from(this.sessions.values()).filter(session => session.syncState === state);
|
|
14271
|
-
}
|
|
14272
|
-
/**
|
|
14273
|
-
* Delete a session
|
|
14274
|
-
*/
|
|
14275
|
-
deleteSession(sessionId) {
|
|
14276
|
-
this.sessions.delete(sessionId);
|
|
14277
|
-
}
|
|
14278
|
-
/**
|
|
14279
|
-
* Get all pending sessions
|
|
14280
|
-
*/
|
|
14281
|
-
getPendingSessions() {
|
|
14282
|
-
return this.getSessionsByState('PENDING');
|
|
14283
|
-
}
|
|
14284
|
-
/**
|
|
14285
|
-
* Get all syncing sessions
|
|
14286
|
-
*/
|
|
14287
|
-
getSyncingSessions() {
|
|
14288
|
-
return this.getSessionsByState('SYNCING');
|
|
14289
|
-
}
|
|
14290
|
-
}
|
|
14291
|
-
// Singleton instance
|
|
14292
|
-
let storageInstance = null;
|
|
14293
|
-
const getWatchSessionStorage = () => {
|
|
14294
|
-
if (!storageInstance) {
|
|
14295
|
-
storageInstance = new WatchSessionStorage();
|
|
14296
|
-
}
|
|
14297
|
-
return storageInstance;
|
|
14298
|
-
};
|
|
14299
|
-
|
|
14300
|
-
const privateKey = "-----BEGIN PRIVATE KEY-----\nMIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQDAARz+hmBgi8pJ\nQb8LeY41gtHhk+ACMwRfhsn7GqpqRQNG2qU0755mzZuVDUqjQMGSo8THJB7O+OJs\nflbZRkFXlFoFOVNw1UpNOgwEQZ6wB9oRwzepTJAfF1sVhm/o/ixvXh1zDFNDy6yZ\npXyiiJHUVxqyjllZhxnwdvjoVtDs6hW6awG09bB9nh/TTejlUKXoAgzqVwu/1QMu\nUVViET495elEe19aUarEy+oL2iKeXCEvqda/pWNBdbieFyJvvZ08HN8dPuT88wq2\njZLEAth1vrwQ2IAa4ktaLcBQdLJgIkrbDvAiVZ8lQAjS/bq5vXQikTGvoPlC5bbn\nvuOM/3eLAgMBAAECggEAVZ+peHAghq2QVj71nX5lxsNCKaCyYwixSJBpfouTt7Rz\nE6PpzMOXFi1W1o+I22jDakuSM2SOQKqI/u0QefB0r0O/KVk5NrZHXk0mkrdYtxOp\nUgaGyf8UvmjB+8VqHrNKyZdk9qtmbnNj01kTTcAtmE4H39zPR7eR/8Rul94vaZbs\nwCnKJS3mLT3JxyGug6lxanveKkjG+CKC1nJQYWaxCJxaFSzbwXQPvDhB+TvrIbee\npd5v4EAyEJohpr+T9oDGGJkb/KARBZCtwLyB976PKJwwBA8MRVL1i5QwawuMiMq5\nUtnOnbGKtCeFzaLbNU0Qi8bqyims84EQxC6DOu1fkQKBgQDdvsoBsEhsOXV7hlIJ\naEd0eSJZVkdqimxH8uGoMM2FeNaOrcB6yBXqTSP0R3OIyf8eaY6yjRvP30ZNXcll\n/gD3O1Mu6YmWQdt1W2WA6pKOsUuPXasf0pdOF7IiFZKlSabz5YHXFqwVuqm8loaj\nsXel3YWqPVdHiankE7tz+3ssnQKBgQDdqi4TNdD1MdEpihx19jr0QjUiXW3939FK\nqp30HESPEGDGQzXdmJgif9HhZb+cJSuWaHEbjgBrYahvgCF+y6LbEpOD+D/dmT+s\nDEAQaR84sah6dokwPjV8fjBSrcVFjCS+doxv0d3p/9OUEeyUhFrY03nxtIEYkLIE\n/Zvn37b4RwKBgQCLENVFe9XfsaVhQ5r9dV2iyTlmh7qgMZG5CbTFs12hQGhm8McO\n+Z7s41YSJCFr/yq1WwP4LJDtrBw99vyQr1zRsG35tNLp3gGRNzGQSQyC2uQFVHw2\np+7mNewsfhUK/gbrXNsyFnDz6635rPlhfbII3sWuP2wWXFqkxE9CbMwR7QKBgQC6\nawDMzxmo2/iYArrkyevSuEuPVxvFwpF1RgAI6C0QVCnPE38dmdN4UB7mfHekje4W\nVEercMURidPp0cxZolCYBQtilUjAyL0vqC3In1/Ogjq6oy3FEMxSop1pKxMY5j+Q\nnoqFD+6deLUrddeNH7J3X4LSr4dSbX4JjG+tlgt+yQKBgQCuwTL4hA6KqeInQ0Ta\n9VQX5Qr8hFlqJz1gpymi/k63tW/Ob8yedbg3WWNWyShwRMFYyY9S81ITFWM95uL6\nvF3x9rmRjwElJw9PMwVu6dmf/CO0Z1wzXSp2VVD12gbrUD/0/d7MUoJ9LgC8X8f/\nn0txLHYGHbx+nf95+JUg6lV3hg==\n-----END PRIVATE KEY-----";
|
|
14301
|
-
/*
|
|
14302
|
-
* The crypto algorithm used for importing key and signing string
|
|
14303
|
-
*/
|
|
14304
|
-
const ALGORITHM = {
|
|
14305
|
-
name: 'RSASSA-PKCS1-v1_5',
|
|
14306
|
-
hash: { name: 'SHA-256' },
|
|
14307
|
-
};
|
|
14308
|
-
/*
|
|
14309
|
-
* IMPORTANT!
|
|
14310
|
-
* If you are recieving key from other platforms use an online tool to convert
|
|
14311
|
-
* the PKCS1 to PKCS8. For instance the key from Android SDK is of the format
|
|
14312
|
-
* PKCS1.
|
|
14313
|
-
*
|
|
14314
|
-
* If recieving from the platform, verify if it's already in the expected
|
|
14315
|
-
* format. Otherwise the crypto.subtle.importKey will throw a DOMException
|
|
14316
|
-
*/
|
|
14317
|
-
const PRIVATE_KEY_SIGNATURE = 'pkcs8';
|
|
14318
|
-
/*
|
|
14319
|
-
* Ensure that the private key in the .env follows this format
|
|
14320
|
-
*/
|
|
14321
|
-
const PEM_HEADER = '-----BEGIN PRIVATE KEY-----';
|
|
14322
|
-
const PEM_FOOTER = '-----END PRIVATE KEY-----';
|
|
14323
|
-
/*
|
|
14324
|
-
* The crypto.subtle.sign function returns an ArrayBuffer whereas the server
|
|
14325
|
-
* expects a base64 string. This util helps facilitate that process
|
|
14326
|
-
*/
|
|
14327
|
-
function base64FromArrayBuffer(buffer) {
|
|
14328
|
-
const uint8Array = new Uint8Array(buffer);
|
|
14329
|
-
let binary = '';
|
|
14330
|
-
uint8Array.forEach(byte => {
|
|
14331
|
-
binary += String.fromCharCode(byte);
|
|
14332
|
-
});
|
|
14333
|
-
return jsBase64.btoa(binary);
|
|
14334
|
-
}
|
|
14335
|
-
/*
|
|
14336
|
-
* Encode ASN.1 length field
|
|
14337
|
-
*/
|
|
14338
|
-
function encodeLength(length) {
|
|
14339
|
-
if (length < 128) {
|
|
14340
|
-
return new Uint8Array([length]);
|
|
14418
|
+
async persistModel(queryPayload) {
|
|
14419
|
+
await this.queryStreamController.saveToMainDB(queryPayload);
|
|
14341
14420
|
}
|
|
14342
|
-
|
|
14343
|
-
|
|
14421
|
+
persistQueryStream({ response, direction, refresh, }) {
|
|
14422
|
+
this.queryStreamController.appendToQueryStream(response, direction, refresh);
|
|
14344
14423
|
}
|
|
14345
|
-
|
|
14346
|
-
|
|
14347
|
-
|
|
14348
|
-
|
|
14349
|
-
|
|
14350
|
-
|
|
14351
|
-
|
|
14352
|
-
|
|
14353
|
-
|
|
14354
|
-
|
|
14355
|
-
|
|
14356
|
-
|
|
14357
|
-
|
|
14358
|
-
|
|
14359
|
-
|
|
14360
|
-
0x2a,
|
|
14361
|
-
0x86,
|
|
14362
|
-
0x48,
|
|
14363
|
-
0x86,
|
|
14364
|
-
0xf7,
|
|
14365
|
-
0x0d,
|
|
14366
|
-
0x01,
|
|
14367
|
-
0x01,
|
|
14368
|
-
0x01,
|
|
14369
|
-
0x05,
|
|
14370
|
-
0x00, // NULL
|
|
14371
|
-
]);
|
|
14372
|
-
// Version (INTEGER 0)
|
|
14373
|
-
const version = new Uint8Array([0x02, 0x01, 0x00]);
|
|
14374
|
-
// OCTET STRING tag + length + pkcs1 data
|
|
14375
|
-
const octetStringTag = 0x04;
|
|
14376
|
-
const octetStringLength = encodeLength(pkcs1.length);
|
|
14377
|
-
// Calculate total content length (version + algorithm + octet string)
|
|
14378
|
-
const contentLength = version.length + algorithmIdentifier.length + 1 + octetStringLength.length + pkcs1.length;
|
|
14379
|
-
// SEQUENCE tag + length
|
|
14380
|
-
const sequenceTag = 0x30;
|
|
14381
|
-
const sequenceLength = encodeLength(contentLength);
|
|
14382
|
-
// Build the PKCS8 structure
|
|
14383
|
-
const pkcs8 = new Uint8Array(1 + sequenceLength.length + contentLength);
|
|
14384
|
-
let offset = 0;
|
|
14385
|
-
pkcs8[offset] = sequenceTag;
|
|
14386
|
-
offset += 1;
|
|
14387
|
-
pkcs8.set(sequenceLength, offset);
|
|
14388
|
-
offset += sequenceLength.length;
|
|
14389
|
-
pkcs8.set(version, offset);
|
|
14390
|
-
offset += version.length;
|
|
14391
|
-
pkcs8.set(algorithmIdentifier, offset);
|
|
14392
|
-
offset += algorithmIdentifier.length;
|
|
14393
|
-
pkcs8[offset] = octetStringTag;
|
|
14394
|
-
offset += 1;
|
|
14395
|
-
pkcs8.set(octetStringLength, offset);
|
|
14396
|
-
offset += octetStringLength.length;
|
|
14397
|
-
pkcs8.set(pkcs1, offset);
|
|
14398
|
-
return pkcs8;
|
|
14399
|
-
}
|
|
14400
|
-
async function importPrivateKey(keyString) {
|
|
14401
|
-
// Remove PEM headers if present and any whitespace
|
|
14402
|
-
let base64Key = keyString;
|
|
14403
|
-
if (keyString.includes(PEM_HEADER)) {
|
|
14404
|
-
base64Key = keyString
|
|
14405
|
-
.substring(PEM_HEADER.length, keyString.length - PEM_FOOTER.length)
|
|
14406
|
-
.replace(/\s/g, '');
|
|
14424
|
+
startSubscription() {
|
|
14425
|
+
return this.queryStreamController.subscribeRTE([
|
|
14426
|
+
{
|
|
14427
|
+
fn: onLocalInvitationCreated,
|
|
14428
|
+
action: InvitationActionsEnum.OnLocalInvitationCreated,
|
|
14429
|
+
},
|
|
14430
|
+
{
|
|
14431
|
+
fn: onLocalInvitationUpdated,
|
|
14432
|
+
action: InvitationActionsEnum.OnLocalInvitationUpdated,
|
|
14433
|
+
},
|
|
14434
|
+
{
|
|
14435
|
+
fn: onLocalInvitationCanceled,
|
|
14436
|
+
action: InvitationActionsEnum.OnLocalInvitationCanceled,
|
|
14437
|
+
},
|
|
14438
|
+
]);
|
|
14407
14439
|
}
|
|
14408
|
-
|
|
14409
|
-
|
|
14440
|
+
notifyChange({ origin, loading, error }) {
|
|
14441
|
+
var _a, _b;
|
|
14442
|
+
const collection = (_a = pullFromCache(this.cacheKey)) === null || _a === void 0 ? void 0 : _a.data;
|
|
14443
|
+
if (!collection)
|
|
14444
|
+
return;
|
|
14445
|
+
const data = this.applyFilter((_b = collection.data
|
|
14446
|
+
.map(id => pullFromCache(['invitation', 'get', id]))
|
|
14447
|
+
.filter(isNonNullable)
|
|
14448
|
+
.map(({ data }) => invitationLinkedObject(data))) !== null && _b !== void 0 ? _b : []);
|
|
14449
|
+
if (!this.shouldNotify(data) && origin === 'event')
|
|
14450
|
+
return;
|
|
14451
|
+
this.callback({
|
|
14452
|
+
onNextPage: () => this.loadPage({ direction: "next" /* Amity.LiveCollectionPageDirection.NEXT */ }),
|
|
14453
|
+
data,
|
|
14454
|
+
hasNextPage: !!this.paginationController.getNextToken(),
|
|
14455
|
+
loading,
|
|
14456
|
+
error,
|
|
14457
|
+
});
|
|
14410
14458
|
}
|
|
14411
|
-
|
|
14412
|
-
|
|
14413
|
-
|
|
14414
|
-
|
|
14415
|
-
|
|
14416
|
-
|
|
14459
|
+
applyFilter(data) {
|
|
14460
|
+
let invitations = data;
|
|
14461
|
+
if (this.query.targetId) {
|
|
14462
|
+
invitations = invitations.filter(invitation => invitation.targetId === this.query.targetId);
|
|
14463
|
+
}
|
|
14464
|
+
if (this.query.statuses) {
|
|
14465
|
+
invitations = invitations.filter(invitation => { var _a; return (_a = this.query.statuses) === null || _a === void 0 ? void 0 : _a.includes(invitation.status); });
|
|
14466
|
+
}
|
|
14467
|
+
if (this.query.targetType) {
|
|
14468
|
+
invitations = invitations.filter(invitation => invitation.targetType === this.query.targetType);
|
|
14469
|
+
}
|
|
14470
|
+
if (this.query.type) {
|
|
14471
|
+
invitations = invitations.filter(invitation => invitation.type === this.query.type);
|
|
14472
|
+
}
|
|
14473
|
+
const sortFn = (() => {
|
|
14474
|
+
switch (this.query.sortBy) {
|
|
14475
|
+
case 'firstCreated':
|
|
14476
|
+
return sortByFirstCreated;
|
|
14477
|
+
case 'lastCreated':
|
|
14478
|
+
return sortByLastCreated;
|
|
14479
|
+
default:
|
|
14480
|
+
return sortByLastCreated;
|
|
14481
|
+
}
|
|
14482
|
+
})();
|
|
14483
|
+
invitations = invitations.sort(sortFn);
|
|
14484
|
+
return invitations;
|
|
14417
14485
|
}
|
|
14418
|
-
// Convert PKCS1 to PKCS8 (crypto.subtle requires PKCS8)
|
|
14419
|
-
const pkcs8 = pkcs1ToPkcs8(pkcs1);
|
|
14420
|
-
// Import the key
|
|
14421
|
-
const key = await crypto.subtle.importKey(PRIVATE_KEY_SIGNATURE, pkcs8.buffer, ALGORITHM, false, ['sign']);
|
|
14422
|
-
return key;
|
|
14423
|
-
}
|
|
14424
|
-
async function createSignature({ timestamp, rooms, }) {
|
|
14425
|
-
const dataStr = rooms
|
|
14426
|
-
.map(item => Object.keys(item)
|
|
14427
|
-
.sort()
|
|
14428
|
-
.map(key => `${key}=${item[key]}`)
|
|
14429
|
-
.join('&'))
|
|
14430
|
-
.join(';');
|
|
14431
|
-
/*
|
|
14432
|
-
* nonceStr needs to be unique for each request
|
|
14433
|
-
*/
|
|
14434
|
-
const nonceStr = uuid__default["default"].v4();
|
|
14435
|
-
const signStr = `nonceStr=${nonceStr}×tamp=${timestamp}&data=${dataStr}==`;
|
|
14436
|
-
const encoder = new TextEncoder();
|
|
14437
|
-
const data = encoder.encode(signStr);
|
|
14438
|
-
const key = await importPrivateKey(privateKey);
|
|
14439
|
-
const sign = await crypto.subtle.sign(ALGORITHM, key, data);
|
|
14440
|
-
return { signature: base64FromArrayBuffer(sign), nonceStr };
|
|
14441
14486
|
}
|
|
14442
14487
|
|
|
14443
14488
|
/**
|
|
14444
|
-
*
|
|
14445
|
-
*
|
|
14489
|
+
* Get invitations
|
|
14490
|
+
*
|
|
14491
|
+
* @param params the query parameters
|
|
14492
|
+
* @param callback the callback to be called when the invitations are updated
|
|
14493
|
+
* @returns invitations
|
|
14494
|
+
*
|
|
14495
|
+
* @category Invitation Live Collection
|
|
14496
|
+
*
|
|
14446
14497
|
*/
|
|
14447
|
-
|
|
14448
|
-
const
|
|
14449
|
-
|
|
14450
|
-
|
|
14451
|
-
if (pendingSessions.length === 0) {
|
|
14452
|
-
return true;
|
|
14498
|
+
const getInvitations$1 = (params, callback, config) => {
|
|
14499
|
+
const { log, cache } = getActiveClient();
|
|
14500
|
+
if (!cache) {
|
|
14501
|
+
console.log(ENABLE_CACHE_MESSAGE);
|
|
14453
14502
|
}
|
|
14454
|
-
|
|
14455
|
-
|
|
14456
|
-
|
|
14457
|
-
|
|
14458
|
-
|
|
14459
|
-
|
|
14460
|
-
|
|
14461
|
-
|
|
14462
|
-
|
|
14463
|
-
}));
|
|
14464
|
-
|
|
14465
|
-
|
|
14466
|
-
|
|
14467
|
-
|
|
14468
|
-
|
|
14469
|
-
|
|
14470
|
-
|
|
14471
|
-
|
|
14472
|
-
|
|
14473
|
-
|
|
14474
|
-
|
|
14475
|
-
|
|
14476
|
-
|
|
14477
|
-
|
|
14478
|
-
|
|
14479
|
-
|
|
14480
|
-
|
|
14481
|
-
|
|
14482
|
-
|
|
14483
|
-
|
|
14484
|
-
|
|
14485
|
-
|
|
14486
|
-
|
|
14487
|
-
|
|
14488
|
-
|
|
14489
|
-
|
|
14503
|
+
const timestamp = Date.now();
|
|
14504
|
+
log(`getInvitations: (tmpid: ${timestamp}) > listen`);
|
|
14505
|
+
const invitationsLiveCollection = new InvitationsLiveCollectionController(params, callback);
|
|
14506
|
+
const disposers = invitationsLiveCollection.startSubscription();
|
|
14507
|
+
const cacheKey = invitationsLiveCollection.getCacheKey();
|
|
14508
|
+
disposers.push(() => {
|
|
14509
|
+
dropFromCache(cacheKey);
|
|
14510
|
+
});
|
|
14511
|
+
return () => {
|
|
14512
|
+
log(`getInvitations (tmpid: ${timestamp}) > dispose`);
|
|
14513
|
+
disposers.forEach(fn => fn());
|
|
14514
|
+
};
|
|
14515
|
+
};
|
|
14516
|
+
|
|
14517
|
+
const categoryLinkedObject = (category) => {
|
|
14518
|
+
return Object.assign(Object.assign({}, category), { get avatar() {
|
|
14519
|
+
var _a;
|
|
14520
|
+
if (!category.avatarFileId)
|
|
14521
|
+
return undefined;
|
|
14522
|
+
const avatar = (_a = pullFromCache([
|
|
14523
|
+
'file',
|
|
14524
|
+
'get',
|
|
14525
|
+
`${category.avatarFileId}`,
|
|
14526
|
+
])) === null || _a === void 0 ? void 0 : _a.data;
|
|
14527
|
+
return avatar;
|
|
14528
|
+
} });
|
|
14529
|
+
};
|
|
14530
|
+
|
|
14531
|
+
const communityLinkedObject = (community) => {
|
|
14532
|
+
return Object.assign(Object.assign({}, community), { get categories() {
|
|
14533
|
+
var _a;
|
|
14534
|
+
return ((_a = community === null || community === void 0 ? void 0 : community.categoryIds) !== null && _a !== void 0 ? _a : [])
|
|
14535
|
+
.map(categoryId => {
|
|
14536
|
+
const cacheData = pullFromCache(['category', 'get', categoryId]);
|
|
14537
|
+
if (cacheData === null || cacheData === void 0 ? void 0 : cacheData.data)
|
|
14538
|
+
return categoryLinkedObject(cacheData.data);
|
|
14539
|
+
return undefined;
|
|
14540
|
+
})
|
|
14541
|
+
.filter(category => !!category);
|
|
14542
|
+
},
|
|
14543
|
+
get avatar() {
|
|
14544
|
+
var _a;
|
|
14545
|
+
if (!community.avatarFileId)
|
|
14546
|
+
return undefined;
|
|
14547
|
+
const avatar = (_a = pullFromCache([
|
|
14548
|
+
'file',
|
|
14549
|
+
'get',
|
|
14550
|
+
community.avatarFileId,
|
|
14551
|
+
])) === null || _a === void 0 ? void 0 : _a.data;
|
|
14552
|
+
return avatar;
|
|
14553
|
+
}, createInvitations: async (userIds) => {
|
|
14554
|
+
await createInvitations({
|
|
14555
|
+
type: "communityMemberInvite" /* InvitationTypeEnum.CommunityMemberInvite */,
|
|
14556
|
+
targetType: 'community',
|
|
14557
|
+
targetId: community.communityId,
|
|
14558
|
+
userIds,
|
|
14490
14559
|
});
|
|
14491
|
-
})
|
|
14492
|
-
|
|
14560
|
+
}, getMemberInvitations: (params, callback) => {
|
|
14561
|
+
return getInvitations$1(Object.assign(Object.assign({}, params), { targetId: community.communityId, targetType: 'community', type: "communityMemberInvite" /* InvitationTypeEnum.CommunityMemberInvite */ }), callback);
|
|
14562
|
+
}, getInvitation: async () => {
|
|
14563
|
+
const { data } = await getInvitation({
|
|
14564
|
+
targetType: 'community',
|
|
14565
|
+
targetId: community.communityId,
|
|
14566
|
+
});
|
|
14567
|
+
return data;
|
|
14568
|
+
}, join: async () => joinRequest(community.communityId), getJoinRequests: (params, callback) => {
|
|
14569
|
+
return getJoinRequests(Object.assign(Object.assign({}, params), { communityId: community.communityId }), callback);
|
|
14570
|
+
}, getMyJoinRequest: async () => {
|
|
14571
|
+
const { data } = await getMyJoinRequest(community.communityId);
|
|
14572
|
+
return data;
|
|
14573
|
+
} });
|
|
14574
|
+
};
|
|
14575
|
+
|
|
14576
|
+
class StoryComputedValue {
|
|
14577
|
+
constructor(targetId, lastStoryExpiresAt, lastStorySeenExpiresAt) {
|
|
14578
|
+
this._syncingStoriesCount = 0;
|
|
14579
|
+
this._errorStoriesCount = 0;
|
|
14580
|
+
this._targetId = targetId;
|
|
14581
|
+
this._lastStoryExpiresAt = lastStoryExpiresAt;
|
|
14582
|
+
this._lastStorySeenExpiresAt = lastStorySeenExpiresAt;
|
|
14583
|
+
this.cacheStoryExpireTime = pullFromCache([
|
|
14584
|
+
"story-expire" /* STORY_KEY_CACHE.EXPIRE */,
|
|
14585
|
+
this._targetId,
|
|
14586
|
+
]);
|
|
14587
|
+
this.cacheStoreSeenTime = pullFromCache([
|
|
14588
|
+
"story-last-seen" /* STORY_KEY_CACHE.LAST_SEEN */,
|
|
14589
|
+
this._targetId,
|
|
14590
|
+
]);
|
|
14591
|
+
this.getTotalStoryByStatus();
|
|
14493
14592
|
}
|
|
14494
|
-
|
|
14495
|
-
|
|
14496
|
-
|
|
14497
|
-
|
|
14498
|
-
|
|
14499
|
-
|
|
14500
|
-
|
|
14501
|
-
|
|
14502
|
-
|
|
14503
|
-
|
|
14504
|
-
|
|
14505
|
-
|
|
14506
|
-
|
|
14507
|
-
|
|
14508
|
-
|
|
14509
|
-
|
|
14510
|
-
|
|
14511
|
-
|
|
14512
|
-
|
|
14513
|
-
|
|
14514
|
-
|
|
14593
|
+
get lastStoryExpiresAt() {
|
|
14594
|
+
return this._lastStoryExpiresAt ? new Date(this._lastStoryExpiresAt).getTime() : 0;
|
|
14595
|
+
}
|
|
14596
|
+
get lastStorySeenExpiresAt() {
|
|
14597
|
+
return this._lastStorySeenExpiresAt ? new Date(this._lastStorySeenExpiresAt).getTime() : 0;
|
|
14598
|
+
}
|
|
14599
|
+
get localLastStoryExpires() {
|
|
14600
|
+
var _a, _b;
|
|
14601
|
+
return ((_a = this.cacheStoryExpireTime) === null || _a === void 0 ? void 0 : _a.data)
|
|
14602
|
+
? new Date((_b = this.cacheStoryExpireTime) === null || _b === void 0 ? void 0 : _b.data).getTime()
|
|
14603
|
+
: 0;
|
|
14604
|
+
}
|
|
14605
|
+
get localLastStorySeenExpiresAt() {
|
|
14606
|
+
var _a, _b;
|
|
14607
|
+
return ((_a = this.cacheStoreSeenTime) === null || _a === void 0 ? void 0 : _a.data) ? new Date((_b = this.cacheStoreSeenTime) === null || _b === void 0 ? void 0 : _b.data).getTime() : 0;
|
|
14608
|
+
}
|
|
14609
|
+
get isContainUnSyncedStory() {
|
|
14610
|
+
const currentSyncingState = pullFromCache([
|
|
14611
|
+
"story-sync-state" /* STORY_KEY_CACHE.SYNC_STATE */,
|
|
14612
|
+
this._targetId,
|
|
14613
|
+
]);
|
|
14614
|
+
if (!(currentSyncingState === null || currentSyncingState === void 0 ? void 0 : currentSyncingState.data))
|
|
14615
|
+
return false;
|
|
14616
|
+
return ["syncing" /* Amity.SyncState.Syncing */, "error" /* Amity.SyncState.Error */].includes(currentSyncingState.data);
|
|
14515
14617
|
}
|
|
14516
|
-
|
|
14517
|
-
|
|
14518
|
-
|
|
14519
|
-
* Room statuses that are considered watchable
|
|
14520
|
-
*/
|
|
14521
|
-
const WATCHABLE_ROOM_STATUSES = ['live', 'recorded'];
|
|
14522
|
-
/**
|
|
14523
|
-
* Generate a random jitter delay between 5 and 30 seconds
|
|
14524
|
-
*/
|
|
14525
|
-
const getJitterDelay = () => {
|
|
14526
|
-
const minDelay = 5000; // 5 seconds
|
|
14527
|
-
const maxDelay = 30000; // 30 seconds
|
|
14528
|
-
return Math.floor(Math.random() * (maxDelay - minDelay + 1)) + minDelay;
|
|
14529
|
-
};
|
|
14530
|
-
/**
|
|
14531
|
-
* Wait for network connection with timeout
|
|
14532
|
-
* @param maxWaitTime Maximum time to wait in milliseconds (default: 60000 = 60 seconds)
|
|
14533
|
-
* @returns Promise that resolves when network is available or timeout is reached
|
|
14534
|
-
*/
|
|
14535
|
-
const waitForNetwork = (maxWaitTime = 60000) => {
|
|
14536
|
-
return new Promise(resolve => {
|
|
14537
|
-
// Simple check - if navigator.onLine is available, use it
|
|
14538
|
-
// Otherwise, assume network is available
|
|
14539
|
-
if (typeof navigator === 'undefined' || typeof navigator.onLine === 'undefined') {
|
|
14540
|
-
resolve();
|
|
14541
|
-
return;
|
|
14618
|
+
getLocalLastSortingDate() {
|
|
14619
|
+
if (this.isContainUnSyncedStory) {
|
|
14620
|
+
return this.localLastStoryExpires;
|
|
14542
14621
|
}
|
|
14543
|
-
|
|
14544
|
-
const checkInterval = 1000; // 1 second
|
|
14545
|
-
const checkConnection = () => {
|
|
14546
|
-
if (navigator.onLine || Date.now() - startTime >= maxWaitTime) {
|
|
14547
|
-
resolve();
|
|
14548
|
-
}
|
|
14549
|
-
else {
|
|
14550
|
-
setTimeout(checkConnection, checkInterval);
|
|
14551
|
-
}
|
|
14552
|
-
};
|
|
14553
|
-
checkConnection();
|
|
14554
|
-
});
|
|
14555
|
-
};
|
|
14556
|
-
/**
|
|
14557
|
-
* AmityRoomAnalytics provides analytics capabilities for room watch sessions
|
|
14558
|
-
*/
|
|
14559
|
-
class AmityRoomAnalytics {
|
|
14560
|
-
constructor(room) {
|
|
14561
|
-
this.storage = getWatchSessionStorage();
|
|
14562
|
-
this.client = getActiveClient();
|
|
14563
|
-
this.room = room;
|
|
14622
|
+
return this.lastStoryExpiresAt;
|
|
14564
14623
|
}
|
|
14565
|
-
|
|
14566
|
-
|
|
14567
|
-
|
|
14568
|
-
|
|
14569
|
-
|
|
14570
|
-
|
|
14571
|
-
|
|
14572
|
-
|
|
14573
|
-
|
|
14574
|
-
throw new ASCApiError('room is not in watchable state', 500000 /* Amity.ServerError.BUSINESS_ERROR */, "error" /* Amity.ErrorLevel.ERROR */);
|
|
14624
|
+
getHasUnseenFlag() {
|
|
14625
|
+
const now = new Date().getTime();
|
|
14626
|
+
const highestSeen = Math.max(this.lastStorySeenExpiresAt, this.localLastStorySeenExpiresAt);
|
|
14627
|
+
pullFromCache([
|
|
14628
|
+
"story-sync-state" /* STORY_KEY_CACHE.SYNC_STATE */,
|
|
14629
|
+
this._targetId,
|
|
14630
|
+
]);
|
|
14631
|
+
if (this.isContainUnSyncedStory) {
|
|
14632
|
+
return this.localLastStoryExpires > now && this.localLastStoryExpires > highestSeen;
|
|
14575
14633
|
}
|
|
14576
|
-
|
|
14577
|
-
const prefix = this.room.status === 'live' ? 'room_' : 'room_playback_';
|
|
14578
|
-
const sessionId = prefix + uuid__default["default"].v4();
|
|
14579
|
-
// Create watch session entity
|
|
14580
|
-
const session = {
|
|
14581
|
-
sessionId,
|
|
14582
|
-
roomId: this.room.roomId,
|
|
14583
|
-
watchSeconds: 0,
|
|
14584
|
-
startTime: startedAt,
|
|
14585
|
-
endTime: null,
|
|
14586
|
-
syncState: 'PENDING',
|
|
14587
|
-
syncedAt: null,
|
|
14588
|
-
retryCount: 0,
|
|
14589
|
-
};
|
|
14590
|
-
// Persist to storage
|
|
14591
|
-
this.storage.addSession(session);
|
|
14592
|
-
return sessionId;
|
|
14634
|
+
return this.lastStoryExpiresAt > now && this.lastStoryExpiresAt > highestSeen;
|
|
14593
14635
|
}
|
|
14594
|
-
|
|
14595
|
-
|
|
14596
|
-
|
|
14597
|
-
|
|
14598
|
-
|
|
14599
|
-
|
|
14600
|
-
*/
|
|
14601
|
-
async updateWatchSession(sessionId, duration, endedAt) {
|
|
14602
|
-
const session = this.storage.getSession(sessionId);
|
|
14603
|
-
if (!session) {
|
|
14604
|
-
throw new Error(`Watch session ${sessionId} not found`);
|
|
14636
|
+
getTotalStoryByStatus() {
|
|
14637
|
+
const stories = queryCache(["story" /* STORY_KEY_CACHE.STORY */, 'get']);
|
|
14638
|
+
if (!stories) {
|
|
14639
|
+
this._errorStoriesCount = 0;
|
|
14640
|
+
this._syncingStoriesCount = 0;
|
|
14641
|
+
return;
|
|
14605
14642
|
}
|
|
14606
|
-
|
|
14607
|
-
|
|
14608
|
-
|
|
14609
|
-
|
|
14643
|
+
const groupByType = stories.reduce((acc, story) => {
|
|
14644
|
+
const { data: { targetId, syncState, isDeleted }, } = story;
|
|
14645
|
+
if (targetId === this._targetId && !isDeleted) {
|
|
14646
|
+
acc[syncState] += 1;
|
|
14647
|
+
}
|
|
14648
|
+
return acc;
|
|
14649
|
+
}, {
|
|
14650
|
+
syncing: 0,
|
|
14651
|
+
error: 0,
|
|
14652
|
+
synced: 0,
|
|
14610
14653
|
});
|
|
14654
|
+
this._errorStoriesCount = groupByType.error;
|
|
14655
|
+
this._syncingStoriesCount = groupByType.syncing;
|
|
14611
14656
|
}
|
|
14612
|
-
|
|
14613
|
-
|
|
14614
|
-
|
|
14615
|
-
|
|
14616
|
-
|
|
14617
|
-
// Execute with jitter delay (5-30 seconds)
|
|
14618
|
-
const jitterDelay = getJitterDelay();
|
|
14619
|
-
this.client.log('room/RoomAnalytics: syncPendingWatchSessions called, jitter delay:', `${jitterDelay}ms`);
|
|
14620
|
-
setTimeout(async () => {
|
|
14621
|
-
this.client.log('room/RoomAnalytics: Jitter delay completed, starting sync process');
|
|
14622
|
-
try {
|
|
14623
|
-
// Reset any SYNCING sessions back to PENDING
|
|
14624
|
-
const syncingSessions = this.storage.getSyncingSessions();
|
|
14625
|
-
this.client.log('room/RoomAnalytics: SYNCING sessions to reset:', syncingSessions.length);
|
|
14626
|
-
syncingSessions.forEach(session => {
|
|
14627
|
-
this.storage.updateSession(session.sessionId, { syncState: 'PENDING' });
|
|
14628
|
-
});
|
|
14629
|
-
// Wait for network connection (max 60 seconds)
|
|
14630
|
-
await waitForNetwork(60000);
|
|
14631
|
-
this.client.log('room/RoomAnalytics: Network available');
|
|
14632
|
-
// Sync pending sessions
|
|
14633
|
-
this.client.log('room/RoomAnalytics: Calling syncWatchSessions()');
|
|
14634
|
-
await syncWatchSessions();
|
|
14635
|
-
this.client.log('room/RoomAnalytics: syncWatchSessions completed');
|
|
14636
|
-
}
|
|
14637
|
-
catch (error) {
|
|
14638
|
-
// Error is already handled in syncWatchSessions
|
|
14639
|
-
console.error('Failed to sync watch sessions:', error);
|
|
14640
|
-
}
|
|
14641
|
-
}, jitterDelay);
|
|
14657
|
+
get syncingStoriesCount() {
|
|
14658
|
+
return this._syncingStoriesCount;
|
|
14659
|
+
}
|
|
14660
|
+
get failedStoriesCount() {
|
|
14661
|
+
return this._errorStoriesCount;
|
|
14642
14662
|
}
|
|
14643
14663
|
}
|
|
14644
14664
|
|
|
14645
|
-
const
|
|
14646
|
-
|
|
14647
|
-
|
|
14648
|
-
|
|
14649
|
-
|
|
14650
|
-
|
|
14665
|
+
const storyTargetLinkedObject = (storyTarget) => {
|
|
14666
|
+
const { targetType, targetId, lastStoryExpiresAt, lastStorySeenExpiresAt, targetUpdatedAt, localFilter, } = storyTarget;
|
|
14667
|
+
const computedValue = new StoryComputedValue(targetId, lastStoryExpiresAt, lastStorySeenExpiresAt);
|
|
14668
|
+
return {
|
|
14669
|
+
targetType,
|
|
14670
|
+
targetId,
|
|
14671
|
+
lastStoryExpiresAt,
|
|
14672
|
+
updatedAt: targetUpdatedAt,
|
|
14673
|
+
// Additional data
|
|
14674
|
+
hasUnseen: computedValue.getHasUnseenFlag(),
|
|
14675
|
+
syncingStoriesCount: computedValue.syncingStoriesCount,
|
|
14676
|
+
failedStoriesCount: computedValue.failedStoriesCount,
|
|
14677
|
+
localFilter,
|
|
14678
|
+
localLastExpires: computedValue.localLastStoryExpires,
|
|
14679
|
+
localLastSeen: computedValue.localLastStorySeenExpiresAt,
|
|
14680
|
+
localSortingDate: computedValue.getLocalLastSortingDate(),
|
|
14681
|
+
};
|
|
14682
|
+
};
|
|
14683
|
+
|
|
14684
|
+
const storyLinkedObject = (story) => {
|
|
14685
|
+
const analyticsEngineInstance = AnalyticsEngine$1.getInstance();
|
|
14686
|
+
const storyTargetCache = pullFromCache([
|
|
14687
|
+
"storyTarget" /* STORY_KEY_CACHE.STORY_TARGET */,
|
|
14688
|
+
'get',
|
|
14689
|
+
story.targetId,
|
|
14690
|
+
]);
|
|
14691
|
+
const communityCacheData = pullFromCache(['community', 'get', story.targetId]);
|
|
14692
|
+
return Object.assign(Object.assign({}, story), { analytics: {
|
|
14693
|
+
markAsSeen: () => {
|
|
14694
|
+
if (!story.expiresAt)
|
|
14695
|
+
return;
|
|
14696
|
+
if (story.syncState !== "synced" /* Amity.SyncState.Synced */)
|
|
14697
|
+
return;
|
|
14698
|
+
analyticsEngineInstance.markStoryAsViewed(story);
|
|
14699
|
+
},
|
|
14700
|
+
markLinkAsClicked: () => {
|
|
14701
|
+
if (!story.expiresAt)
|
|
14702
|
+
return;
|
|
14703
|
+
if (story.syncState !== "synced" /* Amity.SyncState.Synced */)
|
|
14704
|
+
return;
|
|
14705
|
+
analyticsEngineInstance.markStoryAsClicked(story);
|
|
14706
|
+
},
|
|
14707
|
+
}, get videoData() {
|
|
14708
|
+
var _a, _b;
|
|
14709
|
+
const cache = pullFromCache([
|
|
14710
|
+
'file',
|
|
14711
|
+
'get',
|
|
14712
|
+
(_b = (_a = story.data) === null || _a === void 0 ? void 0 : _a.videoFileId) === null || _b === void 0 ? void 0 : _b.original,
|
|
14713
|
+
]);
|
|
14714
|
+
if (!cache)
|
|
14715
|
+
return undefined;
|
|
14716
|
+
const { data } = cache;
|
|
14717
|
+
return data || undefined;
|
|
14718
|
+
},
|
|
14719
|
+
get imageData() {
|
|
14720
|
+
var _a, _b;
|
|
14721
|
+
if (!((_a = story.data) === null || _a === void 0 ? void 0 : _a.fileId))
|
|
14722
|
+
return undefined;
|
|
14723
|
+
const cache = pullFromCache(['file', 'get', (_b = story.data) === null || _b === void 0 ? void 0 : _b.fileId]);
|
|
14724
|
+
if (!cache)
|
|
14725
|
+
return undefined;
|
|
14726
|
+
const { data } = cache;
|
|
14727
|
+
if (!data)
|
|
14728
|
+
return undefined;
|
|
14729
|
+
return Object.assign(Object.assign({}, data), { fileUrl: `${data.fileUrl}?size=full` });
|
|
14651
14730
|
},
|
|
14652
14731
|
get community() {
|
|
14653
|
-
|
|
14654
|
-
|
|
14732
|
+
if (story.targetType !== 'community')
|
|
14733
|
+
return undefined;
|
|
14734
|
+
if (!(communityCacheData === null || communityCacheData === void 0 ? void 0 : communityCacheData.data))
|
|
14735
|
+
return undefined;
|
|
14736
|
+
return communityLinkedObject(communityCacheData.data);
|
|
14737
|
+
},
|
|
14738
|
+
get communityCategories() {
|
|
14739
|
+
if (story.targetType !== 'community')
|
|
14740
|
+
return undefined;
|
|
14741
|
+
if (!communityCacheData)
|
|
14742
|
+
return undefined;
|
|
14743
|
+
const { data: { categoryIds }, } = communityCacheData;
|
|
14744
|
+
if (categoryIds.length === 0)
|
|
14745
|
+
return undefined;
|
|
14746
|
+
return categoryIds
|
|
14747
|
+
.map(categoryId => {
|
|
14748
|
+
const categoryCacheData = pullFromCache(['category', 'get', categoryId]);
|
|
14749
|
+
return (categoryCacheData === null || categoryCacheData === void 0 ? void 0 : categoryCacheData.data) || undefined;
|
|
14750
|
+
})
|
|
14751
|
+
.filter(category => category !== undefined);
|
|
14752
|
+
},
|
|
14753
|
+
get creator() {
|
|
14754
|
+
const cacheData = pullFromCache(['user', 'get', story.creatorPublicId]);
|
|
14755
|
+
if (!(cacheData === null || cacheData === void 0 ? void 0 : cacheData.data))
|
|
14655
14756
|
return;
|
|
14656
|
-
return (
|
|
14757
|
+
return userLinkedObject(cacheData.data);
|
|
14657
14758
|
},
|
|
14658
|
-
get
|
|
14659
|
-
|
|
14660
|
-
|
|
14661
|
-
return
|
|
14759
|
+
get storyTarget() {
|
|
14760
|
+
if (!(storyTargetCache === null || storyTargetCache === void 0 ? void 0 : storyTargetCache.data))
|
|
14761
|
+
return;
|
|
14762
|
+
return storyTargetLinkedObject(storyTargetCache.data);
|
|
14662
14763
|
},
|
|
14663
|
-
get
|
|
14664
|
-
|
|
14665
|
-
|
|
14666
|
-
|
|
14667
|
-
|
|
14668
|
-
|
|
14669
|
-
|
|
14670
|
-
|
|
14671
|
-
return undefined;
|
|
14672
|
-
return roomLinkedObject(roomCache);
|
|
14673
|
-
})
|
|
14674
|
-
.filter(isNonNullable);
|
|
14675
|
-
}, participants: room.participants.map(participant => (Object.assign(Object.assign({}, participant), { get user() {
|
|
14676
|
-
var _a;
|
|
14677
|
-
const user = (_a = pullFromCache(['user', 'get', participant.userId])) === null || _a === void 0 ? void 0 : _a.data;
|
|
14678
|
-
return user ? userLinkedObject(user) : user;
|
|
14679
|
-
} }))), getLiveChat: () => getLiveChat(room), createInvitation: (userId) => createInvitations({
|
|
14680
|
-
type: "livestreamCohostInvite" /* InvitationTypeEnum.LivestreamCohostInvite */,
|
|
14681
|
-
targetType: 'room',
|
|
14682
|
-
targetId: room.roomId,
|
|
14683
|
-
userIds: [userId],
|
|
14684
|
-
}), getInvitations: async () => {
|
|
14685
|
-
const { data } = await getInvitation({
|
|
14686
|
-
targetId: room.roomId,
|
|
14687
|
-
targetType: 'room',
|
|
14688
|
-
type: "livestreamCohostInvite" /* InvitationTypeEnum.LivestreamCohostInvite */,
|
|
14689
|
-
});
|
|
14690
|
-
return data;
|
|
14691
|
-
}, analytics() {
|
|
14692
|
-
// Use 'this' to avoid creating a new room object
|
|
14693
|
-
return new AmityRoomAnalytics(this);
|
|
14764
|
+
get isSeen() {
|
|
14765
|
+
const cacheData = pullFromCache(["story-last-seen" /* STORY_KEY_CACHE.LAST_SEEN */, story.targetId]);
|
|
14766
|
+
if (!(storyTargetCache === null || storyTargetCache === void 0 ? void 0 : storyTargetCache.data))
|
|
14767
|
+
return false;
|
|
14768
|
+
const localLastSeen = (cacheData === null || cacheData === void 0 ? void 0 : cacheData.data) ? new Date(cacheData.data).getTime() : 0;
|
|
14769
|
+
const serverLastSeen = new Date(storyTargetCache === null || storyTargetCache === void 0 ? void 0 : storyTargetCache.data.lastStorySeenExpiresAt).getTime() || 0;
|
|
14770
|
+
const expiresAt = new Date(story.expiresAt).getTime();
|
|
14771
|
+
return Math.max(localLastSeen, serverLastSeen) >= expiresAt;
|
|
14694
14772
|
} });
|
|
14695
14773
|
};
|
|
14696
14774
|
|
|
14697
|
-
const pollLinkedObject = (poll) => {
|
|
14698
|
-
return Object.assign(Object.assign({}, poll), { answers: poll.answers.map(answer => (Object.assign(Object.assign({}, answer), { get image() {
|
|
14699
|
-
var _a;
|
|
14700
|
-
if (!answer.fileId)
|
|
14701
|
-
return undefined;
|
|
14702
|
-
return (_a = pullFromCache(['file', 'get', answer.fileId])) === null || _a === void 0 ? void 0 : _a.data;
|
|
14703
|
-
} }))) });
|
|
14704
|
-
};
|
|
14705
|
-
|
|
14706
|
-
/*
|
|
14707
|
-
* verifies membership status
|
|
14708
|
-
*/
|
|
14709
|
-
function isMember(membership) {
|
|
14710
|
-
return membership !== 'none';
|
|
14711
|
-
}
|
|
14712
|
-
/*
|
|
14713
|
-
* checks if currently logged in user is part of the community
|
|
14714
|
-
*/
|
|
14715
|
-
function isCurrentUserPartOfCommunity(c, m) {
|
|
14716
|
-
const { userId } = getActiveUser();
|
|
14717
|
-
return c.communityId === m.communityId && m.userId === userId;
|
|
14718
|
-
}
|
|
14719
|
-
/*
|
|
14720
|
-
* For mqtt events server will not send user specific data as it's broadcasted
|
|
14721
|
-
* to multiple users and it also does not include communityUser
|
|
14722
|
-
*
|
|
14723
|
-
* Client SDK needs to check for the existing isJoined field in cache data before calculating.
|
|
14724
|
-
* Althought this can be calculated, it's not scalable.
|
|
14725
|
-
*/
|
|
14726
|
-
function updateMembershipStatus(communities, communityUsers) {
|
|
14727
|
-
return communities.map(c => {
|
|
14728
|
-
const cachedCommunity = pullFromCache([
|
|
14729
|
-
'community',
|
|
14730
|
-
'get',
|
|
14731
|
-
c.communityId,
|
|
14732
|
-
]);
|
|
14733
|
-
if ((cachedCommunity === null || cachedCommunity === void 0 ? void 0 : cachedCommunity.data) && (cachedCommunity === null || cachedCommunity === void 0 ? void 0 : cachedCommunity.data.hasOwnProperty('isJoined'))) {
|
|
14734
|
-
return Object.assign(Object.assign({}, cachedCommunity.data), c);
|
|
14735
|
-
}
|
|
14736
|
-
const isJoined = c.isJoined !== undefined
|
|
14737
|
-
? c.isJoined
|
|
14738
|
-
: communityUsers.some(m => isCurrentUserPartOfCommunity(c, m) && isMember(m.communityMembership));
|
|
14739
|
-
return Object.assign(Object.assign({}, c), { isJoined });
|
|
14740
|
-
});
|
|
14741
|
-
}
|
|
14742
|
-
|
|
14743
|
-
const getMatchPostSetting = (value) => {
|
|
14744
|
-
var _a;
|
|
14745
|
-
return (_a = Object.keys(CommunityPostSettingMaps).find(key => value.needApprovalOnPostCreation ===
|
|
14746
|
-
CommunityPostSettingMaps[key].needApprovalOnPostCreation &&
|
|
14747
|
-
value.onlyAdminCanPost === CommunityPostSettingMaps[key].onlyAdminCanPost)) !== null && _a !== void 0 ? _a : DefaultCommunityPostSetting;
|
|
14748
|
-
};
|
|
14749
|
-
function addPostSetting({ communities }) {
|
|
14750
|
-
return communities.map((_a) => {
|
|
14751
|
-
var { needApprovalOnPostCreation, onlyAdminCanPost } = _a, restCommunityPayload = __rest(_a, ["needApprovalOnPostCreation", "onlyAdminCanPost"]);
|
|
14752
|
-
return (Object.assign({ postSetting: getMatchPostSetting({
|
|
14753
|
-
needApprovalOnPostCreation,
|
|
14754
|
-
onlyAdminCanPost,
|
|
14755
|
-
}) }, restCommunityPayload));
|
|
14756
|
-
});
|
|
14757
|
-
}
|
|
14758
|
-
const prepareCommunityPayload = (rawPayload) => {
|
|
14759
|
-
const communitiesWithPostSetting = addPostSetting({ communities: rawPayload.communities });
|
|
14760
|
-
// Convert users to internal format
|
|
14761
|
-
const internalUsers = rawPayload.users.map(convertRawUserToInternalUser);
|
|
14762
|
-
// map users with community
|
|
14763
|
-
const mappedCommunityUsers = rawPayload.communityUsers.map(communityUser => {
|
|
14764
|
-
const user = internalUsers.find(user => user.userId === communityUser.userId);
|
|
14765
|
-
return Object.assign(Object.assign({}, communityUser), { user });
|
|
14766
|
-
});
|
|
14767
|
-
const communityWithMembershipStatus = updateMembershipStatus(communitiesWithPostSetting, mappedCommunityUsers);
|
|
14768
|
-
return Object.assign(Object.assign({}, rawPayload), { users: rawPayload.users.map(convertRawUserToInternalUser), communities: communityWithMembershipStatus, communityUsers: mappedCommunityUsers });
|
|
14769
|
-
};
|
|
14770
|
-
const prepareCommunityJoinRequestPayload = (rawPayload) => {
|
|
14771
|
-
const mappedJoinRequests = rawPayload.joinRequests.map(joinRequest => {
|
|
14772
|
-
return Object.assign(Object.assign({}, joinRequest), { joinRequestId: joinRequest._id });
|
|
14773
|
-
});
|
|
14774
|
-
const users = rawPayload.users.map(convertRawUserToInternalUser);
|
|
14775
|
-
return Object.assign(Object.assign({}, rawPayload), { joinRequests: mappedJoinRequests, users });
|
|
14776
|
-
};
|
|
14777
|
-
const prepareCommunityMembershipPayload = (rawPayload) => {
|
|
14778
|
-
const communitiesWithPostSetting = addPostSetting({ communities: rawPayload.communities });
|
|
14779
|
-
// map users with community
|
|
14780
|
-
const mappedCommunityUsers = rawPayload.communityUsers.map(communityUser => {
|
|
14781
|
-
const user = rawPayload.users.find(user => user.userId === communityUser.userId);
|
|
14782
|
-
return Object.assign(Object.assign({}, communityUser), { user });
|
|
14783
|
-
});
|
|
14784
|
-
const communityWithMembershipStatus = updateMembershipStatus(communitiesWithPostSetting, mappedCommunityUsers);
|
|
14785
|
-
return Object.assign(Object.assign({}, rawPayload), { communities: communityWithMembershipStatus, communityUsers: mappedCommunityUsers });
|
|
14786
|
-
};
|
|
14787
|
-
const prepareCommunityRequest = (params) => {
|
|
14788
|
-
const { postSetting = undefined, storySetting } = params, restParam = __rest(params, ["postSetting", "storySetting"]);
|
|
14789
|
-
return Object.assign(Object.assign(Object.assign({}, restParam), (postSetting ? CommunityPostSettingMaps[postSetting] : undefined)), {
|
|
14790
|
-
// Convert story setting to the actual value. (Allow by default)
|
|
14791
|
-
allowCommentInStory: typeof (storySetting === null || storySetting === void 0 ? void 0 : storySetting.enableComment) === 'boolean' ? storySetting.enableComment : true });
|
|
14792
|
-
};
|
|
14793
|
-
const prepareSemanticSearchCommunityPayload = (_a) => {
|
|
14794
|
-
var communityPayload = __rest(_a, ["searchResult"]);
|
|
14795
|
-
const processedCommunityPayload = prepareCommunityPayload(communityPayload);
|
|
14796
|
-
return Object.assign({}, processedCommunityPayload);
|
|
14797
|
-
};
|
|
14798
|
-
|
|
14799
14775
|
/* begin_public_function
|
|
14800
|
-
id:
|
|
14776
|
+
id: channel.create
|
|
14801
14777
|
*/
|
|
14802
14778
|
/**
|
|
14803
14779
|
* ```js
|
|
14804
|
-
* import {
|
|
14805
|
-
* const
|
|
14780
|
+
* import { createChannel } from '@amityco/ts-sdk-react-native'
|
|
14781
|
+
* const created = await createChannel({ displayName: 'foobar' })
|
|
14806
14782
|
* ```
|
|
14807
14783
|
*
|
|
14808
|
-
*
|
|
14784
|
+
* Creates an {@link Amity.Channel}
|
|
14809
14785
|
*
|
|
14810
|
-
* @param
|
|
14811
|
-
* @returns
|
|
14786
|
+
* @param bundle The data necessary to create a new {@link Amity.Channel}
|
|
14787
|
+
* @returns The newly created {@link Amity.Channel}
|
|
14812
14788
|
*
|
|
14813
|
-
* @category
|
|
14789
|
+
* @category Channel API
|
|
14814
14790
|
* @async
|
|
14815
14791
|
*/
|
|
14816
|
-
const
|
|
14817
|
-
var _a;
|
|
14792
|
+
const createChannel = async (bundle) => {
|
|
14818
14793
|
const client = getActiveClient();
|
|
14819
|
-
client.log('
|
|
14820
|
-
|
|
14821
|
-
|
|
14822
|
-
|
|
14823
|
-
|
|
14824
|
-
'joinRequest',
|
|
14825
|
-
'get',
|
|
14826
|
-
joinRequest.joinRequestId,
|
|
14827
|
-
])) === null || _a === void 0 ? void 0 : _a.data;
|
|
14828
|
-
if (joinRequestCache) {
|
|
14829
|
-
upsertInCache(['joinRequest', 'get', joinRequest.joinRequestId], {
|
|
14830
|
-
status: "approved" /* JoinRequestStatusEnum.Approved */,
|
|
14831
|
-
});
|
|
14832
|
-
fireEvent('local.joinRequest.updated', [joinRequestCache]);
|
|
14794
|
+
client.log('user/createChannel', bundle);
|
|
14795
|
+
let payload;
|
|
14796
|
+
/* c8 ignore next */
|
|
14797
|
+
if ((bundle === null || bundle === void 0 ? void 0 : bundle.type) === 'conversation') {
|
|
14798
|
+
payload = await client.http.post('/api/v3/channels/conversation', Object.assign(Object.assign({}, bundle), { isDistinct: true }));
|
|
14833
14799
|
}
|
|
14834
|
-
|
|
14800
|
+
else {
|
|
14801
|
+
const { isPublic } = bundle, restParams = __rest(bundle, ["isPublic"]);
|
|
14802
|
+
payload = await client.http.post('/api/v3/channels', Object.assign(Object.assign({}, restParams), {
|
|
14803
|
+
/* c8 ignore next */
|
|
14804
|
+
isPublic: (bundle === null || bundle === void 0 ? void 0 : bundle.type) === 'community' ? isPublic : undefined }));
|
|
14805
|
+
}
|
|
14806
|
+
const data = await prepareChannelPayload(payload.data);
|
|
14807
|
+
const cachedAt = client.cache && Date.now();
|
|
14808
|
+
if (client.cache)
|
|
14809
|
+
ingestInCache(data, { cachedAt });
|
|
14810
|
+
const { channels } = data;
|
|
14811
|
+
return {
|
|
14812
|
+
data: constructChannelObject(channels[0]),
|
|
14813
|
+
cachedAt,
|
|
14814
|
+
};
|
|
14835
14815
|
};
|
|
14836
14816
|
/* end_public_function */
|
|
14837
14817
|
|
|
14838
|
-
/* begin_public_function
|
|
14839
|
-
id: joinRequest.cancel
|
|
14840
|
-
*/
|
|
14841
14818
|
/**
|
|
14842
14819
|
* ```js
|
|
14843
|
-
* import {
|
|
14844
|
-
* const
|
|
14820
|
+
* import { getChannel } from '@amityco/ts-sdk-react-native'
|
|
14821
|
+
* const channel = await getChannel('foobar')
|
|
14845
14822
|
* ```
|
|
14846
14823
|
*
|
|
14847
|
-
*
|
|
14824
|
+
* Fetches a {@link Amity.Channel} object
|
|
14848
14825
|
*
|
|
14849
|
-
* @param
|
|
14850
|
-
* @returns
|
|
14826
|
+
* @param channelId the ID of the {@link Amity.Channel} to fetch
|
|
14827
|
+
* @returns the associated {@link Amity.Channel} object
|
|
14851
14828
|
*
|
|
14852
|
-
* @category
|
|
14829
|
+
* @category Channel API
|
|
14853
14830
|
* @async
|
|
14854
14831
|
*/
|
|
14855
|
-
const
|
|
14856
|
-
var _a;
|
|
14832
|
+
const getChannel$1 = async (channelId) => {
|
|
14857
14833
|
const client = getActiveClient();
|
|
14858
|
-
client.log('
|
|
14859
|
-
|
|
14860
|
-
|
|
14861
|
-
|
|
14862
|
-
|
|
14863
|
-
|
|
14864
|
-
|
|
14865
|
-
|
|
14866
|
-
|
|
14867
|
-
status: "cancelled" /* JoinRequestStatusEnum.Cancelled */,
|
|
14868
|
-
});
|
|
14869
|
-
fireEvent('local.joinRequest.deleted', [joinRequestCache]);
|
|
14834
|
+
client.log('channel/getChannel', channelId);
|
|
14835
|
+
isInTombstone('channel', channelId);
|
|
14836
|
+
let data;
|
|
14837
|
+
try {
|
|
14838
|
+
const { data: payload } = await client.http.get(`/api/v3/channels/${encodeURIComponent(channelId)}`);
|
|
14839
|
+
data = await prepareChannelPayload(payload);
|
|
14840
|
+
if (client.isUnreadCountEnabled && client.getMarkerSyncConsistentMode()) {
|
|
14841
|
+
prepareUnreadCountInfo(payload);
|
|
14842
|
+
}
|
|
14870
14843
|
}
|
|
14871
|
-
|
|
14844
|
+
catch (error) {
|
|
14845
|
+
if (checkIfShouldGoesToTombstone(error === null || error === void 0 ? void 0 : error.code)) {
|
|
14846
|
+
// NOTE: use channelPublicId as tombstone cache key since we cannot get the channelPrivateId that come along with channel data from server
|
|
14847
|
+
pushToTombstone('channel', channelId);
|
|
14848
|
+
}
|
|
14849
|
+
throw error;
|
|
14850
|
+
}
|
|
14851
|
+
const cachedAt = client.cache && Date.now();
|
|
14852
|
+
if (client.cache)
|
|
14853
|
+
ingestInCache(data, { cachedAt });
|
|
14854
|
+
const { channels } = data;
|
|
14855
|
+
return {
|
|
14856
|
+
data: channels.find(channel => channel.channelId === channelId),
|
|
14857
|
+
cachedAt,
|
|
14858
|
+
};
|
|
14872
14859
|
};
|
|
14873
|
-
/* end_public_function */
|
|
14874
|
-
|
|
14875
|
-
/* begin_public_function
|
|
14876
|
-
id: joinRequest.reject
|
|
14877
|
-
*/
|
|
14878
14860
|
/**
|
|
14879
14861
|
* ```js
|
|
14880
|
-
* import {
|
|
14881
|
-
* const
|
|
14862
|
+
* import { getChannel } from '@amityco/ts-sdk-react-native'
|
|
14863
|
+
* const channel = getChannel.locally('foobar')
|
|
14882
14864
|
* ```
|
|
14883
14865
|
*
|
|
14884
|
-
*
|
|
14866
|
+
* Fetches a {@link Amity.Channel} object from cache
|
|
14885
14867
|
*
|
|
14886
|
-
* @param
|
|
14887
|
-
* @returns
|
|
14868
|
+
* @param channelId the ID of the {@link Amity.Channel} to fetch
|
|
14869
|
+
* @returns the associated {@link Amity.Channel} object
|
|
14888
14870
|
*
|
|
14889
|
-
* @category
|
|
14890
|
-
* @async
|
|
14871
|
+
* @category Channel API
|
|
14891
14872
|
*/
|
|
14892
|
-
|
|
14873
|
+
getChannel$1.locally = (channelId) => {
|
|
14893
14874
|
var _a;
|
|
14894
14875
|
const client = getActiveClient();
|
|
14895
|
-
client.log('
|
|
14896
|
-
|
|
14897
|
-
|
|
14876
|
+
client.log('channel/getChannel.locally', channelId);
|
|
14877
|
+
if (!client.cache)
|
|
14878
|
+
return;
|
|
14879
|
+
// use queryCache to get all channel caches and filter by channelPublicId since we use channelPrivateId as cache key
|
|
14880
|
+
const cached = (_a = queryCache(['channel', 'get'])) === null || _a === void 0 ? void 0 : _a.filter(({ data }) => {
|
|
14881
|
+
return data.channelPublicId === channelId;
|
|
14898
14882
|
});
|
|
14899
|
-
|
|
14900
|
-
|
|
14901
|
-
|
|
14902
|
-
|
|
14903
|
-
|
|
14904
|
-
|
|
14905
|
-
upsertInCache(['joinRequest', 'get', joinRequest.joinRequestId], {
|
|
14906
|
-
status: "rejected" /* JoinRequestStatusEnum.Rejected */,
|
|
14907
|
-
});
|
|
14908
|
-
fireEvent('local.joinRequest.updated', [joinRequestCache]);
|
|
14909
|
-
}
|
|
14910
|
-
return data.success;
|
|
14911
|
-
};
|
|
14912
|
-
/* end_public_function */
|
|
14913
|
-
|
|
14914
|
-
const joinRequestLinkedObject = (joinRequest) => {
|
|
14915
|
-
return Object.assign(Object.assign({}, joinRequest), { get user() {
|
|
14916
|
-
var _a;
|
|
14917
|
-
const user = (_a = pullFromCache([
|
|
14918
|
-
'user',
|
|
14919
|
-
'get',
|
|
14920
|
-
joinRequest.requestorPublicId,
|
|
14921
|
-
])) === null || _a === void 0 ? void 0 : _a.data;
|
|
14922
|
-
if (!user)
|
|
14923
|
-
return undefined;
|
|
14924
|
-
return userLinkedObject(user);
|
|
14925
|
-
}, cancel: async () => {
|
|
14926
|
-
await cancelJoinRequest(joinRequest);
|
|
14927
|
-
}, approve: async () => {
|
|
14928
|
-
await approveJoinRequest(joinRequest);
|
|
14929
|
-
}, reject: async () => {
|
|
14930
|
-
await rejectJoinRequest(joinRequest);
|
|
14931
|
-
} });
|
|
14883
|
+
if (!cached || (cached === null || cached === void 0 ? void 0 : cached.length) === 0)
|
|
14884
|
+
return;
|
|
14885
|
+
return {
|
|
14886
|
+
data: cached[0].data,
|
|
14887
|
+
cachedAt: cached[0].cachedAt,
|
|
14888
|
+
};
|
|
14932
14889
|
};
|
|
14933
14890
|
|
|
14934
|
-
/* begin_public_function
|
|
14935
|
-
id: community.getMyJoinRequest
|
|
14936
|
-
*/
|
|
14937
14891
|
/**
|
|
14938
14892
|
* ```js
|
|
14939
|
-
* import {
|
|
14940
|
-
* const
|
|
14893
|
+
* import { getStream } from '@amityco/ts-sdk-react-native'
|
|
14894
|
+
* const stream = await getStream('foobar')
|
|
14941
14895
|
* ```
|
|
14942
14896
|
*
|
|
14943
|
-
*
|
|
14897
|
+
* Fetches a {@link Amity.Channel} object linked with a current stream
|
|
14944
14898
|
*
|
|
14945
|
-
* @param
|
|
14946
|
-
* @returns
|
|
14899
|
+
* @param stream {@link Amity.Stream} that has linked live channel
|
|
14900
|
+
* @returns the associated {@link Amity.Channel<'live'>} object
|
|
14947
14901
|
*
|
|
14948
|
-
* @category
|
|
14902
|
+
* @category Stream API
|
|
14949
14903
|
* @async
|
|
14950
14904
|
*/
|
|
14951
|
-
const
|
|
14905
|
+
const getLiveChat$1 = async (stream) => {
|
|
14906
|
+
var _a;
|
|
14952
14907
|
const client = getActiveClient();
|
|
14953
|
-
client.log('
|
|
14954
|
-
|
|
14955
|
-
|
|
14956
|
-
|
|
14957
|
-
|
|
14958
|
-
|
|
14959
|
-
|
|
14960
|
-
|
|
14961
|
-
|
|
14962
|
-
|
|
14908
|
+
client.log('stream/getLiveChat', stream.streamId);
|
|
14909
|
+
if (stream.channelId) {
|
|
14910
|
+
const channel = (_a = pullFromCache([
|
|
14911
|
+
'channel',
|
|
14912
|
+
'get',
|
|
14913
|
+
stream.channelId,
|
|
14914
|
+
])) === null || _a === void 0 ? void 0 : _a.data;
|
|
14915
|
+
if (channel)
|
|
14916
|
+
return channelLinkedObject(constructChannelObject(channel));
|
|
14917
|
+
const { data } = await getChannel$1(stream.channelId);
|
|
14918
|
+
return channelLinkedObject(constructChannelObject(data));
|
|
14919
|
+
}
|
|
14920
|
+
// No Channel ID
|
|
14921
|
+
// streamer: create a new live channel
|
|
14922
|
+
if (stream.userId === client.userId) {
|
|
14923
|
+
const { data: channel } = await createChannel({
|
|
14924
|
+
type: 'live',
|
|
14925
|
+
postId: stream.postId,
|
|
14926
|
+
videoStreamId: stream.streamId,
|
|
14927
|
+
});
|
|
14928
|
+
// Update channelId to stream object in cache
|
|
14929
|
+
mergeInCache(['stream', 'get', stream.streamId], {
|
|
14930
|
+
channelId: channel.channelId,
|
|
14931
|
+
});
|
|
14932
|
+
return channel;
|
|
14933
|
+
}
|
|
14934
|
+
// watcher: return undefined
|
|
14935
|
+
return undefined;
|
|
14963
14936
|
};
|
|
14964
|
-
/* end_public_function */
|
|
14965
14937
|
|
|
14966
|
-
|
|
14967
|
-
|
|
14968
|
-
|
|
14938
|
+
const GET_WATCHER_URLS = Symbol('getWatcherUrls');
|
|
14939
|
+
const streamLinkedObject = (stream) => {
|
|
14940
|
+
return Object.assign(Object.assign({}, stream), { get moderation() {
|
|
14941
|
+
var _a;
|
|
14942
|
+
return (_a = pullFromCache(['streamModeration', 'get', stream.streamId])) === null || _a === void 0 ? void 0 : _a.data;
|
|
14943
|
+
},
|
|
14944
|
+
get post() {
|
|
14945
|
+
var _a;
|
|
14946
|
+
if (stream.referenceType !== 'post')
|
|
14947
|
+
return;
|
|
14948
|
+
return (_a = pullFromCache(['post', 'get', stream.referenceId])) === null || _a === void 0 ? void 0 : _a.data;
|
|
14949
|
+
},
|
|
14950
|
+
get community() {
|
|
14951
|
+
var _a;
|
|
14952
|
+
if (stream.targetType !== 'community')
|
|
14953
|
+
return;
|
|
14954
|
+
return (_a = pullFromCache(['community', 'get', stream.targetId])) === null || _a === void 0 ? void 0 : _a.data;
|
|
14955
|
+
},
|
|
14956
|
+
get user() {
|
|
14957
|
+
var _a;
|
|
14958
|
+
return (_a = pullFromCache(['user', 'get', stream.userId])) === null || _a === void 0 ? void 0 : _a.data;
|
|
14959
|
+
},
|
|
14960
|
+
get childStreams() {
|
|
14961
|
+
if (!stream.childStreamIds || stream.childStreamIds.length === 0)
|
|
14962
|
+
return [];
|
|
14963
|
+
return stream.childStreamIds
|
|
14964
|
+
.map(id => {
|
|
14965
|
+
var _a;
|
|
14966
|
+
const streamCache = (_a = pullFromCache(['stream', 'get', id])) === null || _a === void 0 ? void 0 : _a.data;
|
|
14967
|
+
if (!streamCache)
|
|
14968
|
+
return undefined;
|
|
14969
|
+
return streamLinkedObject(streamCache);
|
|
14970
|
+
})
|
|
14971
|
+
.filter(isNonNullable);
|
|
14972
|
+
}, getLiveChat: () => getLiveChat$1(stream), isBanned: !stream.watcherUrl, watcherUrl: null, get [GET_WATCHER_URLS]() {
|
|
14973
|
+
return stream.watcherUrl;
|
|
14974
|
+
} });
|
|
14975
|
+
};
|
|
14976
|
+
|
|
14977
|
+
const commentLinkedObject = (comment) => {
|
|
14978
|
+
return Object.assign(Object.assign({}, comment), { get target() {
|
|
14979
|
+
const commentTypes = {
|
|
14980
|
+
type: comment.targetType,
|
|
14981
|
+
};
|
|
14982
|
+
if (comment.targetType === 'user') {
|
|
14983
|
+
return Object.assign(Object.assign({}, commentTypes), { userId: comment.targetId });
|
|
14984
|
+
}
|
|
14985
|
+
if (commentTypes.type === 'content') {
|
|
14986
|
+
return Object.assign(Object.assign({}, commentTypes), { contentId: comment.targetId });
|
|
14987
|
+
}
|
|
14988
|
+
if (commentTypes.type === 'community') {
|
|
14989
|
+
const cacheData = pullFromCache([
|
|
14990
|
+
'communityUsers',
|
|
14991
|
+
'get',
|
|
14992
|
+
`${comment.targetId}#${comment.userId}`,
|
|
14993
|
+
]);
|
|
14994
|
+
return Object.assign(Object.assign({}, commentTypes), { communityId: comment.targetId, creatorMember: cacheData === null || cacheData === void 0 ? void 0 : cacheData.data });
|
|
14995
|
+
}
|
|
14996
|
+
return {
|
|
14997
|
+
type: 'unknown',
|
|
14998
|
+
};
|
|
14999
|
+
},
|
|
15000
|
+
get creator() {
|
|
15001
|
+
const cacheData = pullFromCache(['user', 'get', comment.userId]);
|
|
15002
|
+
if (cacheData === null || cacheData === void 0 ? void 0 : cacheData.data)
|
|
15003
|
+
return userLinkedObject(cacheData.data);
|
|
15004
|
+
return undefined;
|
|
15005
|
+
},
|
|
15006
|
+
get childrenComment() {
|
|
15007
|
+
return comment.children
|
|
15008
|
+
.map(childCommentId => {
|
|
15009
|
+
const commentCache = pullFromCache([
|
|
15010
|
+
'comment',
|
|
15011
|
+
'get',
|
|
15012
|
+
childCommentId,
|
|
15013
|
+
]);
|
|
15014
|
+
if (!(commentCache === null || commentCache === void 0 ? void 0 : commentCache.data))
|
|
15015
|
+
return;
|
|
15016
|
+
return commentCache === null || commentCache === void 0 ? void 0 : commentCache.data;
|
|
15017
|
+
})
|
|
15018
|
+
.filter(isNonNullable)
|
|
15019
|
+
.map(item => commentLinkedObject(item));
|
|
15020
|
+
} });
|
|
15021
|
+
};
|
|
15022
|
+
|
|
15023
|
+
function isAmityImagePost(post) {
|
|
15024
|
+
return !!(post.data &&
|
|
15025
|
+
typeof post.data !== 'string' &&
|
|
15026
|
+
'fileId' in post.data &&
|
|
15027
|
+
post.dataType === 'image');
|
|
15028
|
+
}
|
|
15029
|
+
function isAmityFilePost(post) {
|
|
15030
|
+
return !!(post.data &&
|
|
15031
|
+
typeof post.data !== 'string' &&
|
|
15032
|
+
'fileId' in post.data &&
|
|
15033
|
+
post.dataType === 'file');
|
|
15034
|
+
}
|
|
15035
|
+
function isAmityVideoPost(post) {
|
|
15036
|
+
return !!(post.data &&
|
|
15037
|
+
typeof post.data !== 'string' &&
|
|
15038
|
+
'videoFileId' in post.data &&
|
|
15039
|
+
'thumbnailFileId' in post.data &&
|
|
15040
|
+
post.dataType === 'video');
|
|
15041
|
+
}
|
|
15042
|
+
function isAmityLivestreamPost(post) {
|
|
15043
|
+
return !!(post.data &&
|
|
15044
|
+
typeof post.data !== 'string' &&
|
|
15045
|
+
'streamId' in post.data &&
|
|
15046
|
+
post.dataType === 'liveStream');
|
|
15047
|
+
}
|
|
15048
|
+
function isAmityPollPost(post) {
|
|
15049
|
+
return !!(post.data &&
|
|
15050
|
+
typeof post.data !== 'string' &&
|
|
15051
|
+
'pollId' in post.data &&
|
|
15052
|
+
post.dataType === 'poll');
|
|
15053
|
+
}
|
|
15054
|
+
function isAmityClipPost(post) {
|
|
15055
|
+
return !!(post.data &&
|
|
15056
|
+
typeof post.data !== 'string' &&
|
|
15057
|
+
'fileId' in post.data &&
|
|
15058
|
+
post.dataType === 'clip');
|
|
15059
|
+
}
|
|
15060
|
+
function isAmityAudioPost(post) {
|
|
15061
|
+
return !!(post.data &&
|
|
15062
|
+
typeof post.data !== 'string' &&
|
|
15063
|
+
'fileId' in post.data &&
|
|
15064
|
+
post.dataType === 'audio');
|
|
15065
|
+
}
|
|
15066
|
+
function isAmityRoomPost(post) {
|
|
15067
|
+
return !!(post.data &&
|
|
15068
|
+
typeof post.data !== 'string' &&
|
|
15069
|
+
'roomId' in post.data &&
|
|
15070
|
+
post.dataType === 'room');
|
|
15071
|
+
}
|
|
15072
|
+
|
|
14969
15073
|
/**
|
|
14970
15074
|
* ```js
|
|
14971
|
-
* import {
|
|
14972
|
-
* const
|
|
15075
|
+
* import { RoomRepository } from '@amityco/ts-sdk-react-native'
|
|
15076
|
+
* const stream = await getStream('foobar')
|
|
14973
15077
|
* ```
|
|
14974
15078
|
*
|
|
14975
|
-
*
|
|
15079
|
+
* Fetches a {@link Amity.Channel} object linked with a current stream
|
|
14976
15080
|
*
|
|
14977
|
-
* @param
|
|
14978
|
-
* @returns
|
|
15081
|
+
* @param stream {@link Amity.Stream} that has linked live channel
|
|
15082
|
+
* @returns the associated {@link Amity.Channel<'live'>} object
|
|
14979
15083
|
*
|
|
14980
|
-
* @category
|
|
15084
|
+
* @category Stream API
|
|
14981
15085
|
* @async
|
|
14982
15086
|
*/
|
|
14983
|
-
const
|
|
15087
|
+
const getLiveChat = async (room) => {
|
|
14984
15088
|
var _a;
|
|
14985
15089
|
const client = getActiveClient();
|
|
14986
|
-
client.log('
|
|
14987
|
-
|
|
14988
|
-
|
|
14989
|
-
|
|
14990
|
-
|
|
14991
|
-
|
|
14992
|
-
|
|
14993
|
-
|
|
14994
|
-
|
|
14995
|
-
|
|
14996
|
-
|
|
14997
|
-
if (community) {
|
|
14998
|
-
const updatedCommunity = Object.assign(Object.assign({}, community), { isJoined: true });
|
|
14999
|
-
upsertInCache(['community', 'get', communityId], updatedCommunity);
|
|
15000
|
-
}
|
|
15090
|
+
client.log('room/getLiveChat', room.roomId);
|
|
15091
|
+
if (room.liveChannelId) {
|
|
15092
|
+
const channel = (_a = pullFromCache([
|
|
15093
|
+
'channel',
|
|
15094
|
+
'get',
|
|
15095
|
+
room.liveChannelId,
|
|
15096
|
+
])) === null || _a === void 0 ? void 0 : _a.data;
|
|
15097
|
+
if (channel)
|
|
15098
|
+
return channelLinkedObject(constructChannelObject(channel));
|
|
15099
|
+
const { data } = await getChannel$1(room.liveChannelId);
|
|
15100
|
+
return channelLinkedObject(constructChannelObject(data));
|
|
15001
15101
|
}
|
|
15002
|
-
|
|
15003
|
-
|
|
15004
|
-
|
|
15005
|
-
|
|
15006
|
-
|
|
15007
|
-
|
|
15008
|
-
|
|
15009
|
-
/**
|
|
15010
|
-
* TODO: handle cache receive cache option, and cache policy
|
|
15011
|
-
* TODO: check if querybyIds is supported
|
|
15012
|
-
*/
|
|
15013
|
-
class JoinRequestsPaginationController extends PaginationController {
|
|
15014
|
-
async getRequest(queryParams, token) {
|
|
15015
|
-
const { limit = 20, communityId } = queryParams, params = __rest(queryParams, ["limit", "communityId"]);
|
|
15016
|
-
const options = token ? { token } : { limit };
|
|
15017
|
-
const { data: queryResponse } = await this.http.get(`/api/v4/communities/${communityId}/join`, {
|
|
15018
|
-
params: Object.assign(Object.assign({}, params), { options }),
|
|
15102
|
+
// No Channel ID
|
|
15103
|
+
// streamer: create a new live channel
|
|
15104
|
+
if (room.createdBy === client.userId) {
|
|
15105
|
+
const { data: channel } = await createChannel({
|
|
15106
|
+
type: 'live',
|
|
15107
|
+
postId: room.referenceId,
|
|
15108
|
+
roomId: room.roomId,
|
|
15019
15109
|
});
|
|
15020
|
-
|
|
15021
|
-
|
|
15022
|
-
|
|
15023
|
-
|
|
15024
|
-
|
|
15025
|
-
(function (EnumJoinRequestAction) {
|
|
15026
|
-
EnumJoinRequestAction["OnLocalJoinRequestCreated"] = "OnLocalJoinRequestCreated";
|
|
15027
|
-
EnumJoinRequestAction["OnLocalJoinRequestUpdated"] = "OnLocalJoinRequestUpdated";
|
|
15028
|
-
EnumJoinRequestAction["OnLocalJoinRequestDeleted"] = "OnLocalJoinRequestDeleted";
|
|
15029
|
-
})(EnumJoinRequestAction$1 || (EnumJoinRequestAction$1 = {}));
|
|
15030
|
-
|
|
15031
|
-
class JoinRequestsQueryStreamController extends QueryStreamController {
|
|
15032
|
-
constructor(query, cacheKey, notifyChange, preparePayload) {
|
|
15033
|
-
super(query, cacheKey);
|
|
15034
|
-
this.notifyChange = notifyChange;
|
|
15035
|
-
this.preparePayload = preparePayload;
|
|
15036
|
-
}
|
|
15037
|
-
async saveToMainDB(response) {
|
|
15038
|
-
const processedPayload = await this.preparePayload(response);
|
|
15039
|
-
const client = getActiveClient();
|
|
15040
|
-
const cachedAt = client.cache && Date.now();
|
|
15041
|
-
if (client.cache) {
|
|
15042
|
-
ingestInCache(processedPayload, { cachedAt });
|
|
15043
|
-
}
|
|
15044
|
-
}
|
|
15045
|
-
appendToQueryStream(response, direction, refresh = false) {
|
|
15046
|
-
var _a, _b;
|
|
15047
|
-
if (refresh) {
|
|
15048
|
-
pushToCache(this.cacheKey, {
|
|
15049
|
-
data: response.joinRequests.map(joinRequest => getResolver('joinRequest')({ joinRequestId: joinRequest._id })),
|
|
15050
|
-
});
|
|
15051
|
-
}
|
|
15052
|
-
else {
|
|
15053
|
-
const collection = (_a = pullFromCache(this.cacheKey)) === null || _a === void 0 ? void 0 : _a.data;
|
|
15054
|
-
const joinRequests = (_b = collection === null || collection === void 0 ? void 0 : collection.data) !== null && _b !== void 0 ? _b : [];
|
|
15055
|
-
pushToCache(this.cacheKey, Object.assign(Object.assign({}, collection), { data: [
|
|
15056
|
-
...new Set([
|
|
15057
|
-
...joinRequests,
|
|
15058
|
-
...response.joinRequests.map(joinRequest => getResolver('joinRequest')({ joinRequestId: joinRequest._id })),
|
|
15059
|
-
]),
|
|
15060
|
-
] }));
|
|
15061
|
-
}
|
|
15062
|
-
}
|
|
15063
|
-
reactor(action) {
|
|
15064
|
-
return (joinRequest) => {
|
|
15065
|
-
var _a;
|
|
15066
|
-
const collection = (_a = pullFromCache(this.cacheKey)) === null || _a === void 0 ? void 0 : _a.data;
|
|
15067
|
-
if (!collection)
|
|
15068
|
-
return;
|
|
15069
|
-
if (action === EnumJoinRequestAction$1.OnLocalJoinRequestUpdated) {
|
|
15070
|
-
const isExist = collection.data.find(id => id === joinRequest[0].joinRequestId);
|
|
15071
|
-
if (!isExist)
|
|
15072
|
-
return;
|
|
15073
|
-
}
|
|
15074
|
-
if (action === EnumJoinRequestAction$1.OnLocalJoinRequestCreated) {
|
|
15075
|
-
collection.data = [
|
|
15076
|
-
...new Set([
|
|
15077
|
-
...joinRequest.map(joinRequest => joinRequest.joinRequestId),
|
|
15078
|
-
...collection.data,
|
|
15079
|
-
]),
|
|
15080
|
-
];
|
|
15081
|
-
}
|
|
15082
|
-
if (action === EnumJoinRequestAction$1.OnLocalJoinRequestDeleted) {
|
|
15083
|
-
collection.data = collection.data.filter(id => id !== joinRequest[0].joinRequestId);
|
|
15084
|
-
}
|
|
15085
|
-
pushToCache(this.cacheKey, collection);
|
|
15086
|
-
this.notifyChange({ origin: "event" /* Amity.LiveDataOrigin.EVENT */, loading: false });
|
|
15087
|
-
};
|
|
15088
|
-
}
|
|
15089
|
-
subscribeRTE(createSubscriber) {
|
|
15090
|
-
return createSubscriber.map(subscriber => subscriber.fn(this.reactor(subscriber.action)));
|
|
15110
|
+
// Update channelId to stream object in cache
|
|
15111
|
+
mergeInCache(['room', 'get', room.roomId], {
|
|
15112
|
+
liveChannelId: channel.channelId,
|
|
15113
|
+
});
|
|
15114
|
+
return channel;
|
|
15091
15115
|
}
|
|
15092
|
-
|
|
15093
|
-
|
|
15094
|
-
/**
|
|
15095
|
-
* ```js
|
|
15096
|
-
* import { onJoinRequestCreated } from '@amityco/ts-sdk-react-native'
|
|
15097
|
-
* const dispose = onJoinRequestCreated(data => {
|
|
15098
|
-
* // ...
|
|
15099
|
-
* })
|
|
15100
|
-
* ```
|
|
15101
|
-
*
|
|
15102
|
-
* Fired when an {@link Amity.CommunityJoinRequestPayload} has been created
|
|
15103
|
-
*
|
|
15104
|
-
* @param callback The function to call when the event was fired
|
|
15105
|
-
* @returns an {@link Amity.Unsubscriber} function to stop listening
|
|
15106
|
-
*
|
|
15107
|
-
* @category JoinRequest Events
|
|
15108
|
-
*/
|
|
15109
|
-
const onJoinRequestCreated = (callback) => {
|
|
15110
|
-
const client = getActiveClient();
|
|
15111
|
-
const disposers = [
|
|
15112
|
-
createEventSubscriber(client, 'onJoinRequestCreated', 'local.joinRequest.created', payload => callback(payload)),
|
|
15113
|
-
];
|
|
15114
|
-
return () => {
|
|
15115
|
-
disposers.forEach(fn => fn());
|
|
15116
|
-
};
|
|
15117
|
-
};
|
|
15118
|
-
|
|
15119
|
-
/**
|
|
15120
|
-
* ```js
|
|
15121
|
-
* import { onJoinRequestUpdated } from '@amityco/ts-sdk-react-native'
|
|
15122
|
-
* const dispose = onJoinRequestUpdated(data => {
|
|
15123
|
-
* // ...
|
|
15124
|
-
* })
|
|
15125
|
-
* ```
|
|
15126
|
-
*
|
|
15127
|
-
* Fired when an {@link Amity.CommunityJoinRequestPayload} has been created
|
|
15128
|
-
*
|
|
15129
|
-
* @param callback The function to call when the event was fired
|
|
15130
|
-
* @returns an {@link Amity.Unsubscriber} function to stop listening
|
|
15131
|
-
*
|
|
15132
|
-
* @category JoinRequest Events
|
|
15133
|
-
*/
|
|
15134
|
-
const onJoinRequestUpdated = (callback) => {
|
|
15135
|
-
const client = getActiveClient();
|
|
15136
|
-
const disposers = [
|
|
15137
|
-
createEventSubscriber(client, 'onJoinRequestUpdated', 'local.joinRequest.updated', payload => callback(payload)),
|
|
15138
|
-
];
|
|
15139
|
-
return () => {
|
|
15140
|
-
disposers.forEach(fn => fn());
|
|
15141
|
-
};
|
|
15116
|
+
// watcher: return undefined
|
|
15117
|
+
return undefined;
|
|
15142
15118
|
};
|
|
15143
15119
|
|
|
15144
15120
|
/**
|
|
15145
|
-
*
|
|
15146
|
-
*
|
|
15147
|
-
* const dispose = onJoinRequestDeleted(data => {
|
|
15148
|
-
* // ...
|
|
15149
|
-
* })
|
|
15150
|
-
* ```
|
|
15151
|
-
*
|
|
15152
|
-
* Fired when an {@link Amity.CommunityJoinRequestPayload} has been created
|
|
15153
|
-
*
|
|
15154
|
-
* @param callback The function to call when the event was fired
|
|
15155
|
-
* @returns an {@link Amity.Unsubscriber} function to stop listening
|
|
15156
|
-
*
|
|
15157
|
-
* @category JoinRequest Events
|
|
15121
|
+
* WatchSessionStorage manages watch session data in memory
|
|
15122
|
+
* Similar to UsageCollector for stream watch minutes
|
|
15158
15123
|
*/
|
|
15159
|
-
|
|
15160
|
-
|
|
15161
|
-
|
|
15162
|
-
createEventSubscriber(client, 'onJoinRequestDeleted', 'local.joinRequest.deleted', payload => callback(payload)),
|
|
15163
|
-
];
|
|
15164
|
-
return () => {
|
|
15165
|
-
disposers.forEach(fn => fn());
|
|
15166
|
-
};
|
|
15167
|
-
};
|
|
15168
|
-
|
|
15169
|
-
class JoinRequestsLiveCollectionController extends LiveCollectionController {
|
|
15170
|
-
constructor(query, callback) {
|
|
15171
|
-
const queryStreamId = hash__default["default"](query);
|
|
15172
|
-
const cacheKey = ['joinRequest', 'collection', queryStreamId];
|
|
15173
|
-
const paginationController = new JoinRequestsPaginationController(query);
|
|
15174
|
-
super(paginationController, queryStreamId, cacheKey, callback);
|
|
15175
|
-
this.query = query;
|
|
15176
|
-
this.queryStreamController = new JoinRequestsQueryStreamController(this.query, this.cacheKey, this.notifyChange.bind(this), prepareCommunityJoinRequestPayload);
|
|
15177
|
-
this.callback = callback.bind(this);
|
|
15178
|
-
this.loadPage({ initial: true });
|
|
15124
|
+
class WatchSessionStorage {
|
|
15125
|
+
constructor() {
|
|
15126
|
+
this.sessions = new Map();
|
|
15179
15127
|
}
|
|
15180
|
-
|
|
15181
|
-
|
|
15182
|
-
|
|
15183
|
-
|
|
15184
|
-
|
|
15185
|
-
|
|
15186
|
-
|
|
15187
|
-
|
|
15188
|
-
|
|
15128
|
+
/**
|
|
15129
|
+
* Add a new watch session
|
|
15130
|
+
*/
|
|
15131
|
+
addSession(session) {
|
|
15132
|
+
this.sessions.set(session.sessionId, session);
|
|
15133
|
+
}
|
|
15134
|
+
/**
|
|
15135
|
+
* Get a watch session by sessionId
|
|
15136
|
+
*/
|
|
15137
|
+
getSession(sessionId) {
|
|
15138
|
+
return this.sessions.get(sessionId);
|
|
15189
15139
|
}
|
|
15190
|
-
|
|
15191
|
-
|
|
15140
|
+
/**
|
|
15141
|
+
* Update a watch session
|
|
15142
|
+
*/
|
|
15143
|
+
updateSession(sessionId, updates) {
|
|
15144
|
+
const session = this.sessions.get(sessionId);
|
|
15145
|
+
if (session) {
|
|
15146
|
+
this.sessions.set(sessionId, Object.assign(Object.assign({}, session), updates));
|
|
15147
|
+
}
|
|
15192
15148
|
}
|
|
15193
|
-
|
|
15194
|
-
|
|
15195
|
-
|
|
15149
|
+
/**
|
|
15150
|
+
* Get all sessions with a specific sync state
|
|
15151
|
+
*/
|
|
15152
|
+
getSessionsByState(state) {
|
|
15153
|
+
return Array.from(this.sessions.values()).filter(session => session.syncState === state);
|
|
15196
15154
|
}
|
|
15197
|
-
|
|
15198
|
-
|
|
15199
|
-
|
|
15200
|
-
|
|
15201
|
-
|
|
15202
|
-
]);
|
|
15155
|
+
/**
|
|
15156
|
+
* Delete a session
|
|
15157
|
+
*/
|
|
15158
|
+
deleteSession(sessionId) {
|
|
15159
|
+
this.sessions.delete(sessionId);
|
|
15203
15160
|
}
|
|
15204
|
-
|
|
15205
|
-
|
|
15206
|
-
|
|
15207
|
-
|
|
15208
|
-
|
|
15209
|
-
const data = this.applyFilter(collection.data
|
|
15210
|
-
.map(id => pullFromCache(['joinRequest', 'get', id]))
|
|
15211
|
-
.filter(isNonNullable)
|
|
15212
|
-
.map(({ data }) => data)
|
|
15213
|
-
.map(joinRequestLinkedObject));
|
|
15214
|
-
if (!this.shouldNotify(data) && origin === 'event')
|
|
15215
|
-
return;
|
|
15216
|
-
this.callback({
|
|
15217
|
-
onNextPage: () => this.loadPage({ direction: "next" /* Amity.LiveCollectionPageDirection.NEXT */ }),
|
|
15218
|
-
data,
|
|
15219
|
-
hasNextPage: !!this.paginationController.getNextToken(),
|
|
15220
|
-
loading,
|
|
15221
|
-
error,
|
|
15222
|
-
});
|
|
15161
|
+
/**
|
|
15162
|
+
* Get all pending sessions
|
|
15163
|
+
*/
|
|
15164
|
+
getPendingSessions() {
|
|
15165
|
+
return this.getSessionsByState('PENDING');
|
|
15223
15166
|
}
|
|
15224
|
-
|
|
15225
|
-
|
|
15226
|
-
|
|
15227
|
-
|
|
15228
|
-
|
|
15229
|
-
const sortFn = (() => {
|
|
15230
|
-
switch (this.query.sortBy) {
|
|
15231
|
-
case 'firstCreated':
|
|
15232
|
-
return sortByFirstCreated;
|
|
15233
|
-
case 'lastCreated':
|
|
15234
|
-
return sortByLastCreated;
|
|
15235
|
-
default:
|
|
15236
|
-
return sortByLastCreated;
|
|
15237
|
-
}
|
|
15238
|
-
})();
|
|
15239
|
-
joinRequest = joinRequest.sort(sortFn);
|
|
15240
|
-
return joinRequest;
|
|
15167
|
+
/**
|
|
15168
|
+
* Get all syncing sessions
|
|
15169
|
+
*/
|
|
15170
|
+
getSyncingSessions() {
|
|
15171
|
+
return this.getSessionsByState('SYNCING');
|
|
15241
15172
|
}
|
|
15242
15173
|
}
|
|
15174
|
+
// Singleton instance
|
|
15175
|
+
let storageInstance = null;
|
|
15176
|
+
const getWatchSessionStorage = () => {
|
|
15177
|
+
if (!storageInstance) {
|
|
15178
|
+
storageInstance = new WatchSessionStorage();
|
|
15179
|
+
}
|
|
15180
|
+
return storageInstance;
|
|
15181
|
+
};
|
|
15243
15182
|
|
|
15244
|
-
|
|
15245
|
-
|
|
15246
|
-
*
|
|
15247
|
-
|
|
15248
|
-
|
|
15249
|
-
|
|
15250
|
-
|
|
15251
|
-
|
|
15183
|
+
const privateKey = "-----BEGIN PRIVATE KEY-----\nMIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQDAARz+hmBgi8pJ\nQb8LeY41gtHhk+ACMwRfhsn7GqpqRQNG2qU0755mzZuVDUqjQMGSo8THJB7O+OJs\nflbZRkFXlFoFOVNw1UpNOgwEQZ6wB9oRwzepTJAfF1sVhm/o/ixvXh1zDFNDy6yZ\npXyiiJHUVxqyjllZhxnwdvjoVtDs6hW6awG09bB9nh/TTejlUKXoAgzqVwu/1QMu\nUVViET495elEe19aUarEy+oL2iKeXCEvqda/pWNBdbieFyJvvZ08HN8dPuT88wq2\njZLEAth1vrwQ2IAa4ktaLcBQdLJgIkrbDvAiVZ8lQAjS/bq5vXQikTGvoPlC5bbn\nvuOM/3eLAgMBAAECggEAVZ+peHAghq2QVj71nX5lxsNCKaCyYwixSJBpfouTt7Rz\nE6PpzMOXFi1W1o+I22jDakuSM2SOQKqI/u0QefB0r0O/KVk5NrZHXk0mkrdYtxOp\nUgaGyf8UvmjB+8VqHrNKyZdk9qtmbnNj01kTTcAtmE4H39zPR7eR/8Rul94vaZbs\nwCnKJS3mLT3JxyGug6lxanveKkjG+CKC1nJQYWaxCJxaFSzbwXQPvDhB+TvrIbee\npd5v4EAyEJohpr+T9oDGGJkb/KARBZCtwLyB976PKJwwBA8MRVL1i5QwawuMiMq5\nUtnOnbGKtCeFzaLbNU0Qi8bqyims84EQxC6DOu1fkQKBgQDdvsoBsEhsOXV7hlIJ\naEd0eSJZVkdqimxH8uGoMM2FeNaOrcB6yBXqTSP0R3OIyf8eaY6yjRvP30ZNXcll\n/gD3O1Mu6YmWQdt1W2WA6pKOsUuPXasf0pdOF7IiFZKlSabz5YHXFqwVuqm8loaj\nsXel3YWqPVdHiankE7tz+3ssnQKBgQDdqi4TNdD1MdEpihx19jr0QjUiXW3939FK\nqp30HESPEGDGQzXdmJgif9HhZb+cJSuWaHEbjgBrYahvgCF+y6LbEpOD+D/dmT+s\nDEAQaR84sah6dokwPjV8fjBSrcVFjCS+doxv0d3p/9OUEeyUhFrY03nxtIEYkLIE\n/Zvn37b4RwKBgQCLENVFe9XfsaVhQ5r9dV2iyTlmh7qgMZG5CbTFs12hQGhm8McO\n+Z7s41YSJCFr/yq1WwP4LJDtrBw99vyQr1zRsG35tNLp3gGRNzGQSQyC2uQFVHw2\np+7mNewsfhUK/gbrXNsyFnDz6635rPlhfbII3sWuP2wWXFqkxE9CbMwR7QKBgQC6\nawDMzxmo2/iYArrkyevSuEuPVxvFwpF1RgAI6C0QVCnPE38dmdN4UB7mfHekje4W\nVEercMURidPp0cxZolCYBQtilUjAyL0vqC3In1/Ogjq6oy3FEMxSop1pKxMY5j+Q\nnoqFD+6deLUrddeNH7J3X4LSr4dSbX4JjG+tlgt+yQKBgQCuwTL4hA6KqeInQ0Ta\n9VQX5Qr8hFlqJz1gpymi/k63tW/Ob8yedbg3WWNWyShwRMFYyY9S81ITFWM95uL6\nvF3x9rmRjwElJw9PMwVu6dmf/CO0Z1wzXSp2VVD12gbrUD/0/d7MUoJ9LgC8X8f/\nn0txLHYGHbx+nf95+JUg6lV3hg==\n-----END PRIVATE KEY-----";
|
|
15184
|
+
/*
|
|
15185
|
+
* The crypto algorithm used for importing key and signing string
|
|
15186
|
+
*/
|
|
15187
|
+
const ALGORITHM = {
|
|
15188
|
+
name: 'RSASSA-PKCS1-v1_5',
|
|
15189
|
+
hash: { name: 'SHA-256' },
|
|
15190
|
+
};
|
|
15191
|
+
/*
|
|
15192
|
+
* IMPORTANT!
|
|
15193
|
+
* If you are recieving key from other platforms use an online tool to convert
|
|
15194
|
+
* the PKCS1 to PKCS8. For instance the key from Android SDK is of the format
|
|
15195
|
+
* PKCS1.
|
|
15252
15196
|
*
|
|
15197
|
+
* If recieving from the platform, verify if it's already in the expected
|
|
15198
|
+
* format. Otherwise the crypto.subtle.importKey will throw a DOMException
|
|
15253
15199
|
*/
|
|
15254
|
-
const
|
|
15255
|
-
|
|
15256
|
-
|
|
15257
|
-
|
|
15258
|
-
|
|
15259
|
-
|
|
15260
|
-
|
|
15261
|
-
|
|
15262
|
-
|
|
15263
|
-
|
|
15264
|
-
|
|
15265
|
-
|
|
15200
|
+
const PRIVATE_KEY_SIGNATURE = 'pkcs8';
|
|
15201
|
+
/*
|
|
15202
|
+
* Ensure that the private key in the .env follows this format
|
|
15203
|
+
*/
|
|
15204
|
+
const PEM_HEADER = '-----BEGIN PRIVATE KEY-----';
|
|
15205
|
+
const PEM_FOOTER = '-----END PRIVATE KEY-----';
|
|
15206
|
+
/*
|
|
15207
|
+
* The crypto.subtle.sign function returns an ArrayBuffer whereas the server
|
|
15208
|
+
* expects a base64 string. This util helps facilitate that process
|
|
15209
|
+
*/
|
|
15210
|
+
function base64FromArrayBuffer(buffer) {
|
|
15211
|
+
const uint8Array = new Uint8Array(buffer);
|
|
15212
|
+
let binary = '';
|
|
15213
|
+
uint8Array.forEach(byte => {
|
|
15214
|
+
binary += String.fromCharCode(byte);
|
|
15266
15215
|
});
|
|
15267
|
-
return ()
|
|
15268
|
-
log(`getJoinRequests (tmpid: ${timestamp}) > dispose`);
|
|
15269
|
-
disposers.forEach(fn => fn());
|
|
15270
|
-
};
|
|
15271
|
-
};
|
|
15272
|
-
|
|
15273
|
-
var InvitationActionsEnum;
|
|
15274
|
-
(function (InvitationActionsEnum) {
|
|
15275
|
-
InvitationActionsEnum["OnLocalInvitationCreated"] = "onLocalInvitationCreated";
|
|
15276
|
-
InvitationActionsEnum["OnLocalInvitationUpdated"] = "onLocalInvitationUpdated";
|
|
15277
|
-
InvitationActionsEnum["OnLocalInvitationCanceled"] = "onLocalInvitationCanceled";
|
|
15278
|
-
})(InvitationActionsEnum || (InvitationActionsEnum = {}));
|
|
15279
|
-
|
|
15280
|
-
class InvitationsPaginationController extends PaginationController {
|
|
15281
|
-
async getRequest(queryParams, token) {
|
|
15282
|
-
const { limit = COLLECTION_DEFAULT_PAGINATION_LIMIT } = queryParams, params = __rest(queryParams, ["limit"]);
|
|
15283
|
-
const options = token ? { token } : { limit };
|
|
15284
|
-
const { data } = await this.http.get('/api/v1/invitations', { params: Object.assign(Object.assign({}, params), { options }) });
|
|
15285
|
-
return data;
|
|
15286
|
-
}
|
|
15216
|
+
return jsBase64.btoa(binary);
|
|
15287
15217
|
}
|
|
15288
|
-
|
|
15289
|
-
|
|
15290
|
-
|
|
15291
|
-
|
|
15292
|
-
|
|
15293
|
-
|
|
15294
|
-
}
|
|
15295
|
-
async saveToMainDB(response) {
|
|
15296
|
-
const processedPayload = await this.preparePayload(response);
|
|
15297
|
-
const client = getActiveClient();
|
|
15298
|
-
const cachedAt = client.cache && Date.now();
|
|
15299
|
-
if (client.cache) {
|
|
15300
|
-
ingestInCache(processedPayload, { cachedAt });
|
|
15301
|
-
}
|
|
15218
|
+
/*
|
|
15219
|
+
* Encode ASN.1 length field
|
|
15220
|
+
*/
|
|
15221
|
+
function encodeLength(length) {
|
|
15222
|
+
if (length < 128) {
|
|
15223
|
+
return new Uint8Array([length]);
|
|
15302
15224
|
}
|
|
15303
|
-
|
|
15304
|
-
|
|
15305
|
-
if (refresh) {
|
|
15306
|
-
pushToCache(this.cacheKey, {
|
|
15307
|
-
data: response.invitations.map(getResolver('invitation')),
|
|
15308
|
-
});
|
|
15309
|
-
}
|
|
15310
|
-
else {
|
|
15311
|
-
const collection = (_a = pullFromCache(this.cacheKey)) === null || _a === void 0 ? void 0 : _a.data;
|
|
15312
|
-
const invitations = (_b = collection === null || collection === void 0 ? void 0 : collection.data) !== null && _b !== void 0 ? _b : [];
|
|
15313
|
-
pushToCache(this.cacheKey, Object.assign(Object.assign({}, collection), { data: [
|
|
15314
|
-
...new Set([...invitations, ...response.invitations.map(getResolver('invitation'))]),
|
|
15315
|
-
] }));
|
|
15316
|
-
}
|
|
15225
|
+
if (length < 256) {
|
|
15226
|
+
return new Uint8Array([0x81, length]);
|
|
15317
15227
|
}
|
|
15318
|
-
|
|
15319
|
-
|
|
15320
|
-
|
|
15321
|
-
|
|
15322
|
-
|
|
15323
|
-
|
|
15324
|
-
|
|
15325
|
-
|
|
15326
|
-
|
|
15327
|
-
|
|
15328
|
-
|
|
15329
|
-
|
|
15330
|
-
|
|
15331
|
-
|
|
15332
|
-
|
|
15333
|
-
|
|
15334
|
-
|
|
15335
|
-
|
|
15336
|
-
|
|
15337
|
-
|
|
15338
|
-
|
|
15339
|
-
|
|
15340
|
-
|
|
15341
|
-
|
|
15342
|
-
|
|
15228
|
+
// eslint-disable-next-line no-bitwise
|
|
15229
|
+
return new Uint8Array([0x82, (length >> 8) & 0xff, length & 0xff]);
|
|
15230
|
+
}
|
|
15231
|
+
/*
|
|
15232
|
+
* Convert PKCS1 private key to PKCS8 format
|
|
15233
|
+
* PKCS1 is RSA-specific format, PKCS8 is generic format that crypto.subtle requires
|
|
15234
|
+
* Android uses PKCS8EncodedKeySpec which expects PKCS8 format
|
|
15235
|
+
*/
|
|
15236
|
+
function pkcs1ToPkcs8(pkcs1) {
|
|
15237
|
+
// Algorithm identifier for RSA
|
|
15238
|
+
const algorithmIdentifier = new Uint8Array([
|
|
15239
|
+
0x30,
|
|
15240
|
+
0x0d,
|
|
15241
|
+
0x06,
|
|
15242
|
+
0x09,
|
|
15243
|
+
0x2a,
|
|
15244
|
+
0x86,
|
|
15245
|
+
0x48,
|
|
15246
|
+
0x86,
|
|
15247
|
+
0xf7,
|
|
15248
|
+
0x0d,
|
|
15249
|
+
0x01,
|
|
15250
|
+
0x01,
|
|
15251
|
+
0x01,
|
|
15252
|
+
0x05,
|
|
15253
|
+
0x00, // NULL
|
|
15254
|
+
]);
|
|
15255
|
+
// Version (INTEGER 0)
|
|
15256
|
+
const version = new Uint8Array([0x02, 0x01, 0x00]);
|
|
15257
|
+
// OCTET STRING tag + length + pkcs1 data
|
|
15258
|
+
const octetStringTag = 0x04;
|
|
15259
|
+
const octetStringLength = encodeLength(pkcs1.length);
|
|
15260
|
+
// Calculate total content length (version + algorithm + octet string)
|
|
15261
|
+
const contentLength = version.length + algorithmIdentifier.length + 1 + octetStringLength.length + pkcs1.length;
|
|
15262
|
+
// SEQUENCE tag + length
|
|
15263
|
+
const sequenceTag = 0x30;
|
|
15264
|
+
const sequenceLength = encodeLength(contentLength);
|
|
15265
|
+
// Build the PKCS8 structure
|
|
15266
|
+
const pkcs8 = new Uint8Array(1 + sequenceLength.length + contentLength);
|
|
15267
|
+
let offset = 0;
|
|
15268
|
+
pkcs8[offset] = sequenceTag;
|
|
15269
|
+
offset += 1;
|
|
15270
|
+
pkcs8.set(sequenceLength, offset);
|
|
15271
|
+
offset += sequenceLength.length;
|
|
15272
|
+
pkcs8.set(version, offset);
|
|
15273
|
+
offset += version.length;
|
|
15274
|
+
pkcs8.set(algorithmIdentifier, offset);
|
|
15275
|
+
offset += algorithmIdentifier.length;
|
|
15276
|
+
pkcs8[offset] = octetStringTag;
|
|
15277
|
+
offset += 1;
|
|
15278
|
+
pkcs8.set(octetStringLength, offset);
|
|
15279
|
+
offset += octetStringLength.length;
|
|
15280
|
+
pkcs8.set(pkcs1, offset);
|
|
15281
|
+
return pkcs8;
|
|
15282
|
+
}
|
|
15283
|
+
async function importPrivateKey(keyString) {
|
|
15284
|
+
// Remove PEM headers if present and any whitespace
|
|
15285
|
+
let base64Key = keyString;
|
|
15286
|
+
if (keyString.includes(PEM_HEADER)) {
|
|
15287
|
+
base64Key = keyString
|
|
15288
|
+
.substring(PEM_HEADER.length, keyString.length - PEM_FOOTER.length)
|
|
15289
|
+
.replace(/\s/g, '');
|
|
15343
15290
|
}
|
|
15344
|
-
|
|
15345
|
-
|
|
15291
|
+
else {
|
|
15292
|
+
base64Key = keyString.replace(/\s/g, '');
|
|
15293
|
+
}
|
|
15294
|
+
// Base64 decode to get binary data
|
|
15295
|
+
const binaryDerString = jsBase64.atob(base64Key);
|
|
15296
|
+
// Convert to Uint8Array for manipulation
|
|
15297
|
+
const pkcs1 = new Uint8Array(binaryDerString.length);
|
|
15298
|
+
for (let i = 0; i < binaryDerString.length; i += 1) {
|
|
15299
|
+
pkcs1[i] = binaryDerString.charCodeAt(i);
|
|
15346
15300
|
}
|
|
15301
|
+
// Convert PKCS1 to PKCS8 (crypto.subtle requires PKCS8)
|
|
15302
|
+
const pkcs8 = pkcs1ToPkcs8(pkcs1);
|
|
15303
|
+
// Import the key
|
|
15304
|
+
const key = await crypto.subtle.importKey(PRIVATE_KEY_SIGNATURE, pkcs8.buffer, ALGORITHM, false, ['sign']);
|
|
15305
|
+
return key;
|
|
15306
|
+
}
|
|
15307
|
+
async function createSignature({ timestamp, rooms, }) {
|
|
15308
|
+
const dataStr = rooms
|
|
15309
|
+
.map(item => Object.keys(item)
|
|
15310
|
+
.sort()
|
|
15311
|
+
.map(key => `${key}=${item[key]}`)
|
|
15312
|
+
.join('&'))
|
|
15313
|
+
.join(';');
|
|
15314
|
+
/*
|
|
15315
|
+
* nonceStr needs to be unique for each request
|
|
15316
|
+
*/
|
|
15317
|
+
const nonceStr = uuid__default["default"].v4();
|
|
15318
|
+
const signStr = `nonceStr=${nonceStr}×tamp=${timestamp}&data=${dataStr}==`;
|
|
15319
|
+
const encoder = new TextEncoder();
|
|
15320
|
+
const data = encoder.encode(signStr);
|
|
15321
|
+
const key = await importPrivateKey(privateKey);
|
|
15322
|
+
const sign = await crypto.subtle.sign(ALGORITHM, key, data);
|
|
15323
|
+
return { signature: base64FromArrayBuffer(sign), nonceStr };
|
|
15347
15324
|
}
|
|
15348
15325
|
|
|
15349
15326
|
/**
|
|
15350
|
-
*
|
|
15351
|
-
*
|
|
15352
|
-
* const dispose = onLocalInvitationCreated(data => {
|
|
15353
|
-
* // ...
|
|
15354
|
-
* })
|
|
15355
|
-
* ```
|
|
15356
|
-
*
|
|
15357
|
-
* Fired when an {@link Amity.InvitationPayload} has been created
|
|
15358
|
-
*
|
|
15359
|
-
* @param callback The function to call when the event was fired
|
|
15360
|
-
* @returns an {@link Amity.Unsubscriber} function to stop listening
|
|
15361
|
-
*
|
|
15362
|
-
* @category Invitation Events
|
|
15363
|
-
*/
|
|
15364
|
-
const onLocalInvitationCreated = (callback) => {
|
|
15365
|
-
const client = getActiveClient();
|
|
15366
|
-
const disposers = [
|
|
15367
|
-
createEventSubscriber(client, 'onLocalInvitationCreated', 'local.invitation.created', payload => callback(payload)),
|
|
15368
|
-
];
|
|
15369
|
-
return () => {
|
|
15370
|
-
disposers.forEach(fn => fn());
|
|
15371
|
-
};
|
|
15372
|
-
};
|
|
15373
|
-
|
|
15374
|
-
/**
|
|
15375
|
-
* ```js
|
|
15376
|
-
* import { onLocalInvitationUpdated } from '@amityco/ts-sdk-react-native'
|
|
15377
|
-
* const dispose = onLocalInvitationUpdated(data => {
|
|
15378
|
-
* // ...
|
|
15379
|
-
* })
|
|
15380
|
-
* ```
|
|
15381
|
-
*
|
|
15382
|
-
* Fired when an {@link Amity.InvitationPayload} has been updated
|
|
15383
|
-
*
|
|
15384
|
-
* @param callback The function to call when the event was fired
|
|
15385
|
-
* @returns an {@link Amity.Unsubscriber} function to stop listening
|
|
15386
|
-
*
|
|
15387
|
-
* @category Invitation Events
|
|
15388
|
-
*/
|
|
15389
|
-
const onLocalInvitationUpdated = (callback) => {
|
|
15390
|
-
const client = getActiveClient();
|
|
15391
|
-
const disposers = [
|
|
15392
|
-
createEventSubscriber(client, 'onLocalInvitationUpdated', 'local.invitation.updated', payload => callback(payload)),
|
|
15393
|
-
];
|
|
15394
|
-
return () => {
|
|
15395
|
-
disposers.forEach(fn => fn());
|
|
15396
|
-
};
|
|
15397
|
-
};
|
|
15398
|
-
|
|
15399
|
-
/**
|
|
15400
|
-
* ```js
|
|
15401
|
-
* import { onLocalInvitationCanceled } from '@amityco/ts-sdk-react-native'
|
|
15402
|
-
* const dispose = onLocalInvitationCanceled(data => {
|
|
15403
|
-
* // ...
|
|
15404
|
-
* })
|
|
15405
|
-
* ```
|
|
15406
|
-
*
|
|
15407
|
-
* Fired when an {@link Amity.InvitationPayload} has been deleted
|
|
15408
|
-
*
|
|
15409
|
-
* @param callback The function to call when the event was fired
|
|
15410
|
-
* @returns an {@link Amity.Unsubscriber} function to stop listening
|
|
15411
|
-
*
|
|
15412
|
-
* @category Invitation Events
|
|
15327
|
+
* Sync pending watch sessions to backend
|
|
15328
|
+
* This function implements the full sync flow with network resilience
|
|
15413
15329
|
*/
|
|
15414
|
-
|
|
15415
|
-
const
|
|
15416
|
-
|
|
15417
|
-
|
|
15418
|
-
|
|
15419
|
-
|
|
15420
|
-
disposers.forEach(fn => fn());
|
|
15421
|
-
};
|
|
15422
|
-
};
|
|
15423
|
-
|
|
15424
|
-
class InvitationsLiveCollectionController extends LiveCollectionController {
|
|
15425
|
-
constructor(query, callback) {
|
|
15426
|
-
const queryStreamId = hash__default["default"](query);
|
|
15427
|
-
const cacheKey = ['invitation', 'collection', queryStreamId];
|
|
15428
|
-
const paginationController = new InvitationsPaginationController(query);
|
|
15429
|
-
super(paginationController, queryStreamId, cacheKey, callback);
|
|
15430
|
-
this.query = query;
|
|
15431
|
-
this.queryStreamController = new InvitationsQueryStreamController(this.query, this.cacheKey, this.notifyChange.bind(this), prepareInvitationPayload);
|
|
15432
|
-
this.callback = callback.bind(this);
|
|
15433
|
-
this.loadPage({ initial: true });
|
|
15330
|
+
async function syncWatchSessions() {
|
|
15331
|
+
const storage = getWatchSessionStorage();
|
|
15332
|
+
// Get all pending sessions
|
|
15333
|
+
const pendingSessions = storage.getPendingSessions();
|
|
15334
|
+
if (pendingSessions.length === 0) {
|
|
15335
|
+
return true;
|
|
15434
15336
|
}
|
|
15435
|
-
|
|
15436
|
-
|
|
15437
|
-
|
|
15438
|
-
|
|
15439
|
-
|
|
15440
|
-
|
|
15441
|
-
|
|
15442
|
-
|
|
15337
|
+
try {
|
|
15338
|
+
const timestamp = new Date().toISOString();
|
|
15339
|
+
// Convert sessions to API format - always include all fields like syncUsage does
|
|
15340
|
+
const rooms = pendingSessions.map(session => ({
|
|
15341
|
+
sessionId: session.sessionId,
|
|
15342
|
+
roomId: session.roomId,
|
|
15343
|
+
watchSeconds: session.watchSeconds,
|
|
15344
|
+
startTime: session.startTime.toISOString(),
|
|
15345
|
+
endTime: session.endTime ? session.endTime.toISOString() : '',
|
|
15346
|
+
}));
|
|
15347
|
+
// Create signature (reuse from stream feature) - pass directly like syncUsage
|
|
15348
|
+
const signatureData = await createSignature({
|
|
15349
|
+
timestamp,
|
|
15350
|
+
rooms,
|
|
15351
|
+
});
|
|
15352
|
+
if (!signatureData || !signatureData.signature) {
|
|
15353
|
+
throw new Error('Signature is undefined');
|
|
15443
15354
|
}
|
|
15444
|
-
|
|
15445
|
-
|
|
15446
|
-
|
|
15447
|
-
|
|
15448
|
-
|
|
15449
|
-
|
|
15450
|
-
|
|
15451
|
-
|
|
15452
|
-
|
|
15453
|
-
|
|
15454
|
-
|
|
15455
|
-
|
|
15456
|
-
|
|
15457
|
-
|
|
15458
|
-
|
|
15459
|
-
|
|
15460
|
-
|
|
15461
|
-
|
|
15462
|
-
|
|
15463
|
-
action: InvitationActionsEnum.OnLocalInvitationCanceled,
|
|
15464
|
-
},
|
|
15465
|
-
]);
|
|
15466
|
-
}
|
|
15467
|
-
notifyChange({ origin, loading, error }) {
|
|
15468
|
-
var _a, _b;
|
|
15469
|
-
const collection = (_a = pullFromCache(this.cacheKey)) === null || _a === void 0 ? void 0 : _a.data;
|
|
15470
|
-
if (!collection)
|
|
15471
|
-
return;
|
|
15472
|
-
const data = this.applyFilter((_b = collection.data
|
|
15473
|
-
.map(id => pullFromCache(['invitation', 'get', id]))
|
|
15474
|
-
.filter(isNonNullable)
|
|
15475
|
-
.map(({ data }) => invitationLinkedObject(data))) !== null && _b !== void 0 ? _b : []);
|
|
15476
|
-
if (!this.shouldNotify(data) && origin === 'event')
|
|
15477
|
-
return;
|
|
15478
|
-
this.callback({
|
|
15479
|
-
onNextPage: () => this.loadPage({ direction: "next" /* Amity.LiveCollectionPageDirection.NEXT */ }),
|
|
15480
|
-
data,
|
|
15481
|
-
hasNextPage: !!this.paginationController.getNextToken(),
|
|
15482
|
-
loading,
|
|
15483
|
-
error,
|
|
15355
|
+
// Update sync state to SYNCING
|
|
15356
|
+
pendingSessions.forEach(session => {
|
|
15357
|
+
storage.updateSession(session.sessionId, { syncState: 'SYNCING' });
|
|
15358
|
+
});
|
|
15359
|
+
const payload = {
|
|
15360
|
+
signature: signatureData.signature,
|
|
15361
|
+
nonceStr: signatureData.nonceStr,
|
|
15362
|
+
timestamp,
|
|
15363
|
+
rooms,
|
|
15364
|
+
};
|
|
15365
|
+
const client = getActiveClient();
|
|
15366
|
+
// Send to backend
|
|
15367
|
+
await client.http.post('/api/v3/user-event/room', payload);
|
|
15368
|
+
// Success - update to SYNCED
|
|
15369
|
+
pendingSessions.forEach(session => {
|
|
15370
|
+
storage.updateSession(session.sessionId, {
|
|
15371
|
+
syncState: 'SYNCED',
|
|
15372
|
+
syncedAt: new Date(),
|
|
15373
|
+
});
|
|
15484
15374
|
});
|
|
15375
|
+
return true;
|
|
15485
15376
|
}
|
|
15486
|
-
|
|
15487
|
-
|
|
15488
|
-
|
|
15489
|
-
|
|
15490
|
-
|
|
15491
|
-
|
|
15492
|
-
|
|
15493
|
-
|
|
15494
|
-
|
|
15495
|
-
|
|
15496
|
-
|
|
15497
|
-
|
|
15498
|
-
|
|
15499
|
-
|
|
15500
|
-
|
|
15501
|
-
|
|
15502
|
-
|
|
15503
|
-
|
|
15504
|
-
case 'lastCreated':
|
|
15505
|
-
return sortByLastCreated;
|
|
15506
|
-
default:
|
|
15507
|
-
return sortByLastCreated;
|
|
15377
|
+
catch (err) {
|
|
15378
|
+
console.error('[SDK syncWatchSessions] ERROR caught:', (err === null || err === void 0 ? void 0 : err.message) || err);
|
|
15379
|
+
// Failure - update back to PENDING and increment retry count
|
|
15380
|
+
pendingSessions.forEach(session => {
|
|
15381
|
+
const currentSession = storage.getSession(session.sessionId);
|
|
15382
|
+
if (currentSession) {
|
|
15383
|
+
const newRetryCount = currentSession.retryCount + 1;
|
|
15384
|
+
if (newRetryCount >= 3) {
|
|
15385
|
+
// Delete session if retry count exceeds 3
|
|
15386
|
+
storage.deleteSession(session.sessionId);
|
|
15387
|
+
}
|
|
15388
|
+
else {
|
|
15389
|
+
// Update to PENDING with incremented retry count
|
|
15390
|
+
storage.updateSession(session.sessionId, {
|
|
15391
|
+
syncState: 'PENDING',
|
|
15392
|
+
retryCount: newRetryCount,
|
|
15393
|
+
});
|
|
15394
|
+
}
|
|
15508
15395
|
}
|
|
15509
|
-
})
|
|
15510
|
-
|
|
15511
|
-
return invitations;
|
|
15396
|
+
});
|
|
15397
|
+
return false;
|
|
15512
15398
|
}
|
|
15513
15399
|
}
|
|
15514
15400
|
|
|
15515
15401
|
/**
|
|
15516
|
-
*
|
|
15517
|
-
*
|
|
15518
|
-
* @param params the query parameters
|
|
15519
|
-
* @param callback the callback to be called when the invitations are updated
|
|
15520
|
-
* @returns invitations
|
|
15521
|
-
*
|
|
15522
|
-
* @category Invitation Live Collection
|
|
15523
|
-
*
|
|
15402
|
+
* Room statuses that are considered watchable
|
|
15524
15403
|
*/
|
|
15525
|
-
const
|
|
15526
|
-
|
|
15527
|
-
|
|
15528
|
-
|
|
15529
|
-
|
|
15530
|
-
const
|
|
15531
|
-
|
|
15532
|
-
|
|
15533
|
-
|
|
15534
|
-
|
|
15535
|
-
|
|
15536
|
-
|
|
15404
|
+
const WATCHABLE_ROOM_STATUSES = ['live', 'recorded'];
|
|
15405
|
+
/**
|
|
15406
|
+
* Generate a random jitter delay between 5 and 30 seconds
|
|
15407
|
+
*/
|
|
15408
|
+
const getJitterDelay = () => {
|
|
15409
|
+
const minDelay = 5000; // 5 seconds
|
|
15410
|
+
const maxDelay = 30000; // 30 seconds
|
|
15411
|
+
return Math.floor(Math.random() * (maxDelay - minDelay + 1)) + minDelay;
|
|
15412
|
+
};
|
|
15413
|
+
/**
|
|
15414
|
+
* Wait for network connection with timeout
|
|
15415
|
+
* @param maxWaitTime Maximum time to wait in milliseconds (default: 60000 = 60 seconds)
|
|
15416
|
+
* @returns Promise that resolves when network is available or timeout is reached
|
|
15417
|
+
*/
|
|
15418
|
+
const waitForNetwork = (maxWaitTime = 60000) => {
|
|
15419
|
+
return new Promise(resolve => {
|
|
15420
|
+
// Simple check - if navigator.onLine is available, use it
|
|
15421
|
+
// Otherwise, assume network is available
|
|
15422
|
+
if (typeof navigator === 'undefined' || typeof navigator.onLine === 'undefined') {
|
|
15423
|
+
resolve();
|
|
15424
|
+
return;
|
|
15425
|
+
}
|
|
15426
|
+
const startTime = Date.now();
|
|
15427
|
+
const checkInterval = 1000; // 1 second
|
|
15428
|
+
const checkConnection = () => {
|
|
15429
|
+
if (navigator.onLine || Date.now() - startTime >= maxWaitTime) {
|
|
15430
|
+
resolve();
|
|
15431
|
+
}
|
|
15432
|
+
else {
|
|
15433
|
+
setTimeout(checkConnection, checkInterval);
|
|
15434
|
+
}
|
|
15435
|
+
};
|
|
15436
|
+
checkConnection();
|
|
15537
15437
|
});
|
|
15538
|
-
return () => {
|
|
15539
|
-
log(`getInvitations (tmpid: ${timestamp}) > dispose`);
|
|
15540
|
-
disposers.forEach(fn => fn());
|
|
15541
|
-
};
|
|
15542
15438
|
};
|
|
15439
|
+
/**
|
|
15440
|
+
* AmityRoomAnalytics provides analytics capabilities for room watch sessions
|
|
15441
|
+
*/
|
|
15442
|
+
class AmityRoomAnalytics {
|
|
15443
|
+
constructor(room) {
|
|
15444
|
+
this.storage = getWatchSessionStorage();
|
|
15445
|
+
this.client = getActiveClient();
|
|
15446
|
+
this.room = room;
|
|
15447
|
+
}
|
|
15448
|
+
/**
|
|
15449
|
+
* Create a new watch session for the current room
|
|
15450
|
+
* @param startedAt The timestamp when watching started
|
|
15451
|
+
* @returns Promise<string> sessionId unique identifier for this watch session
|
|
15452
|
+
* @throws ASCApiError if room is not in watchable state (not LIVE or RECORDED)
|
|
15453
|
+
*/
|
|
15454
|
+
async createWatchSession(startedAt) {
|
|
15455
|
+
// Validate room status
|
|
15456
|
+
if (!WATCHABLE_ROOM_STATUSES.includes(this.room.status)) {
|
|
15457
|
+
throw new ASCApiError('room is not in watchable state', 500000 /* Amity.ServerError.BUSINESS_ERROR */, "error" /* Amity.ErrorLevel.ERROR */);
|
|
15458
|
+
}
|
|
15459
|
+
// Generate session ID with prefix
|
|
15460
|
+
const prefix = this.room.status === 'live' ? 'room_' : 'room_playback_';
|
|
15461
|
+
const sessionId = prefix + uuid__default["default"].v4();
|
|
15462
|
+
// Create watch session entity
|
|
15463
|
+
const session = {
|
|
15464
|
+
sessionId,
|
|
15465
|
+
roomId: this.room.roomId,
|
|
15466
|
+
watchSeconds: 0,
|
|
15467
|
+
startTime: startedAt,
|
|
15468
|
+
endTime: null,
|
|
15469
|
+
syncState: 'PENDING',
|
|
15470
|
+
syncedAt: null,
|
|
15471
|
+
retryCount: 0,
|
|
15472
|
+
};
|
|
15473
|
+
// Persist to storage
|
|
15474
|
+
this.storage.addSession(session);
|
|
15475
|
+
return sessionId;
|
|
15476
|
+
}
|
|
15477
|
+
/**
|
|
15478
|
+
* Update an existing watch session with duration
|
|
15479
|
+
* @param sessionId The unique identifier of the watch session
|
|
15480
|
+
* @param duration The total watch duration in seconds
|
|
15481
|
+
* @param endedAt The timestamp when this update occurred
|
|
15482
|
+
* @returns Promise<void> Completion status
|
|
15483
|
+
*/
|
|
15484
|
+
async updateWatchSession(sessionId, duration, endedAt) {
|
|
15485
|
+
const session = this.storage.getSession(sessionId);
|
|
15486
|
+
if (!session) {
|
|
15487
|
+
throw new Error(`Watch session ${sessionId} not found`);
|
|
15488
|
+
}
|
|
15489
|
+
// Update session
|
|
15490
|
+
this.storage.updateSession(sessionId, {
|
|
15491
|
+
watchSeconds: duration,
|
|
15492
|
+
endTime: endedAt,
|
|
15493
|
+
});
|
|
15494
|
+
}
|
|
15495
|
+
/**
|
|
15496
|
+
* Sync all pending watch sessions to backend
|
|
15497
|
+
* This function uses jitter delay and handles network resilience
|
|
15498
|
+
*/
|
|
15499
|
+
syncPendingWatchSessions() {
|
|
15500
|
+
// Execute with jitter delay (5-30 seconds)
|
|
15501
|
+
const jitterDelay = getJitterDelay();
|
|
15502
|
+
this.client.log('room/RoomAnalytics: syncPendingWatchSessions called, jitter delay:', `${jitterDelay}ms`);
|
|
15503
|
+
setTimeout(async () => {
|
|
15504
|
+
this.client.log('room/RoomAnalytics: Jitter delay completed, starting sync process');
|
|
15505
|
+
try {
|
|
15506
|
+
// Reset any SYNCING sessions back to PENDING
|
|
15507
|
+
const syncingSessions = this.storage.getSyncingSessions();
|
|
15508
|
+
this.client.log('room/RoomAnalytics: SYNCING sessions to reset:', syncingSessions.length);
|
|
15509
|
+
syncingSessions.forEach(session => {
|
|
15510
|
+
this.storage.updateSession(session.sessionId, { syncState: 'PENDING' });
|
|
15511
|
+
});
|
|
15512
|
+
// Wait for network connection (max 60 seconds)
|
|
15513
|
+
await waitForNetwork(60000);
|
|
15514
|
+
this.client.log('room/RoomAnalytics: Network available');
|
|
15515
|
+
// Sync pending sessions
|
|
15516
|
+
this.client.log('room/RoomAnalytics: Calling syncWatchSessions()');
|
|
15517
|
+
await syncWatchSessions();
|
|
15518
|
+
this.client.log('room/RoomAnalytics: syncWatchSessions completed');
|
|
15519
|
+
}
|
|
15520
|
+
catch (error) {
|
|
15521
|
+
// Error is already handled in syncWatchSessions
|
|
15522
|
+
console.error('Failed to sync watch sessions:', error);
|
|
15523
|
+
}
|
|
15524
|
+
}, jitterDelay);
|
|
15525
|
+
}
|
|
15526
|
+
}
|
|
15543
15527
|
|
|
15544
|
-
const
|
|
15545
|
-
return Object.assign(Object.assign({},
|
|
15528
|
+
const roomLinkedObject = (room) => {
|
|
15529
|
+
return Object.assign(Object.assign({}, room), { get post() {
|
|
15546
15530
|
var _a;
|
|
15547
|
-
|
|
15548
|
-
|
|
15549
|
-
|
|
15550
|
-
if (cacheData === null || cacheData === void 0 ? void 0 : cacheData.data)
|
|
15551
|
-
return categoryLinkedObject(cacheData.data);
|
|
15552
|
-
return undefined;
|
|
15553
|
-
})
|
|
15554
|
-
.filter(category => !!category);
|
|
15531
|
+
if (room.referenceType !== 'post')
|
|
15532
|
+
return;
|
|
15533
|
+
return (_a = pullFromCache(['post', 'get', room.referenceId])) === null || _a === void 0 ? void 0 : _a.data;
|
|
15555
15534
|
},
|
|
15556
|
-
get
|
|
15535
|
+
get community() {
|
|
15557
15536
|
var _a;
|
|
15558
|
-
if (
|
|
15559
|
-
return
|
|
15560
|
-
|
|
15561
|
-
|
|
15562
|
-
|
|
15563
|
-
|
|
15564
|
-
])) === null || _a === void 0 ? void 0 : _a.data;
|
|
15565
|
-
return
|
|
15566
|
-
},
|
|
15567
|
-
|
|
15568
|
-
|
|
15569
|
-
|
|
15570
|
-
|
|
15571
|
-
|
|
15572
|
-
|
|
15573
|
-
|
|
15574
|
-
|
|
15575
|
-
|
|
15537
|
+
if (room.targetType !== 'community')
|
|
15538
|
+
return;
|
|
15539
|
+
return (_a = pullFromCache(['community', 'get', room.targetId])) === null || _a === void 0 ? void 0 : _a.data;
|
|
15540
|
+
},
|
|
15541
|
+
get user() {
|
|
15542
|
+
var _a;
|
|
15543
|
+
const user = (_a = pullFromCache(['user', 'get', room.createdBy])) === null || _a === void 0 ? void 0 : _a.data;
|
|
15544
|
+
return user ? userLinkedObject(user) : user;
|
|
15545
|
+
},
|
|
15546
|
+
get childRooms() {
|
|
15547
|
+
if (!room.childRoomIds || room.childRoomIds.length === 0)
|
|
15548
|
+
return [];
|
|
15549
|
+
return room.childRoomIds
|
|
15550
|
+
.map(id => {
|
|
15551
|
+
var _a;
|
|
15552
|
+
const roomCache = (_a = pullFromCache(['room', 'get', id])) === null || _a === void 0 ? void 0 : _a.data;
|
|
15553
|
+
if (!roomCache)
|
|
15554
|
+
return undefined;
|
|
15555
|
+
return roomLinkedObject(roomCache);
|
|
15556
|
+
})
|
|
15557
|
+
.filter(isNonNullable);
|
|
15558
|
+
}, participants: room.participants.map(participant => (Object.assign(Object.assign({}, participant), { get user() {
|
|
15559
|
+
var _a;
|
|
15560
|
+
const user = (_a = pullFromCache(['user', 'get', participant.userId])) === null || _a === void 0 ? void 0 : _a.data;
|
|
15561
|
+
return user ? userLinkedObject(user) : user;
|
|
15562
|
+
} }))), getLiveChat: () => getLiveChat(room), createInvitation: (userId) => createInvitations({
|
|
15563
|
+
type: "livestreamCohostInvite" /* InvitationTypeEnum.LivestreamCohostInvite */,
|
|
15564
|
+
targetType: 'room',
|
|
15565
|
+
targetId: room.roomId,
|
|
15566
|
+
userIds: [userId],
|
|
15567
|
+
}), getInvitations: async () => {
|
|
15576
15568
|
const { data } = await getInvitation({
|
|
15577
|
-
|
|
15578
|
-
|
|
15569
|
+
targetId: room.roomId,
|
|
15570
|
+
targetType: 'room',
|
|
15571
|
+
type: "livestreamCohostInvite" /* InvitationTypeEnum.LivestreamCohostInvite */,
|
|
15579
15572
|
});
|
|
15580
15573
|
return data;
|
|
15581
|
-
},
|
|
15582
|
-
|
|
15583
|
-
|
|
15584
|
-
const { data } = await getMyJoinRequest(community.communityId);
|
|
15585
|
-
return data;
|
|
15574
|
+
}, analytics() {
|
|
15575
|
+
// Use 'this' to avoid creating a new room object
|
|
15576
|
+
return new AmityRoomAnalytics(this);
|
|
15586
15577
|
} });
|
|
15587
15578
|
};
|
|
15588
15579
|
|
|
15580
|
+
const pollLinkedObject = (poll) => {
|
|
15581
|
+
return Object.assign(Object.assign({}, poll), { answers: poll.answers.map(answer => (Object.assign(Object.assign({}, answer), { get image() {
|
|
15582
|
+
var _a;
|
|
15583
|
+
if (!answer.fileId)
|
|
15584
|
+
return undefined;
|
|
15585
|
+
return (_a = pullFromCache(['file', 'get', answer.fileId])) === null || _a === void 0 ? void 0 : _a.data;
|
|
15586
|
+
} }))) });
|
|
15587
|
+
};
|
|
15588
|
+
|
|
15589
15589
|
const productLinkedObject = (product) => {
|
|
15590
15590
|
const analyticsEngineInstance = AnalyticsEngine$1.getInstance();
|
|
15591
15591
|
return Object.assign(Object.assign({}, product), { analytics: {
|