@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.esm.js
CHANGED
|
@@ -300,8 +300,8 @@ var NotificationRolesFilterTypeEnum;
|
|
|
300
300
|
|
|
301
301
|
function getVersion() {
|
|
302
302
|
try {
|
|
303
|
-
// the string ''v7.
|
|
304
|
-
return 'v7.
|
|
303
|
+
// the string ''v7.24.0-esm'' should be replaced by actual value by @rollup/plugin-replace
|
|
304
|
+
return 'v7.24.0-esm';
|
|
305
305
|
}
|
|
306
306
|
catch (error) {
|
|
307
307
|
return '__dev__';
|
|
@@ -29564,562 +29564,571 @@ var index$r = /*#__PURE__*/Object.freeze({
|
|
|
29564
29564
|
getMyFollowInfo: getMyFollowInfo
|
|
29565
29565
|
});
|
|
29566
29566
|
|
|
29567
|
-
|
|
29568
|
-
|
|
29569
|
-
|
|
29570
|
-
|
|
29571
|
-
|
|
29572
|
-
|
|
29573
|
-
|
|
29574
|
-
|
|
29575
|
-
|
|
29576
|
-
|
|
29577
|
-
|
|
29578
|
-
|
|
29579
|
-
|
|
29580
|
-
|
|
29581
|
-
|
|
29582
|
-
|
|
29583
|
-
|
|
29584
|
-
|
|
29585
|
-
|
|
29586
|
-
|
|
29587
|
-
|
|
29588
|
-
|
|
29589
|
-
|
|
29590
|
-
|
|
29591
|
-
|
|
29592
|
-
|
|
29593
|
-
? new Date((_b = this.cacheStoryExpireTime) === null || _b === void 0 ? void 0 : _b.data).getTime()
|
|
29594
|
-
: 0;
|
|
29595
|
-
}
|
|
29596
|
-
get localLastStorySeenExpiresAt() {
|
|
29597
|
-
var _a, _b;
|
|
29598
|
-
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;
|
|
29599
|
-
}
|
|
29600
|
-
get isContainUnSyncedStory() {
|
|
29601
|
-
const currentSyncingState = pullFromCache([
|
|
29602
|
-
"story-sync-state" /* STORY_KEY_CACHE.SYNC_STATE */,
|
|
29603
|
-
this._targetId,
|
|
29604
|
-
]);
|
|
29605
|
-
if (!(currentSyncingState === null || currentSyncingState === void 0 ? void 0 : currentSyncingState.data))
|
|
29606
|
-
return false;
|
|
29607
|
-
return ["syncing" /* Amity.SyncState.Syncing */, "error" /* Amity.SyncState.Error */].includes(currentSyncingState.data);
|
|
29608
|
-
}
|
|
29609
|
-
getLocalLastSortingDate() {
|
|
29610
|
-
if (this.isContainUnSyncedStory) {
|
|
29611
|
-
return this.localLastStoryExpires;
|
|
29612
|
-
}
|
|
29613
|
-
return this.lastStoryExpiresAt;
|
|
29614
|
-
}
|
|
29615
|
-
getHasUnseenFlag() {
|
|
29616
|
-
const now = new Date().getTime();
|
|
29617
|
-
const highestSeen = Math.max(this.lastStorySeenExpiresAt, this.localLastStorySeenExpiresAt);
|
|
29618
|
-
pullFromCache([
|
|
29619
|
-
"story-sync-state" /* STORY_KEY_CACHE.SYNC_STATE */,
|
|
29620
|
-
this._targetId,
|
|
29567
|
+
/*
|
|
29568
|
+
* verifies membership status
|
|
29569
|
+
*/
|
|
29570
|
+
function isMember(membership) {
|
|
29571
|
+
return membership !== 'none';
|
|
29572
|
+
}
|
|
29573
|
+
/*
|
|
29574
|
+
* checks if currently logged in user is part of the community
|
|
29575
|
+
*/
|
|
29576
|
+
function isCurrentUserPartOfCommunity(c, m) {
|
|
29577
|
+
const { userId } = getActiveUser();
|
|
29578
|
+
return c.communityId === m.communityId && m.userId === userId;
|
|
29579
|
+
}
|
|
29580
|
+
/*
|
|
29581
|
+
* For mqtt events server will not send user specific data as it's broadcasted
|
|
29582
|
+
* to multiple users and it also does not include communityUser
|
|
29583
|
+
*
|
|
29584
|
+
* Client SDK needs to check for the existing isJoined field in cache data before calculating.
|
|
29585
|
+
* Althought this can be calculated, it's not scalable.
|
|
29586
|
+
*/
|
|
29587
|
+
function updateMembershipStatus(communities, communityUsers) {
|
|
29588
|
+
return communities.map(c => {
|
|
29589
|
+
const cachedCommunity = pullFromCache([
|
|
29590
|
+
'community',
|
|
29591
|
+
'get',
|
|
29592
|
+
c.communityId,
|
|
29621
29593
|
]);
|
|
29622
|
-
if (
|
|
29623
|
-
return
|
|
29624
|
-
}
|
|
29625
|
-
return this.lastStoryExpiresAt > now && this.lastStoryExpiresAt > highestSeen;
|
|
29626
|
-
}
|
|
29627
|
-
getTotalStoryByStatus() {
|
|
29628
|
-
const stories = queryCache(["story" /* STORY_KEY_CACHE.STORY */, 'get']);
|
|
29629
|
-
if (!stories) {
|
|
29630
|
-
this._errorStoriesCount = 0;
|
|
29631
|
-
this._syncingStoriesCount = 0;
|
|
29632
|
-
return;
|
|
29594
|
+
if ((cachedCommunity === null || cachedCommunity === void 0 ? void 0 : cachedCommunity.data) && (cachedCommunity === null || cachedCommunity === void 0 ? void 0 : cachedCommunity.data.hasOwnProperty('isJoined'))) {
|
|
29595
|
+
return Object.assign(Object.assign({}, cachedCommunity.data), c);
|
|
29633
29596
|
}
|
|
29634
|
-
const
|
|
29635
|
-
|
|
29636
|
-
|
|
29637
|
-
|
|
29638
|
-
|
|
29639
|
-
|
|
29640
|
-
|
|
29641
|
-
|
|
29642
|
-
|
|
29643
|
-
|
|
29597
|
+
const isJoined = c.isJoined !== undefined
|
|
29598
|
+
? c.isJoined
|
|
29599
|
+
: communityUsers.some(m => isCurrentUserPartOfCommunity(c, m) && isMember(m.communityMembership));
|
|
29600
|
+
return Object.assign(Object.assign({}, c), { isJoined });
|
|
29601
|
+
});
|
|
29602
|
+
}
|
|
29603
|
+
|
|
29604
|
+
const getMatchPostSetting = (value) => {
|
|
29605
|
+
var _a;
|
|
29606
|
+
return (_a = Object.keys(CommunityPostSettingMaps).find(key => value.needApprovalOnPostCreation ===
|
|
29607
|
+
CommunityPostSettingMaps[key].needApprovalOnPostCreation &&
|
|
29608
|
+
value.onlyAdminCanPost === CommunityPostSettingMaps[key].onlyAdminCanPost)) !== null && _a !== void 0 ? _a : DefaultCommunityPostSetting;
|
|
29609
|
+
};
|
|
29610
|
+
function addPostSetting({ communities }) {
|
|
29611
|
+
return communities.map((_a) => {
|
|
29612
|
+
var { needApprovalOnPostCreation, onlyAdminCanPost } = _a, restCommunityPayload = __rest(_a, ["needApprovalOnPostCreation", "onlyAdminCanPost"]);
|
|
29613
|
+
return (Object.assign({ postSetting: getMatchPostSetting({
|
|
29614
|
+
needApprovalOnPostCreation,
|
|
29615
|
+
onlyAdminCanPost,
|
|
29616
|
+
}) }, restCommunityPayload));
|
|
29617
|
+
});
|
|
29618
|
+
}
|
|
29619
|
+
const prepareCommunityPayload = (rawPayload) => {
|
|
29620
|
+
const communitiesWithPostSetting = addPostSetting({ communities: rawPayload.communities });
|
|
29621
|
+
// Convert users to internal format
|
|
29622
|
+
const internalUsers = rawPayload.users.map(convertRawUserToInternalUser);
|
|
29623
|
+
// map users with community
|
|
29624
|
+
const mappedCommunityUsers = rawPayload.communityUsers.map(communityUser => {
|
|
29625
|
+
const user = internalUsers.find(user => user.userId === communityUser.userId);
|
|
29626
|
+
return Object.assign(Object.assign({}, communityUser), { user });
|
|
29627
|
+
});
|
|
29628
|
+
const communityWithMembershipStatus = updateMembershipStatus(communitiesWithPostSetting, mappedCommunityUsers);
|
|
29629
|
+
return Object.assign(Object.assign({}, rawPayload), { users: rawPayload.users.map(convertRawUserToInternalUser), communities: communityWithMembershipStatus, communityUsers: mappedCommunityUsers });
|
|
29630
|
+
};
|
|
29631
|
+
const prepareCommunityJoinRequestPayload = (rawPayload) => {
|
|
29632
|
+
const mappedJoinRequests = rawPayload.joinRequests.map(joinRequest => {
|
|
29633
|
+
return Object.assign(Object.assign({}, joinRequest), { joinRequestId: joinRequest._id });
|
|
29634
|
+
});
|
|
29635
|
+
const users = rawPayload.users.map(convertRawUserToInternalUser);
|
|
29636
|
+
return Object.assign(Object.assign({}, rawPayload), { joinRequests: mappedJoinRequests, users });
|
|
29637
|
+
};
|
|
29638
|
+
const prepareCommunityMembershipPayload = (rawPayload) => {
|
|
29639
|
+
const communitiesWithPostSetting = addPostSetting({ communities: rawPayload.communities });
|
|
29640
|
+
// map users with community
|
|
29641
|
+
const mappedCommunityUsers = rawPayload.communityUsers.map(communityUser => {
|
|
29642
|
+
const user = rawPayload.users.find(user => user.userId === communityUser.userId);
|
|
29643
|
+
return Object.assign(Object.assign({}, communityUser), { user });
|
|
29644
|
+
});
|
|
29645
|
+
const communityWithMembershipStatus = updateMembershipStatus(communitiesWithPostSetting, mappedCommunityUsers);
|
|
29646
|
+
return Object.assign(Object.assign({}, rawPayload), { communities: communityWithMembershipStatus, communityUsers: mappedCommunityUsers });
|
|
29647
|
+
};
|
|
29648
|
+
const prepareCommunityRequest = (params) => {
|
|
29649
|
+
const { postSetting = undefined, storySetting } = params, restParam = __rest(params, ["postSetting", "storySetting"]);
|
|
29650
|
+
return Object.assign(Object.assign(Object.assign({}, restParam), (postSetting ? CommunityPostSettingMaps[postSetting] : undefined)), {
|
|
29651
|
+
// Convert story setting to the actual value. (Allow by default)
|
|
29652
|
+
allowCommentInStory: typeof (storySetting === null || storySetting === void 0 ? void 0 : storySetting.enableComment) === 'boolean' ? storySetting.enableComment : true });
|
|
29653
|
+
};
|
|
29654
|
+
const prepareSemanticSearchCommunityPayload = (_a) => {
|
|
29655
|
+
var communityPayload = __rest(_a, ["searchResult"]);
|
|
29656
|
+
const processedCommunityPayload = prepareCommunityPayload(communityPayload);
|
|
29657
|
+
return Object.assign({}, processedCommunityPayload);
|
|
29658
|
+
};
|
|
29659
|
+
|
|
29660
|
+
/* begin_public_function
|
|
29661
|
+
id: joinRequest.approve
|
|
29662
|
+
*/
|
|
29663
|
+
/**
|
|
29664
|
+
* ```js
|
|
29665
|
+
* import { joinRequest } from '@amityco/ts-sdk-react-native'
|
|
29666
|
+
* const isAccepted = await joinRequest.approve()
|
|
29667
|
+
* ```
|
|
29668
|
+
*
|
|
29669
|
+
* Accepts a {@link Amity.JoinRequest} object
|
|
29670
|
+
*
|
|
29671
|
+
* @param joinRequest the {@link Amity.JoinRequest} to accept
|
|
29672
|
+
* @returns A success boolean if the {@link Amity.JoinRequest} was accepted
|
|
29673
|
+
*
|
|
29674
|
+
* @category Join Request API
|
|
29675
|
+
* @async
|
|
29676
|
+
*/
|
|
29677
|
+
const approveJoinRequest = async (joinRequest) => {
|
|
29678
|
+
var _a;
|
|
29679
|
+
const client = getActiveClient();
|
|
29680
|
+
client.log('joinRequest/approveJoinRequest', joinRequest.joinRequestId);
|
|
29681
|
+
const { data } = await client.http.post(`/api/v4/communities/${joinRequest.targetId}/join/approve`, {
|
|
29682
|
+
userId: joinRequest.requestorInternalId,
|
|
29683
|
+
});
|
|
29684
|
+
const joinRequestCache = (_a = pullFromCache([
|
|
29685
|
+
'joinRequest',
|
|
29686
|
+
'get',
|
|
29687
|
+
joinRequest.joinRequestId,
|
|
29688
|
+
])) === null || _a === void 0 ? void 0 : _a.data;
|
|
29689
|
+
if (joinRequestCache) {
|
|
29690
|
+
upsertInCache(['joinRequest', 'get', joinRequest.joinRequestId], {
|
|
29691
|
+
status: "approved" /* JoinRequestStatusEnum.Approved */,
|
|
29644
29692
|
});
|
|
29645
|
-
|
|
29646
|
-
this._syncingStoriesCount = groupByType.syncing;
|
|
29647
|
-
}
|
|
29648
|
-
get syncingStoriesCount() {
|
|
29649
|
-
return this._syncingStoriesCount;
|
|
29650
|
-
}
|
|
29651
|
-
get failedStoriesCount() {
|
|
29652
|
-
return this._errorStoriesCount;
|
|
29693
|
+
fireEvent('local.joinRequest.updated', [joinRequestCache]);
|
|
29653
29694
|
}
|
|
29654
|
-
|
|
29695
|
+
return data.success;
|
|
29696
|
+
};
|
|
29697
|
+
/* end_public_function */
|
|
29655
29698
|
|
|
29656
|
-
|
|
29657
|
-
|
|
29658
|
-
|
|
29659
|
-
|
|
29660
|
-
|
|
29661
|
-
|
|
29662
|
-
|
|
29663
|
-
|
|
29664
|
-
|
|
29665
|
-
|
|
29666
|
-
|
|
29667
|
-
|
|
29668
|
-
|
|
29669
|
-
|
|
29670
|
-
|
|
29671
|
-
|
|
29672
|
-
|
|
29699
|
+
/* begin_public_function
|
|
29700
|
+
id: joinRequest.cancel
|
|
29701
|
+
*/
|
|
29702
|
+
/**
|
|
29703
|
+
* ```js
|
|
29704
|
+
* import { joinRequest } from '@amityco/ts-sdk-react-native'
|
|
29705
|
+
* const isCanceled = await joinRequest.cancel()
|
|
29706
|
+
* ```
|
|
29707
|
+
*
|
|
29708
|
+
* Cancels a {@link Amity.JoinRequest} object
|
|
29709
|
+
*
|
|
29710
|
+
* @param joinRequest the {@link Amity.JoinRequest} to cancel
|
|
29711
|
+
* @returns A success boolean if the {@link Amity.JoinRequest} was canceled
|
|
29712
|
+
*
|
|
29713
|
+
* @category Join Request API
|
|
29714
|
+
* @async
|
|
29715
|
+
*/
|
|
29716
|
+
const cancelJoinRequest = async (joinRequest) => {
|
|
29717
|
+
var _a;
|
|
29718
|
+
const client = getActiveClient();
|
|
29719
|
+
client.log('joinRequest/cancelJoinRequest', joinRequest.joinRequestId);
|
|
29720
|
+
const { data } = await client.http.delete(`/api/v4/communities/${joinRequest.targetId}/join`);
|
|
29721
|
+
const joinRequestCache = (_a = pullFromCache([
|
|
29722
|
+
'joinRequest',
|
|
29723
|
+
'get',
|
|
29724
|
+
joinRequest.joinRequestId,
|
|
29725
|
+
])) === null || _a === void 0 ? void 0 : _a.data;
|
|
29726
|
+
if (joinRequestCache) {
|
|
29727
|
+
upsertInCache(['joinRequest', 'get', joinRequest.joinRequestId], {
|
|
29728
|
+
status: "cancelled" /* JoinRequestStatusEnum.Cancelled */,
|
|
29729
|
+
});
|
|
29730
|
+
fireEvent('local.joinRequest.deleted', [joinRequestCache]);
|
|
29731
|
+
}
|
|
29732
|
+
return data.success;
|
|
29673
29733
|
};
|
|
29734
|
+
/* end_public_function */
|
|
29674
29735
|
|
|
29675
|
-
|
|
29676
|
-
|
|
29677
|
-
|
|
29678
|
-
|
|
29736
|
+
/* begin_public_function
|
|
29737
|
+
id: joinRequest.reject
|
|
29738
|
+
*/
|
|
29739
|
+
/**
|
|
29740
|
+
* ```js
|
|
29741
|
+
* import { joinRequest } from '@amityco/ts-sdk-react-native'
|
|
29742
|
+
* const isRejected = await joinRequest.reject()
|
|
29743
|
+
* ```
|
|
29744
|
+
*
|
|
29745
|
+
* Rejects a {@link Amity.JoinRequest} object
|
|
29746
|
+
*
|
|
29747
|
+
* @param joinRequest the {@link Amity.JoinRequest} to reject
|
|
29748
|
+
* @returns A success boolean if the {@link Amity.JoinRequest} was rejected
|
|
29749
|
+
*
|
|
29750
|
+
* @category Join Request API
|
|
29751
|
+
* @async
|
|
29752
|
+
*/
|
|
29753
|
+
const rejectJoinRequest = async (joinRequest) => {
|
|
29754
|
+
var _a;
|
|
29755
|
+
const client = getActiveClient();
|
|
29756
|
+
client.log('joinRequest/rejectJoinRequest', joinRequest.joinRequestId);
|
|
29757
|
+
const { data } = await client.http.post(`/api/v4/communities/${joinRequest.targetId}/join/reject`, {
|
|
29758
|
+
userId: joinRequest.requestorInternalId,
|
|
29759
|
+
});
|
|
29760
|
+
const joinRequestCache = (_a = pullFromCache([
|
|
29761
|
+
'joinRequest',
|
|
29679
29762
|
'get',
|
|
29680
|
-
|
|
29681
|
-
]);
|
|
29682
|
-
|
|
29683
|
-
|
|
29684
|
-
|
|
29685
|
-
|
|
29686
|
-
|
|
29687
|
-
|
|
29688
|
-
|
|
29689
|
-
|
|
29690
|
-
|
|
29691
|
-
|
|
29692
|
-
|
|
29693
|
-
|
|
29694
|
-
|
|
29695
|
-
|
|
29696
|
-
|
|
29697
|
-
|
|
29698
|
-
|
|
29699
|
-
|
|
29700
|
-
|
|
29701
|
-
'file',
|
|
29702
|
-
'get',
|
|
29703
|
-
(_b = (_a = story.data) === null || _a === void 0 ? void 0 : _a.videoFileId) === null || _b === void 0 ? void 0 : _b.original,
|
|
29704
|
-
]);
|
|
29705
|
-
if (!cache)
|
|
29706
|
-
return undefined;
|
|
29707
|
-
const { data } = cache;
|
|
29708
|
-
return data || undefined;
|
|
29709
|
-
},
|
|
29710
|
-
get imageData() {
|
|
29711
|
-
var _a, _b;
|
|
29712
|
-
if (!((_a = story.data) === null || _a === void 0 ? void 0 : _a.fileId))
|
|
29713
|
-
return undefined;
|
|
29714
|
-
const cache = pullFromCache(['file', 'get', (_b = story.data) === null || _b === void 0 ? void 0 : _b.fileId]);
|
|
29715
|
-
if (!cache)
|
|
29716
|
-
return undefined;
|
|
29717
|
-
const { data } = cache;
|
|
29718
|
-
if (!data)
|
|
29719
|
-
return undefined;
|
|
29720
|
-
return Object.assign(Object.assign({}, data), { fileUrl: `${data.fileUrl}?size=full` });
|
|
29721
|
-
},
|
|
29722
|
-
get community() {
|
|
29723
|
-
if (story.targetType !== 'community')
|
|
29724
|
-
return undefined;
|
|
29725
|
-
if (!communityCacheData)
|
|
29726
|
-
return undefined;
|
|
29727
|
-
return (communityCacheData === null || communityCacheData === void 0 ? void 0 : communityCacheData.data) || undefined;
|
|
29728
|
-
},
|
|
29729
|
-
get communityCategories() {
|
|
29730
|
-
if (story.targetType !== 'community')
|
|
29731
|
-
return undefined;
|
|
29732
|
-
if (!communityCacheData)
|
|
29733
|
-
return undefined;
|
|
29734
|
-
const { data: { categoryIds }, } = communityCacheData;
|
|
29735
|
-
if (categoryIds.length === 0)
|
|
29763
|
+
joinRequest.joinRequestId,
|
|
29764
|
+
])) === null || _a === void 0 ? void 0 : _a.data;
|
|
29765
|
+
if (joinRequestCache) {
|
|
29766
|
+
upsertInCache(['joinRequest', 'get', joinRequest.joinRequestId], {
|
|
29767
|
+
status: "rejected" /* JoinRequestStatusEnum.Rejected */,
|
|
29768
|
+
});
|
|
29769
|
+
fireEvent('local.joinRequest.updated', [joinRequestCache]);
|
|
29770
|
+
}
|
|
29771
|
+
return data.success;
|
|
29772
|
+
};
|
|
29773
|
+
/* end_public_function */
|
|
29774
|
+
|
|
29775
|
+
const joinRequestLinkedObject = (joinRequest) => {
|
|
29776
|
+
return Object.assign(Object.assign({}, joinRequest), { get user() {
|
|
29777
|
+
var _a;
|
|
29778
|
+
const user = (_a = pullFromCache([
|
|
29779
|
+
'user',
|
|
29780
|
+
'get',
|
|
29781
|
+
joinRequest.requestorPublicId,
|
|
29782
|
+
])) === null || _a === void 0 ? void 0 : _a.data;
|
|
29783
|
+
if (!user)
|
|
29736
29784
|
return undefined;
|
|
29737
|
-
return
|
|
29738
|
-
|
|
29739
|
-
|
|
29740
|
-
|
|
29741
|
-
|
|
29742
|
-
|
|
29743
|
-
|
|
29744
|
-
get creator() {
|
|
29745
|
-
const cacheData = pullFromCache(['user', 'get', story.creatorPublicId]);
|
|
29746
|
-
if (!(cacheData === null || cacheData === void 0 ? void 0 : cacheData.data))
|
|
29747
|
-
return;
|
|
29748
|
-
return userLinkedObject(cacheData.data);
|
|
29749
|
-
},
|
|
29750
|
-
get storyTarget() {
|
|
29751
|
-
if (!(storyTargetCache === null || storyTargetCache === void 0 ? void 0 : storyTargetCache.data))
|
|
29752
|
-
return;
|
|
29753
|
-
return storyTargetLinkedObject(storyTargetCache.data);
|
|
29754
|
-
},
|
|
29755
|
-
get isSeen() {
|
|
29756
|
-
const cacheData = pullFromCache(["story-last-seen" /* STORY_KEY_CACHE.LAST_SEEN */, story.targetId]);
|
|
29757
|
-
if (!(storyTargetCache === null || storyTargetCache === void 0 ? void 0 : storyTargetCache.data))
|
|
29758
|
-
return false;
|
|
29759
|
-
const localLastSeen = (cacheData === null || cacheData === void 0 ? void 0 : cacheData.data) ? new Date(cacheData.data).getTime() : 0;
|
|
29760
|
-
const serverLastSeen = new Date(storyTargetCache === null || storyTargetCache === void 0 ? void 0 : storyTargetCache.data.lastStorySeenExpiresAt).getTime() || 0;
|
|
29761
|
-
const expiresAt = new Date(story.expiresAt).getTime();
|
|
29762
|
-
return Math.max(localLastSeen, serverLastSeen) >= expiresAt;
|
|
29785
|
+
return userLinkedObject(user);
|
|
29786
|
+
}, cancel: async () => {
|
|
29787
|
+
await cancelJoinRequest(joinRequest);
|
|
29788
|
+
}, approve: async () => {
|
|
29789
|
+
await approveJoinRequest(joinRequest);
|
|
29790
|
+
}, reject: async () => {
|
|
29791
|
+
await rejectJoinRequest(joinRequest);
|
|
29763
29792
|
} });
|
|
29764
29793
|
};
|
|
29765
29794
|
|
|
29766
29795
|
/* begin_public_function
|
|
29767
|
-
id:
|
|
29796
|
+
id: community.getMyJoinRequest
|
|
29768
29797
|
*/
|
|
29769
29798
|
/**
|
|
29770
29799
|
* ```js
|
|
29771
|
-
* import {
|
|
29772
|
-
* const
|
|
29800
|
+
* import { community } from '@amityco/ts-sdk-react-native'
|
|
29801
|
+
* const isJoined = await community.getMyJoinRequest('foobar')
|
|
29773
29802
|
* ```
|
|
29774
29803
|
*
|
|
29775
|
-
*
|
|
29804
|
+
* Joins a {@link Amity.Community} object
|
|
29776
29805
|
*
|
|
29777
|
-
* @param
|
|
29778
|
-
* @returns
|
|
29806
|
+
* @param communityId the {@link Amity.Community} to join
|
|
29807
|
+
* @returns A success boolean if the {@link Amity.Community} was joined
|
|
29779
29808
|
*
|
|
29780
|
-
* @category
|
|
29809
|
+
* @category Community API
|
|
29781
29810
|
* @async
|
|
29782
29811
|
*/
|
|
29783
|
-
const
|
|
29812
|
+
const getMyJoinRequest = async (communityId) => {
|
|
29784
29813
|
const client = getActiveClient();
|
|
29785
|
-
client.log('
|
|
29786
|
-
|
|
29787
|
-
|
|
29788
|
-
if ((bundle === null || bundle === void 0 ? void 0 : bundle.type) === 'conversation') {
|
|
29789
|
-
payload = await client.http.post('/api/v3/channels/conversation', Object.assign(Object.assign({}, bundle), { isDistinct: true }));
|
|
29790
|
-
}
|
|
29791
|
-
else {
|
|
29792
|
-
const { isPublic } = bundle, restParams = __rest(bundle, ["isPublic"]);
|
|
29793
|
-
payload = await client.http.post('/api/v3/channels', Object.assign(Object.assign({}, restParams), {
|
|
29794
|
-
/* c8 ignore next */
|
|
29795
|
-
isPublic: (bundle === null || bundle === void 0 ? void 0 : bundle.type) === 'community' ? isPublic : undefined }));
|
|
29796
|
-
}
|
|
29797
|
-
const data = await prepareChannelPayload(payload.data);
|
|
29814
|
+
client.log('community/myJoinRequest', communityId);
|
|
29815
|
+
const { data: payload } = await client.http.get(`/api/v4/communities/${communityId}/join/me`);
|
|
29816
|
+
const data = prepareCommunityJoinRequestPayload(payload);
|
|
29798
29817
|
const cachedAt = client.cache && Date.now();
|
|
29799
29818
|
if (client.cache)
|
|
29800
29819
|
ingestInCache(data, { cachedAt });
|
|
29801
|
-
const { channels } = data;
|
|
29802
29820
|
return {
|
|
29803
|
-
data:
|
|
29821
|
+
data: data.joinRequests[0] ? joinRequestLinkedObject(data.joinRequests[0]) : undefined,
|
|
29804
29822
|
cachedAt,
|
|
29805
29823
|
};
|
|
29806
29824
|
};
|
|
29807
29825
|
/* end_public_function */
|
|
29808
29826
|
|
|
29827
|
+
/* begin_public_function
|
|
29828
|
+
id: community.join
|
|
29829
|
+
*/
|
|
29809
29830
|
/**
|
|
29810
29831
|
* ```js
|
|
29811
|
-
* import {
|
|
29812
|
-
* const
|
|
29832
|
+
* import { community } from '@amityco/ts-sdk-react-native'
|
|
29833
|
+
* const isJoined = await community.join('foobar')
|
|
29813
29834
|
* ```
|
|
29814
29835
|
*
|
|
29815
|
-
*
|
|
29836
|
+
* Joins a {@link Amity.Community} object
|
|
29816
29837
|
*
|
|
29817
|
-
* @param
|
|
29818
|
-
* @returns
|
|
29838
|
+
* @param communityId the {@link Amity.Community} to join
|
|
29839
|
+
* @returns A status join result
|
|
29819
29840
|
*
|
|
29820
|
-
* @category
|
|
29841
|
+
* @category Community API
|
|
29821
29842
|
* @async
|
|
29822
29843
|
*/
|
|
29823
|
-
const
|
|
29844
|
+
const joinRequest = async (communityId) => {
|
|
29845
|
+
var _a;
|
|
29824
29846
|
const client = getActiveClient();
|
|
29825
|
-
client.log('
|
|
29826
|
-
|
|
29827
|
-
|
|
29828
|
-
|
|
29829
|
-
|
|
29830
|
-
data
|
|
29831
|
-
|
|
29832
|
-
|
|
29847
|
+
client.log('community/joinRequest', communityId);
|
|
29848
|
+
const { data: payload } = await client.http.post(`/api/v4/communities/${communityId}/join`);
|
|
29849
|
+
const data = prepareCommunityJoinRequestPayload(payload);
|
|
29850
|
+
const cachedAt = client.cache && Date.now();
|
|
29851
|
+
if (client.cache)
|
|
29852
|
+
ingestInCache(data, { cachedAt });
|
|
29853
|
+
const status = data.joinRequests[0].status === "approved" /* JoinRequestStatusEnum.Approved */
|
|
29854
|
+
? "success" /* JoinResultStatusEnum.Success */
|
|
29855
|
+
: "pending" /* JoinResultStatusEnum.Pending */;
|
|
29856
|
+
if (status === "success" /* JoinResultStatusEnum.Success */ && client.cache) {
|
|
29857
|
+
const community = (_a = pullFromCache(['community', 'get', communityId])) === null || _a === void 0 ? void 0 : _a.data;
|
|
29858
|
+
if (community) {
|
|
29859
|
+
const updatedCommunity = Object.assign(Object.assign({}, community), { isJoined: true });
|
|
29860
|
+
upsertInCache(['community', 'get', communityId], updatedCommunity);
|
|
29833
29861
|
}
|
|
29834
29862
|
}
|
|
29835
|
-
|
|
29836
|
-
|
|
29837
|
-
|
|
29838
|
-
|
|
29863
|
+
fireEvent('v4.local.community.joined', data.joinRequests);
|
|
29864
|
+
return status === "success" /* JoinResultStatusEnum.Success */
|
|
29865
|
+
? { status }
|
|
29866
|
+
: { status, request: joinRequestLinkedObject(data.joinRequests[0]) };
|
|
29867
|
+
};
|
|
29868
|
+
/* end_public_function */
|
|
29869
|
+
|
|
29870
|
+
/**
|
|
29871
|
+
* TODO: handle cache receive cache option, and cache policy
|
|
29872
|
+
* TODO: check if querybyIds is supported
|
|
29873
|
+
*/
|
|
29874
|
+
class JoinRequestsPaginationController extends PaginationController {
|
|
29875
|
+
async getRequest(queryParams, token) {
|
|
29876
|
+
const { limit = 20, communityId } = queryParams, params = __rest(queryParams, ["limit", "communityId"]);
|
|
29877
|
+
const options = token ? { token } : { limit };
|
|
29878
|
+
const { data: queryResponse } = await this.http.get(`/api/v4/communities/${communityId}/join`, {
|
|
29879
|
+
params: Object.assign(Object.assign({}, params), { options }),
|
|
29880
|
+
});
|
|
29881
|
+
return queryResponse;
|
|
29882
|
+
}
|
|
29883
|
+
}
|
|
29884
|
+
|
|
29885
|
+
var EnumJoinRequestAction$1;
|
|
29886
|
+
(function (EnumJoinRequestAction) {
|
|
29887
|
+
EnumJoinRequestAction["OnLocalJoinRequestCreated"] = "OnLocalJoinRequestCreated";
|
|
29888
|
+
EnumJoinRequestAction["OnLocalJoinRequestUpdated"] = "OnLocalJoinRequestUpdated";
|
|
29889
|
+
EnumJoinRequestAction["OnLocalJoinRequestDeleted"] = "OnLocalJoinRequestDeleted";
|
|
29890
|
+
})(EnumJoinRequestAction$1 || (EnumJoinRequestAction$1 = {}));
|
|
29891
|
+
|
|
29892
|
+
class JoinRequestsQueryStreamController extends QueryStreamController {
|
|
29893
|
+
constructor(query, cacheKey, notifyChange, preparePayload) {
|
|
29894
|
+
super(query, cacheKey);
|
|
29895
|
+
this.notifyChange = notifyChange;
|
|
29896
|
+
this.preparePayload = preparePayload;
|
|
29897
|
+
}
|
|
29898
|
+
async saveToMainDB(response) {
|
|
29899
|
+
const processedPayload = await this.preparePayload(response);
|
|
29900
|
+
const client = getActiveClient();
|
|
29901
|
+
const cachedAt = client.cache && Date.now();
|
|
29902
|
+
if (client.cache) {
|
|
29903
|
+
ingestInCache(processedPayload, { cachedAt });
|
|
29839
29904
|
}
|
|
29840
|
-
throw error;
|
|
29841
29905
|
}
|
|
29842
|
-
|
|
29843
|
-
|
|
29844
|
-
|
|
29845
|
-
|
|
29846
|
-
|
|
29847
|
-
|
|
29848
|
-
|
|
29906
|
+
appendToQueryStream(response, direction, refresh = false) {
|
|
29907
|
+
var _a, _b;
|
|
29908
|
+
if (refresh) {
|
|
29909
|
+
pushToCache(this.cacheKey, {
|
|
29910
|
+
data: response.joinRequests.map(joinRequest => getResolver('joinRequest')({ joinRequestId: joinRequest._id })),
|
|
29911
|
+
});
|
|
29912
|
+
}
|
|
29913
|
+
else {
|
|
29914
|
+
const collection = (_a = pullFromCache(this.cacheKey)) === null || _a === void 0 ? void 0 : _a.data;
|
|
29915
|
+
const joinRequests = (_b = collection === null || collection === void 0 ? void 0 : collection.data) !== null && _b !== void 0 ? _b : [];
|
|
29916
|
+
pushToCache(this.cacheKey, Object.assign(Object.assign({}, collection), { data: [
|
|
29917
|
+
...new Set([
|
|
29918
|
+
...joinRequests,
|
|
29919
|
+
...response.joinRequests.map(joinRequest => getResolver('joinRequest')({ joinRequestId: joinRequest._id })),
|
|
29920
|
+
]),
|
|
29921
|
+
] }));
|
|
29922
|
+
}
|
|
29923
|
+
}
|
|
29924
|
+
reactor(action) {
|
|
29925
|
+
return (joinRequest) => {
|
|
29926
|
+
var _a;
|
|
29927
|
+
const collection = (_a = pullFromCache(this.cacheKey)) === null || _a === void 0 ? void 0 : _a.data;
|
|
29928
|
+
if (!collection)
|
|
29929
|
+
return;
|
|
29930
|
+
if (action === EnumJoinRequestAction$1.OnLocalJoinRequestUpdated) {
|
|
29931
|
+
const isExist = collection.data.find(id => id === joinRequest[0].joinRequestId);
|
|
29932
|
+
if (!isExist)
|
|
29933
|
+
return;
|
|
29934
|
+
}
|
|
29935
|
+
if (action === EnumJoinRequestAction$1.OnLocalJoinRequestCreated) {
|
|
29936
|
+
collection.data = [
|
|
29937
|
+
...new Set([
|
|
29938
|
+
...joinRequest.map(joinRequest => joinRequest.joinRequestId),
|
|
29939
|
+
...collection.data,
|
|
29940
|
+
]),
|
|
29941
|
+
];
|
|
29942
|
+
}
|
|
29943
|
+
if (action === EnumJoinRequestAction$1.OnLocalJoinRequestDeleted) {
|
|
29944
|
+
collection.data = collection.data.filter(id => id !== joinRequest[0].joinRequestId);
|
|
29945
|
+
}
|
|
29946
|
+
pushToCache(this.cacheKey, collection);
|
|
29947
|
+
this.notifyChange({ origin: "event" /* Amity.LiveDataOrigin.EVENT */, loading: false });
|
|
29948
|
+
};
|
|
29949
|
+
}
|
|
29950
|
+
subscribeRTE(createSubscriber) {
|
|
29951
|
+
return createSubscriber.map(subscriber => subscriber.fn(this.reactor(subscriber.action)));
|
|
29952
|
+
}
|
|
29953
|
+
}
|
|
29954
|
+
|
|
29955
|
+
/**
|
|
29956
|
+
* ```js
|
|
29957
|
+
* import { onJoinRequestCreated } from '@amityco/ts-sdk-react-native'
|
|
29958
|
+
* const dispose = onJoinRequestCreated(data => {
|
|
29959
|
+
* // ...
|
|
29960
|
+
* })
|
|
29961
|
+
* ```
|
|
29962
|
+
*
|
|
29963
|
+
* Fired when an {@link Amity.CommunityJoinRequestPayload} has been created
|
|
29964
|
+
*
|
|
29965
|
+
* @param callback The function to call when the event was fired
|
|
29966
|
+
* @returns an {@link Amity.Unsubscriber} function to stop listening
|
|
29967
|
+
*
|
|
29968
|
+
* @category JoinRequest Events
|
|
29969
|
+
*/
|
|
29970
|
+
const onJoinRequestCreated = (callback) => {
|
|
29971
|
+
const client = getActiveClient();
|
|
29972
|
+
const disposers = [
|
|
29973
|
+
createEventSubscriber(client, 'onJoinRequestCreated', 'local.joinRequest.created', payload => callback(payload)),
|
|
29974
|
+
];
|
|
29975
|
+
return () => {
|
|
29976
|
+
disposers.forEach(fn => fn());
|
|
29849
29977
|
};
|
|
29850
29978
|
};
|
|
29979
|
+
|
|
29851
29980
|
/**
|
|
29852
|
-
* ```js
|
|
29853
|
-
* import {
|
|
29854
|
-
* const
|
|
29981
|
+
* ```js
|
|
29982
|
+
* import { onJoinRequestUpdated } from '@amityco/ts-sdk-react-native'
|
|
29983
|
+
* const dispose = onJoinRequestUpdated(data => {
|
|
29984
|
+
* // ...
|
|
29985
|
+
* })
|
|
29855
29986
|
* ```
|
|
29856
29987
|
*
|
|
29857
|
-
*
|
|
29988
|
+
* Fired when an {@link Amity.CommunityJoinRequestPayload} has been created
|
|
29858
29989
|
*
|
|
29859
|
-
* @param
|
|
29860
|
-
* @returns
|
|
29990
|
+
* @param callback The function to call when the event was fired
|
|
29991
|
+
* @returns an {@link Amity.Unsubscriber} function to stop listening
|
|
29861
29992
|
*
|
|
29862
|
-
* @category
|
|
29993
|
+
* @category JoinRequest Events
|
|
29863
29994
|
*/
|
|
29864
|
-
|
|
29865
|
-
var _a;
|
|
29995
|
+
const onJoinRequestUpdated = (callback) => {
|
|
29866
29996
|
const client = getActiveClient();
|
|
29867
|
-
|
|
29868
|
-
|
|
29869
|
-
|
|
29870
|
-
|
|
29871
|
-
|
|
29872
|
-
return data.channelPublicId === channelId;
|
|
29873
|
-
});
|
|
29874
|
-
if (!cached || (cached === null || cached === void 0 ? void 0 : cached.length) === 0)
|
|
29875
|
-
return;
|
|
29876
|
-
return {
|
|
29877
|
-
data: cached[0].data,
|
|
29878
|
-
cachedAt: cached[0].cachedAt,
|
|
29997
|
+
const disposers = [
|
|
29998
|
+
createEventSubscriber(client, 'onJoinRequestUpdated', 'local.joinRequest.updated', payload => callback(payload)),
|
|
29999
|
+
];
|
|
30000
|
+
return () => {
|
|
30001
|
+
disposers.forEach(fn => fn());
|
|
29879
30002
|
};
|
|
29880
30003
|
};
|
|
29881
30004
|
|
|
29882
30005
|
/**
|
|
29883
30006
|
* ```js
|
|
29884
|
-
* import {
|
|
29885
|
-
* const
|
|
30007
|
+
* import { onJoinRequestDeleted } from '@amityco/ts-sdk-react-native'
|
|
30008
|
+
* const dispose = onJoinRequestDeleted(data => {
|
|
30009
|
+
* // ...
|
|
30010
|
+
* })
|
|
29886
30011
|
* ```
|
|
29887
30012
|
*
|
|
29888
|
-
*
|
|
30013
|
+
* Fired when an {@link Amity.CommunityJoinRequestPayload} has been created
|
|
29889
30014
|
*
|
|
29890
|
-
* @param
|
|
29891
|
-
* @returns
|
|
30015
|
+
* @param callback The function to call when the event was fired
|
|
30016
|
+
* @returns an {@link Amity.Unsubscriber} function to stop listening
|
|
29892
30017
|
*
|
|
29893
|
-
* @category
|
|
29894
|
-
* @async
|
|
30018
|
+
* @category JoinRequest Events
|
|
29895
30019
|
*/
|
|
29896
|
-
const
|
|
29897
|
-
var _a;
|
|
30020
|
+
const onJoinRequestDeleted = (callback) => {
|
|
29898
30021
|
const client = getActiveClient();
|
|
29899
|
-
|
|
29900
|
-
|
|
29901
|
-
|
|
29902
|
-
|
|
29903
|
-
|
|
29904
|
-
|
|
29905
|
-
])) === null || _a === void 0 ? void 0 : _a.data;
|
|
29906
|
-
if (channel)
|
|
29907
|
-
return channelLinkedObject(constructChannelObject(channel));
|
|
29908
|
-
const { data } = await getChannel$1(stream.channelId);
|
|
29909
|
-
return channelLinkedObject(constructChannelObject(data));
|
|
29910
|
-
}
|
|
29911
|
-
// No Channel ID
|
|
29912
|
-
// streamer: create a new live channel
|
|
29913
|
-
if (stream.userId === client.userId) {
|
|
29914
|
-
const { data: channel } = await createChannel({
|
|
29915
|
-
type: 'live',
|
|
29916
|
-
postId: stream.postId,
|
|
29917
|
-
videoStreamId: stream.streamId,
|
|
29918
|
-
});
|
|
29919
|
-
// Update channelId to stream object in cache
|
|
29920
|
-
mergeInCache(['stream', 'get', stream.streamId], {
|
|
29921
|
-
channelId: channel.channelId,
|
|
29922
|
-
});
|
|
29923
|
-
return channel;
|
|
29924
|
-
}
|
|
29925
|
-
// watcher: return undefined
|
|
29926
|
-
return undefined;
|
|
29927
|
-
};
|
|
29928
|
-
|
|
29929
|
-
const GET_WATCHER_URLS = Symbol('getWatcherUrls');
|
|
29930
|
-
const streamLinkedObject = (stream) => {
|
|
29931
|
-
return Object.assign(Object.assign({}, stream), { get moderation() {
|
|
29932
|
-
var _a;
|
|
29933
|
-
return (_a = pullFromCache(['streamModeration', 'get', stream.streamId])) === null || _a === void 0 ? void 0 : _a.data;
|
|
29934
|
-
},
|
|
29935
|
-
get post() {
|
|
29936
|
-
var _a;
|
|
29937
|
-
if (stream.referenceType !== 'post')
|
|
29938
|
-
return;
|
|
29939
|
-
return (_a = pullFromCache(['post', 'get', stream.referenceId])) === null || _a === void 0 ? void 0 : _a.data;
|
|
29940
|
-
},
|
|
29941
|
-
get community() {
|
|
29942
|
-
var _a;
|
|
29943
|
-
if (stream.targetType !== 'community')
|
|
29944
|
-
return;
|
|
29945
|
-
return (_a = pullFromCache(['community', 'get', stream.targetId])) === null || _a === void 0 ? void 0 : _a.data;
|
|
29946
|
-
},
|
|
29947
|
-
get user() {
|
|
29948
|
-
var _a;
|
|
29949
|
-
return (_a = pullFromCache(['user', 'get', stream.userId])) === null || _a === void 0 ? void 0 : _a.data;
|
|
29950
|
-
},
|
|
29951
|
-
get childStreams() {
|
|
29952
|
-
if (!stream.childStreamIds || stream.childStreamIds.length === 0)
|
|
29953
|
-
return [];
|
|
29954
|
-
return stream.childStreamIds
|
|
29955
|
-
.map(id => {
|
|
29956
|
-
var _a;
|
|
29957
|
-
const streamCache = (_a = pullFromCache(['stream', 'get', id])) === null || _a === void 0 ? void 0 : _a.data;
|
|
29958
|
-
if (!streamCache)
|
|
29959
|
-
return undefined;
|
|
29960
|
-
return streamLinkedObject(streamCache);
|
|
29961
|
-
})
|
|
29962
|
-
.filter(isNonNullable);
|
|
29963
|
-
}, getLiveChat: () => getLiveChat$1(stream), isBanned: !stream.watcherUrl, watcherUrl: null, get [GET_WATCHER_URLS]() {
|
|
29964
|
-
return stream.watcherUrl;
|
|
29965
|
-
} });
|
|
29966
|
-
};
|
|
29967
|
-
|
|
29968
|
-
const categoryLinkedObject = (category) => {
|
|
29969
|
-
return Object.assign(Object.assign({}, category), { get avatar() {
|
|
29970
|
-
var _a;
|
|
29971
|
-
if (!category.avatarFileId)
|
|
29972
|
-
return undefined;
|
|
29973
|
-
const avatar = (_a = pullFromCache([
|
|
29974
|
-
'file',
|
|
29975
|
-
'get',
|
|
29976
|
-
`${category.avatarFileId}`,
|
|
29977
|
-
])) === null || _a === void 0 ? void 0 : _a.data;
|
|
29978
|
-
return avatar;
|
|
29979
|
-
} });
|
|
29980
|
-
};
|
|
29981
|
-
|
|
29982
|
-
const commentLinkedObject = (comment) => {
|
|
29983
|
-
return Object.assign(Object.assign({}, comment), { get target() {
|
|
29984
|
-
const commentTypes = {
|
|
29985
|
-
type: comment.targetType,
|
|
29986
|
-
};
|
|
29987
|
-
if (comment.targetType === 'user') {
|
|
29988
|
-
return Object.assign(Object.assign({}, commentTypes), { userId: comment.targetId });
|
|
29989
|
-
}
|
|
29990
|
-
if (commentTypes.type === 'content') {
|
|
29991
|
-
return Object.assign(Object.assign({}, commentTypes), { contentId: comment.targetId });
|
|
29992
|
-
}
|
|
29993
|
-
if (commentTypes.type === 'community') {
|
|
29994
|
-
const cacheData = pullFromCache([
|
|
29995
|
-
'communityUsers',
|
|
29996
|
-
'get',
|
|
29997
|
-
`${comment.targetId}#${comment.userId}`,
|
|
29998
|
-
]);
|
|
29999
|
-
return Object.assign(Object.assign({}, commentTypes), { communityId: comment.targetId, creatorMember: cacheData === null || cacheData === void 0 ? void 0 : cacheData.data });
|
|
30000
|
-
}
|
|
30001
|
-
return {
|
|
30002
|
-
type: 'unknown',
|
|
30003
|
-
};
|
|
30004
|
-
},
|
|
30005
|
-
get creator() {
|
|
30006
|
-
const cacheData = pullFromCache(['user', 'get', comment.userId]);
|
|
30007
|
-
if (cacheData === null || cacheData === void 0 ? void 0 : cacheData.data)
|
|
30008
|
-
return userLinkedObject(cacheData.data);
|
|
30009
|
-
return undefined;
|
|
30010
|
-
},
|
|
30011
|
-
get childrenComment() {
|
|
30012
|
-
return comment.children
|
|
30013
|
-
.map(childCommentId => {
|
|
30014
|
-
const commentCache = pullFromCache([
|
|
30015
|
-
'comment',
|
|
30016
|
-
'get',
|
|
30017
|
-
childCommentId,
|
|
30018
|
-
]);
|
|
30019
|
-
if (!(commentCache === null || commentCache === void 0 ? void 0 : commentCache.data))
|
|
30020
|
-
return;
|
|
30021
|
-
return commentCache === null || commentCache === void 0 ? void 0 : commentCache.data;
|
|
30022
|
-
})
|
|
30023
|
-
.filter(isNonNullable)
|
|
30024
|
-
.map(item => commentLinkedObject(item));
|
|
30025
|
-
} });
|
|
30022
|
+
const disposers = [
|
|
30023
|
+
createEventSubscriber(client, 'onJoinRequestDeleted', 'local.joinRequest.deleted', payload => callback(payload)),
|
|
30024
|
+
];
|
|
30025
|
+
return () => {
|
|
30026
|
+
disposers.forEach(fn => fn());
|
|
30027
|
+
};
|
|
30026
30028
|
};
|
|
30027
30029
|
|
|
30028
|
-
|
|
30029
|
-
|
|
30030
|
-
|
|
30031
|
-
'
|
|
30032
|
-
|
|
30033
|
-
|
|
30034
|
-
|
|
30035
|
-
|
|
30036
|
-
|
|
30037
|
-
|
|
30038
|
-
|
|
30039
|
-
|
|
30040
|
-
|
|
30041
|
-
|
|
30042
|
-
|
|
30043
|
-
|
|
30044
|
-
|
|
30045
|
-
|
|
30046
|
-
}
|
|
30047
|
-
|
|
30048
|
-
|
|
30049
|
-
|
|
30050
|
-
|
|
30051
|
-
|
|
30052
|
-
}
|
|
30053
|
-
|
|
30054
|
-
|
|
30055
|
-
|
|
30056
|
-
|
|
30057
|
-
|
|
30058
|
-
}
|
|
30059
|
-
|
|
30060
|
-
|
|
30061
|
-
|
|
30062
|
-
|
|
30063
|
-
|
|
30064
|
-
|
|
30065
|
-
|
|
30066
|
-
|
|
30067
|
-
|
|
30068
|
-
|
|
30069
|
-
|
|
30070
|
-
|
|
30071
|
-
|
|
30072
|
-
|
|
30073
|
-
|
|
30074
|
-
|
|
30075
|
-
|
|
30030
|
+
class JoinRequestsLiveCollectionController extends LiveCollectionController {
|
|
30031
|
+
constructor(query, callback) {
|
|
30032
|
+
const queryStreamId = hash(query);
|
|
30033
|
+
const cacheKey = ['joinRequest', 'collection', queryStreamId];
|
|
30034
|
+
const paginationController = new JoinRequestsPaginationController(query);
|
|
30035
|
+
super(paginationController, queryStreamId, cacheKey, callback);
|
|
30036
|
+
this.query = query;
|
|
30037
|
+
this.queryStreamController = new JoinRequestsQueryStreamController(this.query, this.cacheKey, this.notifyChange.bind(this), prepareCommunityJoinRequestPayload);
|
|
30038
|
+
this.callback = callback.bind(this);
|
|
30039
|
+
this.loadPage({ initial: true });
|
|
30040
|
+
}
|
|
30041
|
+
setup() {
|
|
30042
|
+
var _a;
|
|
30043
|
+
const collection = (_a = pullFromCache(this.cacheKey)) === null || _a === void 0 ? void 0 : _a.data;
|
|
30044
|
+
if (!collection) {
|
|
30045
|
+
pushToCache(this.cacheKey, {
|
|
30046
|
+
data: [],
|
|
30047
|
+
params: this.query,
|
|
30048
|
+
});
|
|
30049
|
+
}
|
|
30050
|
+
}
|
|
30051
|
+
async persistModel(queryPayload) {
|
|
30052
|
+
await this.queryStreamController.saveToMainDB(queryPayload);
|
|
30053
|
+
}
|
|
30054
|
+
persistQueryStream({ response, direction, refresh, }) {
|
|
30055
|
+
const joinRequestResponse = response;
|
|
30056
|
+
this.queryStreamController.appendToQueryStream(joinRequestResponse, direction, refresh);
|
|
30057
|
+
}
|
|
30058
|
+
startSubscription() {
|
|
30059
|
+
return this.queryStreamController.subscribeRTE([
|
|
30060
|
+
{ fn: onJoinRequestCreated, action: EnumJoinRequestAction$1.OnLocalJoinRequestCreated },
|
|
30061
|
+
{ fn: onJoinRequestUpdated, action: EnumJoinRequestAction$1.OnLocalJoinRequestUpdated },
|
|
30062
|
+
{ fn: onJoinRequestDeleted, action: EnumJoinRequestAction$1.OnLocalJoinRequestDeleted },
|
|
30063
|
+
]);
|
|
30064
|
+
}
|
|
30065
|
+
notifyChange({ origin, loading, error }) {
|
|
30066
|
+
var _a;
|
|
30067
|
+
const collection = (_a = pullFromCache(this.cacheKey)) === null || _a === void 0 ? void 0 : _a.data;
|
|
30068
|
+
if (!collection)
|
|
30069
|
+
return;
|
|
30070
|
+
const data = this.applyFilter(collection.data
|
|
30071
|
+
.map(id => pullFromCache(['joinRequest', 'get', id]))
|
|
30072
|
+
.filter(isNonNullable)
|
|
30073
|
+
.map(({ data }) => data)
|
|
30074
|
+
.map(joinRequestLinkedObject));
|
|
30075
|
+
if (!this.shouldNotify(data) && origin === 'event')
|
|
30076
|
+
return;
|
|
30077
|
+
this.callback({
|
|
30078
|
+
onNextPage: () => this.loadPage({ direction: "next" /* Amity.LiveCollectionPageDirection.NEXT */ }),
|
|
30079
|
+
data,
|
|
30080
|
+
hasNextPage: !!this.paginationController.getNextToken(),
|
|
30081
|
+
loading,
|
|
30082
|
+
error,
|
|
30083
|
+
});
|
|
30084
|
+
}
|
|
30085
|
+
applyFilter(data) {
|
|
30086
|
+
let joinRequest = data;
|
|
30087
|
+
if (this.query.status) {
|
|
30088
|
+
joinRequest = joinRequest.filter(joinRequest => joinRequest.status === this.query.status);
|
|
30089
|
+
}
|
|
30090
|
+
const sortFn = (() => {
|
|
30091
|
+
switch (this.query.sortBy) {
|
|
30092
|
+
case 'firstCreated':
|
|
30093
|
+
return sortByFirstCreated;
|
|
30094
|
+
case 'lastCreated':
|
|
30095
|
+
return sortByLastCreated;
|
|
30096
|
+
default:
|
|
30097
|
+
return sortByLastCreated;
|
|
30098
|
+
}
|
|
30099
|
+
})();
|
|
30100
|
+
joinRequest = joinRequest.sort(sortFn);
|
|
30101
|
+
return joinRequest;
|
|
30102
|
+
}
|
|
30076
30103
|
}
|
|
30077
30104
|
|
|
30078
30105
|
/**
|
|
30079
|
-
*
|
|
30080
|
-
* import { RoomRepository } from '@amityco/ts-sdk-react-native'
|
|
30081
|
-
* const stream = await getStream('foobar')
|
|
30082
|
-
* ```
|
|
30106
|
+
* Get Join Requests
|
|
30083
30107
|
*
|
|
30084
|
-
*
|
|
30108
|
+
* @param params the query parameters
|
|
30109
|
+
* @param callback the callback to be called when the join request are updated
|
|
30110
|
+
* @returns joinRequests
|
|
30085
30111
|
*
|
|
30086
|
-
* @
|
|
30087
|
-
* @returns the associated {@link Amity.Channel<'live'>} object
|
|
30112
|
+
* @category joinRequest Live Collection
|
|
30088
30113
|
*
|
|
30089
|
-
* @category Stream API
|
|
30090
|
-
* @async
|
|
30091
30114
|
*/
|
|
30092
|
-
const
|
|
30093
|
-
|
|
30094
|
-
|
|
30095
|
-
|
|
30096
|
-
if (room.liveChannelId) {
|
|
30097
|
-
const channel = (_a = pullFromCache([
|
|
30098
|
-
'channel',
|
|
30099
|
-
'get',
|
|
30100
|
-
room.liveChannelId,
|
|
30101
|
-
])) === null || _a === void 0 ? void 0 : _a.data;
|
|
30102
|
-
if (channel)
|
|
30103
|
-
return channelLinkedObject(constructChannelObject(channel));
|
|
30104
|
-
const { data } = await getChannel$1(room.liveChannelId);
|
|
30105
|
-
return channelLinkedObject(constructChannelObject(data));
|
|
30106
|
-
}
|
|
30107
|
-
// No Channel ID
|
|
30108
|
-
// streamer: create a new live channel
|
|
30109
|
-
if (room.createdBy === client.userId) {
|
|
30110
|
-
const { data: channel } = await createChannel({
|
|
30111
|
-
type: 'live',
|
|
30112
|
-
postId: room.referenceId,
|
|
30113
|
-
roomId: room.roomId,
|
|
30114
|
-
});
|
|
30115
|
-
// Update channelId to stream object in cache
|
|
30116
|
-
mergeInCache(['room', 'get', room.roomId], {
|
|
30117
|
-
liveChannelId: channel.channelId,
|
|
30118
|
-
});
|
|
30119
|
-
return channel;
|
|
30115
|
+
const getJoinRequests = (params, callback, config) => {
|
|
30116
|
+
const { log, cache } = getActiveClient();
|
|
30117
|
+
if (!cache) {
|
|
30118
|
+
console.log(ENABLE_CACHE_MESSAGE);
|
|
30120
30119
|
}
|
|
30121
|
-
|
|
30122
|
-
|
|
30120
|
+
const timestamp = Date.now();
|
|
30121
|
+
log(`getJoinRequests: (tmpid: ${timestamp}) > listen`);
|
|
30122
|
+
const joinRequestLiveCollection = new JoinRequestsLiveCollectionController(params, callback);
|
|
30123
|
+
const disposers = joinRequestLiveCollection.startSubscription();
|
|
30124
|
+
const cacheKey = joinRequestLiveCollection.getCacheKey();
|
|
30125
|
+
disposers.push(() => {
|
|
30126
|
+
dropFromCache(cacheKey);
|
|
30127
|
+
});
|
|
30128
|
+
return () => {
|
|
30129
|
+
log(`getJoinRequests (tmpid: ${timestamp}) > dispose`);
|
|
30130
|
+
disposers.forEach(fn => fn());
|
|
30131
|
+
};
|
|
30123
30132
|
};
|
|
30124
30133
|
|
|
30125
30134
|
const convertRawInvitationToInternalInvitation = (rawInvitation) => {
|
|
@@ -30274,1391 +30283,1382 @@ const invitationLinkedObject = (invitation) => {
|
|
|
30274
30283
|
} });
|
|
30275
30284
|
};
|
|
30276
30285
|
|
|
30277
|
-
/* begin_public_function
|
|
30278
|
-
id: invitation.get
|
|
30279
|
-
*/
|
|
30286
|
+
/* begin_public_function
|
|
30287
|
+
id: invitation.get
|
|
30288
|
+
*/
|
|
30289
|
+
/**
|
|
30290
|
+
* ```js
|
|
30291
|
+
* import { getInvitation } from '@amityco/ts-sdk-react-native'
|
|
30292
|
+
* const { invitation } = await getInvitation(targetType, targetId)
|
|
30293
|
+
* ```
|
|
30294
|
+
*
|
|
30295
|
+
* Get a {@link Amity.Invitation} object
|
|
30296
|
+
*
|
|
30297
|
+
* @param targetType The type of the target of the {@link Amity.Invitation}
|
|
30298
|
+
* @param targetId The ID of the target of the {@link Amity.Invitation}
|
|
30299
|
+
* @returns A {@link Amity.Invitation} object
|
|
30300
|
+
*
|
|
30301
|
+
* @category Invitation API
|
|
30302
|
+
* @async
|
|
30303
|
+
*/
|
|
30304
|
+
const getInvitation = async (params) => {
|
|
30305
|
+
const client = getActiveClient();
|
|
30306
|
+
client.log('invitation/getInvitation', params.targetType, params.targetId, params.type);
|
|
30307
|
+
const { data: payload } = await client.http.get(`/api/v1/invitations/me`, { params });
|
|
30308
|
+
const data = prepareMyInvitationsPayload(payload);
|
|
30309
|
+
const cachedAt = client.cache && Date.now();
|
|
30310
|
+
if (client.cache)
|
|
30311
|
+
ingestInCache(data, { cachedAt });
|
|
30312
|
+
return {
|
|
30313
|
+
data: data.invitations[0] ? invitationLinkedObject(data.invitations[0]) : undefined,
|
|
30314
|
+
cachedAt,
|
|
30315
|
+
};
|
|
30316
|
+
};
|
|
30317
|
+
/* end_public_function */
|
|
30318
|
+
|
|
30319
|
+
var InvitationActionsEnum;
|
|
30320
|
+
(function (InvitationActionsEnum) {
|
|
30321
|
+
InvitationActionsEnum["OnLocalInvitationCreated"] = "onLocalInvitationCreated";
|
|
30322
|
+
InvitationActionsEnum["OnLocalInvitationUpdated"] = "onLocalInvitationUpdated";
|
|
30323
|
+
InvitationActionsEnum["OnLocalInvitationCanceled"] = "onLocalInvitationCanceled";
|
|
30324
|
+
})(InvitationActionsEnum || (InvitationActionsEnum = {}));
|
|
30325
|
+
|
|
30326
|
+
class InvitationsPaginationController extends PaginationController {
|
|
30327
|
+
async getRequest(queryParams, token) {
|
|
30328
|
+
const { limit = COLLECTION_DEFAULT_PAGINATION_LIMIT } = queryParams, params = __rest(queryParams, ["limit"]);
|
|
30329
|
+
const options = token ? { token } : { limit };
|
|
30330
|
+
const { data } = await this.http.get('/api/v1/invitations', { params: Object.assign(Object.assign({}, params), { options }) });
|
|
30331
|
+
return data;
|
|
30332
|
+
}
|
|
30333
|
+
}
|
|
30334
|
+
|
|
30335
|
+
class InvitationsQueryStreamController extends QueryStreamController {
|
|
30336
|
+
constructor(query, cacheKey, notifyChange, preparePayload) {
|
|
30337
|
+
super(query, cacheKey);
|
|
30338
|
+
this.notifyChange = notifyChange;
|
|
30339
|
+
this.preparePayload = preparePayload;
|
|
30340
|
+
}
|
|
30341
|
+
async saveToMainDB(response) {
|
|
30342
|
+
const processedPayload = await this.preparePayload(response);
|
|
30343
|
+
const client = getActiveClient();
|
|
30344
|
+
const cachedAt = client.cache && Date.now();
|
|
30345
|
+
if (client.cache) {
|
|
30346
|
+
ingestInCache(processedPayload, { cachedAt });
|
|
30347
|
+
}
|
|
30348
|
+
}
|
|
30349
|
+
appendToQueryStream(response, direction, refresh = false) {
|
|
30350
|
+
var _a, _b;
|
|
30351
|
+
if (refresh) {
|
|
30352
|
+
pushToCache(this.cacheKey, {
|
|
30353
|
+
data: response.invitations.map(getResolver('invitation')),
|
|
30354
|
+
});
|
|
30355
|
+
}
|
|
30356
|
+
else {
|
|
30357
|
+
const collection = (_a = pullFromCache(this.cacheKey)) === null || _a === void 0 ? void 0 : _a.data;
|
|
30358
|
+
const invitations = (_b = collection === null || collection === void 0 ? void 0 : collection.data) !== null && _b !== void 0 ? _b : [];
|
|
30359
|
+
pushToCache(this.cacheKey, Object.assign(Object.assign({}, collection), { data: [
|
|
30360
|
+
...new Set([...invitations, ...response.invitations.map(getResolver('invitation'))]),
|
|
30361
|
+
] }));
|
|
30362
|
+
}
|
|
30363
|
+
}
|
|
30364
|
+
reactor(action) {
|
|
30365
|
+
return (invitations) => {
|
|
30366
|
+
var _a;
|
|
30367
|
+
const collection = (_a = pullFromCache(this.cacheKey)) === null || _a === void 0 ? void 0 : _a.data;
|
|
30368
|
+
if (!collection)
|
|
30369
|
+
return;
|
|
30370
|
+
if (action === InvitationActionsEnum.OnLocalInvitationUpdated) {
|
|
30371
|
+
const isExist = collection.data.find(id => id === invitations[0].invitationId);
|
|
30372
|
+
if (!isExist)
|
|
30373
|
+
return;
|
|
30374
|
+
}
|
|
30375
|
+
if (action === InvitationActionsEnum.OnLocalInvitationCreated) {
|
|
30376
|
+
collection.data = [
|
|
30377
|
+
...new Set([
|
|
30378
|
+
...invitations.map(invitation => invitation.invitationId),
|
|
30379
|
+
...collection.data,
|
|
30380
|
+
]),
|
|
30381
|
+
];
|
|
30382
|
+
}
|
|
30383
|
+
if (action === InvitationActionsEnum.OnLocalInvitationDeleted) {
|
|
30384
|
+
collection.data = collection.data.filter(id => id !== invitations[0].invitationId);
|
|
30385
|
+
}
|
|
30386
|
+
pushToCache(this.cacheKey, collection);
|
|
30387
|
+
this.notifyChange({ origin: "event" /* Amity.LiveDataOrigin.EVENT */, loading: false });
|
|
30388
|
+
};
|
|
30389
|
+
}
|
|
30390
|
+
subscribeRTE(createSubscriber) {
|
|
30391
|
+
return createSubscriber.map(subscriber => subscriber.fn(this.reactor(subscriber.action)));
|
|
30392
|
+
}
|
|
30393
|
+
}
|
|
30394
|
+
|
|
30395
|
+
/**
|
|
30396
|
+
* ```js
|
|
30397
|
+
* import { onLocalInvitationCreated } from '@amityco/ts-sdk-react-native'
|
|
30398
|
+
* const dispose = onLocalInvitationCreated(data => {
|
|
30399
|
+
* // ...
|
|
30400
|
+
* })
|
|
30401
|
+
* ```
|
|
30402
|
+
*
|
|
30403
|
+
* Fired when an {@link Amity.InvitationPayload} has been created
|
|
30404
|
+
*
|
|
30405
|
+
* @param callback The function to call when the event was fired
|
|
30406
|
+
* @returns an {@link Amity.Unsubscriber} function to stop listening
|
|
30407
|
+
*
|
|
30408
|
+
* @category Invitation Events
|
|
30409
|
+
*/
|
|
30410
|
+
const onLocalInvitationCreated = (callback) => {
|
|
30411
|
+
const client = getActiveClient();
|
|
30412
|
+
const disposers = [
|
|
30413
|
+
createEventSubscriber(client, 'onLocalInvitationCreated', 'local.invitation.created', payload => callback(payload)),
|
|
30414
|
+
];
|
|
30415
|
+
return () => {
|
|
30416
|
+
disposers.forEach(fn => fn());
|
|
30417
|
+
};
|
|
30418
|
+
};
|
|
30419
|
+
|
|
30420
|
+
/**
|
|
30421
|
+
* ```js
|
|
30422
|
+
* import { onLocalInvitationUpdated } from '@amityco/ts-sdk-react-native'
|
|
30423
|
+
* const dispose = onLocalInvitationUpdated(data => {
|
|
30424
|
+
* // ...
|
|
30425
|
+
* })
|
|
30426
|
+
* ```
|
|
30427
|
+
*
|
|
30428
|
+
* Fired when an {@link Amity.InvitationPayload} has been updated
|
|
30429
|
+
*
|
|
30430
|
+
* @param callback The function to call when the event was fired
|
|
30431
|
+
* @returns an {@link Amity.Unsubscriber} function to stop listening
|
|
30432
|
+
*
|
|
30433
|
+
* @category Invitation Events
|
|
30434
|
+
*/
|
|
30435
|
+
const onLocalInvitationUpdated = (callback) => {
|
|
30436
|
+
const client = getActiveClient();
|
|
30437
|
+
const disposers = [
|
|
30438
|
+
createEventSubscriber(client, 'onLocalInvitationUpdated', 'local.invitation.updated', payload => callback(payload)),
|
|
30439
|
+
];
|
|
30440
|
+
return () => {
|
|
30441
|
+
disposers.forEach(fn => fn());
|
|
30442
|
+
};
|
|
30443
|
+
};
|
|
30444
|
+
|
|
30280
30445
|
/**
|
|
30281
30446
|
* ```js
|
|
30282
|
-
* import {
|
|
30283
|
-
* const
|
|
30447
|
+
* import { onLocalInvitationCanceled } from '@amityco/ts-sdk-react-native'
|
|
30448
|
+
* const dispose = onLocalInvitationCanceled(data => {
|
|
30449
|
+
* // ...
|
|
30450
|
+
* })
|
|
30284
30451
|
* ```
|
|
30285
30452
|
*
|
|
30286
|
-
*
|
|
30453
|
+
* Fired when an {@link Amity.InvitationPayload} has been deleted
|
|
30287
30454
|
*
|
|
30288
|
-
* @param
|
|
30289
|
-
* @
|
|
30290
|
-
* @returns A {@link Amity.Invitation} object
|
|
30455
|
+
* @param callback The function to call when the event was fired
|
|
30456
|
+
* @returns an {@link Amity.Unsubscriber} function to stop listening
|
|
30291
30457
|
*
|
|
30292
|
-
* @category Invitation
|
|
30293
|
-
* @async
|
|
30458
|
+
* @category Invitation Events
|
|
30294
30459
|
*/
|
|
30295
|
-
const
|
|
30460
|
+
const onLocalInvitationCanceled = (callback) => {
|
|
30296
30461
|
const client = getActiveClient();
|
|
30297
|
-
|
|
30298
|
-
|
|
30299
|
-
|
|
30300
|
-
|
|
30301
|
-
|
|
30302
|
-
ingestInCache(data, { cachedAt });
|
|
30303
|
-
return {
|
|
30304
|
-
data: data.invitations[0] ? invitationLinkedObject(data.invitations[0]) : undefined,
|
|
30305
|
-
cachedAt,
|
|
30462
|
+
const disposers = [
|
|
30463
|
+
createEventSubscriber(client, 'onLocalInvitationCanceled', 'local.invitation.canceled', payload => callback(payload)),
|
|
30464
|
+
];
|
|
30465
|
+
return () => {
|
|
30466
|
+
disposers.forEach(fn => fn());
|
|
30306
30467
|
};
|
|
30307
30468
|
};
|
|
30308
|
-
/* end_public_function */
|
|
30309
30469
|
|
|
30310
|
-
|
|
30311
|
-
|
|
30312
|
-
|
|
30313
|
-
|
|
30314
|
-
|
|
30315
|
-
|
|
30316
|
-
this.
|
|
30317
|
-
|
|
30318
|
-
|
|
30319
|
-
|
|
30320
|
-
*/
|
|
30321
|
-
addSession(session) {
|
|
30322
|
-
this.sessions.set(session.sessionId, session);
|
|
30323
|
-
}
|
|
30324
|
-
/**
|
|
30325
|
-
* Get a watch session by sessionId
|
|
30326
|
-
*/
|
|
30327
|
-
getSession(sessionId) {
|
|
30328
|
-
return this.sessions.get(sessionId);
|
|
30470
|
+
class InvitationsLiveCollectionController extends LiveCollectionController {
|
|
30471
|
+
constructor(query, callback) {
|
|
30472
|
+
const queryStreamId = hash(query);
|
|
30473
|
+
const cacheKey = ['invitation', 'collection', queryStreamId];
|
|
30474
|
+
const paginationController = new InvitationsPaginationController(query);
|
|
30475
|
+
super(paginationController, queryStreamId, cacheKey, callback);
|
|
30476
|
+
this.query = query;
|
|
30477
|
+
this.queryStreamController = new InvitationsQueryStreamController(this.query, this.cacheKey, this.notifyChange.bind(this), prepareInvitationPayload);
|
|
30478
|
+
this.callback = callback.bind(this);
|
|
30479
|
+
this.loadPage({ initial: true });
|
|
30329
30480
|
}
|
|
30330
|
-
|
|
30331
|
-
|
|
30332
|
-
|
|
30333
|
-
|
|
30334
|
-
|
|
30335
|
-
|
|
30336
|
-
|
|
30481
|
+
setup() {
|
|
30482
|
+
var _a;
|
|
30483
|
+
const collection = (_a = pullFromCache(this.cacheKey)) === null || _a === void 0 ? void 0 : _a.data;
|
|
30484
|
+
if (!collection) {
|
|
30485
|
+
pushToCache(this.cacheKey, {
|
|
30486
|
+
data: [],
|
|
30487
|
+
params: this.query,
|
|
30488
|
+
});
|
|
30337
30489
|
}
|
|
30338
30490
|
}
|
|
30339
|
-
|
|
30340
|
-
|
|
30341
|
-
*/
|
|
30342
|
-
getSessionsByState(state) {
|
|
30343
|
-
return Array.from(this.sessions.values()).filter(session => session.syncState === state);
|
|
30344
|
-
}
|
|
30345
|
-
/**
|
|
30346
|
-
* Delete a session
|
|
30347
|
-
*/
|
|
30348
|
-
deleteSession(sessionId) {
|
|
30349
|
-
this.sessions.delete(sessionId);
|
|
30350
|
-
}
|
|
30351
|
-
/**
|
|
30352
|
-
* Get all pending sessions
|
|
30353
|
-
*/
|
|
30354
|
-
getPendingSessions() {
|
|
30355
|
-
return this.getSessionsByState('PENDING');
|
|
30356
|
-
}
|
|
30357
|
-
/**
|
|
30358
|
-
* Get all syncing sessions
|
|
30359
|
-
*/
|
|
30360
|
-
getSyncingSessions() {
|
|
30361
|
-
return this.getSessionsByState('SYNCING');
|
|
30362
|
-
}
|
|
30363
|
-
}
|
|
30364
|
-
// Singleton instance
|
|
30365
|
-
let storageInstance = null;
|
|
30366
|
-
const getWatchSessionStorage = () => {
|
|
30367
|
-
if (!storageInstance) {
|
|
30368
|
-
storageInstance = new WatchSessionStorage();
|
|
30369
|
-
}
|
|
30370
|
-
return storageInstance;
|
|
30371
|
-
};
|
|
30372
|
-
|
|
30373
|
-
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-----";
|
|
30374
|
-
/*
|
|
30375
|
-
* The crypto algorithm used for importing key and signing string
|
|
30376
|
-
*/
|
|
30377
|
-
const ALGORITHM = {
|
|
30378
|
-
name: 'RSASSA-PKCS1-v1_5',
|
|
30379
|
-
hash: { name: 'SHA-256' },
|
|
30380
|
-
};
|
|
30381
|
-
/*
|
|
30382
|
-
* IMPORTANT!
|
|
30383
|
-
* If you are recieving key from other platforms use an online tool to convert
|
|
30384
|
-
* the PKCS1 to PKCS8. For instance the key from Android SDK is of the format
|
|
30385
|
-
* PKCS1.
|
|
30386
|
-
*
|
|
30387
|
-
* If recieving from the platform, verify if it's already in the expected
|
|
30388
|
-
* format. Otherwise the crypto.subtle.importKey will throw a DOMException
|
|
30389
|
-
*/
|
|
30390
|
-
const PRIVATE_KEY_SIGNATURE = 'pkcs8';
|
|
30391
|
-
/*
|
|
30392
|
-
* Ensure that the private key in the .env follows this format
|
|
30393
|
-
*/
|
|
30394
|
-
const PEM_HEADER = '-----BEGIN PRIVATE KEY-----';
|
|
30395
|
-
const PEM_FOOTER = '-----END PRIVATE KEY-----';
|
|
30396
|
-
/*
|
|
30397
|
-
* The crypto.subtle.sign function returns an ArrayBuffer whereas the server
|
|
30398
|
-
* expects a base64 string. This util helps facilitate that process
|
|
30399
|
-
*/
|
|
30400
|
-
function base64FromArrayBuffer(buffer) {
|
|
30401
|
-
const uint8Array = new Uint8Array(buffer);
|
|
30402
|
-
let binary = '';
|
|
30403
|
-
uint8Array.forEach(byte => {
|
|
30404
|
-
binary += String.fromCharCode(byte);
|
|
30405
|
-
});
|
|
30406
|
-
return btoa(binary);
|
|
30407
|
-
}
|
|
30408
|
-
/*
|
|
30409
|
-
* Encode ASN.1 length field
|
|
30410
|
-
*/
|
|
30411
|
-
function encodeLength(length) {
|
|
30412
|
-
if (length < 128) {
|
|
30413
|
-
return new Uint8Array([length]);
|
|
30491
|
+
async persistModel(queryPayload) {
|
|
30492
|
+
await this.queryStreamController.saveToMainDB(queryPayload);
|
|
30414
30493
|
}
|
|
30415
|
-
|
|
30416
|
-
|
|
30494
|
+
persistQueryStream({ response, direction, refresh, }) {
|
|
30495
|
+
this.queryStreamController.appendToQueryStream(response, direction, refresh);
|
|
30417
30496
|
}
|
|
30418
|
-
|
|
30419
|
-
|
|
30420
|
-
|
|
30421
|
-
|
|
30422
|
-
|
|
30423
|
-
|
|
30424
|
-
|
|
30425
|
-
|
|
30426
|
-
|
|
30427
|
-
|
|
30428
|
-
|
|
30429
|
-
|
|
30430
|
-
|
|
30431
|
-
|
|
30432
|
-
|
|
30433
|
-
0x2a,
|
|
30434
|
-
0x86,
|
|
30435
|
-
0x48,
|
|
30436
|
-
0x86,
|
|
30437
|
-
0xf7,
|
|
30438
|
-
0x0d,
|
|
30439
|
-
0x01,
|
|
30440
|
-
0x01,
|
|
30441
|
-
0x01,
|
|
30442
|
-
0x05,
|
|
30443
|
-
0x00, // NULL
|
|
30444
|
-
]);
|
|
30445
|
-
// Version (INTEGER 0)
|
|
30446
|
-
const version = new Uint8Array([0x02, 0x01, 0x00]);
|
|
30447
|
-
// OCTET STRING tag + length + pkcs1 data
|
|
30448
|
-
const octetStringTag = 0x04;
|
|
30449
|
-
const octetStringLength = encodeLength(pkcs1.length);
|
|
30450
|
-
// Calculate total content length (version + algorithm + octet string)
|
|
30451
|
-
const contentLength = version.length + algorithmIdentifier.length + 1 + octetStringLength.length + pkcs1.length;
|
|
30452
|
-
// SEQUENCE tag + length
|
|
30453
|
-
const sequenceTag = 0x30;
|
|
30454
|
-
const sequenceLength = encodeLength(contentLength);
|
|
30455
|
-
// Build the PKCS8 structure
|
|
30456
|
-
const pkcs8 = new Uint8Array(1 + sequenceLength.length + contentLength);
|
|
30457
|
-
let offset = 0;
|
|
30458
|
-
pkcs8[offset] = sequenceTag;
|
|
30459
|
-
offset += 1;
|
|
30460
|
-
pkcs8.set(sequenceLength, offset);
|
|
30461
|
-
offset += sequenceLength.length;
|
|
30462
|
-
pkcs8.set(version, offset);
|
|
30463
|
-
offset += version.length;
|
|
30464
|
-
pkcs8.set(algorithmIdentifier, offset);
|
|
30465
|
-
offset += algorithmIdentifier.length;
|
|
30466
|
-
pkcs8[offset] = octetStringTag;
|
|
30467
|
-
offset += 1;
|
|
30468
|
-
pkcs8.set(octetStringLength, offset);
|
|
30469
|
-
offset += octetStringLength.length;
|
|
30470
|
-
pkcs8.set(pkcs1, offset);
|
|
30471
|
-
return pkcs8;
|
|
30472
|
-
}
|
|
30473
|
-
async function importPrivateKey(keyString) {
|
|
30474
|
-
// Remove PEM headers if present and any whitespace
|
|
30475
|
-
let base64Key = keyString;
|
|
30476
|
-
if (keyString.includes(PEM_HEADER)) {
|
|
30477
|
-
base64Key = keyString
|
|
30478
|
-
.substring(PEM_HEADER.length, keyString.length - PEM_FOOTER.length)
|
|
30479
|
-
.replace(/\s/g, '');
|
|
30497
|
+
startSubscription() {
|
|
30498
|
+
return this.queryStreamController.subscribeRTE([
|
|
30499
|
+
{
|
|
30500
|
+
fn: onLocalInvitationCreated,
|
|
30501
|
+
action: InvitationActionsEnum.OnLocalInvitationCreated,
|
|
30502
|
+
},
|
|
30503
|
+
{
|
|
30504
|
+
fn: onLocalInvitationUpdated,
|
|
30505
|
+
action: InvitationActionsEnum.OnLocalInvitationUpdated,
|
|
30506
|
+
},
|
|
30507
|
+
{
|
|
30508
|
+
fn: onLocalInvitationCanceled,
|
|
30509
|
+
action: InvitationActionsEnum.OnLocalInvitationCanceled,
|
|
30510
|
+
},
|
|
30511
|
+
]);
|
|
30480
30512
|
}
|
|
30481
|
-
|
|
30482
|
-
|
|
30513
|
+
notifyChange({ origin, loading, error }) {
|
|
30514
|
+
var _a, _b;
|
|
30515
|
+
const collection = (_a = pullFromCache(this.cacheKey)) === null || _a === void 0 ? void 0 : _a.data;
|
|
30516
|
+
if (!collection)
|
|
30517
|
+
return;
|
|
30518
|
+
const data = this.applyFilter((_b = collection.data
|
|
30519
|
+
.map(id => pullFromCache(['invitation', 'get', id]))
|
|
30520
|
+
.filter(isNonNullable)
|
|
30521
|
+
.map(({ data }) => invitationLinkedObject(data))) !== null && _b !== void 0 ? _b : []);
|
|
30522
|
+
if (!this.shouldNotify(data) && origin === 'event')
|
|
30523
|
+
return;
|
|
30524
|
+
this.callback({
|
|
30525
|
+
onNextPage: () => this.loadPage({ direction: "next" /* Amity.LiveCollectionPageDirection.NEXT */ }),
|
|
30526
|
+
data,
|
|
30527
|
+
hasNextPage: !!this.paginationController.getNextToken(),
|
|
30528
|
+
loading,
|
|
30529
|
+
error,
|
|
30530
|
+
});
|
|
30483
30531
|
}
|
|
30484
|
-
|
|
30485
|
-
|
|
30486
|
-
|
|
30487
|
-
|
|
30488
|
-
|
|
30489
|
-
|
|
30532
|
+
applyFilter(data) {
|
|
30533
|
+
let invitations = data;
|
|
30534
|
+
if (this.query.targetId) {
|
|
30535
|
+
invitations = invitations.filter(invitation => invitation.targetId === this.query.targetId);
|
|
30536
|
+
}
|
|
30537
|
+
if (this.query.statuses) {
|
|
30538
|
+
invitations = invitations.filter(invitation => { var _a; return (_a = this.query.statuses) === null || _a === void 0 ? void 0 : _a.includes(invitation.status); });
|
|
30539
|
+
}
|
|
30540
|
+
if (this.query.targetType) {
|
|
30541
|
+
invitations = invitations.filter(invitation => invitation.targetType === this.query.targetType);
|
|
30542
|
+
}
|
|
30543
|
+
if (this.query.type) {
|
|
30544
|
+
invitations = invitations.filter(invitation => invitation.type === this.query.type);
|
|
30545
|
+
}
|
|
30546
|
+
const sortFn = (() => {
|
|
30547
|
+
switch (this.query.sortBy) {
|
|
30548
|
+
case 'firstCreated':
|
|
30549
|
+
return sortByFirstCreated;
|
|
30550
|
+
case 'lastCreated':
|
|
30551
|
+
return sortByLastCreated;
|
|
30552
|
+
default:
|
|
30553
|
+
return sortByLastCreated;
|
|
30554
|
+
}
|
|
30555
|
+
})();
|
|
30556
|
+
invitations = invitations.sort(sortFn);
|
|
30557
|
+
return invitations;
|
|
30490
30558
|
}
|
|
30491
|
-
// Convert PKCS1 to PKCS8 (crypto.subtle requires PKCS8)
|
|
30492
|
-
const pkcs8 = pkcs1ToPkcs8(pkcs1);
|
|
30493
|
-
// Import the key
|
|
30494
|
-
const key = await crypto.subtle.importKey(PRIVATE_KEY_SIGNATURE, pkcs8.buffer, ALGORITHM, false, ['sign']);
|
|
30495
|
-
return key;
|
|
30496
|
-
}
|
|
30497
|
-
async function createSignature({ timestamp, rooms, }) {
|
|
30498
|
-
const dataStr = rooms
|
|
30499
|
-
.map(item => Object.keys(item)
|
|
30500
|
-
.sort()
|
|
30501
|
-
.map(key => `${key}=${item[key]}`)
|
|
30502
|
-
.join('&'))
|
|
30503
|
-
.join(';');
|
|
30504
|
-
/*
|
|
30505
|
-
* nonceStr needs to be unique for each request
|
|
30506
|
-
*/
|
|
30507
|
-
const nonceStr = uuid$1.v4();
|
|
30508
|
-
const signStr = `nonceStr=${nonceStr}×tamp=${timestamp}&data=${dataStr}==`;
|
|
30509
|
-
const encoder = new TextEncoder();
|
|
30510
|
-
const data = encoder.encode(signStr);
|
|
30511
|
-
const key = await importPrivateKey(privateKey);
|
|
30512
|
-
const sign = await crypto.subtle.sign(ALGORITHM, key, data);
|
|
30513
|
-
return { signature: base64FromArrayBuffer(sign), nonceStr };
|
|
30514
30559
|
}
|
|
30515
30560
|
|
|
30516
30561
|
/**
|
|
30517
|
-
*
|
|
30518
|
-
*
|
|
30562
|
+
* Get invitations
|
|
30563
|
+
*
|
|
30564
|
+
* @param params the query parameters
|
|
30565
|
+
* @param callback the callback to be called when the invitations are updated
|
|
30566
|
+
* @returns invitations
|
|
30567
|
+
*
|
|
30568
|
+
* @category Invitation Live Collection
|
|
30569
|
+
*
|
|
30519
30570
|
*/
|
|
30520
|
-
|
|
30521
|
-
const
|
|
30522
|
-
|
|
30523
|
-
|
|
30524
|
-
if (pendingSessions.length === 0) {
|
|
30525
|
-
return true;
|
|
30571
|
+
const getInvitations$1 = (params, callback, config) => {
|
|
30572
|
+
const { log, cache } = getActiveClient();
|
|
30573
|
+
if (!cache) {
|
|
30574
|
+
console.log(ENABLE_CACHE_MESSAGE);
|
|
30526
30575
|
}
|
|
30527
|
-
|
|
30528
|
-
|
|
30529
|
-
|
|
30530
|
-
|
|
30531
|
-
|
|
30532
|
-
|
|
30533
|
-
|
|
30534
|
-
|
|
30535
|
-
|
|
30536
|
-
}));
|
|
30537
|
-
|
|
30538
|
-
|
|
30539
|
-
|
|
30540
|
-
|
|
30541
|
-
|
|
30542
|
-
|
|
30543
|
-
|
|
30544
|
-
|
|
30545
|
-
|
|
30546
|
-
|
|
30547
|
-
|
|
30548
|
-
|
|
30549
|
-
|
|
30550
|
-
|
|
30551
|
-
|
|
30552
|
-
|
|
30553
|
-
|
|
30554
|
-
|
|
30555
|
-
|
|
30556
|
-
|
|
30557
|
-
|
|
30558
|
-
|
|
30559
|
-
|
|
30560
|
-
|
|
30561
|
-
|
|
30562
|
-
|
|
30576
|
+
const timestamp = Date.now();
|
|
30577
|
+
log(`getInvitations: (tmpid: ${timestamp}) > listen`);
|
|
30578
|
+
const invitationsLiveCollection = new InvitationsLiveCollectionController(params, callback);
|
|
30579
|
+
const disposers = invitationsLiveCollection.startSubscription();
|
|
30580
|
+
const cacheKey = invitationsLiveCollection.getCacheKey();
|
|
30581
|
+
disposers.push(() => {
|
|
30582
|
+
dropFromCache(cacheKey);
|
|
30583
|
+
});
|
|
30584
|
+
return () => {
|
|
30585
|
+
log(`getInvitations (tmpid: ${timestamp}) > dispose`);
|
|
30586
|
+
disposers.forEach(fn => fn());
|
|
30587
|
+
};
|
|
30588
|
+
};
|
|
30589
|
+
|
|
30590
|
+
const categoryLinkedObject = (category) => {
|
|
30591
|
+
return Object.assign(Object.assign({}, category), { get avatar() {
|
|
30592
|
+
var _a;
|
|
30593
|
+
if (!category.avatarFileId)
|
|
30594
|
+
return undefined;
|
|
30595
|
+
const avatar = (_a = pullFromCache([
|
|
30596
|
+
'file',
|
|
30597
|
+
'get',
|
|
30598
|
+
`${category.avatarFileId}`,
|
|
30599
|
+
])) === null || _a === void 0 ? void 0 : _a.data;
|
|
30600
|
+
return avatar;
|
|
30601
|
+
} });
|
|
30602
|
+
};
|
|
30603
|
+
|
|
30604
|
+
const communityLinkedObject = (community) => {
|
|
30605
|
+
return Object.assign(Object.assign({}, community), { get categories() {
|
|
30606
|
+
var _a;
|
|
30607
|
+
return ((_a = community === null || community === void 0 ? void 0 : community.categoryIds) !== null && _a !== void 0 ? _a : [])
|
|
30608
|
+
.map(categoryId => {
|
|
30609
|
+
const cacheData = pullFromCache(['category', 'get', categoryId]);
|
|
30610
|
+
if (cacheData === null || cacheData === void 0 ? void 0 : cacheData.data)
|
|
30611
|
+
return categoryLinkedObject(cacheData.data);
|
|
30612
|
+
return undefined;
|
|
30613
|
+
})
|
|
30614
|
+
.filter(category => !!category);
|
|
30615
|
+
},
|
|
30616
|
+
get avatar() {
|
|
30617
|
+
var _a;
|
|
30618
|
+
if (!community.avatarFileId)
|
|
30619
|
+
return undefined;
|
|
30620
|
+
const avatar = (_a = pullFromCache([
|
|
30621
|
+
'file',
|
|
30622
|
+
'get',
|
|
30623
|
+
community.avatarFileId,
|
|
30624
|
+
])) === null || _a === void 0 ? void 0 : _a.data;
|
|
30625
|
+
return avatar;
|
|
30626
|
+
}, createInvitations: async (userIds) => {
|
|
30627
|
+
await createInvitations({
|
|
30628
|
+
type: "communityMemberInvite" /* InvitationTypeEnum.CommunityMemberInvite */,
|
|
30629
|
+
targetType: 'community',
|
|
30630
|
+
targetId: community.communityId,
|
|
30631
|
+
userIds,
|
|
30563
30632
|
});
|
|
30564
|
-
})
|
|
30565
|
-
|
|
30633
|
+
}, getMemberInvitations: (params, callback) => {
|
|
30634
|
+
return getInvitations$1(Object.assign(Object.assign({}, params), { targetId: community.communityId, targetType: 'community', type: "communityMemberInvite" /* InvitationTypeEnum.CommunityMemberInvite */ }), callback);
|
|
30635
|
+
}, getInvitation: async () => {
|
|
30636
|
+
const { data } = await getInvitation({
|
|
30637
|
+
targetType: 'community',
|
|
30638
|
+
targetId: community.communityId,
|
|
30639
|
+
});
|
|
30640
|
+
return data;
|
|
30641
|
+
}, join: async () => joinRequest(community.communityId), getJoinRequests: (params, callback) => {
|
|
30642
|
+
return getJoinRequests(Object.assign(Object.assign({}, params), { communityId: community.communityId }), callback);
|
|
30643
|
+
}, getMyJoinRequest: async () => {
|
|
30644
|
+
const { data } = await getMyJoinRequest(community.communityId);
|
|
30645
|
+
return data;
|
|
30646
|
+
} });
|
|
30647
|
+
};
|
|
30648
|
+
|
|
30649
|
+
class StoryComputedValue {
|
|
30650
|
+
constructor(targetId, lastStoryExpiresAt, lastStorySeenExpiresAt) {
|
|
30651
|
+
this._syncingStoriesCount = 0;
|
|
30652
|
+
this._errorStoriesCount = 0;
|
|
30653
|
+
this._targetId = targetId;
|
|
30654
|
+
this._lastStoryExpiresAt = lastStoryExpiresAt;
|
|
30655
|
+
this._lastStorySeenExpiresAt = lastStorySeenExpiresAt;
|
|
30656
|
+
this.cacheStoryExpireTime = pullFromCache([
|
|
30657
|
+
"story-expire" /* STORY_KEY_CACHE.EXPIRE */,
|
|
30658
|
+
this._targetId,
|
|
30659
|
+
]);
|
|
30660
|
+
this.cacheStoreSeenTime = pullFromCache([
|
|
30661
|
+
"story-last-seen" /* STORY_KEY_CACHE.LAST_SEEN */,
|
|
30662
|
+
this._targetId,
|
|
30663
|
+
]);
|
|
30664
|
+
this.getTotalStoryByStatus();
|
|
30566
30665
|
}
|
|
30567
|
-
|
|
30568
|
-
|
|
30569
|
-
|
|
30570
|
-
|
|
30571
|
-
|
|
30572
|
-
|
|
30573
|
-
|
|
30574
|
-
|
|
30575
|
-
|
|
30576
|
-
|
|
30577
|
-
|
|
30578
|
-
|
|
30579
|
-
|
|
30580
|
-
|
|
30581
|
-
|
|
30582
|
-
|
|
30583
|
-
|
|
30584
|
-
|
|
30585
|
-
|
|
30586
|
-
|
|
30587
|
-
|
|
30666
|
+
get lastStoryExpiresAt() {
|
|
30667
|
+
return this._lastStoryExpiresAt ? new Date(this._lastStoryExpiresAt).getTime() : 0;
|
|
30668
|
+
}
|
|
30669
|
+
get lastStorySeenExpiresAt() {
|
|
30670
|
+
return this._lastStorySeenExpiresAt ? new Date(this._lastStorySeenExpiresAt).getTime() : 0;
|
|
30671
|
+
}
|
|
30672
|
+
get localLastStoryExpires() {
|
|
30673
|
+
var _a, _b;
|
|
30674
|
+
return ((_a = this.cacheStoryExpireTime) === null || _a === void 0 ? void 0 : _a.data)
|
|
30675
|
+
? new Date((_b = this.cacheStoryExpireTime) === null || _b === void 0 ? void 0 : _b.data).getTime()
|
|
30676
|
+
: 0;
|
|
30677
|
+
}
|
|
30678
|
+
get localLastStorySeenExpiresAt() {
|
|
30679
|
+
var _a, _b;
|
|
30680
|
+
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;
|
|
30681
|
+
}
|
|
30682
|
+
get isContainUnSyncedStory() {
|
|
30683
|
+
const currentSyncingState = pullFromCache([
|
|
30684
|
+
"story-sync-state" /* STORY_KEY_CACHE.SYNC_STATE */,
|
|
30685
|
+
this._targetId,
|
|
30686
|
+
]);
|
|
30687
|
+
if (!(currentSyncingState === null || currentSyncingState === void 0 ? void 0 : currentSyncingState.data))
|
|
30688
|
+
return false;
|
|
30689
|
+
return ["syncing" /* Amity.SyncState.Syncing */, "error" /* Amity.SyncState.Error */].includes(currentSyncingState.data);
|
|
30588
30690
|
}
|
|
30589
|
-
|
|
30590
|
-
|
|
30591
|
-
|
|
30592
|
-
* Room statuses that are considered watchable
|
|
30593
|
-
*/
|
|
30594
|
-
const WATCHABLE_ROOM_STATUSES = ['live', 'recorded'];
|
|
30595
|
-
/**
|
|
30596
|
-
* Generate a random jitter delay between 5 and 30 seconds
|
|
30597
|
-
*/
|
|
30598
|
-
const getJitterDelay = () => {
|
|
30599
|
-
const minDelay = 5000; // 5 seconds
|
|
30600
|
-
const maxDelay = 30000; // 30 seconds
|
|
30601
|
-
return Math.floor(Math.random() * (maxDelay - minDelay + 1)) + minDelay;
|
|
30602
|
-
};
|
|
30603
|
-
/**
|
|
30604
|
-
* Wait for network connection with timeout
|
|
30605
|
-
* @param maxWaitTime Maximum time to wait in milliseconds (default: 60000 = 60 seconds)
|
|
30606
|
-
* @returns Promise that resolves when network is available or timeout is reached
|
|
30607
|
-
*/
|
|
30608
|
-
const waitForNetwork = (maxWaitTime = 60000) => {
|
|
30609
|
-
return new Promise(resolve => {
|
|
30610
|
-
// Simple check - if navigator.onLine is available, use it
|
|
30611
|
-
// Otherwise, assume network is available
|
|
30612
|
-
if (typeof navigator === 'undefined' || typeof navigator.onLine === 'undefined') {
|
|
30613
|
-
resolve();
|
|
30614
|
-
return;
|
|
30691
|
+
getLocalLastSortingDate() {
|
|
30692
|
+
if (this.isContainUnSyncedStory) {
|
|
30693
|
+
return this.localLastStoryExpires;
|
|
30615
30694
|
}
|
|
30616
|
-
|
|
30617
|
-
const checkInterval = 1000; // 1 second
|
|
30618
|
-
const checkConnection = () => {
|
|
30619
|
-
if (navigator.onLine || Date.now() - startTime >= maxWaitTime) {
|
|
30620
|
-
resolve();
|
|
30621
|
-
}
|
|
30622
|
-
else {
|
|
30623
|
-
setTimeout(checkConnection, checkInterval);
|
|
30624
|
-
}
|
|
30625
|
-
};
|
|
30626
|
-
checkConnection();
|
|
30627
|
-
});
|
|
30628
|
-
};
|
|
30629
|
-
/**
|
|
30630
|
-
* AmityRoomAnalytics provides analytics capabilities for room watch sessions
|
|
30631
|
-
*/
|
|
30632
|
-
class AmityRoomAnalytics {
|
|
30633
|
-
constructor(room) {
|
|
30634
|
-
this.storage = getWatchSessionStorage();
|
|
30635
|
-
this.client = getActiveClient();
|
|
30636
|
-
this.room = room;
|
|
30695
|
+
return this.lastStoryExpiresAt;
|
|
30637
30696
|
}
|
|
30638
|
-
|
|
30639
|
-
|
|
30640
|
-
|
|
30641
|
-
|
|
30642
|
-
|
|
30643
|
-
|
|
30644
|
-
|
|
30645
|
-
|
|
30646
|
-
|
|
30647
|
-
throw new ASCApiError('room is not in watchable state', 500000 /* Amity.ServerError.BUSINESS_ERROR */, "error" /* Amity.ErrorLevel.ERROR */);
|
|
30697
|
+
getHasUnseenFlag() {
|
|
30698
|
+
const now = new Date().getTime();
|
|
30699
|
+
const highestSeen = Math.max(this.lastStorySeenExpiresAt, this.localLastStorySeenExpiresAt);
|
|
30700
|
+
pullFromCache([
|
|
30701
|
+
"story-sync-state" /* STORY_KEY_CACHE.SYNC_STATE */,
|
|
30702
|
+
this._targetId,
|
|
30703
|
+
]);
|
|
30704
|
+
if (this.isContainUnSyncedStory) {
|
|
30705
|
+
return this.localLastStoryExpires > now && this.localLastStoryExpires > highestSeen;
|
|
30648
30706
|
}
|
|
30649
|
-
|
|
30650
|
-
const prefix = this.room.status === 'live' ? 'room_' : 'room_playback_';
|
|
30651
|
-
const sessionId = prefix + uuid$1.v4();
|
|
30652
|
-
// Create watch session entity
|
|
30653
|
-
const session = {
|
|
30654
|
-
sessionId,
|
|
30655
|
-
roomId: this.room.roomId,
|
|
30656
|
-
watchSeconds: 0,
|
|
30657
|
-
startTime: startedAt,
|
|
30658
|
-
endTime: null,
|
|
30659
|
-
syncState: 'PENDING',
|
|
30660
|
-
syncedAt: null,
|
|
30661
|
-
retryCount: 0,
|
|
30662
|
-
};
|
|
30663
|
-
// Persist to storage
|
|
30664
|
-
this.storage.addSession(session);
|
|
30665
|
-
return sessionId;
|
|
30707
|
+
return this.lastStoryExpiresAt > now && this.lastStoryExpiresAt > highestSeen;
|
|
30666
30708
|
}
|
|
30667
|
-
|
|
30668
|
-
|
|
30669
|
-
|
|
30670
|
-
|
|
30671
|
-
|
|
30672
|
-
|
|
30673
|
-
*/
|
|
30674
|
-
async updateWatchSession(sessionId, duration, endedAt) {
|
|
30675
|
-
const session = this.storage.getSession(sessionId);
|
|
30676
|
-
if (!session) {
|
|
30677
|
-
throw new Error(`Watch session ${sessionId} not found`);
|
|
30709
|
+
getTotalStoryByStatus() {
|
|
30710
|
+
const stories = queryCache(["story" /* STORY_KEY_CACHE.STORY */, 'get']);
|
|
30711
|
+
if (!stories) {
|
|
30712
|
+
this._errorStoriesCount = 0;
|
|
30713
|
+
this._syncingStoriesCount = 0;
|
|
30714
|
+
return;
|
|
30678
30715
|
}
|
|
30679
|
-
|
|
30680
|
-
|
|
30681
|
-
|
|
30682
|
-
|
|
30716
|
+
const groupByType = stories.reduce((acc, story) => {
|
|
30717
|
+
const { data: { targetId, syncState, isDeleted }, } = story;
|
|
30718
|
+
if (targetId === this._targetId && !isDeleted) {
|
|
30719
|
+
acc[syncState] += 1;
|
|
30720
|
+
}
|
|
30721
|
+
return acc;
|
|
30722
|
+
}, {
|
|
30723
|
+
syncing: 0,
|
|
30724
|
+
error: 0,
|
|
30725
|
+
synced: 0,
|
|
30683
30726
|
});
|
|
30727
|
+
this._errorStoriesCount = groupByType.error;
|
|
30728
|
+
this._syncingStoriesCount = groupByType.syncing;
|
|
30684
30729
|
}
|
|
30685
|
-
|
|
30686
|
-
|
|
30687
|
-
|
|
30688
|
-
|
|
30689
|
-
|
|
30690
|
-
// Execute with jitter delay (5-30 seconds)
|
|
30691
|
-
const jitterDelay = getJitterDelay();
|
|
30692
|
-
this.client.log('room/RoomAnalytics: syncPendingWatchSessions called, jitter delay:', `${jitterDelay}ms`);
|
|
30693
|
-
setTimeout(async () => {
|
|
30694
|
-
this.client.log('room/RoomAnalytics: Jitter delay completed, starting sync process');
|
|
30695
|
-
try {
|
|
30696
|
-
// Reset any SYNCING sessions back to PENDING
|
|
30697
|
-
const syncingSessions = this.storage.getSyncingSessions();
|
|
30698
|
-
this.client.log('room/RoomAnalytics: SYNCING sessions to reset:', syncingSessions.length);
|
|
30699
|
-
syncingSessions.forEach(session => {
|
|
30700
|
-
this.storage.updateSession(session.sessionId, { syncState: 'PENDING' });
|
|
30701
|
-
});
|
|
30702
|
-
// Wait for network connection (max 60 seconds)
|
|
30703
|
-
await waitForNetwork(60000);
|
|
30704
|
-
this.client.log('room/RoomAnalytics: Network available');
|
|
30705
|
-
// Sync pending sessions
|
|
30706
|
-
this.client.log('room/RoomAnalytics: Calling syncWatchSessions()');
|
|
30707
|
-
await syncWatchSessions();
|
|
30708
|
-
this.client.log('room/RoomAnalytics: syncWatchSessions completed');
|
|
30709
|
-
}
|
|
30710
|
-
catch (error) {
|
|
30711
|
-
// Error is already handled in syncWatchSessions
|
|
30712
|
-
console.error('Failed to sync watch sessions:', error);
|
|
30713
|
-
}
|
|
30714
|
-
}, jitterDelay);
|
|
30730
|
+
get syncingStoriesCount() {
|
|
30731
|
+
return this._syncingStoriesCount;
|
|
30732
|
+
}
|
|
30733
|
+
get failedStoriesCount() {
|
|
30734
|
+
return this._errorStoriesCount;
|
|
30715
30735
|
}
|
|
30716
30736
|
}
|
|
30717
30737
|
|
|
30718
|
-
const
|
|
30719
|
-
|
|
30720
|
-
|
|
30721
|
-
|
|
30722
|
-
|
|
30723
|
-
|
|
30738
|
+
const storyTargetLinkedObject = (storyTarget) => {
|
|
30739
|
+
const { targetType, targetId, lastStoryExpiresAt, lastStorySeenExpiresAt, targetUpdatedAt, localFilter, } = storyTarget;
|
|
30740
|
+
const computedValue = new StoryComputedValue(targetId, lastStoryExpiresAt, lastStorySeenExpiresAt);
|
|
30741
|
+
return {
|
|
30742
|
+
targetType,
|
|
30743
|
+
targetId,
|
|
30744
|
+
lastStoryExpiresAt,
|
|
30745
|
+
updatedAt: targetUpdatedAt,
|
|
30746
|
+
// Additional data
|
|
30747
|
+
hasUnseen: computedValue.getHasUnseenFlag(),
|
|
30748
|
+
syncingStoriesCount: computedValue.syncingStoriesCount,
|
|
30749
|
+
failedStoriesCount: computedValue.failedStoriesCount,
|
|
30750
|
+
localFilter,
|
|
30751
|
+
localLastExpires: computedValue.localLastStoryExpires,
|
|
30752
|
+
localLastSeen: computedValue.localLastStorySeenExpiresAt,
|
|
30753
|
+
localSortingDate: computedValue.getLocalLastSortingDate(),
|
|
30754
|
+
};
|
|
30755
|
+
};
|
|
30756
|
+
|
|
30757
|
+
const storyLinkedObject = (story) => {
|
|
30758
|
+
const analyticsEngineInstance = AnalyticsEngine$1.getInstance();
|
|
30759
|
+
const storyTargetCache = pullFromCache([
|
|
30760
|
+
"storyTarget" /* STORY_KEY_CACHE.STORY_TARGET */,
|
|
30761
|
+
'get',
|
|
30762
|
+
story.targetId,
|
|
30763
|
+
]);
|
|
30764
|
+
const communityCacheData = pullFromCache(['community', 'get', story.targetId]);
|
|
30765
|
+
return Object.assign(Object.assign({}, story), { analytics: {
|
|
30766
|
+
markAsSeen: () => {
|
|
30767
|
+
if (!story.expiresAt)
|
|
30768
|
+
return;
|
|
30769
|
+
if (story.syncState !== "synced" /* Amity.SyncState.Synced */)
|
|
30770
|
+
return;
|
|
30771
|
+
analyticsEngineInstance.markStoryAsViewed(story);
|
|
30772
|
+
},
|
|
30773
|
+
markLinkAsClicked: () => {
|
|
30774
|
+
if (!story.expiresAt)
|
|
30775
|
+
return;
|
|
30776
|
+
if (story.syncState !== "synced" /* Amity.SyncState.Synced */)
|
|
30777
|
+
return;
|
|
30778
|
+
analyticsEngineInstance.markStoryAsClicked(story);
|
|
30779
|
+
},
|
|
30780
|
+
}, get videoData() {
|
|
30781
|
+
var _a, _b;
|
|
30782
|
+
const cache = pullFromCache([
|
|
30783
|
+
'file',
|
|
30784
|
+
'get',
|
|
30785
|
+
(_b = (_a = story.data) === null || _a === void 0 ? void 0 : _a.videoFileId) === null || _b === void 0 ? void 0 : _b.original,
|
|
30786
|
+
]);
|
|
30787
|
+
if (!cache)
|
|
30788
|
+
return undefined;
|
|
30789
|
+
const { data } = cache;
|
|
30790
|
+
return data || undefined;
|
|
30791
|
+
},
|
|
30792
|
+
get imageData() {
|
|
30793
|
+
var _a, _b;
|
|
30794
|
+
if (!((_a = story.data) === null || _a === void 0 ? void 0 : _a.fileId))
|
|
30795
|
+
return undefined;
|
|
30796
|
+
const cache = pullFromCache(['file', 'get', (_b = story.data) === null || _b === void 0 ? void 0 : _b.fileId]);
|
|
30797
|
+
if (!cache)
|
|
30798
|
+
return undefined;
|
|
30799
|
+
const { data } = cache;
|
|
30800
|
+
if (!data)
|
|
30801
|
+
return undefined;
|
|
30802
|
+
return Object.assign(Object.assign({}, data), { fileUrl: `${data.fileUrl}?size=full` });
|
|
30724
30803
|
},
|
|
30725
30804
|
get community() {
|
|
30726
|
-
|
|
30727
|
-
|
|
30805
|
+
if (story.targetType !== 'community')
|
|
30806
|
+
return undefined;
|
|
30807
|
+
if (!(communityCacheData === null || communityCacheData === void 0 ? void 0 : communityCacheData.data))
|
|
30808
|
+
return undefined;
|
|
30809
|
+
return communityLinkedObject(communityCacheData.data);
|
|
30810
|
+
},
|
|
30811
|
+
get communityCategories() {
|
|
30812
|
+
if (story.targetType !== 'community')
|
|
30813
|
+
return undefined;
|
|
30814
|
+
if (!communityCacheData)
|
|
30815
|
+
return undefined;
|
|
30816
|
+
const { data: { categoryIds }, } = communityCacheData;
|
|
30817
|
+
if (categoryIds.length === 0)
|
|
30818
|
+
return undefined;
|
|
30819
|
+
return categoryIds
|
|
30820
|
+
.map(categoryId => {
|
|
30821
|
+
const categoryCacheData = pullFromCache(['category', 'get', categoryId]);
|
|
30822
|
+
return (categoryCacheData === null || categoryCacheData === void 0 ? void 0 : categoryCacheData.data) || undefined;
|
|
30823
|
+
})
|
|
30824
|
+
.filter(category => category !== undefined);
|
|
30825
|
+
},
|
|
30826
|
+
get creator() {
|
|
30827
|
+
const cacheData = pullFromCache(['user', 'get', story.creatorPublicId]);
|
|
30828
|
+
if (!(cacheData === null || cacheData === void 0 ? void 0 : cacheData.data))
|
|
30728
30829
|
return;
|
|
30729
|
-
return (
|
|
30830
|
+
return userLinkedObject(cacheData.data);
|
|
30730
30831
|
},
|
|
30731
|
-
get
|
|
30732
|
-
|
|
30733
|
-
|
|
30734
|
-
return
|
|
30832
|
+
get storyTarget() {
|
|
30833
|
+
if (!(storyTargetCache === null || storyTargetCache === void 0 ? void 0 : storyTargetCache.data))
|
|
30834
|
+
return;
|
|
30835
|
+
return storyTargetLinkedObject(storyTargetCache.data);
|
|
30735
30836
|
},
|
|
30736
|
-
get
|
|
30737
|
-
|
|
30738
|
-
|
|
30739
|
-
|
|
30740
|
-
|
|
30741
|
-
|
|
30742
|
-
|
|
30743
|
-
|
|
30744
|
-
return undefined;
|
|
30745
|
-
return roomLinkedObject(roomCache);
|
|
30746
|
-
})
|
|
30747
|
-
.filter(isNonNullable);
|
|
30748
|
-
}, participants: room.participants.map(participant => (Object.assign(Object.assign({}, participant), { get user() {
|
|
30749
|
-
var _a;
|
|
30750
|
-
const user = (_a = pullFromCache(['user', 'get', participant.userId])) === null || _a === void 0 ? void 0 : _a.data;
|
|
30751
|
-
return user ? userLinkedObject(user) : user;
|
|
30752
|
-
} }))), getLiveChat: () => getLiveChat(room), createInvitation: (userId) => createInvitations({
|
|
30753
|
-
type: "livestreamCohostInvite" /* InvitationTypeEnum.LivestreamCohostInvite */,
|
|
30754
|
-
targetType: 'room',
|
|
30755
|
-
targetId: room.roomId,
|
|
30756
|
-
userIds: [userId],
|
|
30757
|
-
}), getInvitations: async () => {
|
|
30758
|
-
const { data } = await getInvitation({
|
|
30759
|
-
targetId: room.roomId,
|
|
30760
|
-
targetType: 'room',
|
|
30761
|
-
type: "livestreamCohostInvite" /* InvitationTypeEnum.LivestreamCohostInvite */,
|
|
30762
|
-
});
|
|
30763
|
-
return data;
|
|
30764
|
-
}, analytics() {
|
|
30765
|
-
// Use 'this' to avoid creating a new room object
|
|
30766
|
-
return new AmityRoomAnalytics(this);
|
|
30837
|
+
get isSeen() {
|
|
30838
|
+
const cacheData = pullFromCache(["story-last-seen" /* STORY_KEY_CACHE.LAST_SEEN */, story.targetId]);
|
|
30839
|
+
if (!(storyTargetCache === null || storyTargetCache === void 0 ? void 0 : storyTargetCache.data))
|
|
30840
|
+
return false;
|
|
30841
|
+
const localLastSeen = (cacheData === null || cacheData === void 0 ? void 0 : cacheData.data) ? new Date(cacheData.data).getTime() : 0;
|
|
30842
|
+
const serverLastSeen = new Date(storyTargetCache === null || storyTargetCache === void 0 ? void 0 : storyTargetCache.data.lastStorySeenExpiresAt).getTime() || 0;
|
|
30843
|
+
const expiresAt = new Date(story.expiresAt).getTime();
|
|
30844
|
+
return Math.max(localLastSeen, serverLastSeen) >= expiresAt;
|
|
30767
30845
|
} });
|
|
30768
30846
|
};
|
|
30769
30847
|
|
|
30770
|
-
const pollLinkedObject = (poll) => {
|
|
30771
|
-
return Object.assign(Object.assign({}, poll), { answers: poll.answers.map(answer => (Object.assign(Object.assign({}, answer), { get image() {
|
|
30772
|
-
var _a;
|
|
30773
|
-
if (!answer.fileId)
|
|
30774
|
-
return undefined;
|
|
30775
|
-
return (_a = pullFromCache(['file', 'get', answer.fileId])) === null || _a === void 0 ? void 0 : _a.data;
|
|
30776
|
-
} }))) });
|
|
30777
|
-
};
|
|
30778
|
-
|
|
30779
|
-
/*
|
|
30780
|
-
* verifies membership status
|
|
30781
|
-
*/
|
|
30782
|
-
function isMember(membership) {
|
|
30783
|
-
return membership !== 'none';
|
|
30784
|
-
}
|
|
30785
|
-
/*
|
|
30786
|
-
* checks if currently logged in user is part of the community
|
|
30787
|
-
*/
|
|
30788
|
-
function isCurrentUserPartOfCommunity(c, m) {
|
|
30789
|
-
const { userId } = getActiveUser();
|
|
30790
|
-
return c.communityId === m.communityId && m.userId === userId;
|
|
30791
|
-
}
|
|
30792
|
-
/*
|
|
30793
|
-
* For mqtt events server will not send user specific data as it's broadcasted
|
|
30794
|
-
* to multiple users and it also does not include communityUser
|
|
30795
|
-
*
|
|
30796
|
-
* Client SDK needs to check for the existing isJoined field in cache data before calculating.
|
|
30797
|
-
* Althought this can be calculated, it's not scalable.
|
|
30798
|
-
*/
|
|
30799
|
-
function updateMembershipStatus(communities, communityUsers) {
|
|
30800
|
-
return communities.map(c => {
|
|
30801
|
-
const cachedCommunity = pullFromCache([
|
|
30802
|
-
'community',
|
|
30803
|
-
'get',
|
|
30804
|
-
c.communityId,
|
|
30805
|
-
]);
|
|
30806
|
-
if ((cachedCommunity === null || cachedCommunity === void 0 ? void 0 : cachedCommunity.data) && (cachedCommunity === null || cachedCommunity === void 0 ? void 0 : cachedCommunity.data.hasOwnProperty('isJoined'))) {
|
|
30807
|
-
return Object.assign(Object.assign({}, cachedCommunity.data), c);
|
|
30808
|
-
}
|
|
30809
|
-
const isJoined = c.isJoined !== undefined
|
|
30810
|
-
? c.isJoined
|
|
30811
|
-
: communityUsers.some(m => isCurrentUserPartOfCommunity(c, m) && isMember(m.communityMembership));
|
|
30812
|
-
return Object.assign(Object.assign({}, c), { isJoined });
|
|
30813
|
-
});
|
|
30814
|
-
}
|
|
30815
|
-
|
|
30816
|
-
const getMatchPostSetting = (value) => {
|
|
30817
|
-
var _a;
|
|
30818
|
-
return (_a = Object.keys(CommunityPostSettingMaps).find(key => value.needApprovalOnPostCreation ===
|
|
30819
|
-
CommunityPostSettingMaps[key].needApprovalOnPostCreation &&
|
|
30820
|
-
value.onlyAdminCanPost === CommunityPostSettingMaps[key].onlyAdminCanPost)) !== null && _a !== void 0 ? _a : DefaultCommunityPostSetting;
|
|
30821
|
-
};
|
|
30822
|
-
function addPostSetting({ communities }) {
|
|
30823
|
-
return communities.map((_a) => {
|
|
30824
|
-
var { needApprovalOnPostCreation, onlyAdminCanPost } = _a, restCommunityPayload = __rest(_a, ["needApprovalOnPostCreation", "onlyAdminCanPost"]);
|
|
30825
|
-
return (Object.assign({ postSetting: getMatchPostSetting({
|
|
30826
|
-
needApprovalOnPostCreation,
|
|
30827
|
-
onlyAdminCanPost,
|
|
30828
|
-
}) }, restCommunityPayload));
|
|
30829
|
-
});
|
|
30830
|
-
}
|
|
30831
|
-
const prepareCommunityPayload = (rawPayload) => {
|
|
30832
|
-
const communitiesWithPostSetting = addPostSetting({ communities: rawPayload.communities });
|
|
30833
|
-
// Convert users to internal format
|
|
30834
|
-
const internalUsers = rawPayload.users.map(convertRawUserToInternalUser);
|
|
30835
|
-
// map users with community
|
|
30836
|
-
const mappedCommunityUsers = rawPayload.communityUsers.map(communityUser => {
|
|
30837
|
-
const user = internalUsers.find(user => user.userId === communityUser.userId);
|
|
30838
|
-
return Object.assign(Object.assign({}, communityUser), { user });
|
|
30839
|
-
});
|
|
30840
|
-
const communityWithMembershipStatus = updateMembershipStatus(communitiesWithPostSetting, mappedCommunityUsers);
|
|
30841
|
-
return Object.assign(Object.assign({}, rawPayload), { users: rawPayload.users.map(convertRawUserToInternalUser), communities: communityWithMembershipStatus, communityUsers: mappedCommunityUsers });
|
|
30842
|
-
};
|
|
30843
|
-
const prepareCommunityJoinRequestPayload = (rawPayload) => {
|
|
30844
|
-
const mappedJoinRequests = rawPayload.joinRequests.map(joinRequest => {
|
|
30845
|
-
return Object.assign(Object.assign({}, joinRequest), { joinRequestId: joinRequest._id });
|
|
30846
|
-
});
|
|
30847
|
-
const users = rawPayload.users.map(convertRawUserToInternalUser);
|
|
30848
|
-
return Object.assign(Object.assign({}, rawPayload), { joinRequests: mappedJoinRequests, users });
|
|
30849
|
-
};
|
|
30850
|
-
const prepareCommunityMembershipPayload = (rawPayload) => {
|
|
30851
|
-
const communitiesWithPostSetting = addPostSetting({ communities: rawPayload.communities });
|
|
30852
|
-
// map users with community
|
|
30853
|
-
const mappedCommunityUsers = rawPayload.communityUsers.map(communityUser => {
|
|
30854
|
-
const user = rawPayload.users.find(user => user.userId === communityUser.userId);
|
|
30855
|
-
return Object.assign(Object.assign({}, communityUser), { user });
|
|
30856
|
-
});
|
|
30857
|
-
const communityWithMembershipStatus = updateMembershipStatus(communitiesWithPostSetting, mappedCommunityUsers);
|
|
30858
|
-
return Object.assign(Object.assign({}, rawPayload), { communities: communityWithMembershipStatus, communityUsers: mappedCommunityUsers });
|
|
30859
|
-
};
|
|
30860
|
-
const prepareCommunityRequest = (params) => {
|
|
30861
|
-
const { postSetting = undefined, storySetting } = params, restParam = __rest(params, ["postSetting", "storySetting"]);
|
|
30862
|
-
return Object.assign(Object.assign(Object.assign({}, restParam), (postSetting ? CommunityPostSettingMaps[postSetting] : undefined)), {
|
|
30863
|
-
// Convert story setting to the actual value. (Allow by default)
|
|
30864
|
-
allowCommentInStory: typeof (storySetting === null || storySetting === void 0 ? void 0 : storySetting.enableComment) === 'boolean' ? storySetting.enableComment : true });
|
|
30865
|
-
};
|
|
30866
|
-
const prepareSemanticSearchCommunityPayload = (_a) => {
|
|
30867
|
-
var communityPayload = __rest(_a, ["searchResult"]);
|
|
30868
|
-
const processedCommunityPayload = prepareCommunityPayload(communityPayload);
|
|
30869
|
-
return Object.assign({}, processedCommunityPayload);
|
|
30870
|
-
};
|
|
30871
|
-
|
|
30872
30848
|
/* begin_public_function
|
|
30873
|
-
id:
|
|
30849
|
+
id: channel.create
|
|
30874
30850
|
*/
|
|
30875
30851
|
/**
|
|
30876
30852
|
* ```js
|
|
30877
|
-
* import {
|
|
30878
|
-
* const
|
|
30853
|
+
* import { createChannel } from '@amityco/ts-sdk-react-native'
|
|
30854
|
+
* const created = await createChannel({ displayName: 'foobar' })
|
|
30879
30855
|
* ```
|
|
30880
30856
|
*
|
|
30881
|
-
*
|
|
30857
|
+
* Creates an {@link Amity.Channel}
|
|
30882
30858
|
*
|
|
30883
|
-
* @param
|
|
30884
|
-
* @returns
|
|
30859
|
+
* @param bundle The data necessary to create a new {@link Amity.Channel}
|
|
30860
|
+
* @returns The newly created {@link Amity.Channel}
|
|
30885
30861
|
*
|
|
30886
|
-
* @category
|
|
30862
|
+
* @category Channel API
|
|
30887
30863
|
* @async
|
|
30888
30864
|
*/
|
|
30889
|
-
const
|
|
30890
|
-
var _a;
|
|
30865
|
+
const createChannel = async (bundle) => {
|
|
30891
30866
|
const client = getActiveClient();
|
|
30892
|
-
client.log('
|
|
30893
|
-
|
|
30894
|
-
|
|
30895
|
-
|
|
30896
|
-
|
|
30897
|
-
'joinRequest',
|
|
30898
|
-
'get',
|
|
30899
|
-
joinRequest.joinRequestId,
|
|
30900
|
-
])) === null || _a === void 0 ? void 0 : _a.data;
|
|
30901
|
-
if (joinRequestCache) {
|
|
30902
|
-
upsertInCache(['joinRequest', 'get', joinRequest.joinRequestId], {
|
|
30903
|
-
status: "approved" /* JoinRequestStatusEnum.Approved */,
|
|
30904
|
-
});
|
|
30905
|
-
fireEvent('local.joinRequest.updated', [joinRequestCache]);
|
|
30867
|
+
client.log('user/createChannel', bundle);
|
|
30868
|
+
let payload;
|
|
30869
|
+
/* c8 ignore next */
|
|
30870
|
+
if ((bundle === null || bundle === void 0 ? void 0 : bundle.type) === 'conversation') {
|
|
30871
|
+
payload = await client.http.post('/api/v3/channels/conversation', Object.assign(Object.assign({}, bundle), { isDistinct: true }));
|
|
30906
30872
|
}
|
|
30907
|
-
|
|
30873
|
+
else {
|
|
30874
|
+
const { isPublic } = bundle, restParams = __rest(bundle, ["isPublic"]);
|
|
30875
|
+
payload = await client.http.post('/api/v3/channels', Object.assign(Object.assign({}, restParams), {
|
|
30876
|
+
/* c8 ignore next */
|
|
30877
|
+
isPublic: (bundle === null || bundle === void 0 ? void 0 : bundle.type) === 'community' ? isPublic : undefined }));
|
|
30878
|
+
}
|
|
30879
|
+
const data = await prepareChannelPayload(payload.data);
|
|
30880
|
+
const cachedAt = client.cache && Date.now();
|
|
30881
|
+
if (client.cache)
|
|
30882
|
+
ingestInCache(data, { cachedAt });
|
|
30883
|
+
const { channels } = data;
|
|
30884
|
+
return {
|
|
30885
|
+
data: constructChannelObject(channels[0]),
|
|
30886
|
+
cachedAt,
|
|
30887
|
+
};
|
|
30908
30888
|
};
|
|
30909
30889
|
/* end_public_function */
|
|
30910
30890
|
|
|
30911
|
-
/* begin_public_function
|
|
30912
|
-
id: joinRequest.cancel
|
|
30913
|
-
*/
|
|
30914
30891
|
/**
|
|
30915
30892
|
* ```js
|
|
30916
|
-
* import {
|
|
30917
|
-
* const
|
|
30893
|
+
* import { getChannel } from '@amityco/ts-sdk-react-native'
|
|
30894
|
+
* const channel = await getChannel('foobar')
|
|
30918
30895
|
* ```
|
|
30919
30896
|
*
|
|
30920
|
-
*
|
|
30897
|
+
* Fetches a {@link Amity.Channel} object
|
|
30921
30898
|
*
|
|
30922
|
-
* @param
|
|
30923
|
-
* @returns
|
|
30899
|
+
* @param channelId the ID of the {@link Amity.Channel} to fetch
|
|
30900
|
+
* @returns the associated {@link Amity.Channel} object
|
|
30924
30901
|
*
|
|
30925
|
-
* @category
|
|
30902
|
+
* @category Channel API
|
|
30926
30903
|
* @async
|
|
30927
30904
|
*/
|
|
30928
|
-
const
|
|
30929
|
-
var _a;
|
|
30905
|
+
const getChannel$1 = async (channelId) => {
|
|
30930
30906
|
const client = getActiveClient();
|
|
30931
|
-
client.log('
|
|
30932
|
-
|
|
30933
|
-
|
|
30934
|
-
|
|
30935
|
-
|
|
30936
|
-
|
|
30937
|
-
|
|
30938
|
-
|
|
30939
|
-
|
|
30940
|
-
status: "cancelled" /* JoinRequestStatusEnum.Cancelled */,
|
|
30941
|
-
});
|
|
30942
|
-
fireEvent('local.joinRequest.deleted', [joinRequestCache]);
|
|
30907
|
+
client.log('channel/getChannel', channelId);
|
|
30908
|
+
isInTombstone('channel', channelId);
|
|
30909
|
+
let data;
|
|
30910
|
+
try {
|
|
30911
|
+
const { data: payload } = await client.http.get(`/api/v3/channels/${encodeURIComponent(channelId)}`);
|
|
30912
|
+
data = await prepareChannelPayload(payload);
|
|
30913
|
+
if (client.isUnreadCountEnabled && client.getMarkerSyncConsistentMode()) {
|
|
30914
|
+
prepareUnreadCountInfo(payload);
|
|
30915
|
+
}
|
|
30943
30916
|
}
|
|
30944
|
-
|
|
30917
|
+
catch (error) {
|
|
30918
|
+
if (checkIfShouldGoesToTombstone(error === null || error === void 0 ? void 0 : error.code)) {
|
|
30919
|
+
// NOTE: use channelPublicId as tombstone cache key since we cannot get the channelPrivateId that come along with channel data from server
|
|
30920
|
+
pushToTombstone('channel', channelId);
|
|
30921
|
+
}
|
|
30922
|
+
throw error;
|
|
30923
|
+
}
|
|
30924
|
+
const cachedAt = client.cache && Date.now();
|
|
30925
|
+
if (client.cache)
|
|
30926
|
+
ingestInCache(data, { cachedAt });
|
|
30927
|
+
const { channels } = data;
|
|
30928
|
+
return {
|
|
30929
|
+
data: channels.find(channel => channel.channelId === channelId),
|
|
30930
|
+
cachedAt,
|
|
30931
|
+
};
|
|
30945
30932
|
};
|
|
30946
|
-
/* end_public_function */
|
|
30947
|
-
|
|
30948
|
-
/* begin_public_function
|
|
30949
|
-
id: joinRequest.reject
|
|
30950
|
-
*/
|
|
30951
30933
|
/**
|
|
30952
30934
|
* ```js
|
|
30953
|
-
* import {
|
|
30954
|
-
* const
|
|
30935
|
+
* import { getChannel } from '@amityco/ts-sdk-react-native'
|
|
30936
|
+
* const channel = getChannel.locally('foobar')
|
|
30955
30937
|
* ```
|
|
30956
30938
|
*
|
|
30957
|
-
*
|
|
30939
|
+
* Fetches a {@link Amity.Channel} object from cache
|
|
30958
30940
|
*
|
|
30959
|
-
* @param
|
|
30960
|
-
* @returns
|
|
30941
|
+
* @param channelId the ID of the {@link Amity.Channel} to fetch
|
|
30942
|
+
* @returns the associated {@link Amity.Channel} object
|
|
30961
30943
|
*
|
|
30962
|
-
* @category
|
|
30963
|
-
* @async
|
|
30944
|
+
* @category Channel API
|
|
30964
30945
|
*/
|
|
30965
|
-
|
|
30946
|
+
getChannel$1.locally = (channelId) => {
|
|
30966
30947
|
var _a;
|
|
30967
30948
|
const client = getActiveClient();
|
|
30968
|
-
client.log('
|
|
30969
|
-
|
|
30970
|
-
|
|
30949
|
+
client.log('channel/getChannel.locally', channelId);
|
|
30950
|
+
if (!client.cache)
|
|
30951
|
+
return;
|
|
30952
|
+
// use queryCache to get all channel caches and filter by channelPublicId since we use channelPrivateId as cache key
|
|
30953
|
+
const cached = (_a = queryCache(['channel', 'get'])) === null || _a === void 0 ? void 0 : _a.filter(({ data }) => {
|
|
30954
|
+
return data.channelPublicId === channelId;
|
|
30971
30955
|
});
|
|
30972
|
-
|
|
30973
|
-
|
|
30974
|
-
|
|
30975
|
-
|
|
30976
|
-
|
|
30977
|
-
|
|
30978
|
-
upsertInCache(['joinRequest', 'get', joinRequest.joinRequestId], {
|
|
30979
|
-
status: "rejected" /* JoinRequestStatusEnum.Rejected */,
|
|
30980
|
-
});
|
|
30981
|
-
fireEvent('local.joinRequest.updated', [joinRequestCache]);
|
|
30982
|
-
}
|
|
30983
|
-
return data.success;
|
|
30984
|
-
};
|
|
30985
|
-
/* end_public_function */
|
|
30986
|
-
|
|
30987
|
-
const joinRequestLinkedObject = (joinRequest) => {
|
|
30988
|
-
return Object.assign(Object.assign({}, joinRequest), { get user() {
|
|
30989
|
-
var _a;
|
|
30990
|
-
const user = (_a = pullFromCache([
|
|
30991
|
-
'user',
|
|
30992
|
-
'get',
|
|
30993
|
-
joinRequest.requestorPublicId,
|
|
30994
|
-
])) === null || _a === void 0 ? void 0 : _a.data;
|
|
30995
|
-
if (!user)
|
|
30996
|
-
return undefined;
|
|
30997
|
-
return userLinkedObject(user);
|
|
30998
|
-
}, cancel: async () => {
|
|
30999
|
-
await cancelJoinRequest(joinRequest);
|
|
31000
|
-
}, approve: async () => {
|
|
31001
|
-
await approveJoinRequest(joinRequest);
|
|
31002
|
-
}, reject: async () => {
|
|
31003
|
-
await rejectJoinRequest(joinRequest);
|
|
31004
|
-
} });
|
|
30956
|
+
if (!cached || (cached === null || cached === void 0 ? void 0 : cached.length) === 0)
|
|
30957
|
+
return;
|
|
30958
|
+
return {
|
|
30959
|
+
data: cached[0].data,
|
|
30960
|
+
cachedAt: cached[0].cachedAt,
|
|
30961
|
+
};
|
|
31005
30962
|
};
|
|
31006
30963
|
|
|
31007
|
-
/* begin_public_function
|
|
31008
|
-
id: community.getMyJoinRequest
|
|
31009
|
-
*/
|
|
31010
30964
|
/**
|
|
31011
30965
|
* ```js
|
|
31012
|
-
* import {
|
|
31013
|
-
* const
|
|
30966
|
+
* import { getStream } from '@amityco/ts-sdk-react-native'
|
|
30967
|
+
* const stream = await getStream('foobar')
|
|
31014
30968
|
* ```
|
|
31015
30969
|
*
|
|
31016
|
-
*
|
|
30970
|
+
* Fetches a {@link Amity.Channel} object linked with a current stream
|
|
31017
30971
|
*
|
|
31018
|
-
* @param
|
|
31019
|
-
* @returns
|
|
30972
|
+
* @param stream {@link Amity.Stream} that has linked live channel
|
|
30973
|
+
* @returns the associated {@link Amity.Channel<'live'>} object
|
|
31020
30974
|
*
|
|
31021
|
-
* @category
|
|
30975
|
+
* @category Stream API
|
|
31022
30976
|
* @async
|
|
31023
30977
|
*/
|
|
31024
|
-
const
|
|
30978
|
+
const getLiveChat$1 = async (stream) => {
|
|
30979
|
+
var _a;
|
|
31025
30980
|
const client = getActiveClient();
|
|
31026
|
-
client.log('
|
|
31027
|
-
|
|
31028
|
-
|
|
31029
|
-
|
|
31030
|
-
|
|
31031
|
-
|
|
31032
|
-
|
|
31033
|
-
|
|
31034
|
-
|
|
31035
|
-
|
|
30981
|
+
client.log('stream/getLiveChat', stream.streamId);
|
|
30982
|
+
if (stream.channelId) {
|
|
30983
|
+
const channel = (_a = pullFromCache([
|
|
30984
|
+
'channel',
|
|
30985
|
+
'get',
|
|
30986
|
+
stream.channelId,
|
|
30987
|
+
])) === null || _a === void 0 ? void 0 : _a.data;
|
|
30988
|
+
if (channel)
|
|
30989
|
+
return channelLinkedObject(constructChannelObject(channel));
|
|
30990
|
+
const { data } = await getChannel$1(stream.channelId);
|
|
30991
|
+
return channelLinkedObject(constructChannelObject(data));
|
|
30992
|
+
}
|
|
30993
|
+
// No Channel ID
|
|
30994
|
+
// streamer: create a new live channel
|
|
30995
|
+
if (stream.userId === client.userId) {
|
|
30996
|
+
const { data: channel } = await createChannel({
|
|
30997
|
+
type: 'live',
|
|
30998
|
+
postId: stream.postId,
|
|
30999
|
+
videoStreamId: stream.streamId,
|
|
31000
|
+
});
|
|
31001
|
+
// Update channelId to stream object in cache
|
|
31002
|
+
mergeInCache(['stream', 'get', stream.streamId], {
|
|
31003
|
+
channelId: channel.channelId,
|
|
31004
|
+
});
|
|
31005
|
+
return channel;
|
|
31006
|
+
}
|
|
31007
|
+
// watcher: return undefined
|
|
31008
|
+
return undefined;
|
|
31036
31009
|
};
|
|
31037
|
-
/* end_public_function */
|
|
31038
31010
|
|
|
31039
|
-
|
|
31040
|
-
|
|
31041
|
-
|
|
31011
|
+
const GET_WATCHER_URLS = Symbol('getWatcherUrls');
|
|
31012
|
+
const streamLinkedObject = (stream) => {
|
|
31013
|
+
return Object.assign(Object.assign({}, stream), { get moderation() {
|
|
31014
|
+
var _a;
|
|
31015
|
+
return (_a = pullFromCache(['streamModeration', 'get', stream.streamId])) === null || _a === void 0 ? void 0 : _a.data;
|
|
31016
|
+
},
|
|
31017
|
+
get post() {
|
|
31018
|
+
var _a;
|
|
31019
|
+
if (stream.referenceType !== 'post')
|
|
31020
|
+
return;
|
|
31021
|
+
return (_a = pullFromCache(['post', 'get', stream.referenceId])) === null || _a === void 0 ? void 0 : _a.data;
|
|
31022
|
+
},
|
|
31023
|
+
get community() {
|
|
31024
|
+
var _a;
|
|
31025
|
+
if (stream.targetType !== 'community')
|
|
31026
|
+
return;
|
|
31027
|
+
return (_a = pullFromCache(['community', 'get', stream.targetId])) === null || _a === void 0 ? void 0 : _a.data;
|
|
31028
|
+
},
|
|
31029
|
+
get user() {
|
|
31030
|
+
var _a;
|
|
31031
|
+
return (_a = pullFromCache(['user', 'get', stream.userId])) === null || _a === void 0 ? void 0 : _a.data;
|
|
31032
|
+
},
|
|
31033
|
+
get childStreams() {
|
|
31034
|
+
if (!stream.childStreamIds || stream.childStreamIds.length === 0)
|
|
31035
|
+
return [];
|
|
31036
|
+
return stream.childStreamIds
|
|
31037
|
+
.map(id => {
|
|
31038
|
+
var _a;
|
|
31039
|
+
const streamCache = (_a = pullFromCache(['stream', 'get', id])) === null || _a === void 0 ? void 0 : _a.data;
|
|
31040
|
+
if (!streamCache)
|
|
31041
|
+
return undefined;
|
|
31042
|
+
return streamLinkedObject(streamCache);
|
|
31043
|
+
})
|
|
31044
|
+
.filter(isNonNullable);
|
|
31045
|
+
}, getLiveChat: () => getLiveChat$1(stream), isBanned: !stream.watcherUrl, watcherUrl: null, get [GET_WATCHER_URLS]() {
|
|
31046
|
+
return stream.watcherUrl;
|
|
31047
|
+
} });
|
|
31048
|
+
};
|
|
31049
|
+
|
|
31050
|
+
const commentLinkedObject = (comment) => {
|
|
31051
|
+
return Object.assign(Object.assign({}, comment), { get target() {
|
|
31052
|
+
const commentTypes = {
|
|
31053
|
+
type: comment.targetType,
|
|
31054
|
+
};
|
|
31055
|
+
if (comment.targetType === 'user') {
|
|
31056
|
+
return Object.assign(Object.assign({}, commentTypes), { userId: comment.targetId });
|
|
31057
|
+
}
|
|
31058
|
+
if (commentTypes.type === 'content') {
|
|
31059
|
+
return Object.assign(Object.assign({}, commentTypes), { contentId: comment.targetId });
|
|
31060
|
+
}
|
|
31061
|
+
if (commentTypes.type === 'community') {
|
|
31062
|
+
const cacheData = pullFromCache([
|
|
31063
|
+
'communityUsers',
|
|
31064
|
+
'get',
|
|
31065
|
+
`${comment.targetId}#${comment.userId}`,
|
|
31066
|
+
]);
|
|
31067
|
+
return Object.assign(Object.assign({}, commentTypes), { communityId: comment.targetId, creatorMember: cacheData === null || cacheData === void 0 ? void 0 : cacheData.data });
|
|
31068
|
+
}
|
|
31069
|
+
return {
|
|
31070
|
+
type: 'unknown',
|
|
31071
|
+
};
|
|
31072
|
+
},
|
|
31073
|
+
get creator() {
|
|
31074
|
+
const cacheData = pullFromCache(['user', 'get', comment.userId]);
|
|
31075
|
+
if (cacheData === null || cacheData === void 0 ? void 0 : cacheData.data)
|
|
31076
|
+
return userLinkedObject(cacheData.data);
|
|
31077
|
+
return undefined;
|
|
31078
|
+
},
|
|
31079
|
+
get childrenComment() {
|
|
31080
|
+
return comment.children
|
|
31081
|
+
.map(childCommentId => {
|
|
31082
|
+
const commentCache = pullFromCache([
|
|
31083
|
+
'comment',
|
|
31084
|
+
'get',
|
|
31085
|
+
childCommentId,
|
|
31086
|
+
]);
|
|
31087
|
+
if (!(commentCache === null || commentCache === void 0 ? void 0 : commentCache.data))
|
|
31088
|
+
return;
|
|
31089
|
+
return commentCache === null || commentCache === void 0 ? void 0 : commentCache.data;
|
|
31090
|
+
})
|
|
31091
|
+
.filter(isNonNullable)
|
|
31092
|
+
.map(item => commentLinkedObject(item));
|
|
31093
|
+
} });
|
|
31094
|
+
};
|
|
31095
|
+
|
|
31096
|
+
function isAmityImagePost(post) {
|
|
31097
|
+
return !!(post.data &&
|
|
31098
|
+
typeof post.data !== 'string' &&
|
|
31099
|
+
'fileId' in post.data &&
|
|
31100
|
+
post.dataType === 'image');
|
|
31101
|
+
}
|
|
31102
|
+
function isAmityFilePost(post) {
|
|
31103
|
+
return !!(post.data &&
|
|
31104
|
+
typeof post.data !== 'string' &&
|
|
31105
|
+
'fileId' in post.data &&
|
|
31106
|
+
post.dataType === 'file');
|
|
31107
|
+
}
|
|
31108
|
+
function isAmityVideoPost(post) {
|
|
31109
|
+
return !!(post.data &&
|
|
31110
|
+
typeof post.data !== 'string' &&
|
|
31111
|
+
'videoFileId' in post.data &&
|
|
31112
|
+
'thumbnailFileId' in post.data &&
|
|
31113
|
+
post.dataType === 'video');
|
|
31114
|
+
}
|
|
31115
|
+
function isAmityLivestreamPost(post) {
|
|
31116
|
+
return !!(post.data &&
|
|
31117
|
+
typeof post.data !== 'string' &&
|
|
31118
|
+
'streamId' in post.data &&
|
|
31119
|
+
post.dataType === 'liveStream');
|
|
31120
|
+
}
|
|
31121
|
+
function isAmityPollPost(post) {
|
|
31122
|
+
return !!(post.data &&
|
|
31123
|
+
typeof post.data !== 'string' &&
|
|
31124
|
+
'pollId' in post.data &&
|
|
31125
|
+
post.dataType === 'poll');
|
|
31126
|
+
}
|
|
31127
|
+
function isAmityClipPost(post) {
|
|
31128
|
+
return !!(post.data &&
|
|
31129
|
+
typeof post.data !== 'string' &&
|
|
31130
|
+
'fileId' in post.data &&
|
|
31131
|
+
post.dataType === 'clip');
|
|
31132
|
+
}
|
|
31133
|
+
function isAmityAudioPost(post) {
|
|
31134
|
+
return !!(post.data &&
|
|
31135
|
+
typeof post.data !== 'string' &&
|
|
31136
|
+
'fileId' in post.data &&
|
|
31137
|
+
post.dataType === 'audio');
|
|
31138
|
+
}
|
|
31139
|
+
function isAmityRoomPost(post) {
|
|
31140
|
+
return !!(post.data &&
|
|
31141
|
+
typeof post.data !== 'string' &&
|
|
31142
|
+
'roomId' in post.data &&
|
|
31143
|
+
post.dataType === 'room');
|
|
31144
|
+
}
|
|
31145
|
+
|
|
31042
31146
|
/**
|
|
31043
31147
|
* ```js
|
|
31044
|
-
* import {
|
|
31045
|
-
* const
|
|
31148
|
+
* import { RoomRepository } from '@amityco/ts-sdk-react-native'
|
|
31149
|
+
* const stream = await getStream('foobar')
|
|
31046
31150
|
* ```
|
|
31047
31151
|
*
|
|
31048
|
-
*
|
|
31152
|
+
* Fetches a {@link Amity.Channel} object linked with a current stream
|
|
31049
31153
|
*
|
|
31050
|
-
* @param
|
|
31051
|
-
* @returns
|
|
31154
|
+
* @param stream {@link Amity.Stream} that has linked live channel
|
|
31155
|
+
* @returns the associated {@link Amity.Channel<'live'>} object
|
|
31052
31156
|
*
|
|
31053
|
-
* @category
|
|
31157
|
+
* @category Stream API
|
|
31054
31158
|
* @async
|
|
31055
31159
|
*/
|
|
31056
|
-
const
|
|
31160
|
+
const getLiveChat = async (room) => {
|
|
31057
31161
|
var _a;
|
|
31058
31162
|
const client = getActiveClient();
|
|
31059
|
-
client.log('
|
|
31060
|
-
|
|
31061
|
-
|
|
31062
|
-
|
|
31063
|
-
|
|
31064
|
-
|
|
31065
|
-
|
|
31066
|
-
|
|
31067
|
-
|
|
31068
|
-
|
|
31069
|
-
|
|
31070
|
-
if (community) {
|
|
31071
|
-
const updatedCommunity = Object.assign(Object.assign({}, community), { isJoined: true });
|
|
31072
|
-
upsertInCache(['community', 'get', communityId], updatedCommunity);
|
|
31073
|
-
}
|
|
31163
|
+
client.log('room/getLiveChat', room.roomId);
|
|
31164
|
+
if (room.liveChannelId) {
|
|
31165
|
+
const channel = (_a = pullFromCache([
|
|
31166
|
+
'channel',
|
|
31167
|
+
'get',
|
|
31168
|
+
room.liveChannelId,
|
|
31169
|
+
])) === null || _a === void 0 ? void 0 : _a.data;
|
|
31170
|
+
if (channel)
|
|
31171
|
+
return channelLinkedObject(constructChannelObject(channel));
|
|
31172
|
+
const { data } = await getChannel$1(room.liveChannelId);
|
|
31173
|
+
return channelLinkedObject(constructChannelObject(data));
|
|
31074
31174
|
}
|
|
31075
|
-
|
|
31076
|
-
|
|
31077
|
-
|
|
31078
|
-
|
|
31079
|
-
|
|
31080
|
-
|
|
31081
|
-
|
|
31082
|
-
/**
|
|
31083
|
-
* TODO: handle cache receive cache option, and cache policy
|
|
31084
|
-
* TODO: check if querybyIds is supported
|
|
31085
|
-
*/
|
|
31086
|
-
class JoinRequestsPaginationController extends PaginationController {
|
|
31087
|
-
async getRequest(queryParams, token) {
|
|
31088
|
-
const { limit = 20, communityId } = queryParams, params = __rest(queryParams, ["limit", "communityId"]);
|
|
31089
|
-
const options = token ? { token } : { limit };
|
|
31090
|
-
const { data: queryResponse } = await this.http.get(`/api/v4/communities/${communityId}/join`, {
|
|
31091
|
-
params: Object.assign(Object.assign({}, params), { options }),
|
|
31175
|
+
// No Channel ID
|
|
31176
|
+
// streamer: create a new live channel
|
|
31177
|
+
if (room.createdBy === client.userId) {
|
|
31178
|
+
const { data: channel } = await createChannel({
|
|
31179
|
+
type: 'live',
|
|
31180
|
+
postId: room.referenceId,
|
|
31181
|
+
roomId: room.roomId,
|
|
31092
31182
|
});
|
|
31093
|
-
|
|
31094
|
-
|
|
31095
|
-
|
|
31096
|
-
|
|
31097
|
-
|
|
31098
|
-
(function (EnumJoinRequestAction) {
|
|
31099
|
-
EnumJoinRequestAction["OnLocalJoinRequestCreated"] = "OnLocalJoinRequestCreated";
|
|
31100
|
-
EnumJoinRequestAction["OnLocalJoinRequestUpdated"] = "OnLocalJoinRequestUpdated";
|
|
31101
|
-
EnumJoinRequestAction["OnLocalJoinRequestDeleted"] = "OnLocalJoinRequestDeleted";
|
|
31102
|
-
})(EnumJoinRequestAction$1 || (EnumJoinRequestAction$1 = {}));
|
|
31103
|
-
|
|
31104
|
-
class JoinRequestsQueryStreamController extends QueryStreamController {
|
|
31105
|
-
constructor(query, cacheKey, notifyChange, preparePayload) {
|
|
31106
|
-
super(query, cacheKey);
|
|
31107
|
-
this.notifyChange = notifyChange;
|
|
31108
|
-
this.preparePayload = preparePayload;
|
|
31109
|
-
}
|
|
31110
|
-
async saveToMainDB(response) {
|
|
31111
|
-
const processedPayload = await this.preparePayload(response);
|
|
31112
|
-
const client = getActiveClient();
|
|
31113
|
-
const cachedAt = client.cache && Date.now();
|
|
31114
|
-
if (client.cache) {
|
|
31115
|
-
ingestInCache(processedPayload, { cachedAt });
|
|
31116
|
-
}
|
|
31117
|
-
}
|
|
31118
|
-
appendToQueryStream(response, direction, refresh = false) {
|
|
31119
|
-
var _a, _b;
|
|
31120
|
-
if (refresh) {
|
|
31121
|
-
pushToCache(this.cacheKey, {
|
|
31122
|
-
data: response.joinRequests.map(joinRequest => getResolver('joinRequest')({ joinRequestId: joinRequest._id })),
|
|
31123
|
-
});
|
|
31124
|
-
}
|
|
31125
|
-
else {
|
|
31126
|
-
const collection = (_a = pullFromCache(this.cacheKey)) === null || _a === void 0 ? void 0 : _a.data;
|
|
31127
|
-
const joinRequests = (_b = collection === null || collection === void 0 ? void 0 : collection.data) !== null && _b !== void 0 ? _b : [];
|
|
31128
|
-
pushToCache(this.cacheKey, Object.assign(Object.assign({}, collection), { data: [
|
|
31129
|
-
...new Set([
|
|
31130
|
-
...joinRequests,
|
|
31131
|
-
...response.joinRequests.map(joinRequest => getResolver('joinRequest')({ joinRequestId: joinRequest._id })),
|
|
31132
|
-
]),
|
|
31133
|
-
] }));
|
|
31134
|
-
}
|
|
31135
|
-
}
|
|
31136
|
-
reactor(action) {
|
|
31137
|
-
return (joinRequest) => {
|
|
31138
|
-
var _a;
|
|
31139
|
-
const collection = (_a = pullFromCache(this.cacheKey)) === null || _a === void 0 ? void 0 : _a.data;
|
|
31140
|
-
if (!collection)
|
|
31141
|
-
return;
|
|
31142
|
-
if (action === EnumJoinRequestAction$1.OnLocalJoinRequestUpdated) {
|
|
31143
|
-
const isExist = collection.data.find(id => id === joinRequest[0].joinRequestId);
|
|
31144
|
-
if (!isExist)
|
|
31145
|
-
return;
|
|
31146
|
-
}
|
|
31147
|
-
if (action === EnumJoinRequestAction$1.OnLocalJoinRequestCreated) {
|
|
31148
|
-
collection.data = [
|
|
31149
|
-
...new Set([
|
|
31150
|
-
...joinRequest.map(joinRequest => joinRequest.joinRequestId),
|
|
31151
|
-
...collection.data,
|
|
31152
|
-
]),
|
|
31153
|
-
];
|
|
31154
|
-
}
|
|
31155
|
-
if (action === EnumJoinRequestAction$1.OnLocalJoinRequestDeleted) {
|
|
31156
|
-
collection.data = collection.data.filter(id => id !== joinRequest[0].joinRequestId);
|
|
31157
|
-
}
|
|
31158
|
-
pushToCache(this.cacheKey, collection);
|
|
31159
|
-
this.notifyChange({ origin: "event" /* Amity.LiveDataOrigin.EVENT */, loading: false });
|
|
31160
|
-
};
|
|
31161
|
-
}
|
|
31162
|
-
subscribeRTE(createSubscriber) {
|
|
31163
|
-
return createSubscriber.map(subscriber => subscriber.fn(this.reactor(subscriber.action)));
|
|
31183
|
+
// Update channelId to stream object in cache
|
|
31184
|
+
mergeInCache(['room', 'get', room.roomId], {
|
|
31185
|
+
liveChannelId: channel.channelId,
|
|
31186
|
+
});
|
|
31187
|
+
return channel;
|
|
31164
31188
|
}
|
|
31165
|
-
|
|
31166
|
-
|
|
31167
|
-
/**
|
|
31168
|
-
* ```js
|
|
31169
|
-
* import { onJoinRequestCreated } from '@amityco/ts-sdk-react-native'
|
|
31170
|
-
* const dispose = onJoinRequestCreated(data => {
|
|
31171
|
-
* // ...
|
|
31172
|
-
* })
|
|
31173
|
-
* ```
|
|
31174
|
-
*
|
|
31175
|
-
* Fired when an {@link Amity.CommunityJoinRequestPayload} has been created
|
|
31176
|
-
*
|
|
31177
|
-
* @param callback The function to call when the event was fired
|
|
31178
|
-
* @returns an {@link Amity.Unsubscriber} function to stop listening
|
|
31179
|
-
*
|
|
31180
|
-
* @category JoinRequest Events
|
|
31181
|
-
*/
|
|
31182
|
-
const onJoinRequestCreated = (callback) => {
|
|
31183
|
-
const client = getActiveClient();
|
|
31184
|
-
const disposers = [
|
|
31185
|
-
createEventSubscriber(client, 'onJoinRequestCreated', 'local.joinRequest.created', payload => callback(payload)),
|
|
31186
|
-
];
|
|
31187
|
-
return () => {
|
|
31188
|
-
disposers.forEach(fn => fn());
|
|
31189
|
-
};
|
|
31190
|
-
};
|
|
31191
|
-
|
|
31192
|
-
/**
|
|
31193
|
-
* ```js
|
|
31194
|
-
* import { onJoinRequestUpdated } from '@amityco/ts-sdk-react-native'
|
|
31195
|
-
* const dispose = onJoinRequestUpdated(data => {
|
|
31196
|
-
* // ...
|
|
31197
|
-
* })
|
|
31198
|
-
* ```
|
|
31199
|
-
*
|
|
31200
|
-
* Fired when an {@link Amity.CommunityJoinRequestPayload} has been created
|
|
31201
|
-
*
|
|
31202
|
-
* @param callback The function to call when the event was fired
|
|
31203
|
-
* @returns an {@link Amity.Unsubscriber} function to stop listening
|
|
31204
|
-
*
|
|
31205
|
-
* @category JoinRequest Events
|
|
31206
|
-
*/
|
|
31207
|
-
const onJoinRequestUpdated = (callback) => {
|
|
31208
|
-
const client = getActiveClient();
|
|
31209
|
-
const disposers = [
|
|
31210
|
-
createEventSubscriber(client, 'onJoinRequestUpdated', 'local.joinRequest.updated', payload => callback(payload)),
|
|
31211
|
-
];
|
|
31212
|
-
return () => {
|
|
31213
|
-
disposers.forEach(fn => fn());
|
|
31214
|
-
};
|
|
31189
|
+
// watcher: return undefined
|
|
31190
|
+
return undefined;
|
|
31215
31191
|
};
|
|
31216
31192
|
|
|
31217
31193
|
/**
|
|
31218
|
-
*
|
|
31219
|
-
*
|
|
31220
|
-
* const dispose = onJoinRequestDeleted(data => {
|
|
31221
|
-
* // ...
|
|
31222
|
-
* })
|
|
31223
|
-
* ```
|
|
31224
|
-
*
|
|
31225
|
-
* Fired when an {@link Amity.CommunityJoinRequestPayload} has been created
|
|
31226
|
-
*
|
|
31227
|
-
* @param callback The function to call when the event was fired
|
|
31228
|
-
* @returns an {@link Amity.Unsubscriber} function to stop listening
|
|
31229
|
-
*
|
|
31230
|
-
* @category JoinRequest Events
|
|
31194
|
+
* WatchSessionStorage manages watch session data in memory
|
|
31195
|
+
* Similar to UsageCollector for stream watch minutes
|
|
31231
31196
|
*/
|
|
31232
|
-
|
|
31233
|
-
|
|
31234
|
-
|
|
31235
|
-
createEventSubscriber(client, 'onJoinRequestDeleted', 'local.joinRequest.deleted', payload => callback(payload)),
|
|
31236
|
-
];
|
|
31237
|
-
return () => {
|
|
31238
|
-
disposers.forEach(fn => fn());
|
|
31239
|
-
};
|
|
31240
|
-
};
|
|
31241
|
-
|
|
31242
|
-
class JoinRequestsLiveCollectionController extends LiveCollectionController {
|
|
31243
|
-
constructor(query, callback) {
|
|
31244
|
-
const queryStreamId = hash(query);
|
|
31245
|
-
const cacheKey = ['joinRequest', 'collection', queryStreamId];
|
|
31246
|
-
const paginationController = new JoinRequestsPaginationController(query);
|
|
31247
|
-
super(paginationController, queryStreamId, cacheKey, callback);
|
|
31248
|
-
this.query = query;
|
|
31249
|
-
this.queryStreamController = new JoinRequestsQueryStreamController(this.query, this.cacheKey, this.notifyChange.bind(this), prepareCommunityJoinRequestPayload);
|
|
31250
|
-
this.callback = callback.bind(this);
|
|
31251
|
-
this.loadPage({ initial: true });
|
|
31197
|
+
class WatchSessionStorage {
|
|
31198
|
+
constructor() {
|
|
31199
|
+
this.sessions = new Map();
|
|
31252
31200
|
}
|
|
31253
|
-
|
|
31254
|
-
|
|
31255
|
-
|
|
31256
|
-
|
|
31257
|
-
|
|
31258
|
-
|
|
31259
|
-
|
|
31260
|
-
|
|
31261
|
-
|
|
31201
|
+
/**
|
|
31202
|
+
* Add a new watch session
|
|
31203
|
+
*/
|
|
31204
|
+
addSession(session) {
|
|
31205
|
+
this.sessions.set(session.sessionId, session);
|
|
31206
|
+
}
|
|
31207
|
+
/**
|
|
31208
|
+
* Get a watch session by sessionId
|
|
31209
|
+
*/
|
|
31210
|
+
getSession(sessionId) {
|
|
31211
|
+
return this.sessions.get(sessionId);
|
|
31262
31212
|
}
|
|
31263
|
-
|
|
31264
|
-
|
|
31213
|
+
/**
|
|
31214
|
+
* Update a watch session
|
|
31215
|
+
*/
|
|
31216
|
+
updateSession(sessionId, updates) {
|
|
31217
|
+
const session = this.sessions.get(sessionId);
|
|
31218
|
+
if (session) {
|
|
31219
|
+
this.sessions.set(sessionId, Object.assign(Object.assign({}, session), updates));
|
|
31220
|
+
}
|
|
31265
31221
|
}
|
|
31266
|
-
|
|
31267
|
-
|
|
31268
|
-
|
|
31222
|
+
/**
|
|
31223
|
+
* Get all sessions with a specific sync state
|
|
31224
|
+
*/
|
|
31225
|
+
getSessionsByState(state) {
|
|
31226
|
+
return Array.from(this.sessions.values()).filter(session => session.syncState === state);
|
|
31269
31227
|
}
|
|
31270
|
-
|
|
31271
|
-
|
|
31272
|
-
|
|
31273
|
-
|
|
31274
|
-
|
|
31275
|
-
]);
|
|
31228
|
+
/**
|
|
31229
|
+
* Delete a session
|
|
31230
|
+
*/
|
|
31231
|
+
deleteSession(sessionId) {
|
|
31232
|
+
this.sessions.delete(sessionId);
|
|
31276
31233
|
}
|
|
31277
|
-
|
|
31278
|
-
|
|
31279
|
-
|
|
31280
|
-
|
|
31281
|
-
|
|
31282
|
-
const data = this.applyFilter(collection.data
|
|
31283
|
-
.map(id => pullFromCache(['joinRequest', 'get', id]))
|
|
31284
|
-
.filter(isNonNullable)
|
|
31285
|
-
.map(({ data }) => data)
|
|
31286
|
-
.map(joinRequestLinkedObject));
|
|
31287
|
-
if (!this.shouldNotify(data) && origin === 'event')
|
|
31288
|
-
return;
|
|
31289
|
-
this.callback({
|
|
31290
|
-
onNextPage: () => this.loadPage({ direction: "next" /* Amity.LiveCollectionPageDirection.NEXT */ }),
|
|
31291
|
-
data,
|
|
31292
|
-
hasNextPage: !!this.paginationController.getNextToken(),
|
|
31293
|
-
loading,
|
|
31294
|
-
error,
|
|
31295
|
-
});
|
|
31234
|
+
/**
|
|
31235
|
+
* Get all pending sessions
|
|
31236
|
+
*/
|
|
31237
|
+
getPendingSessions() {
|
|
31238
|
+
return this.getSessionsByState('PENDING');
|
|
31296
31239
|
}
|
|
31297
|
-
|
|
31298
|
-
|
|
31299
|
-
|
|
31300
|
-
|
|
31301
|
-
|
|
31302
|
-
const sortFn = (() => {
|
|
31303
|
-
switch (this.query.sortBy) {
|
|
31304
|
-
case 'firstCreated':
|
|
31305
|
-
return sortByFirstCreated;
|
|
31306
|
-
case 'lastCreated':
|
|
31307
|
-
return sortByLastCreated;
|
|
31308
|
-
default:
|
|
31309
|
-
return sortByLastCreated;
|
|
31310
|
-
}
|
|
31311
|
-
})();
|
|
31312
|
-
joinRequest = joinRequest.sort(sortFn);
|
|
31313
|
-
return joinRequest;
|
|
31240
|
+
/**
|
|
31241
|
+
* Get all syncing sessions
|
|
31242
|
+
*/
|
|
31243
|
+
getSyncingSessions() {
|
|
31244
|
+
return this.getSessionsByState('SYNCING');
|
|
31314
31245
|
}
|
|
31315
31246
|
}
|
|
31247
|
+
// Singleton instance
|
|
31248
|
+
let storageInstance = null;
|
|
31249
|
+
const getWatchSessionStorage = () => {
|
|
31250
|
+
if (!storageInstance) {
|
|
31251
|
+
storageInstance = new WatchSessionStorage();
|
|
31252
|
+
}
|
|
31253
|
+
return storageInstance;
|
|
31254
|
+
};
|
|
31316
31255
|
|
|
31317
|
-
|
|
31318
|
-
|
|
31319
|
-
*
|
|
31320
|
-
|
|
31321
|
-
|
|
31322
|
-
|
|
31323
|
-
|
|
31324
|
-
|
|
31256
|
+
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-----";
|
|
31257
|
+
/*
|
|
31258
|
+
* The crypto algorithm used for importing key and signing string
|
|
31259
|
+
*/
|
|
31260
|
+
const ALGORITHM = {
|
|
31261
|
+
name: 'RSASSA-PKCS1-v1_5',
|
|
31262
|
+
hash: { name: 'SHA-256' },
|
|
31263
|
+
};
|
|
31264
|
+
/*
|
|
31265
|
+
* IMPORTANT!
|
|
31266
|
+
* If you are recieving key from other platforms use an online tool to convert
|
|
31267
|
+
* the PKCS1 to PKCS8. For instance the key from Android SDK is of the format
|
|
31268
|
+
* PKCS1.
|
|
31325
31269
|
*
|
|
31270
|
+
* If recieving from the platform, verify if it's already in the expected
|
|
31271
|
+
* format. Otherwise the crypto.subtle.importKey will throw a DOMException
|
|
31326
31272
|
*/
|
|
31327
|
-
const
|
|
31328
|
-
|
|
31329
|
-
|
|
31330
|
-
|
|
31331
|
-
|
|
31332
|
-
|
|
31333
|
-
|
|
31334
|
-
|
|
31335
|
-
|
|
31336
|
-
|
|
31337
|
-
|
|
31338
|
-
|
|
31273
|
+
const PRIVATE_KEY_SIGNATURE = 'pkcs8';
|
|
31274
|
+
/*
|
|
31275
|
+
* Ensure that the private key in the .env follows this format
|
|
31276
|
+
*/
|
|
31277
|
+
const PEM_HEADER = '-----BEGIN PRIVATE KEY-----';
|
|
31278
|
+
const PEM_FOOTER = '-----END PRIVATE KEY-----';
|
|
31279
|
+
/*
|
|
31280
|
+
* The crypto.subtle.sign function returns an ArrayBuffer whereas the server
|
|
31281
|
+
* expects a base64 string. This util helps facilitate that process
|
|
31282
|
+
*/
|
|
31283
|
+
function base64FromArrayBuffer(buffer) {
|
|
31284
|
+
const uint8Array = new Uint8Array(buffer);
|
|
31285
|
+
let binary = '';
|
|
31286
|
+
uint8Array.forEach(byte => {
|
|
31287
|
+
binary += String.fromCharCode(byte);
|
|
31339
31288
|
});
|
|
31340
|
-
return ()
|
|
31341
|
-
log(`getJoinRequests (tmpid: ${timestamp}) > dispose`);
|
|
31342
|
-
disposers.forEach(fn => fn());
|
|
31343
|
-
};
|
|
31344
|
-
};
|
|
31345
|
-
|
|
31346
|
-
var InvitationActionsEnum;
|
|
31347
|
-
(function (InvitationActionsEnum) {
|
|
31348
|
-
InvitationActionsEnum["OnLocalInvitationCreated"] = "onLocalInvitationCreated";
|
|
31349
|
-
InvitationActionsEnum["OnLocalInvitationUpdated"] = "onLocalInvitationUpdated";
|
|
31350
|
-
InvitationActionsEnum["OnLocalInvitationCanceled"] = "onLocalInvitationCanceled";
|
|
31351
|
-
})(InvitationActionsEnum || (InvitationActionsEnum = {}));
|
|
31352
|
-
|
|
31353
|
-
class InvitationsPaginationController extends PaginationController {
|
|
31354
|
-
async getRequest(queryParams, token) {
|
|
31355
|
-
const { limit = COLLECTION_DEFAULT_PAGINATION_LIMIT } = queryParams, params = __rest(queryParams, ["limit"]);
|
|
31356
|
-
const options = token ? { token } : { limit };
|
|
31357
|
-
const { data } = await this.http.get('/api/v1/invitations', { params: Object.assign(Object.assign({}, params), { options }) });
|
|
31358
|
-
return data;
|
|
31359
|
-
}
|
|
31289
|
+
return btoa(binary);
|
|
31360
31290
|
}
|
|
31361
|
-
|
|
31362
|
-
|
|
31363
|
-
|
|
31364
|
-
|
|
31365
|
-
|
|
31366
|
-
|
|
31367
|
-
}
|
|
31368
|
-
async saveToMainDB(response) {
|
|
31369
|
-
const processedPayload = await this.preparePayload(response);
|
|
31370
|
-
const client = getActiveClient();
|
|
31371
|
-
const cachedAt = client.cache && Date.now();
|
|
31372
|
-
if (client.cache) {
|
|
31373
|
-
ingestInCache(processedPayload, { cachedAt });
|
|
31374
|
-
}
|
|
31291
|
+
/*
|
|
31292
|
+
* Encode ASN.1 length field
|
|
31293
|
+
*/
|
|
31294
|
+
function encodeLength(length) {
|
|
31295
|
+
if (length < 128) {
|
|
31296
|
+
return new Uint8Array([length]);
|
|
31375
31297
|
}
|
|
31376
|
-
|
|
31377
|
-
|
|
31378
|
-
if (refresh) {
|
|
31379
|
-
pushToCache(this.cacheKey, {
|
|
31380
|
-
data: response.invitations.map(getResolver('invitation')),
|
|
31381
|
-
});
|
|
31382
|
-
}
|
|
31383
|
-
else {
|
|
31384
|
-
const collection = (_a = pullFromCache(this.cacheKey)) === null || _a === void 0 ? void 0 : _a.data;
|
|
31385
|
-
const invitations = (_b = collection === null || collection === void 0 ? void 0 : collection.data) !== null && _b !== void 0 ? _b : [];
|
|
31386
|
-
pushToCache(this.cacheKey, Object.assign(Object.assign({}, collection), { data: [
|
|
31387
|
-
...new Set([...invitations, ...response.invitations.map(getResolver('invitation'))]),
|
|
31388
|
-
] }));
|
|
31389
|
-
}
|
|
31298
|
+
if (length < 256) {
|
|
31299
|
+
return new Uint8Array([0x81, length]);
|
|
31390
31300
|
}
|
|
31391
|
-
|
|
31392
|
-
|
|
31393
|
-
|
|
31394
|
-
|
|
31395
|
-
|
|
31396
|
-
|
|
31397
|
-
|
|
31398
|
-
|
|
31399
|
-
|
|
31400
|
-
|
|
31401
|
-
|
|
31402
|
-
|
|
31403
|
-
|
|
31404
|
-
|
|
31405
|
-
|
|
31406
|
-
|
|
31407
|
-
|
|
31408
|
-
|
|
31409
|
-
|
|
31410
|
-
|
|
31411
|
-
|
|
31412
|
-
|
|
31413
|
-
|
|
31414
|
-
|
|
31415
|
-
|
|
31301
|
+
// eslint-disable-next-line no-bitwise
|
|
31302
|
+
return new Uint8Array([0x82, (length >> 8) & 0xff, length & 0xff]);
|
|
31303
|
+
}
|
|
31304
|
+
/*
|
|
31305
|
+
* Convert PKCS1 private key to PKCS8 format
|
|
31306
|
+
* PKCS1 is RSA-specific format, PKCS8 is generic format that crypto.subtle requires
|
|
31307
|
+
* Android uses PKCS8EncodedKeySpec which expects PKCS8 format
|
|
31308
|
+
*/
|
|
31309
|
+
function pkcs1ToPkcs8(pkcs1) {
|
|
31310
|
+
// Algorithm identifier for RSA
|
|
31311
|
+
const algorithmIdentifier = new Uint8Array([
|
|
31312
|
+
0x30,
|
|
31313
|
+
0x0d,
|
|
31314
|
+
0x06,
|
|
31315
|
+
0x09,
|
|
31316
|
+
0x2a,
|
|
31317
|
+
0x86,
|
|
31318
|
+
0x48,
|
|
31319
|
+
0x86,
|
|
31320
|
+
0xf7,
|
|
31321
|
+
0x0d,
|
|
31322
|
+
0x01,
|
|
31323
|
+
0x01,
|
|
31324
|
+
0x01,
|
|
31325
|
+
0x05,
|
|
31326
|
+
0x00, // NULL
|
|
31327
|
+
]);
|
|
31328
|
+
// Version (INTEGER 0)
|
|
31329
|
+
const version = new Uint8Array([0x02, 0x01, 0x00]);
|
|
31330
|
+
// OCTET STRING tag + length + pkcs1 data
|
|
31331
|
+
const octetStringTag = 0x04;
|
|
31332
|
+
const octetStringLength = encodeLength(pkcs1.length);
|
|
31333
|
+
// Calculate total content length (version + algorithm + octet string)
|
|
31334
|
+
const contentLength = version.length + algorithmIdentifier.length + 1 + octetStringLength.length + pkcs1.length;
|
|
31335
|
+
// SEQUENCE tag + length
|
|
31336
|
+
const sequenceTag = 0x30;
|
|
31337
|
+
const sequenceLength = encodeLength(contentLength);
|
|
31338
|
+
// Build the PKCS8 structure
|
|
31339
|
+
const pkcs8 = new Uint8Array(1 + sequenceLength.length + contentLength);
|
|
31340
|
+
let offset = 0;
|
|
31341
|
+
pkcs8[offset] = sequenceTag;
|
|
31342
|
+
offset += 1;
|
|
31343
|
+
pkcs8.set(sequenceLength, offset);
|
|
31344
|
+
offset += sequenceLength.length;
|
|
31345
|
+
pkcs8.set(version, offset);
|
|
31346
|
+
offset += version.length;
|
|
31347
|
+
pkcs8.set(algorithmIdentifier, offset);
|
|
31348
|
+
offset += algorithmIdentifier.length;
|
|
31349
|
+
pkcs8[offset] = octetStringTag;
|
|
31350
|
+
offset += 1;
|
|
31351
|
+
pkcs8.set(octetStringLength, offset);
|
|
31352
|
+
offset += octetStringLength.length;
|
|
31353
|
+
pkcs8.set(pkcs1, offset);
|
|
31354
|
+
return pkcs8;
|
|
31355
|
+
}
|
|
31356
|
+
async function importPrivateKey(keyString) {
|
|
31357
|
+
// Remove PEM headers if present and any whitespace
|
|
31358
|
+
let base64Key = keyString;
|
|
31359
|
+
if (keyString.includes(PEM_HEADER)) {
|
|
31360
|
+
base64Key = keyString
|
|
31361
|
+
.substring(PEM_HEADER.length, keyString.length - PEM_FOOTER.length)
|
|
31362
|
+
.replace(/\s/g, '');
|
|
31416
31363
|
}
|
|
31417
|
-
|
|
31418
|
-
|
|
31364
|
+
else {
|
|
31365
|
+
base64Key = keyString.replace(/\s/g, '');
|
|
31366
|
+
}
|
|
31367
|
+
// Base64 decode to get binary data
|
|
31368
|
+
const binaryDerString = atob(base64Key);
|
|
31369
|
+
// Convert to Uint8Array for manipulation
|
|
31370
|
+
const pkcs1 = new Uint8Array(binaryDerString.length);
|
|
31371
|
+
for (let i = 0; i < binaryDerString.length; i += 1) {
|
|
31372
|
+
pkcs1[i] = binaryDerString.charCodeAt(i);
|
|
31419
31373
|
}
|
|
31374
|
+
// Convert PKCS1 to PKCS8 (crypto.subtle requires PKCS8)
|
|
31375
|
+
const pkcs8 = pkcs1ToPkcs8(pkcs1);
|
|
31376
|
+
// Import the key
|
|
31377
|
+
const key = await crypto.subtle.importKey(PRIVATE_KEY_SIGNATURE, pkcs8.buffer, ALGORITHM, false, ['sign']);
|
|
31378
|
+
return key;
|
|
31379
|
+
}
|
|
31380
|
+
async function createSignature({ timestamp, rooms, }) {
|
|
31381
|
+
const dataStr = rooms
|
|
31382
|
+
.map(item => Object.keys(item)
|
|
31383
|
+
.sort()
|
|
31384
|
+
.map(key => `${key}=${item[key]}`)
|
|
31385
|
+
.join('&'))
|
|
31386
|
+
.join(';');
|
|
31387
|
+
/*
|
|
31388
|
+
* nonceStr needs to be unique for each request
|
|
31389
|
+
*/
|
|
31390
|
+
const nonceStr = uuid$1.v4();
|
|
31391
|
+
const signStr = `nonceStr=${nonceStr}×tamp=${timestamp}&data=${dataStr}==`;
|
|
31392
|
+
const encoder = new TextEncoder();
|
|
31393
|
+
const data = encoder.encode(signStr);
|
|
31394
|
+
const key = await importPrivateKey(privateKey);
|
|
31395
|
+
const sign = await crypto.subtle.sign(ALGORITHM, key, data);
|
|
31396
|
+
return { signature: base64FromArrayBuffer(sign), nonceStr };
|
|
31420
31397
|
}
|
|
31421
31398
|
|
|
31422
31399
|
/**
|
|
31423
|
-
*
|
|
31424
|
-
*
|
|
31425
|
-
* const dispose = onLocalInvitationCreated(data => {
|
|
31426
|
-
* // ...
|
|
31427
|
-
* })
|
|
31428
|
-
* ```
|
|
31429
|
-
*
|
|
31430
|
-
* Fired when an {@link Amity.InvitationPayload} has been created
|
|
31431
|
-
*
|
|
31432
|
-
* @param callback The function to call when the event was fired
|
|
31433
|
-
* @returns an {@link Amity.Unsubscriber} function to stop listening
|
|
31434
|
-
*
|
|
31435
|
-
* @category Invitation Events
|
|
31436
|
-
*/
|
|
31437
|
-
const onLocalInvitationCreated = (callback) => {
|
|
31438
|
-
const client = getActiveClient();
|
|
31439
|
-
const disposers = [
|
|
31440
|
-
createEventSubscriber(client, 'onLocalInvitationCreated', 'local.invitation.created', payload => callback(payload)),
|
|
31441
|
-
];
|
|
31442
|
-
return () => {
|
|
31443
|
-
disposers.forEach(fn => fn());
|
|
31444
|
-
};
|
|
31445
|
-
};
|
|
31446
|
-
|
|
31447
|
-
/**
|
|
31448
|
-
* ```js
|
|
31449
|
-
* import { onLocalInvitationUpdated } from '@amityco/ts-sdk-react-native'
|
|
31450
|
-
* const dispose = onLocalInvitationUpdated(data => {
|
|
31451
|
-
* // ...
|
|
31452
|
-
* })
|
|
31453
|
-
* ```
|
|
31454
|
-
*
|
|
31455
|
-
* Fired when an {@link Amity.InvitationPayload} has been updated
|
|
31456
|
-
*
|
|
31457
|
-
* @param callback The function to call when the event was fired
|
|
31458
|
-
* @returns an {@link Amity.Unsubscriber} function to stop listening
|
|
31459
|
-
*
|
|
31460
|
-
* @category Invitation Events
|
|
31461
|
-
*/
|
|
31462
|
-
const onLocalInvitationUpdated = (callback) => {
|
|
31463
|
-
const client = getActiveClient();
|
|
31464
|
-
const disposers = [
|
|
31465
|
-
createEventSubscriber(client, 'onLocalInvitationUpdated', 'local.invitation.updated', payload => callback(payload)),
|
|
31466
|
-
];
|
|
31467
|
-
return () => {
|
|
31468
|
-
disposers.forEach(fn => fn());
|
|
31469
|
-
};
|
|
31470
|
-
};
|
|
31471
|
-
|
|
31472
|
-
/**
|
|
31473
|
-
* ```js
|
|
31474
|
-
* import { onLocalInvitationCanceled } from '@amityco/ts-sdk-react-native'
|
|
31475
|
-
* const dispose = onLocalInvitationCanceled(data => {
|
|
31476
|
-
* // ...
|
|
31477
|
-
* })
|
|
31478
|
-
* ```
|
|
31479
|
-
*
|
|
31480
|
-
* Fired when an {@link Amity.InvitationPayload} has been deleted
|
|
31481
|
-
*
|
|
31482
|
-
* @param callback The function to call when the event was fired
|
|
31483
|
-
* @returns an {@link Amity.Unsubscriber} function to stop listening
|
|
31484
|
-
*
|
|
31485
|
-
* @category Invitation Events
|
|
31400
|
+
* Sync pending watch sessions to backend
|
|
31401
|
+
* This function implements the full sync flow with network resilience
|
|
31486
31402
|
*/
|
|
31487
|
-
|
|
31488
|
-
const
|
|
31489
|
-
|
|
31490
|
-
|
|
31491
|
-
|
|
31492
|
-
|
|
31493
|
-
disposers.forEach(fn => fn());
|
|
31494
|
-
};
|
|
31495
|
-
};
|
|
31496
|
-
|
|
31497
|
-
class InvitationsLiveCollectionController extends LiveCollectionController {
|
|
31498
|
-
constructor(query, callback) {
|
|
31499
|
-
const queryStreamId = hash(query);
|
|
31500
|
-
const cacheKey = ['invitation', 'collection', queryStreamId];
|
|
31501
|
-
const paginationController = new InvitationsPaginationController(query);
|
|
31502
|
-
super(paginationController, queryStreamId, cacheKey, callback);
|
|
31503
|
-
this.query = query;
|
|
31504
|
-
this.queryStreamController = new InvitationsQueryStreamController(this.query, this.cacheKey, this.notifyChange.bind(this), prepareInvitationPayload);
|
|
31505
|
-
this.callback = callback.bind(this);
|
|
31506
|
-
this.loadPage({ initial: true });
|
|
31403
|
+
async function syncWatchSessions() {
|
|
31404
|
+
const storage = getWatchSessionStorage();
|
|
31405
|
+
// Get all pending sessions
|
|
31406
|
+
const pendingSessions = storage.getPendingSessions();
|
|
31407
|
+
if (pendingSessions.length === 0) {
|
|
31408
|
+
return true;
|
|
31507
31409
|
}
|
|
31508
|
-
|
|
31509
|
-
|
|
31510
|
-
|
|
31511
|
-
|
|
31512
|
-
|
|
31513
|
-
|
|
31514
|
-
|
|
31515
|
-
|
|
31410
|
+
try {
|
|
31411
|
+
const timestamp = new Date().toISOString();
|
|
31412
|
+
// Convert sessions to API format - always include all fields like syncUsage does
|
|
31413
|
+
const rooms = pendingSessions.map(session => ({
|
|
31414
|
+
sessionId: session.sessionId,
|
|
31415
|
+
roomId: session.roomId,
|
|
31416
|
+
watchSeconds: session.watchSeconds,
|
|
31417
|
+
startTime: session.startTime.toISOString(),
|
|
31418
|
+
endTime: session.endTime ? session.endTime.toISOString() : '',
|
|
31419
|
+
}));
|
|
31420
|
+
// Create signature (reuse from stream feature) - pass directly like syncUsage
|
|
31421
|
+
const signatureData = await createSignature({
|
|
31422
|
+
timestamp,
|
|
31423
|
+
rooms,
|
|
31424
|
+
});
|
|
31425
|
+
if (!signatureData || !signatureData.signature) {
|
|
31426
|
+
throw new Error('Signature is undefined');
|
|
31516
31427
|
}
|
|
31517
|
-
|
|
31518
|
-
|
|
31519
|
-
|
|
31520
|
-
|
|
31521
|
-
|
|
31522
|
-
|
|
31523
|
-
|
|
31524
|
-
|
|
31525
|
-
|
|
31526
|
-
|
|
31527
|
-
|
|
31528
|
-
|
|
31529
|
-
|
|
31530
|
-
|
|
31531
|
-
|
|
31532
|
-
|
|
31533
|
-
|
|
31534
|
-
|
|
31535
|
-
|
|
31536
|
-
action: InvitationActionsEnum.OnLocalInvitationCanceled,
|
|
31537
|
-
},
|
|
31538
|
-
]);
|
|
31539
|
-
}
|
|
31540
|
-
notifyChange({ origin, loading, error }) {
|
|
31541
|
-
var _a, _b;
|
|
31542
|
-
const collection = (_a = pullFromCache(this.cacheKey)) === null || _a === void 0 ? void 0 : _a.data;
|
|
31543
|
-
if (!collection)
|
|
31544
|
-
return;
|
|
31545
|
-
const data = this.applyFilter((_b = collection.data
|
|
31546
|
-
.map(id => pullFromCache(['invitation', 'get', id]))
|
|
31547
|
-
.filter(isNonNullable)
|
|
31548
|
-
.map(({ data }) => invitationLinkedObject(data))) !== null && _b !== void 0 ? _b : []);
|
|
31549
|
-
if (!this.shouldNotify(data) && origin === 'event')
|
|
31550
|
-
return;
|
|
31551
|
-
this.callback({
|
|
31552
|
-
onNextPage: () => this.loadPage({ direction: "next" /* Amity.LiveCollectionPageDirection.NEXT */ }),
|
|
31553
|
-
data,
|
|
31554
|
-
hasNextPage: !!this.paginationController.getNextToken(),
|
|
31555
|
-
loading,
|
|
31556
|
-
error,
|
|
31428
|
+
// Update sync state to SYNCING
|
|
31429
|
+
pendingSessions.forEach(session => {
|
|
31430
|
+
storage.updateSession(session.sessionId, { syncState: 'SYNCING' });
|
|
31431
|
+
});
|
|
31432
|
+
const payload = {
|
|
31433
|
+
signature: signatureData.signature,
|
|
31434
|
+
nonceStr: signatureData.nonceStr,
|
|
31435
|
+
timestamp,
|
|
31436
|
+
rooms,
|
|
31437
|
+
};
|
|
31438
|
+
const client = getActiveClient();
|
|
31439
|
+
// Send to backend
|
|
31440
|
+
await client.http.post('/api/v3/user-event/room', payload);
|
|
31441
|
+
// Success - update to SYNCED
|
|
31442
|
+
pendingSessions.forEach(session => {
|
|
31443
|
+
storage.updateSession(session.sessionId, {
|
|
31444
|
+
syncState: 'SYNCED',
|
|
31445
|
+
syncedAt: new Date(),
|
|
31446
|
+
});
|
|
31557
31447
|
});
|
|
31448
|
+
return true;
|
|
31558
31449
|
}
|
|
31559
|
-
|
|
31560
|
-
|
|
31561
|
-
|
|
31562
|
-
|
|
31563
|
-
|
|
31564
|
-
|
|
31565
|
-
|
|
31566
|
-
|
|
31567
|
-
|
|
31568
|
-
|
|
31569
|
-
|
|
31570
|
-
|
|
31571
|
-
|
|
31572
|
-
|
|
31573
|
-
|
|
31574
|
-
|
|
31575
|
-
|
|
31576
|
-
|
|
31577
|
-
case 'lastCreated':
|
|
31578
|
-
return sortByLastCreated;
|
|
31579
|
-
default:
|
|
31580
|
-
return sortByLastCreated;
|
|
31450
|
+
catch (err) {
|
|
31451
|
+
console.error('[SDK syncWatchSessions] ERROR caught:', (err === null || err === void 0 ? void 0 : err.message) || err);
|
|
31452
|
+
// Failure - update back to PENDING and increment retry count
|
|
31453
|
+
pendingSessions.forEach(session => {
|
|
31454
|
+
const currentSession = storage.getSession(session.sessionId);
|
|
31455
|
+
if (currentSession) {
|
|
31456
|
+
const newRetryCount = currentSession.retryCount + 1;
|
|
31457
|
+
if (newRetryCount >= 3) {
|
|
31458
|
+
// Delete session if retry count exceeds 3
|
|
31459
|
+
storage.deleteSession(session.sessionId);
|
|
31460
|
+
}
|
|
31461
|
+
else {
|
|
31462
|
+
// Update to PENDING with incremented retry count
|
|
31463
|
+
storage.updateSession(session.sessionId, {
|
|
31464
|
+
syncState: 'PENDING',
|
|
31465
|
+
retryCount: newRetryCount,
|
|
31466
|
+
});
|
|
31467
|
+
}
|
|
31581
31468
|
}
|
|
31582
|
-
})
|
|
31583
|
-
|
|
31584
|
-
return invitations;
|
|
31469
|
+
});
|
|
31470
|
+
return false;
|
|
31585
31471
|
}
|
|
31586
31472
|
}
|
|
31587
31473
|
|
|
31588
31474
|
/**
|
|
31589
|
-
*
|
|
31590
|
-
*
|
|
31591
|
-
* @param params the query parameters
|
|
31592
|
-
* @param callback the callback to be called when the invitations are updated
|
|
31593
|
-
* @returns invitations
|
|
31594
|
-
*
|
|
31595
|
-
* @category Invitation Live Collection
|
|
31596
|
-
*
|
|
31475
|
+
* Room statuses that are considered watchable
|
|
31597
31476
|
*/
|
|
31598
|
-
const
|
|
31599
|
-
|
|
31600
|
-
|
|
31601
|
-
|
|
31602
|
-
|
|
31603
|
-
const
|
|
31604
|
-
|
|
31605
|
-
|
|
31606
|
-
|
|
31607
|
-
|
|
31608
|
-
|
|
31609
|
-
|
|
31477
|
+
const WATCHABLE_ROOM_STATUSES = ['live', 'recorded'];
|
|
31478
|
+
/**
|
|
31479
|
+
* Generate a random jitter delay between 5 and 30 seconds
|
|
31480
|
+
*/
|
|
31481
|
+
const getJitterDelay = () => {
|
|
31482
|
+
const minDelay = 5000; // 5 seconds
|
|
31483
|
+
const maxDelay = 30000; // 30 seconds
|
|
31484
|
+
return Math.floor(Math.random() * (maxDelay - minDelay + 1)) + minDelay;
|
|
31485
|
+
};
|
|
31486
|
+
/**
|
|
31487
|
+
* Wait for network connection with timeout
|
|
31488
|
+
* @param maxWaitTime Maximum time to wait in milliseconds (default: 60000 = 60 seconds)
|
|
31489
|
+
* @returns Promise that resolves when network is available or timeout is reached
|
|
31490
|
+
*/
|
|
31491
|
+
const waitForNetwork = (maxWaitTime = 60000) => {
|
|
31492
|
+
return new Promise(resolve => {
|
|
31493
|
+
// Simple check - if navigator.onLine is available, use it
|
|
31494
|
+
// Otherwise, assume network is available
|
|
31495
|
+
if (typeof navigator === 'undefined' || typeof navigator.onLine === 'undefined') {
|
|
31496
|
+
resolve();
|
|
31497
|
+
return;
|
|
31498
|
+
}
|
|
31499
|
+
const startTime = Date.now();
|
|
31500
|
+
const checkInterval = 1000; // 1 second
|
|
31501
|
+
const checkConnection = () => {
|
|
31502
|
+
if (navigator.onLine || Date.now() - startTime >= maxWaitTime) {
|
|
31503
|
+
resolve();
|
|
31504
|
+
}
|
|
31505
|
+
else {
|
|
31506
|
+
setTimeout(checkConnection, checkInterval);
|
|
31507
|
+
}
|
|
31508
|
+
};
|
|
31509
|
+
checkConnection();
|
|
31610
31510
|
});
|
|
31611
|
-
return () => {
|
|
31612
|
-
log(`getInvitations (tmpid: ${timestamp}) > dispose`);
|
|
31613
|
-
disposers.forEach(fn => fn());
|
|
31614
|
-
};
|
|
31615
31511
|
};
|
|
31512
|
+
/**
|
|
31513
|
+
* AmityRoomAnalytics provides analytics capabilities for room watch sessions
|
|
31514
|
+
*/
|
|
31515
|
+
class AmityRoomAnalytics {
|
|
31516
|
+
constructor(room) {
|
|
31517
|
+
this.storage = getWatchSessionStorage();
|
|
31518
|
+
this.client = getActiveClient();
|
|
31519
|
+
this.room = room;
|
|
31520
|
+
}
|
|
31521
|
+
/**
|
|
31522
|
+
* Create a new watch session for the current room
|
|
31523
|
+
* @param startedAt The timestamp when watching started
|
|
31524
|
+
* @returns Promise<string> sessionId unique identifier for this watch session
|
|
31525
|
+
* @throws ASCApiError if room is not in watchable state (not LIVE or RECORDED)
|
|
31526
|
+
*/
|
|
31527
|
+
async createWatchSession(startedAt) {
|
|
31528
|
+
// Validate room status
|
|
31529
|
+
if (!WATCHABLE_ROOM_STATUSES.includes(this.room.status)) {
|
|
31530
|
+
throw new ASCApiError('room is not in watchable state', 500000 /* Amity.ServerError.BUSINESS_ERROR */, "error" /* Amity.ErrorLevel.ERROR */);
|
|
31531
|
+
}
|
|
31532
|
+
// Generate session ID with prefix
|
|
31533
|
+
const prefix = this.room.status === 'live' ? 'room_' : 'room_playback_';
|
|
31534
|
+
const sessionId = prefix + uuid$1.v4();
|
|
31535
|
+
// Create watch session entity
|
|
31536
|
+
const session = {
|
|
31537
|
+
sessionId,
|
|
31538
|
+
roomId: this.room.roomId,
|
|
31539
|
+
watchSeconds: 0,
|
|
31540
|
+
startTime: startedAt,
|
|
31541
|
+
endTime: null,
|
|
31542
|
+
syncState: 'PENDING',
|
|
31543
|
+
syncedAt: null,
|
|
31544
|
+
retryCount: 0,
|
|
31545
|
+
};
|
|
31546
|
+
// Persist to storage
|
|
31547
|
+
this.storage.addSession(session);
|
|
31548
|
+
return sessionId;
|
|
31549
|
+
}
|
|
31550
|
+
/**
|
|
31551
|
+
* Update an existing watch session with duration
|
|
31552
|
+
* @param sessionId The unique identifier of the watch session
|
|
31553
|
+
* @param duration The total watch duration in seconds
|
|
31554
|
+
* @param endedAt The timestamp when this update occurred
|
|
31555
|
+
* @returns Promise<void> Completion status
|
|
31556
|
+
*/
|
|
31557
|
+
async updateWatchSession(sessionId, duration, endedAt) {
|
|
31558
|
+
const session = this.storage.getSession(sessionId);
|
|
31559
|
+
if (!session) {
|
|
31560
|
+
throw new Error(`Watch session ${sessionId} not found`);
|
|
31561
|
+
}
|
|
31562
|
+
// Update session
|
|
31563
|
+
this.storage.updateSession(sessionId, {
|
|
31564
|
+
watchSeconds: duration,
|
|
31565
|
+
endTime: endedAt,
|
|
31566
|
+
});
|
|
31567
|
+
}
|
|
31568
|
+
/**
|
|
31569
|
+
* Sync all pending watch sessions to backend
|
|
31570
|
+
* This function uses jitter delay and handles network resilience
|
|
31571
|
+
*/
|
|
31572
|
+
syncPendingWatchSessions() {
|
|
31573
|
+
// Execute with jitter delay (5-30 seconds)
|
|
31574
|
+
const jitterDelay = getJitterDelay();
|
|
31575
|
+
this.client.log('room/RoomAnalytics: syncPendingWatchSessions called, jitter delay:', `${jitterDelay}ms`);
|
|
31576
|
+
setTimeout(async () => {
|
|
31577
|
+
this.client.log('room/RoomAnalytics: Jitter delay completed, starting sync process');
|
|
31578
|
+
try {
|
|
31579
|
+
// Reset any SYNCING sessions back to PENDING
|
|
31580
|
+
const syncingSessions = this.storage.getSyncingSessions();
|
|
31581
|
+
this.client.log('room/RoomAnalytics: SYNCING sessions to reset:', syncingSessions.length);
|
|
31582
|
+
syncingSessions.forEach(session => {
|
|
31583
|
+
this.storage.updateSession(session.sessionId, { syncState: 'PENDING' });
|
|
31584
|
+
});
|
|
31585
|
+
// Wait for network connection (max 60 seconds)
|
|
31586
|
+
await waitForNetwork(60000);
|
|
31587
|
+
this.client.log('room/RoomAnalytics: Network available');
|
|
31588
|
+
// Sync pending sessions
|
|
31589
|
+
this.client.log('room/RoomAnalytics: Calling syncWatchSessions()');
|
|
31590
|
+
await syncWatchSessions();
|
|
31591
|
+
this.client.log('room/RoomAnalytics: syncWatchSessions completed');
|
|
31592
|
+
}
|
|
31593
|
+
catch (error) {
|
|
31594
|
+
// Error is already handled in syncWatchSessions
|
|
31595
|
+
console.error('Failed to sync watch sessions:', error);
|
|
31596
|
+
}
|
|
31597
|
+
}, jitterDelay);
|
|
31598
|
+
}
|
|
31599
|
+
}
|
|
31616
31600
|
|
|
31617
|
-
const
|
|
31618
|
-
return Object.assign(Object.assign({},
|
|
31601
|
+
const roomLinkedObject = (room) => {
|
|
31602
|
+
return Object.assign(Object.assign({}, room), { get post() {
|
|
31619
31603
|
var _a;
|
|
31620
|
-
|
|
31621
|
-
|
|
31622
|
-
|
|
31623
|
-
if (cacheData === null || cacheData === void 0 ? void 0 : cacheData.data)
|
|
31624
|
-
return categoryLinkedObject(cacheData.data);
|
|
31625
|
-
return undefined;
|
|
31626
|
-
})
|
|
31627
|
-
.filter(category => !!category);
|
|
31604
|
+
if (room.referenceType !== 'post')
|
|
31605
|
+
return;
|
|
31606
|
+
return (_a = pullFromCache(['post', 'get', room.referenceId])) === null || _a === void 0 ? void 0 : _a.data;
|
|
31628
31607
|
},
|
|
31629
|
-
get
|
|
31608
|
+
get community() {
|
|
31630
31609
|
var _a;
|
|
31631
|
-
if (
|
|
31632
|
-
return
|
|
31633
|
-
|
|
31634
|
-
|
|
31635
|
-
|
|
31636
|
-
|
|
31637
|
-
])) === null || _a === void 0 ? void 0 : _a.data;
|
|
31638
|
-
return
|
|
31639
|
-
},
|
|
31640
|
-
|
|
31641
|
-
|
|
31642
|
-
|
|
31643
|
-
|
|
31644
|
-
|
|
31645
|
-
|
|
31646
|
-
|
|
31647
|
-
|
|
31648
|
-
|
|
31610
|
+
if (room.targetType !== 'community')
|
|
31611
|
+
return;
|
|
31612
|
+
return (_a = pullFromCache(['community', 'get', room.targetId])) === null || _a === void 0 ? void 0 : _a.data;
|
|
31613
|
+
},
|
|
31614
|
+
get user() {
|
|
31615
|
+
var _a;
|
|
31616
|
+
const user = (_a = pullFromCache(['user', 'get', room.createdBy])) === null || _a === void 0 ? void 0 : _a.data;
|
|
31617
|
+
return user ? userLinkedObject(user) : user;
|
|
31618
|
+
},
|
|
31619
|
+
get childRooms() {
|
|
31620
|
+
if (!room.childRoomIds || room.childRoomIds.length === 0)
|
|
31621
|
+
return [];
|
|
31622
|
+
return room.childRoomIds
|
|
31623
|
+
.map(id => {
|
|
31624
|
+
var _a;
|
|
31625
|
+
const roomCache = (_a = pullFromCache(['room', 'get', id])) === null || _a === void 0 ? void 0 : _a.data;
|
|
31626
|
+
if (!roomCache)
|
|
31627
|
+
return undefined;
|
|
31628
|
+
return roomLinkedObject(roomCache);
|
|
31629
|
+
})
|
|
31630
|
+
.filter(isNonNullable);
|
|
31631
|
+
}, participants: room.participants.map(participant => (Object.assign(Object.assign({}, participant), { get user() {
|
|
31632
|
+
var _a;
|
|
31633
|
+
const user = (_a = pullFromCache(['user', 'get', participant.userId])) === null || _a === void 0 ? void 0 : _a.data;
|
|
31634
|
+
return user ? userLinkedObject(user) : user;
|
|
31635
|
+
} }))), getLiveChat: () => getLiveChat(room), createInvitation: (userId) => createInvitations({
|
|
31636
|
+
type: "livestreamCohostInvite" /* InvitationTypeEnum.LivestreamCohostInvite */,
|
|
31637
|
+
targetType: 'room',
|
|
31638
|
+
targetId: room.roomId,
|
|
31639
|
+
userIds: [userId],
|
|
31640
|
+
}), getInvitations: async () => {
|
|
31649
31641
|
const { data } = await getInvitation({
|
|
31650
|
-
|
|
31651
|
-
|
|
31642
|
+
targetId: room.roomId,
|
|
31643
|
+
targetType: 'room',
|
|
31644
|
+
type: "livestreamCohostInvite" /* InvitationTypeEnum.LivestreamCohostInvite */,
|
|
31652
31645
|
});
|
|
31653
31646
|
return data;
|
|
31654
|
-
},
|
|
31655
|
-
|
|
31656
|
-
|
|
31657
|
-
const { data } = await getMyJoinRequest(community.communityId);
|
|
31658
|
-
return data;
|
|
31647
|
+
}, analytics() {
|
|
31648
|
+
// Use 'this' to avoid creating a new room object
|
|
31649
|
+
return new AmityRoomAnalytics(this);
|
|
31659
31650
|
} });
|
|
31660
31651
|
};
|
|
31661
31652
|
|
|
31653
|
+
const pollLinkedObject = (poll) => {
|
|
31654
|
+
return Object.assign(Object.assign({}, poll), { answers: poll.answers.map(answer => (Object.assign(Object.assign({}, answer), { get image() {
|
|
31655
|
+
var _a;
|
|
31656
|
+
if (!answer.fileId)
|
|
31657
|
+
return undefined;
|
|
31658
|
+
return (_a = pullFromCache(['file', 'get', answer.fileId])) === null || _a === void 0 ? void 0 : _a.data;
|
|
31659
|
+
} }))) });
|
|
31660
|
+
};
|
|
31661
|
+
|
|
31662
31662
|
const productLinkedObject = (product) => {
|
|
31663
31663
|
const analyticsEngineInstance = AnalyticsEngine$1.getInstance();
|
|
31664
31664
|
return Object.assign(Object.assign({}, product), { analytics: {
|