@amityco/ts-sdk-react-native
Version:
Amity Social Cloud Typescript SDK
127 lines (107 loc) • 4.28 kB
text/typescript
import hash from 'object-hash';
import { pullFromCache, pushToCache } from '~/cache/api';
import { JoinRequestsPaginationController } from './JoinRequestsPaginationController';
import { JoinRequestsQueryStreamController } from './JoinRequestsQueryStreamController';
import { LiveCollectionController } from '~/core/liveCollection/LiveCollectionController';
import { sortByFirstCreated, sortByLastCreated } from '~/core/query';
import { prepareCommunityJoinRequestPayload } from '~/communityRepository/utils';
import { EnumJoinRequestAction } from './enum';
import { isNonNullable } from '~/utils';
import { joinRequestLinkedObject } from '~/utils/linkedObject/joinRequestLinkedObject';
import {
onJoinRequestCreated,
onJoinRequestDeleted,
onJoinRequestUpdated,
} from '~/communityRepository/joinRequest/events/';
export class JoinRequestsLiveCollectionController extends LiveCollectionController<
'joinRequest',
Amity.JoinRequestLiveCollection,
Amity.JoinRequest,
JoinRequestsPaginationController
> {
private queryStreamController: JoinRequestsQueryStreamController;
private query: Amity.JoinRequestLiveCollection;
constructor(
query: Amity.JoinRequestLiveCollection,
callback: Amity.LiveCollectionCallback<Amity.JoinRequest>,
) {
const queryStreamId = hash(query);
const cacheKey = ['joinRequest', 'collection', queryStreamId];
const paginationController = new JoinRequestsPaginationController(query);
super(paginationController, queryStreamId, cacheKey, callback);
this.query = query;
this.queryStreamController = new JoinRequestsQueryStreamController(
this.query,
this.cacheKey,
this.notifyChange.bind(this),
prepareCommunityJoinRequestPayload,
);
this.callback = callback.bind(this);
this.loadPage({ initial: true });
}
protected setup() {
const collection = pullFromCache<Amity.JoinRequestLiveCollectionCache>(this.cacheKey)?.data;
if (!collection) {
pushToCache(this.cacheKey, {
data: [],
params: this.query,
});
}
}
protected async persistModel(queryPayload: Amity.CommunityJoinRequestPayload & Amity.Pagination) {
await this.queryStreamController.saveToMainDB(queryPayload);
}
protected persistQueryStream({
response,
direction,
refresh,
}: Amity.LiveCollectionPersistQueryStreamParams<'joinRequest'>) {
const joinRequestResponse = response as unknown as Amity.CommunityJoinRequestPayload &
Partial<Amity.Pagination>;
this.queryStreamController.appendToQueryStream(joinRequestResponse, direction, refresh);
}
startSubscription() {
return this.queryStreamController.subscribeRTE([
{ fn: onJoinRequestCreated, action: EnumJoinRequestAction.OnLocalJoinRequestCreated },
{ fn: onJoinRequestUpdated, action: EnumJoinRequestAction.OnLocalJoinRequestUpdated },
{ fn: onJoinRequestDeleted, action: EnumJoinRequestAction.OnLocalJoinRequestDeleted },
]);
}
notifyChange({ origin, loading, error }: Amity.LiveCollectionNotifyParams) {
const collection = pullFromCache<Amity.JoinRequestLiveCollectionCache>(this.cacheKey)?.data;
if (!collection) return;
const data = this.applyFilter(
collection.data
.map(id => pullFromCache<Amity.InternalJoinRequest>(['joinRequest', 'get', id])!)
.filter(isNonNullable)
.map(({ data }) => data)
.map(joinRequestLinkedObject),
);
if (!this.shouldNotify(data) && origin === 'event') return;
this.callback({
onNextPage: () => this.loadPage({ direction: Amity.LiveCollectionPageDirection.NEXT }),
data,
hasNextPage: !!this.paginationController.getNextToken(),
loading,
error,
});
}
applyFilter(data: Amity.JoinRequest[]) {
let joinRequest = data;
if (this.query.status) {
joinRequest = joinRequest.filter(joinRequest => joinRequest.status === this.query.status);
}
const sortFn = (() => {
switch (this.query.sortBy) {
case 'firstCreated':
return sortByFirstCreated;
case 'lastCreated':
return sortByLastCreated;
default:
return sortByLastCreated;
}
})();
joinRequest = joinRequest.sort(sortFn);
return joinRequest;
}
}