@amityco/ts-sdk-react-native 6.22.1-600ab29.0 → 6.22.1-b0a1854.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/package.json +3 -1
- package/rollup.config.js +6 -0
- package/src/@types/core/events.ts +8 -0
- package/src/@types/domains/channel.ts +1 -0
- package/src/@types/domains/community.ts +50 -1
- package/src/@types/domains/post.ts +3 -3
- package/src/channelRepository/api/getChannel.ts +1 -1
- package/src/channelRepository/api/getChannelByIds.ts +4 -3
- package/src/channelRepository/api/markAsRead.ts +6 -2
- package/src/channelRepository/channelMembership/observers/getMembers/ChannelMemberLiveCollectionController.ts +2 -2
- package/src/channelRepository/channelMembership/observers/getMembers/ChannelMemberQueryStreamController.ts +5 -2
- package/src/channelRepository/events/onChannelMemberRoleAdded.ts +1 -1
- package/src/channelRepository/events/onChannelMemberRoleRemoved.ts +1 -1
- package/src/channelRepository/observers/getChannel.ts +8 -4
- package/src/channelRepository/observers/getChannels/ChannelLiveCollectionController.ts +10 -8
- package/src/channelRepository/observers/observeChannel.ts +15 -3
- package/src/channelRepository/observers/observeChannels.ts +8 -4
- package/src/client/api/index.ts +3 -0
- package/src/client/api/logout.ts +1 -1
- package/src/client/api/registerPushNotification.ts +37 -0
- package/src/client/api/secureLogout.ts +1 -1
- package/src/client/api/unregisterPushNotification.ts +26 -0
- package/src/client/utils/ReadReceiptSync/readReceiptSyncEngine.ts +6 -3
- package/src/client/utils/markerSyncEngine.ts +4 -1
- package/src/commentRepository/api/createComment.ts +2 -2
- package/src/commentRepository/api/deleteComment.ts +2 -4
- package/src/commentRepository/events/utils.ts +9 -6
- package/src/commentRepository/internalApi/createComment.ts +3 -2
- package/src/commentRepository/internalApi/deleteComment.ts +2 -2
- package/src/communityRepository/api/createCommunity.ts +5 -2
- package/src/communityRepository/api/getCommunities.ts +5 -1
- package/src/communityRepository/api/getCommunity.ts +5 -1
- package/src/communityRepository/api/queryCommunities.ts +2 -2
- package/src/communityRepository/api/updateCommunity.ts +5 -1
- package/src/communityRepository/communityMembership/events/utils.ts +2 -2
- package/src/communityRepository/communityMembership/observers/getMembers/CommunityMembersLiveCollectionController.ts +151 -0
- package/src/communityRepository/communityMembership/observers/getMembers/CommunityMembersPaginationController.ts +26 -0
- package/src/communityRepository/communityMembership/observers/getMembers/CommunityMembersQueryStreamController.ts +114 -0
- package/src/communityRepository/communityMembership/observers/getMembers/enums.ts +10 -0
- package/src/communityRepository/communityMembership/observers/getMembers.ts +15 -128
- package/src/communityRepository/communityMembership/observers/index.ts +1 -0
- package/src/communityRepository/communityMembership/observers/searchMembers/SearchCommunityMembersLiveCollectionController.ts +130 -0
- package/src/communityRepository/communityMembership/observers/searchMembers/SearchCommunityMembersPaginationController.ts +29 -0
- package/src/communityRepository/communityMembership/observers/searchMembers/SearchCommunityMembersQueryStreamController.ts +105 -0
- package/src/communityRepository/communityMembership/observers/searchMembers/enums.ts +9 -0
- package/src/communityRepository/communityMembership/observers/searchMembers.ts +60 -0
- package/src/communityRepository/observers/getCommunities/CommunitiesLiveCollectionController.ts +155 -0
- package/src/communityRepository/observers/getCommunities/CommunitiesPaginationController.ts +31 -0
- package/src/communityRepository/observers/getCommunities/CommunitiesQueryStreamController.ts +89 -0
- package/src/communityRepository/observers/getCommunities/enums.ts +5 -0
- package/src/communityRepository/observers/getCommunities.ts +7 -150
- package/src/communityRepository/observers/index.ts +1 -0
- package/src/communityRepository/observers/searchCommunities/SearchCommunitiesLiveCollectionController.ts +127 -0
- package/src/communityRepository/observers/searchCommunities/SearchCommunitiesPaginationController.ts +31 -0
- package/src/communityRepository/observers/searchCommunities/SearchCommunitiesQueryStreamController.ts +82 -0
- package/src/communityRepository/observers/searchCommunities/enums.ts +5 -0
- package/src/communityRepository/observers/searchCommunities.ts +56 -0
- package/src/communityRepository/utils/payload.ts +35 -1
- package/src/communityRepository/utils/saveCommunityUsers.ts +16 -0
- package/src/core/liveCollection/LiveCollectionController.ts +10 -6
- package/src/fileRepository/api/createFile.ts +5 -2
- package/src/fileRepository/api/createImage.ts +6 -2
- package/src/fileRepository/api/createVideo.ts +5 -2
- package/src/fileRepository/api/uploadFile.ts +5 -2
- package/src/fileRepository/api/uploadImage.ts +5 -2
- package/src/fileRepository/api/uploadVideo.ts +5 -2
- package/src/marker/events/onChannelUnreadUpdatedLocal.ts +29 -0
- package/src/marker/events/onSubChannelMarkerFetched.ts +1 -1
- package/src/marker/events/onSubChannelUnreadUpdatedLocal.ts +29 -0
- package/src/marker/events/onUserFeedMarkerUpdated.ts +3 -4
- package/src/marker/utils/reCalculateChannelUnreadInfo.ts +7 -3
- package/src/messagePreview/utils/getChannelMessagePreviewWithUser.ts +5 -1
- package/src/messageRepository/events/onMessageCreated.ts +4 -0
- package/src/messageRepository/observers/getMessages/MessageLiveCollectionController.ts +3 -3
- package/src/messageRepository/utils/markReadMessage.ts +8 -0
- package/src/postRepository/api/createPost.ts +1 -2
- package/src/postRepository/api/editPost.ts +1 -1
- package/src/postRepository/api/updatePost.ts +1 -1
- package/src/postRepository/observers/getPost.ts +26 -0
- package/src/postRepository/observers/getPosts.ts +31 -0
- package/src/storyRepository/observers/getGlobalStoryTargets/GlobalStoryLiveCollectionController.ts +2 -2
- package/src/storyRepository/observers/getStoriesByTargetIds/StoryLiveCollectionController.ts +1 -1
- package/src/subChannelRepository/observers/getSubChannel.ts +10 -6
- package/src/subChannelRepository/observers/getSubChannels/SubChannelLiveCollectionController.ts +13 -10
- package/src/utils/linkedObject/channelLinkedObject.ts +8 -0
- package/src/utils/linkedObject/index.ts +2 -0
- package/src/utils/linkedObject/messageLinkedObject.ts +2 -7
- package/src/utils/liveObject.ts +3 -0
- package/src/utils/object.ts +15 -0
|
@@ -1,31 +1,7 @@
|
|
|
1
|
-
|
|
2
|
-
import { getResolver } from '~/core/model';
|
|
3
|
-
import { dropFromCache, pullFromCache, pushToCache } from '~/cache/api';
|
|
1
|
+
import { dropFromCache } from '~/cache/api';
|
|
4
2
|
import { getActiveClient } from '~/client/api';
|
|
5
|
-
import {
|
|
6
|
-
|
|
7
|
-
filterByCommunityMembership,
|
|
8
|
-
filterByPropEquality,
|
|
9
|
-
filterByStringComparePartially,
|
|
10
|
-
queryOptions,
|
|
11
|
-
runQuery,
|
|
12
|
-
sortByDisplayName,
|
|
13
|
-
sortByFirstCreated,
|
|
14
|
-
sortByLastCreated,
|
|
15
|
-
} from '~/core/query';
|
|
16
|
-
import {
|
|
17
|
-
COLLECTION_DEFAULT_CACHING_POLICY,
|
|
18
|
-
COLLECTION_DEFAULT_PAGINATION_LIMIT,
|
|
19
|
-
ENABLE_CACHE_MESSAGE,
|
|
20
|
-
} from '~/utils/constants';
|
|
21
|
-
import { CACHE_SHORTEN_LIFESPAN } from '~/cache/utils';
|
|
22
|
-
import { onCommunityCreated, onCommunityDeleted, onCommunityUpdated } from '../events';
|
|
23
|
-
import {
|
|
24
|
-
onCommunityJoined,
|
|
25
|
-
onCommunityLeft,
|
|
26
|
-
onCommunityUserChanged,
|
|
27
|
-
} from '../communityMembership/events';
|
|
28
|
-
import { queryCommunities } from '../api/queryCommunities';
|
|
3
|
+
import { ENABLE_CACHE_MESSAGE } from '~/utils/constants';
|
|
4
|
+
import { CommunityLiveCollectionController } from './getCommunities/CommunitiesLiveCollectionController';
|
|
29
5
|
|
|
30
6
|
/* begin_public_function
|
|
31
7
|
id: community.query
|
|
@@ -53,7 +29,7 @@ export const getCommunities = (
|
|
|
53
29
|
callback: Amity.LiveCollectionCallback<Amity.Community>,
|
|
54
30
|
config?: Amity.LiveCollectionConfig,
|
|
55
31
|
) => {
|
|
56
|
-
const { log, cache
|
|
32
|
+
const { log, cache } = getActiveClient();
|
|
57
33
|
|
|
58
34
|
if (!cache) {
|
|
59
35
|
console.log(ENABLE_CACHE_MESSAGE);
|
|
@@ -62,130 +38,11 @@ export const getCommunities = (
|
|
|
62
38
|
const timestamp = Date.now();
|
|
63
39
|
log(`getCommunities(tmpid: ${timestamp}) > listen`);
|
|
64
40
|
|
|
65
|
-
const
|
|
41
|
+
const communitiesLiveCollection = new CommunityLiveCollectionController(params, callback);
|
|
42
|
+
const disposers = communitiesLiveCollection.startSubscription();
|
|
66
43
|
|
|
67
|
-
const
|
|
68
|
-
const { policy = COLLECTION_DEFAULT_CACHING_POLICY } = config ?? {};
|
|
44
|
+
const cacheKey = communitiesLiveCollection.getCacheKey();
|
|
69
45
|
|
|
70
|
-
const disposers: Amity.Unsubscriber[] = [];
|
|
71
|
-
const cacheKey = ['community', 'collection', queryParams as Amity.Serializable];
|
|
72
|
-
|
|
73
|
-
const responder = (data: Amity.CommunityLiveCollectionCache) => {
|
|
74
|
-
let communities: Amity.Community[] =
|
|
75
|
-
data.data
|
|
76
|
-
.map(communityId => pullFromCache<Amity.Community>(['community', 'get', communityId])!)
|
|
77
|
-
.filter(Boolean)
|
|
78
|
-
.map(({ data }) => data) ?? [];
|
|
79
|
-
|
|
80
|
-
communities = filterByStringComparePartially(communities, 'displayName', params.displayName);
|
|
81
|
-
|
|
82
|
-
if (!params.includeDeleted) {
|
|
83
|
-
communities = filterByPropEquality(communities, 'isDeleted', false);
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
if (params.categoryId) {
|
|
87
|
-
communities = communities.filter(c => c.categoryIds?.includes(params.categoryId!));
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
if (params.tags) {
|
|
91
|
-
communities = communities.filter(c => c.tags?.some(t => params.tags?.includes(t)));
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
if (params.membership && userId) {
|
|
95
|
-
communities = filterByCommunityMembership(communities, params.membership, userId);
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
const sortBy = params.sortBy || 'lastCreated';
|
|
99
|
-
|
|
100
|
-
if (sortBy === 'lastCreated' || sortBy === 'firstCreated') {
|
|
101
|
-
communities = communities.sort(
|
|
102
|
-
sortBy === 'lastCreated' ? sortByLastCreated : sortByFirstCreated,
|
|
103
|
-
);
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
/*
|
|
107
|
-
* The server returns communities with empty | null displayName's first before
|
|
108
|
-
* returning sorted list of communities with displayNames
|
|
109
|
-
*
|
|
110
|
-
* This section needs to be updated as displayNames can be null as well
|
|
111
|
-
*/
|
|
112
|
-
if (sortBy === 'displayName') {
|
|
113
|
-
communities = communities
|
|
114
|
-
// this needs to be aligned with the backend data type
|
|
115
|
-
.map(c => (c.displayName ? c : { ...c, displayName: '' }))
|
|
116
|
-
// @ts-ignore
|
|
117
|
-
.sort(sortByDisplayName);
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
callback({
|
|
121
|
-
onNextPage: onFetch,
|
|
122
|
-
data: communities,
|
|
123
|
-
hasNextPage: !!data.params?.page,
|
|
124
|
-
loading: data.loading,
|
|
125
|
-
error: data.error,
|
|
126
|
-
});
|
|
127
|
-
};
|
|
128
|
-
|
|
129
|
-
const realtimeRouter = (_: Amity.CommunityActionType) => (community: Amity.Community) => {
|
|
130
|
-
const collection = pullFromCache<Amity.CommunityLiveCollectionCache>(cacheKey)?.data;
|
|
131
|
-
if (!collection) return;
|
|
132
|
-
|
|
133
|
-
/*
|
|
134
|
-
* Simply update collection and let responder decide what to do with data
|
|
135
|
-
*/
|
|
136
|
-
collection.data = [...new Set([community.communityId, ...collection.data])];
|
|
137
|
-
|
|
138
|
-
pushToCache(cacheKey, collection);
|
|
139
|
-
responder(collection);
|
|
140
|
-
};
|
|
141
|
-
|
|
142
|
-
const onFetch = (initial = false) => {
|
|
143
|
-
const collection = pullFromCache<Amity.CommunityLiveCollectionCache>(cacheKey)?.data;
|
|
144
|
-
|
|
145
|
-
const communities = collection?.data ?? [];
|
|
146
|
-
|
|
147
|
-
if (!initial && communities.length > 0 && !collection?.params.page) return;
|
|
148
|
-
|
|
149
|
-
const query = createQuery(queryCommunities, {
|
|
150
|
-
...queryParams,
|
|
151
|
-
limit: initial ? limit : undefined,
|
|
152
|
-
page: !initial ? collection?.params.page : undefined,
|
|
153
|
-
});
|
|
154
|
-
|
|
155
|
-
runQuery(
|
|
156
|
-
query,
|
|
157
|
-
({ data: result, error, loading, paging }) => {
|
|
158
|
-
const data = {
|
|
159
|
-
loading,
|
|
160
|
-
error,
|
|
161
|
-
params: { page: paging?.next },
|
|
162
|
-
data: communities,
|
|
163
|
-
};
|
|
164
|
-
|
|
165
|
-
if (result) {
|
|
166
|
-
data.data = initial
|
|
167
|
-
? result.map(getResolver('community'))
|
|
168
|
-
: [...new Set([...communities, ...result.map(getResolver('community'))])];
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
pushToCache(cacheKey, data);
|
|
172
|
-
|
|
173
|
-
responder(data);
|
|
174
|
-
},
|
|
175
|
-
queryOptions(policy, CACHE_SHORTEN_LIFESPAN),
|
|
176
|
-
);
|
|
177
|
-
};
|
|
178
|
-
|
|
179
|
-
disposers.push(
|
|
180
|
-
onCommunityCreated(realtimeRouter('onCreate')),
|
|
181
|
-
onCommunityDeleted(realtimeRouter('onDelete')),
|
|
182
|
-
onCommunityUpdated(realtimeRouter('onUpdate')),
|
|
183
|
-
onCommunityJoined(realtimeRouter('onJoin')),
|
|
184
|
-
onCommunityLeft(realtimeRouter('onLeft')),
|
|
185
|
-
onCommunityUserChanged(realtimeRouter('onMemberCountChanged')),
|
|
186
|
-
);
|
|
187
|
-
|
|
188
|
-
onFetch(true);
|
|
189
46
|
disposers.push(() => dropFromCache(cacheKey));
|
|
190
47
|
|
|
191
48
|
return () => {
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
import hash from 'object-hash';
|
|
2
|
+
import { pullFromCache, pushToCache } from '~/cache/api';
|
|
3
|
+
import { CommunitiesPaginationController } from './SearchCommunitiesPaginationController';
|
|
4
|
+
import { CommunitiesQueryStreamController } from './SearchCommunitiesQueryStreamController';
|
|
5
|
+
import { LiveCollectionController } from '~/core/liveCollection/LiveCollectionController';
|
|
6
|
+
import { onCommunityDeleted, onCommunityUpdated } from '~/communityRepository/events';
|
|
7
|
+
import { filterByCommunityMembership, filterByPropEquality } from '~/core/query';
|
|
8
|
+
import { prepareCommunityPayload } from '~/communityRepository/utils';
|
|
9
|
+
import { getActiveClient } from '~/client';
|
|
10
|
+
import { EnumCommunityActions } from './enums';
|
|
11
|
+
import { EnumCommunityMemberActions } from '~/communityRepository/communityMembership/observers/getMembers/enums';
|
|
12
|
+
import {
|
|
13
|
+
onCommunityJoined,
|
|
14
|
+
onCommunityLeft,
|
|
15
|
+
onCommunityUserChanged,
|
|
16
|
+
} from '~/communityRepository/communityMembership';
|
|
17
|
+
|
|
18
|
+
export class SearchCommunityLiveCollectionController extends LiveCollectionController<
|
|
19
|
+
'community',
|
|
20
|
+
Amity.SearchCommunityLiveCollection,
|
|
21
|
+
Amity.Community,
|
|
22
|
+
CommunitiesPaginationController
|
|
23
|
+
> {
|
|
24
|
+
private queryStreamController: CommunitiesQueryStreamController;
|
|
25
|
+
|
|
26
|
+
private query: Amity.SearchCommunityLiveCollection;
|
|
27
|
+
|
|
28
|
+
constructor(
|
|
29
|
+
query: Amity.SearchCommunityLiveCollection,
|
|
30
|
+
callback: Amity.LiveCollectionCallback<Amity.Community>,
|
|
31
|
+
) {
|
|
32
|
+
const queryStreamId = hash(query);
|
|
33
|
+
const cacheKey = ['community', 'collection', queryStreamId];
|
|
34
|
+
const paginationController = new CommunitiesPaginationController(query);
|
|
35
|
+
|
|
36
|
+
super(paginationController, queryStreamId, cacheKey, callback);
|
|
37
|
+
|
|
38
|
+
this.query = query;
|
|
39
|
+
this.queryStreamController = new CommunitiesQueryStreamController(
|
|
40
|
+
this.query,
|
|
41
|
+
this.cacheKey,
|
|
42
|
+
this.notifyChange.bind(this),
|
|
43
|
+
prepareCommunityPayload,
|
|
44
|
+
);
|
|
45
|
+
|
|
46
|
+
this.callback = callback.bind(this);
|
|
47
|
+
this.loadPage({ initial: true });
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
protected setup() {
|
|
51
|
+
const collection = pullFromCache<Amity.SearchCommunityLiveCollectionCache>(this.cacheKey)?.data;
|
|
52
|
+
if (!collection) {
|
|
53
|
+
pushToCache(this.cacheKey, {
|
|
54
|
+
data: [],
|
|
55
|
+
params: {},
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
protected async persistModel(queryPayload: Amity.CommunityPayload & Amity.Pagination) {
|
|
61
|
+
await this.queryStreamController.saveToMainDB(queryPayload);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
protected persistQueryStream({
|
|
65
|
+
response,
|
|
66
|
+
direction,
|
|
67
|
+
refresh,
|
|
68
|
+
}: Amity.LiveCollectionPersistQueryStreamParams<'community'>) {
|
|
69
|
+
this.queryStreamController.appendToQueryStream(response, direction, refresh);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
startSubscription() {
|
|
73
|
+
return this.queryStreamController.subscribeRTE([
|
|
74
|
+
{ fn: onCommunityDeleted, action: EnumCommunityActions.OnCommunityDeleted },
|
|
75
|
+
{ fn: onCommunityUpdated, action: EnumCommunityActions.OnCommunityUpdated },
|
|
76
|
+
{ fn: onCommunityJoined, action: EnumCommunityMemberActions.OnCommunityJoined },
|
|
77
|
+
{ fn: onCommunityLeft, action: EnumCommunityMemberActions.OnCommunityLeft },
|
|
78
|
+
{ fn: onCommunityUserChanged, action: EnumCommunityMemberActions.OnMemberCountChanged },
|
|
79
|
+
]);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
notifyChange({ origin, loading, error }: Amity.LiveCollectionNotifyParams) {
|
|
83
|
+
const collection = pullFromCache<Amity.SearchCommunityLiveCollectionCache>(this.cacheKey)?.data;
|
|
84
|
+
if (!collection) return;
|
|
85
|
+
|
|
86
|
+
const data = this.applyFilter(
|
|
87
|
+
collection.data
|
|
88
|
+
.map(id => pullFromCache<Amity.Community>(['community', 'get', id])!)
|
|
89
|
+
.filter(Boolean)
|
|
90
|
+
.map(({ data }) => data) ?? [],
|
|
91
|
+
);
|
|
92
|
+
|
|
93
|
+
if (!this.shouldNotify(data) && origin === 'event') return;
|
|
94
|
+
|
|
95
|
+
this.callback({
|
|
96
|
+
onNextPage: () => this.loadPage({ direction: Amity.LiveCollectionPageDirection.NEXT }),
|
|
97
|
+
data,
|
|
98
|
+
hasNextPage: !!this.paginationController.getNextToken(),
|
|
99
|
+
loading,
|
|
100
|
+
error,
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
applyFilter(data: Amity.Community[]) {
|
|
105
|
+
const { userId } = getActiveClient();
|
|
106
|
+
|
|
107
|
+
let communities = data;
|
|
108
|
+
|
|
109
|
+
if (this.query.includeDeleted) {
|
|
110
|
+
communities = filterByPropEquality(communities, 'isDeleted', false);
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
if (this.query.categoryId) {
|
|
114
|
+
communities = communities.filter(c => c.categoryIds?.includes(this.query.categoryId!));
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
if (this.query.tags) {
|
|
118
|
+
communities = communities.filter(c => c.tags?.some(t => this.query.tags?.includes(t)));
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
if (this.query.membership && userId) {
|
|
122
|
+
communities = filterByCommunityMembership(communities, this.query.membership, userId);
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
return communities;
|
|
126
|
+
}
|
|
127
|
+
}
|
package/src/communityRepository/observers/searchCommunities/SearchCommunitiesPaginationController.ts
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { PaginationController } from '~/core/liveCollection/PaginationController';
|
|
2
|
+
import { COLLECTION_DEFAULT_PAGINATION_LIMIT } from '~/utils/constants';
|
|
3
|
+
import { inferIsDeleted } from '~/utils/inferIsDeleted';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* TODO: handle cache receive cache option, and cache policy
|
|
7
|
+
* TODO: check if querybyIds is supported
|
|
8
|
+
*/
|
|
9
|
+
export class CommunitiesPaginationController extends PaginationController<
|
|
10
|
+
'community',
|
|
11
|
+
Amity.SearchCommunityLiveCollection
|
|
12
|
+
> {
|
|
13
|
+
async getRequest(queryParams: Amity.SearchCommunityLiveCollection, token: string | undefined) {
|
|
14
|
+
const { limit = COLLECTION_DEFAULT_PAGINATION_LIMIT, ...params } = queryParams;
|
|
15
|
+
const options = token ? { token } : { limit };
|
|
16
|
+
|
|
17
|
+
const { data: queryResponse } = await this.http.get<Amity.CommunityPayload & Amity.Pagination>(
|
|
18
|
+
`/api/v3/communities`,
|
|
19
|
+
{
|
|
20
|
+
params: {
|
|
21
|
+
...params,
|
|
22
|
+
isDeleted: inferIsDeleted(params.includeDeleted),
|
|
23
|
+
keyword: params.displayName,
|
|
24
|
+
filter: params.membership,
|
|
25
|
+
options,
|
|
26
|
+
},
|
|
27
|
+
},
|
|
28
|
+
);
|
|
29
|
+
return queryResponse;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import { QueryStreamController } from '~/core/liveCollection/QueryStreamController';
|
|
2
|
+
import { pullFromCache, pushToCache } from '~/cache/api';
|
|
3
|
+
import { ingestInCache } from '~/cache/api/ingestInCache';
|
|
4
|
+
import { getResolver } from '~/core/model';
|
|
5
|
+
import { getActiveClient } from '~/client';
|
|
6
|
+
import { EnumCommunityActions } from './enums';
|
|
7
|
+
import { EnumCommunityMemberActions } from '~/communityRepository/communityMembership/observers/getMembers/enums';
|
|
8
|
+
|
|
9
|
+
export class CommunitiesQueryStreamController extends QueryStreamController<
|
|
10
|
+
Amity.CommunityPayload,
|
|
11
|
+
Amity.SearchCommunityLiveCollection
|
|
12
|
+
> {
|
|
13
|
+
private notifyChange: (params: Amity.LiveCollectionNotifyParams) => void;
|
|
14
|
+
|
|
15
|
+
private preparePayload: (response: Amity.CommunityPayload) => Amity.ProcessedCommunityPayload;
|
|
16
|
+
|
|
17
|
+
constructor(
|
|
18
|
+
query: Amity.SearchCommunityLiveCollection,
|
|
19
|
+
cacheKey: string[],
|
|
20
|
+
notifyChange: (params: Amity.LiveCollectionNotifyParams) => void,
|
|
21
|
+
preparePayload: (response: Amity.CommunityPayload) => Amity.ProcessedCommunityPayload,
|
|
22
|
+
) {
|
|
23
|
+
super(query, cacheKey);
|
|
24
|
+
this.notifyChange = notifyChange;
|
|
25
|
+
this.preparePayload = preparePayload;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
async saveToMainDB(response: Amity.CommunityPayload) {
|
|
29
|
+
const processedPayload = await this.preparePayload(response);
|
|
30
|
+
|
|
31
|
+
const client = getActiveClient();
|
|
32
|
+
const cachedAt = client.cache && Date.now();
|
|
33
|
+
|
|
34
|
+
if (client.cache) {
|
|
35
|
+
ingestInCache(processedPayload, { cachedAt });
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
appendToQueryStream(
|
|
40
|
+
response: Amity.CommunityPayload & Partial<Amity.Pagination>,
|
|
41
|
+
direction: Amity.LiveCollectionPageDirection,
|
|
42
|
+
refresh = false,
|
|
43
|
+
) {
|
|
44
|
+
if (refresh) {
|
|
45
|
+
pushToCache(this.cacheKey, {
|
|
46
|
+
data: response.communities.map(getResolver('community')),
|
|
47
|
+
});
|
|
48
|
+
} else {
|
|
49
|
+
const collection = pullFromCache<Amity.SearchCommunityLiveCollectionCache>(
|
|
50
|
+
this.cacheKey,
|
|
51
|
+
)?.data;
|
|
52
|
+
|
|
53
|
+
const communities = collection?.data ?? [];
|
|
54
|
+
|
|
55
|
+
pushToCache(this.cacheKey, {
|
|
56
|
+
...collection,
|
|
57
|
+
data: [...new Set([...communities, ...response.communities.map(getResolver('community'))])],
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
reactor(action: EnumCommunityActions | EnumCommunityMemberActions) {
|
|
63
|
+
return (community: Amity.Community) => {
|
|
64
|
+
const collection = pullFromCache<Amity.SearchCommunityLiveCollectionCache>(
|
|
65
|
+
this.cacheKey,
|
|
66
|
+
)?.data;
|
|
67
|
+
if (!collection) return;
|
|
68
|
+
|
|
69
|
+
pushToCache(this.cacheKey, collection);
|
|
70
|
+
this.notifyChange({ origin: Amity.LiveDataOrigin.EVENT, loading: false });
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
subscribeRTE(
|
|
75
|
+
createSubscriber: {
|
|
76
|
+
fn: (reactor: (channel: Amity.Community) => void) => Amity.Unsubscriber;
|
|
77
|
+
action: EnumCommunityActions | EnumCommunityMemberActions;
|
|
78
|
+
}[],
|
|
79
|
+
) {
|
|
80
|
+
return createSubscriber.map(subscriber => subscriber.fn(this.reactor(subscriber.action)));
|
|
81
|
+
}
|
|
82
|
+
}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { dropFromCache } from '~/cache/api';
|
|
2
|
+
import { getActiveClient } from '~/client/api';
|
|
3
|
+
import { ENABLE_CACHE_MESSAGE } from '~/utils/constants';
|
|
4
|
+
import { SearchCommunityLiveCollectionController } from './searchCommunities/SearchCommunitiesLiveCollectionController';
|
|
5
|
+
|
|
6
|
+
/* begin_public_function
|
|
7
|
+
id: community.query
|
|
8
|
+
*/
|
|
9
|
+
/**
|
|
10
|
+
* ```js
|
|
11
|
+
* import { CommunityRepository } from '@amityco/ts-sdk-react-native'
|
|
12
|
+
*
|
|
13
|
+
* let communities = []
|
|
14
|
+
* const unsub = CommunityRepository.searchCommunities({
|
|
15
|
+
* displayName: Amity.Community['displayName'],
|
|
16
|
+
* }, response => merge(communities, response.data))
|
|
17
|
+
* ```
|
|
18
|
+
*
|
|
19
|
+
* Observe all mutations on a list of {@link Amity.Community}s
|
|
20
|
+
*
|
|
21
|
+
* @param params for querying communities
|
|
22
|
+
* @param callback the function to call when new data are available
|
|
23
|
+
* @returns An {@link Amity.Unsubscriber} function to run when willing to stop observing the communities
|
|
24
|
+
*
|
|
25
|
+
* @category Community Live Collection
|
|
26
|
+
*/
|
|
27
|
+
export const searchCommunities = (
|
|
28
|
+
params: Amity.CommunityLiveCollection,
|
|
29
|
+
callback: Amity.LiveCollectionCallback<Amity.Community>,
|
|
30
|
+
config?: Amity.LiveCollectionConfig,
|
|
31
|
+
) => {
|
|
32
|
+
const { log, cache } = getActiveClient();
|
|
33
|
+
|
|
34
|
+
if (!cache) {
|
|
35
|
+
console.log(ENABLE_CACHE_MESSAGE);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
const timestamp = Date.now();
|
|
39
|
+
log(`searchCommunities(tmpid: ${timestamp}) > listen`);
|
|
40
|
+
|
|
41
|
+
const searchCommunitiesLiveCollection = new SearchCommunityLiveCollectionController(
|
|
42
|
+
params,
|
|
43
|
+
callback,
|
|
44
|
+
);
|
|
45
|
+
const disposers = searchCommunitiesLiveCollection.startSubscription();
|
|
46
|
+
|
|
47
|
+
const cacheKey = searchCommunitiesLiveCollection.getCacheKey();
|
|
48
|
+
|
|
49
|
+
disposers.push(() => dropFromCache(cacheKey));
|
|
50
|
+
|
|
51
|
+
return () => {
|
|
52
|
+
log(`searchCommunities(tmpid: ${timestamp}) > dispose`);
|
|
53
|
+
disposers.forEach(fn => fn());
|
|
54
|
+
};
|
|
55
|
+
};
|
|
56
|
+
/* end_public_function */
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { CommunityPostSettingMaps, DefaultCommunityPostSetting } from '~/@types';
|
|
2
|
+
import { pullFromCache } from '~/cache/api';
|
|
2
3
|
import { withUsers } from '~/group/utils';
|
|
3
4
|
import { updateMembershipStatus } from './communityWithMembership';
|
|
4
5
|
|
|
@@ -13,6 +14,22 @@ const getMatchPostSetting = (value: {
|
|
|
13
14
|
value.onlyAdminCanPost === CommunityPostSettingMaps[key].onlyAdminCanPost,
|
|
14
15
|
) ?? DefaultCommunityPostSetting;
|
|
15
16
|
|
|
17
|
+
const convertCommunityUsersToUniqueObject = (
|
|
18
|
+
communityUsers: Amity.RawMembership<'community'>[],
|
|
19
|
+
) => {
|
|
20
|
+
if (!communityUsers) return communityUsers;
|
|
21
|
+
|
|
22
|
+
const result: {
|
|
23
|
+
[key: string]: Amity.RawMembership<'community'>;
|
|
24
|
+
} = {};
|
|
25
|
+
|
|
26
|
+
communityUsers.forEach(user => {
|
|
27
|
+
result[`${user.userId}#${user.communityId}`] = user;
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
return result;
|
|
31
|
+
};
|
|
32
|
+
|
|
16
33
|
export const prepareCommunityPayload = (
|
|
17
34
|
rawPayload: Amity.CommunityPayload,
|
|
18
35
|
): Amity.ProcessedCommunityPayload => {
|
|
@@ -27,7 +44,24 @@ export const prepareCommunityPayload = (
|
|
|
27
44
|
}),
|
|
28
45
|
);
|
|
29
46
|
|
|
30
|
-
const
|
|
47
|
+
const mergeCommunityUsers = communities.reduce<{
|
|
48
|
+
[key: string]: Amity.RawMembership<'community'>;
|
|
49
|
+
}>((acc, { communityId }) => {
|
|
50
|
+
const users = pullFromCache<Amity.RawMembership<'community'>[]>([
|
|
51
|
+
'communityUsers',
|
|
52
|
+
'collection',
|
|
53
|
+
communityId,
|
|
54
|
+
])?.data;
|
|
55
|
+
|
|
56
|
+
if (!users) return acc;
|
|
57
|
+
|
|
58
|
+
return {
|
|
59
|
+
...convertCommunityUsersToUniqueObject(users),
|
|
60
|
+
...acc,
|
|
61
|
+
};
|
|
62
|
+
}, convertCommunityUsersToUniqueObject(rawPayload.communityUsers));
|
|
63
|
+
|
|
64
|
+
const communityUsers = withUsers(Object.values(mergeCommunityUsers));
|
|
31
65
|
|
|
32
66
|
const communityWithMembershipStatus = updateMembershipStatus(communities, communityUsers);
|
|
33
67
|
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { pushToCache } from '~/cache/api';
|
|
2
|
+
|
|
3
|
+
export const saveCommunityUsers = (
|
|
4
|
+
communities: Amity.CommunityPayload['communities'],
|
|
5
|
+
communityUsers: Amity.CommunityPayload['communityUsers'],
|
|
6
|
+
) => {
|
|
7
|
+
if (communities.length === 0 || communityUsers.length === 0) return;
|
|
8
|
+
|
|
9
|
+
communities.forEach(({ communityId }) => {
|
|
10
|
+
const collection = communityUsers.filter(
|
|
11
|
+
({ communityId: userCommunityId }) => communityId === userCommunityId,
|
|
12
|
+
);
|
|
13
|
+
|
|
14
|
+
pushToCache(['communityUsers', 'collection', communityId], collection);
|
|
15
|
+
});
|
|
16
|
+
};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { convertGetterPropsToStatic } from '~/utils/object';
|
|
1
|
+
import { convertGetterPropsToStatic, removeFunctionProperties } from '~/utils/object';
|
|
2
2
|
import { isEqual } from '~/utils/isEqual';
|
|
3
3
|
import { PaginationController } from './PaginationController';
|
|
4
4
|
import { PaginationNoPageController } from './PaginationNoPageController';
|
|
@@ -57,10 +57,13 @@ export abstract class LiveCollectionController<
|
|
|
57
57
|
}
|
|
58
58
|
}
|
|
59
59
|
|
|
60
|
-
protected loadPage(
|
|
60
|
+
protected loadPage({
|
|
61
61
|
initial = false,
|
|
62
|
-
direction
|
|
63
|
-
|
|
62
|
+
direction = Amity.LiveCollectionPageDirection.NEXT,
|
|
63
|
+
}: {
|
|
64
|
+
initial?: boolean;
|
|
65
|
+
direction?: Amity.LiveCollectionPageDirection;
|
|
66
|
+
}) {
|
|
64
67
|
this.setup();
|
|
65
68
|
|
|
66
69
|
this.notifyChange({ origin: Amity.LiveDataOrigin.LOCAL, loading: true });
|
|
@@ -129,9 +132,10 @@ export abstract class LiveCollectionController<
|
|
|
129
132
|
abstract notifyChange(params: Amity.LiveCollectionNotifyParams): void;
|
|
130
133
|
|
|
131
134
|
protected shouldNotify(data: TPublicPayload[]) {
|
|
132
|
-
|
|
135
|
+
const newData = data.map(convertGetterPropsToStatic).map(removeFunctionProperties);
|
|
136
|
+
if (isEqual(this.snapshot, newData)) return false;
|
|
133
137
|
|
|
134
|
-
this.snapshot =
|
|
138
|
+
this.snapshot = newData as TPublicPayload[];
|
|
135
139
|
return true;
|
|
136
140
|
}
|
|
137
141
|
|
|
@@ -24,8 +24,11 @@ export const createFile = async <T extends Amity.FileType = any>(
|
|
|
24
24
|
const client = getActiveClient();
|
|
25
25
|
client.log('file/createFile', formData);
|
|
26
26
|
|
|
27
|
-
|
|
28
|
-
|
|
27
|
+
const files = formData.getAll('files');
|
|
28
|
+
|
|
29
|
+
if (!files.length) throw new Error('The formData object must have a `files` key.');
|
|
30
|
+
|
|
31
|
+
formData.append('preferredFilename', (files[0] as File).name);
|
|
29
32
|
|
|
30
33
|
const headers =
|
|
31
34
|
'getHeaders' in formData
|
|
@@ -23,8 +23,12 @@ export const createImage = async (
|
|
|
23
23
|
const client = getActiveClient();
|
|
24
24
|
client.log('file/createImage', formData);
|
|
25
25
|
|
|
26
|
-
|
|
27
|
-
|
|
26
|
+
const files = formData.getAll('files');
|
|
27
|
+
|
|
28
|
+
if (!files.length) throw new Error('The formData object must have a `files` key.');
|
|
29
|
+
|
|
30
|
+
formData.append('preferredFilename', (files[0] as File).name);
|
|
31
|
+
|
|
28
32
|
const headers =
|
|
29
33
|
'getHeaders' in formData
|
|
30
34
|
? (formData as any).getHeaders()
|
|
@@ -26,8 +26,11 @@ export const createVideo = async (
|
|
|
26
26
|
const client = getActiveClient();
|
|
27
27
|
client.log('file/createVideo', formData);
|
|
28
28
|
|
|
29
|
-
|
|
30
|
-
|
|
29
|
+
const files = formData.getAll('files');
|
|
30
|
+
|
|
31
|
+
if (!files.length) throw new Error('The formData object must have a `files` key.');
|
|
32
|
+
|
|
33
|
+
formData.append('preferredFilename', (files[0] as File).name);
|
|
31
34
|
|
|
32
35
|
if (feedType) {
|
|
33
36
|
formData.append('feedType', feedType);
|
|
@@ -28,8 +28,11 @@ export const uploadFile = async <T extends Amity.FileType = any>(
|
|
|
28
28
|
const client = getActiveClient();
|
|
29
29
|
client.log('file/uploadFile', formData);
|
|
30
30
|
|
|
31
|
-
|
|
32
|
-
|
|
31
|
+
const files = formData.getAll('files');
|
|
32
|
+
|
|
33
|
+
if (!files.length) throw new Error('The formData object must have a `files` key.');
|
|
34
|
+
|
|
35
|
+
formData.append('preferredFilename', (files[0] as File).name);
|
|
33
36
|
|
|
34
37
|
const headers =
|
|
35
38
|
'getHeaders' in formData
|
|
@@ -28,8 +28,11 @@ export const uploadImage = async (
|
|
|
28
28
|
const client = getActiveClient();
|
|
29
29
|
client.log('file/uploadImage', formData);
|
|
30
30
|
|
|
31
|
-
|
|
32
|
-
|
|
31
|
+
const files = formData.getAll('files');
|
|
32
|
+
|
|
33
|
+
if (!files.length) throw new Error('The formData object must have a `files` key.');
|
|
34
|
+
|
|
35
|
+
formData.append('preferredFilename', (files[0] as File).name);
|
|
33
36
|
|
|
34
37
|
const headers =
|
|
35
38
|
'getHeaders' in formData
|