@amityco/ts-sdk-react-native 6.28.2-fbfd068.0 → 6.28.3-54dff84.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.
Files changed (37) hide show
  1. package/dist/@types/core/payload.d.ts +1 -1
  2. package/dist/@types/core/payload.d.ts.map +1 -1
  3. package/dist/commentRepository/observers/getComments.d.ts +1 -1
  4. package/dist/commentRepository/observers/getComments.d.ts.map +1 -1
  5. package/dist/communityRepository/utils/payload.d.ts +7 -0
  6. package/dist/communityRepository/utils/payload.d.ts.map +1 -1
  7. package/dist/index.cjs.js +284 -180
  8. package/dist/index.esm.js +284 -180
  9. package/dist/index.umd.js +2 -2
  10. package/dist/postRepository/internalApi/getPost.d.ts +5 -0
  11. package/dist/postRepository/internalApi/getPost.d.ts.map +1 -0
  12. package/dist/postRepository/internalApi/index.d.ts +13 -0
  13. package/dist/postRepository/internalApi/index.d.ts.map +1 -0
  14. package/dist/postRepository/observers/getPosts/PostLiveCollectionController.d.ts +14 -0
  15. package/dist/postRepository/observers/getPosts/PostLiveCollectionController.d.ts.map +1 -0
  16. package/dist/postRepository/observers/getPosts/PostPaginationController.d.ts +5 -0
  17. package/dist/postRepository/observers/getPosts/PostPaginationController.d.ts.map +1 -0
  18. package/dist/postRepository/observers/getPosts/PostQueryStreamController.d.ts +15 -0
  19. package/dist/postRepository/observers/getPosts/PostQueryStreamController.d.ts.map +1 -0
  20. package/dist/postRepository/observers/getPosts/enums.d.ts +12 -0
  21. package/dist/postRepository/observers/getPosts/enums.d.ts.map +1 -0
  22. package/dist/postRepository/observers/getPosts.d.ts.map +1 -1
  23. package/dist/postRepository/utils/payload.d.ts +2 -0
  24. package/dist/postRepository/utils/payload.d.ts.map +1 -0
  25. package/dist/utils/tests/dummy/post.d.ts +3 -3
  26. package/package.json +1 -1
  27. package/src/@types/core/payload.ts +1 -1
  28. package/src/commentRepository/observers/getComments.ts +1 -1
  29. package/src/communityRepository/utils/payload.ts +19 -3
  30. package/src/postRepository/internalApi/getPost.ts +65 -0
  31. package/src/postRepository/internalApi/index.ts +16 -0
  32. package/src/postRepository/observers/getPosts/PostLiveCollectionController.ts +190 -0
  33. package/src/postRepository/observers/getPosts/PostPaginationController.ts +45 -0
  34. package/src/postRepository/observers/getPosts/PostQueryStreamController.ts +102 -0
  35. package/src/postRepository/observers/getPosts/enums.ts +11 -0
  36. package/src/postRepository/observers/getPosts.ts +6 -197
  37. package/src/postRepository/utils/payload.ts +17 -0
@@ -0,0 +1,5 @@
1
+ export declare const getPost: {
2
+ (postId: Amity.InternalPost['postId']): Promise<Amity.Cached<Amity.InternalPost>>;
3
+ locally(postId: Amity.InternalPost['postId']): Amity.Cached<Amity.InternalPost> | undefined;
4
+ };
5
+ //# sourceMappingURL=getPost.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"getPost.d.ts","sourceRoot":"","sources":["../../../src/postRepository/internalApi/getPost.ts"],"names":[],"mappings":"AASA,eAAO,MAAM,OAAO;aACV,MAAM,YAAY,CAAC,QAAQ,CAAC,GACnC,QAAQ,MAAM,MAAM,CAAC,MAAM,YAAY,CAAC,CAAC;oBAsClC,MAAM,YAAY,CAAC,QAAQ,CAAC,GACnC,MAAM,MAAM,CAAC,MAAM,YAAY,CAAC,GAAG,SAAS;CAJ9C,CAAC"}
@@ -0,0 +1,13 @@
1
+ export * from './getPostByIds';
2
+ export * from './createPost';
3
+ export * from './updatePost';
4
+ export * from './editPost';
5
+ export * from './deletePost';
6
+ export * from './softDeletePost';
7
+ export * from './hardDeletePost';
8
+ export * from './approvePost';
9
+ export * from './declinePost';
10
+ export * from './flagPost';
11
+ export * from './unflagPost';
12
+ export * from './isPostFlaggedByMe';
13
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/postRepository/internalApi/index.ts"],"names":[],"mappings":"AAAA,cAAc,gBAAgB,CAAC;AAE/B,cAAc,cAAc,CAAC;AAC7B,cAAc,cAAc,CAAC;AAC7B,cAAc,YAAY,CAAC;AAE3B,cAAc,cAAc,CAAC;AAC7B,cAAc,kBAAkB,CAAC;AACjC,cAAc,kBAAkB,CAAC;AAEjC,cAAc,eAAe,CAAC;AAC9B,cAAc,eAAe,CAAC;AAE9B,cAAc,YAAY,CAAC;AAC3B,cAAc,cAAc,CAAC;AAC7B,cAAc,qBAAqB,CAAC"}
@@ -0,0 +1,14 @@
1
+ import { PostPaginationController } from './PostPaginationController';
2
+ import { LiveCollectionController } from '~/core/liveCollection/LiveCollectionController';
3
+ export declare class PostLiveCollectionController extends LiveCollectionController<'post', Amity.PostLiveCollection, Amity.Post, PostPaginationController> {
4
+ private queryStreamController;
5
+ private query;
6
+ constructor(query: Amity.PostLiveCollection, callback: Amity.LiveCollectionCallback<Amity.Post>);
7
+ protected setup(): void;
8
+ protected persistModel(queryPayload: Amity.PostPayload & Amity.Pagination): Promise<void>;
9
+ protected persistQueryStream({ response, direction, refresh, }: Amity.LiveCollectionPersistQueryStreamParams<'post'>): void;
10
+ startSubscription(): Amity.Unsubscriber[];
11
+ notifyChange({ origin, loading, error }: Amity.LiveCollectionNotifyParams): void;
12
+ applyFilter(data: Amity.InternalPost[]): Amity.InternalPost<any>[];
13
+ }
14
+ //# sourceMappingURL=PostLiveCollectionController.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PostLiveCollectionController.d.ts","sourceRoot":"","sources":["../../../../src/postRepository/observers/getPosts/PostLiveCollectionController.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,wBAAwB,EAAE,MAAM,4BAA4B,CAAC;AAEtE,OAAO,EAAE,wBAAwB,EAAE,MAAM,gDAAgD,CAAC;AA2B1F,qBAAa,4BAA6B,SAAQ,wBAAwB,CACxE,MAAM,EACN,KAAK,CAAC,kBAAkB,EACxB,KAAK,CAAC,IAAI,EACV,wBAAwB,CACzB;IACC,OAAO,CAAC,qBAAqB,CAA4B;IAEzD,OAAO,CAAC,KAAK,CAA2B;gBAE5B,KAAK,EAAE,KAAK,CAAC,kBAAkB,EAAE,QAAQ,EAAE,KAAK,CAAC,sBAAsB,CAAC,KAAK,CAAC,IAAI,CAAC;IAmB/F,SAAS,CAAC,KAAK;cAUC,YAAY,CAAC,YAAY,EAAE,KAAK,CAAC,WAAW,GAAG,KAAK,CAAC,UAAU;IAI/E,SAAS,CAAC,kBAAkB,CAAC,EAC3B,QAAQ,EACR,SAAS,EACT,OAAO,GACR,EAAE,KAAK,CAAC,sCAAsC,CAAC,MAAM,CAAC;IAIvD,iBAAiB;IAsDjB,YAAY,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE,KAAK,CAAC,0BAA0B;IAsBzE,WAAW,CAAC,IAAI,EAAE,KAAK,CAAC,YAAY,EAAE;CA+BvC"}
@@ -0,0 +1,5 @@
1
+ import { PaginationController } from '~/core/liveCollection/PaginationController';
2
+ export declare class PostPaginationController extends PaginationController<'post', Amity.PostLiveCollection> {
3
+ getRequest(queryParams: Amity.PostLiveCollection, token: string | undefined): Promise<Amity.PostPayload<any> & Amity.Pagination>;
4
+ }
5
+ //# sourceMappingURL=PostPaginationController.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PostPaginationController.d.ts","sourceRoot":"","sources":["../../../../src/postRepository/observers/getPosts/PostPaginationController.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,4CAA4C,CAAC;AAIlF,qBAAa,wBAAyB,SAAQ,oBAAoB,CAChE,MAAM,EACN,KAAK,CAAC,kBAAkB,CACzB;IACO,UAAU,CAAC,WAAW,EAAE,KAAK,CAAC,kBAAkB,EAAE,KAAK,EAAE,MAAM,GAAG,SAAS;CAoClF"}
@@ -0,0 +1,15 @@
1
+ import { QueryStreamController } from '~/core/liveCollection/QueryStreamController';
2
+ import { EnumPostActions } from './enums';
3
+ export declare class PostQueryStreamController extends QueryStreamController<Amity.PostPayload, Amity.PostLiveCollection> {
4
+ private notifyChange;
5
+ private preparePayload;
6
+ constructor(query: Amity.PostLiveCollection, cacheKey: string[], notifyChange: (params: Amity.LiveCollectionNotifyParams) => void, preparePayload: (response: Amity.PostPayload) => Amity.ProcessedPostPayload);
7
+ saveToMainDB(response: Amity.PostPayload): Promise<void>;
8
+ appendToQueryStream(response: Amity.PostPayload & Partial<Amity.Pagination>, direction: Amity.LiveCollectionPageDirection, refresh?: boolean): void;
9
+ reactor(action: EnumPostActions): (post: Amity.InternalPost) => void;
10
+ subscribeRTE(createSubscriber: {
11
+ fn: (reactor: (post: Amity.InternalPost) => void) => Amity.Unsubscriber;
12
+ action: EnumPostActions;
13
+ }[]): Amity.Unsubscriber[];
14
+ }
15
+ //# sourceMappingURL=PostQueryStreamController.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PostQueryStreamController.d.ts","sourceRoot":"","sources":["../../../../src/postRepository/observers/getPosts/PostQueryStreamController.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,qBAAqB,EAAE,MAAM,6CAA6C,CAAC;AAKpF,OAAO,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAE1C,qBAAa,yBAA0B,SAAQ,qBAAqB,CAClE,KAAK,CAAC,WAAW,EACjB,KAAK,CAAC,kBAAkB,CACzB;IACC,OAAO,CAAC,YAAY,CAAqD;IAEzE,OAAO,CAAC,cAAc,CAA8D;gBAGlF,KAAK,EAAE,KAAK,CAAC,kBAAkB,EAC/B,QAAQ,EAAE,MAAM,EAAE,EAClB,YAAY,EAAE,CAAC,MAAM,EAAE,KAAK,CAAC,0BAA0B,KAAK,IAAI,EAChE,cAAc,EAAE,CAAC,QAAQ,EAAE,KAAK,CAAC,WAAW,KAAK,KAAK,CAAC,oBAAoB;IAOvE,YAAY,CAAC,QAAQ,EAAE,KAAK,CAAC,WAAW;IAW9C,mBAAmB,CACjB,QAAQ,EAAE,KAAK,CAAC,WAAW,GAAG,OAAO,CAAC,KAAK,CAAC,UAAU,CAAC,EACvD,SAAS,EAAE,KAAK,CAAC,2BAA2B,EAC5C,OAAO,UAAQ;IAkBjB,OAAO,CAAC,MAAM,EAAE,eAAe,UACf,MAAM,YAAY;IAkClC,YAAY,CACV,gBAAgB,EAAE;QAChB,EAAE,EAAE,CAAC,OAAO,EAAE,CAAC,IAAI,EAAE,KAAK,CAAC,YAAY,KAAK,IAAI,KAAK,KAAK,CAAC,YAAY,CAAC;QACxE,MAAM,EAAE,eAAe,CAAC;KACzB,EAAE;CAIN"}
@@ -0,0 +1,12 @@
1
+ export declare enum EnumPostActions {
2
+ OnPostCreated = "onPostCreated",
3
+ OnPostUpdated = "onPostUpdated",
4
+ OnPostDeleted = "onPostDeleted",
5
+ OnPostFlagged = "onPostFlagged",
6
+ OnPostUnflagged = "onPostUnflagged",
7
+ OnPostReactionAdded = "onPostReactionAdded",
8
+ OnPostReactionRemoved = "onPostReactionRemoved",
9
+ OnPostApproved = "onPostApproved",
10
+ OnPostDeclined = "onPostDeclined"
11
+ }
12
+ //# sourceMappingURL=enums.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"enums.d.ts","sourceRoot":"","sources":["../../../../src/postRepository/observers/getPosts/enums.ts"],"names":[],"mappings":"AAAA,oBAAY,eAAe;IACzB,aAAa,kBAAkB;IAC/B,aAAa,kBAAkB;IAC/B,aAAa,kBAAkB;IAC/B,aAAa,kBAAkB;IAC/B,eAAe,oBAAoB;IACnC,mBAAmB,wBAAwB;IAC3C,qBAAqB,0BAA0B;IAC/C,cAAc,mBAAmB;IACjC,cAAc,mBAAmB;CAClC"}
@@ -1 +1 @@
1
- {"version":3,"file":"getPosts.d.ts","sourceRoot":"","sources":["../../../src/postRepository/observers/getPosts.ts"],"names":[],"mappings":"AA2CA;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,eAAO,MAAM,QAAQ,WACX,MAAM,kBAAkB,YACtB,MAAM,sBAAsB,CAAC,MAAM,IAAI,CAAC,WACzC,MAAM,oBAAoB,KAClC,MAAM,YAkLR,CAAC"}
1
+ {"version":3,"file":"getPosts.d.ts","sourceRoot":"","sources":["../../../src/postRepository/observers/getPosts.ts"],"names":[],"mappings":"AASA;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,eAAO,MAAM,QAAQ,WACX,MAAM,kBAAkB,YACtB,MAAM,sBAAsB,CAAC,MAAM,IAAI,CAAC,WACzC,MAAM,oBAAoB,KAClC,MAAM,YAqBR,CAAC"}
@@ -0,0 +1,2 @@
1
+ export declare const preparePostPayload: (postPayload: Amity.PostPayload) => Amity.ProcessedPostPayload;
2
+ //# sourceMappingURL=payload.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"payload.d.ts","sourceRoot":"","sources":["../../../src/postRepository/utils/payload.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,kBAAkB,gBAAiB,MAAM,WAAW,KAAG,MAAM,oBAczE,CAAC"}
@@ -29,21 +29,21 @@ export declare const emptyPostPayload: {
29
29
  };
30
30
  export declare const postQueryResponse: {
31
31
  data: Omit<Amity.PostPayload<any>, "communityUsers" | "communities" | "posts"> & {
32
- posts: Amity.Post<any>[];
32
+ posts: Amity.InternalPost<any>[];
33
33
  communities: Amity.Community[];
34
34
  communityUsers: Amity.Membership<"community">[];
35
35
  } & Amity.Pagination;
36
36
  };
37
37
  export declare const postQueryResponse2: {
38
38
  data: Omit<Amity.PostPayload<any>, "communityUsers" | "communities" | "posts"> & {
39
- posts: Amity.Post<any>[];
39
+ posts: Amity.InternalPost<any>[];
40
40
  communities: Amity.Community[];
41
41
  communityUsers: Amity.Membership<"community">[];
42
42
  } & Amity.Pagination;
43
43
  };
44
44
  export declare const postQueryResponsePage2: {
45
45
  data: Omit<Amity.PostPayload<any>, "communityUsers" | "communities" | "posts"> & {
46
- posts: Amity.Post<any>[];
46
+ posts: Amity.InternalPost<any>[];
47
47
  communities: Amity.Community[];
48
48
  communityUsers: Amity.Membership<"community">[];
49
49
  } & Amity.Pagination;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@amityco/ts-sdk-react-native",
3
- "version": "6.28.2-fbfd068.0",
3
+ "version": "6.28.3-54dff84.0",
4
4
  "license": "CC-BY-ND-4.0",
5
5
  "author": "amity.co <developers@amity.co> (https://amity.co)",
6
6
  "description": "Amity Social Cloud Typescript SDK",
@@ -348,7 +348,7 @@ declare global {
348
348
  * - communityUsers: `Amity.RawMembership` -> `Amity.Membership` (Add user getter prop)
349
349
  */
350
350
  type ProcessedPostPayload = Omit<PostPayload, 'communities' | 'communityUsers' | 'posts'> & {
351
- posts: Amity.Post[];
351
+ posts: Amity.InternalPost[];
352
352
  communities: Amity.Community[];
353
353
  communityUsers: Amity.Membership<'community'>[];
354
354
  };
@@ -28,7 +28,7 @@ import { CommentLiveCollectionController } from './getComments/CommentLiveCollec
28
28
  */
29
29
  export const getComments = (
30
30
  params: Amity.CommentLiveCollection,
31
- callback: Amity.LiveCollectionCallback<Amity.InternalComment>,
31
+ callback: Amity.LiveCollectionCallback<Amity.Comment>,
32
32
  config?: Amity.LiveCollectionConfig,
33
33
  ): Amity.Unsubscriber => {
34
34
  const { log, cache } = getActiveClient();
@@ -30,9 +30,13 @@ const convertCommunityUsersToUniqueObject = (
30
30
  return result;
31
31
  };
32
32
 
33
- export const prepareCommunityPayload = (
34
- rawPayload: Amity.CommunityPayload,
35
- ): Amity.ProcessedCommunityPayload => {
33
+ export const convertCommunityPayload = (rawPayload: {
34
+ communities: Amity.RawCommunity[];
35
+ communityUsers: Amity.RawMembership<'community'>[];
36
+ }): {
37
+ communities: Amity.Community[];
38
+ communityUsers: Amity.Membership<'community'>[];
39
+ } => {
36
40
  // Unpack community payload by mapping payload field to postSetting value.
37
41
  const communities = rawPayload.communities.map<Amity.Community>(
38
42
  ({ needApprovalOnPostCreation, onlyAdminCanPost, ...restCommunityPayload }) => ({
@@ -72,6 +76,18 @@ export const prepareCommunityPayload = (
72
76
  };
73
77
  };
74
78
 
79
+ export const prepareCommunityPayload = (
80
+ rawPayload: Amity.CommunityPayload,
81
+ ): Amity.ProcessedCommunityPayload => {
82
+ const { communities, communityUsers } = convertCommunityPayload(rawPayload);
83
+
84
+ return {
85
+ ...rawPayload,
86
+ communities,
87
+ communityUsers,
88
+ };
89
+ };
90
+
75
91
  export const prepareCommunityRequest = <
76
92
  T extends {
77
93
  postSetting?: Amity.Community['postSetting'];
@@ -0,0 +1,65 @@
1
+ import { getActiveClient } from '~/client/api';
2
+
3
+ import { pullFromCache } from '~/cache/api';
4
+ import { ingestInCache } from '~/cache/api/ingestInCache';
5
+ import { isInTombstone } from '~/cache/api/isInTombstone';
6
+ import { checkIfShouldGoesToTombstone } from '~/cache/utils';
7
+ import { pushToTombstone } from '~/cache/api/pushToTombstone';
8
+ import { prepareMembershipPayload } from '~/group/utils';
9
+
10
+ export const getPost = async (
11
+ postId: Amity.InternalPost['postId'],
12
+ ): Promise<Amity.Cached<Amity.InternalPost>> => {
13
+ const client = getActiveClient();
14
+ client.log('post/getPost', postId);
15
+
16
+ isInTombstone('post', postId);
17
+
18
+ let payload: Amity.PostPayload;
19
+
20
+ try {
21
+ // API-FIX: endpoint should not be /list, parameters should be querystring.
22
+ const response = await client.http.get<Amity.PostPayload>(
23
+ `/api/v3/posts/${encodeURIComponent(postId)}`,
24
+ );
25
+ payload = response.data;
26
+ } catch (error) {
27
+ if (checkIfShouldGoesToTombstone((error as Amity.ErrorResponse)?.code)) {
28
+ pushToTombstone('post', postId);
29
+ }
30
+
31
+ throw error;
32
+ }
33
+
34
+ const data = prepareMembershipPayload(payload, 'communityUsers');
35
+
36
+ const cachedAt = client.cache && Date.now();
37
+ if (client.cache) ingestInCache(data, { cachedAt });
38
+
39
+ const { posts } = data;
40
+
41
+ const result = posts.find(post => post.postId === postId)!;
42
+
43
+ return {
44
+ data: result,
45
+ cachedAt,
46
+ };
47
+ };
48
+
49
+ getPost.locally = (
50
+ postId: Amity.InternalPost['postId'],
51
+ ): Amity.Cached<Amity.InternalPost> | undefined => {
52
+ const client = getActiveClient();
53
+ client.log('post/getPost.locally', postId);
54
+
55
+ if (!client.cache) return;
56
+
57
+ const cached = pullFromCache<Amity.InternalPost>(['post', 'get', postId]);
58
+
59
+ if (!cached) return;
60
+
61
+ return {
62
+ data: cached.data,
63
+ cachedAt: cached.cachedAt,
64
+ };
65
+ };
@@ -0,0 +1,16 @@
1
+ export * from './getPostByIds';
2
+
3
+ export * from './createPost';
4
+ export * from './updatePost';
5
+ export * from './editPost';
6
+
7
+ export * from './deletePost';
8
+ export * from './softDeletePost';
9
+ export * from './hardDeletePost';
10
+
11
+ export * from './approvePost';
12
+ export * from './declinePost';
13
+
14
+ export * from './flagPost';
15
+ export * from './unflagPost';
16
+ export * from './isPostFlaggedByMe';
@@ -0,0 +1,190 @@
1
+ import hash from 'object-hash';
2
+ import { pullFromCache, pushToCache } from '~/cache/api';
3
+ import { PostPaginationController } from './PostPaginationController';
4
+ import { PostQueryStreamController } from './PostQueryStreamController';
5
+ import { LiveCollectionController } from '~/core/liveCollection/LiveCollectionController';
6
+ import {
7
+ onPostCreated,
8
+ onPostUpdated,
9
+ onPostDeleted,
10
+ onPostFlagged,
11
+ onPostUnflagged,
12
+ onPostReactionAdded,
13
+ onPostReactionRemoved,
14
+ onPostApproved,
15
+ onPostDeclined,
16
+ } from '~/postRepository/events';
17
+ import {
18
+ filterByFeedType,
19
+ filterByPostDataTypes,
20
+ filterByPropEquality,
21
+ sortByFirstCreated,
22
+ sortByLastCreated,
23
+ } from '~/core/query';
24
+ import { isNonNullable } from '~/utils';
25
+ import { EnumPostActions } from './enums';
26
+ import { LinkedObject } from '~/utils/linkedObject';
27
+ import { preparePostPayload } from '~/postRepository/utils/payload';
28
+ import { convertEventPayload } from '~/utils/event';
29
+ import { onCommentCreated, onCommentDeleted } from '~/commentRepository';
30
+ import { getPost } from '~/postRepository/internalApi/getPost';
31
+
32
+ export class PostLiveCollectionController extends LiveCollectionController<
33
+ 'post',
34
+ Amity.PostLiveCollection,
35
+ Amity.Post,
36
+ PostPaginationController
37
+ > {
38
+ private queryStreamController: PostQueryStreamController;
39
+
40
+ private query: Amity.PostLiveCollection;
41
+
42
+ constructor(query: Amity.PostLiveCollection, callback: Amity.LiveCollectionCallback<Amity.Post>) {
43
+ const queryStreamId = hash(query);
44
+ const cacheKey = ['posts', 'collection', queryStreamId];
45
+ const paginationController = new PostPaginationController(query);
46
+
47
+ super(paginationController, queryStreamId, cacheKey, callback);
48
+
49
+ this.query = query;
50
+ this.queryStreamController = new PostQueryStreamController(
51
+ this.query,
52
+ this.cacheKey,
53
+ this.notifyChange.bind(this),
54
+ preparePostPayload,
55
+ );
56
+
57
+ this.callback = callback.bind(this);
58
+ this.loadPage({ initial: true });
59
+ }
60
+
61
+ protected setup() {
62
+ const collection = pullFromCache<Amity.PostLiveCollectionCache>(this.cacheKey)?.data;
63
+ if (!collection) {
64
+ pushToCache(this.cacheKey, {
65
+ data: [],
66
+ params: {},
67
+ });
68
+ }
69
+ }
70
+
71
+ protected async persistModel(queryPayload: Amity.PostPayload & Amity.Pagination) {
72
+ await this.queryStreamController.saveToMainDB(queryPayload);
73
+ }
74
+
75
+ protected persistQueryStream({
76
+ response,
77
+ direction,
78
+ refresh,
79
+ }: Amity.LiveCollectionPersistQueryStreamParams<'post'>) {
80
+ this.queryStreamController.appendToQueryStream(response, direction, refresh);
81
+ }
82
+
83
+ startSubscription() {
84
+ return this.queryStreamController.subscribeRTE([
85
+ { fn: onPostCreated, action: EnumPostActions.OnPostCreated },
86
+ { fn: onPostUpdated, action: EnumPostActions.OnPostUpdated },
87
+ { fn: onPostDeleted, action: EnumPostActions.OnPostDeleted },
88
+ { fn: onPostFlagged, action: EnumPostActions.OnPostFlagged },
89
+ { fn: onPostUnflagged, action: EnumPostActions.OnPostUnflagged },
90
+ { fn: onPostApproved, action: EnumPostActions.OnPostApproved },
91
+ { fn: onPostDeclined, action: EnumPostActions.OnPostDeclined },
92
+ { fn: onPostReactionAdded, action: EnumPostActions.OnPostReactionAdded },
93
+ { fn: onPostReactionRemoved, action: EnumPostActions.OnPostReactionRemoved },
94
+ {
95
+ fn: convertEventPayload(
96
+ (callback: Amity.Listener<Amity.InternalComment>) => {
97
+ return onCommentCreated(async (comment: Amity.InternalComment) => {
98
+ const currentCollection = pullFromCache<Amity.PostLiveCollectionCache>(
99
+ this.cacheKey,
100
+ )?.data;
101
+
102
+ if (!currentCollection || currentCollection.data.includes(comment.referenceId))
103
+ return;
104
+
105
+ await getPost(comment.referenceId);
106
+ callback(comment);
107
+ });
108
+ },
109
+ 'referenceId',
110
+ 'post',
111
+ ),
112
+ action: EnumPostActions.OnPostUpdated,
113
+ },
114
+ {
115
+ fn: convertEventPayload(
116
+ (callback: Amity.Listener<Amity.InternalComment>) => {
117
+ return onCommentDeleted(async (comment: Amity.InternalComment) => {
118
+ const currentCollection = pullFromCache<Amity.PostLiveCollectionCache>(
119
+ this.cacheKey,
120
+ )?.data;
121
+
122
+ if (!currentCollection || currentCollection.data.includes(comment.referenceId))
123
+ return;
124
+
125
+ await getPost(comment.referenceId);
126
+ callback(comment);
127
+ });
128
+ },
129
+ 'referenceId',
130
+ 'post',
131
+ ),
132
+ action: EnumPostActions.OnPostUpdated,
133
+ },
134
+ ]);
135
+ }
136
+
137
+ notifyChange({ origin, loading, error }: Amity.LiveCollectionNotifyParams) {
138
+ const collection = pullFromCache<Amity.PostLiveCollectionCache>(this.cacheKey)?.data;
139
+ if (!collection) return;
140
+
141
+ const data = this.applyFilter(
142
+ collection.data
143
+ .map(id => pullFromCache<Amity.InternalPost>(['post', 'get', id])!)
144
+ .filter(isNonNullable)
145
+ .map(({ data }) => data) ?? [],
146
+ ).map(LinkedObject.post);
147
+
148
+ if (!this.shouldNotify(data) && origin === 'event') return;
149
+
150
+ this.callback({
151
+ onNextPage: () => this.loadPage({ direction: Amity.LiveCollectionPageDirection.NEXT }),
152
+ data,
153
+ hasNextPage: !!this.paginationController.getNextToken(),
154
+ loading,
155
+ error,
156
+ });
157
+ }
158
+
159
+ applyFilter(data: Amity.InternalPost[]) {
160
+ let posts = data;
161
+
162
+ if (!this.query.includeDeleted) {
163
+ posts = filterByPropEquality(posts, 'isDeleted', false);
164
+ }
165
+
166
+ if (this.query.tags) {
167
+ posts = posts.filter(p => p.tags?.some(t => this.query.tags?.includes(t)));
168
+ }
169
+
170
+ if (this.query.targetType === 'community' && this.query.feedType) {
171
+ posts = filterByFeedType(posts, this.query.feedType);
172
+ }
173
+
174
+ if (this.query.dataTypes?.length) {
175
+ posts = filterByPostDataTypes(posts, this.query.dataTypes);
176
+ }
177
+
178
+ switch (this.query.sortBy) {
179
+ case 'firstCreated':
180
+ posts = posts.sort(sortByFirstCreated);
181
+ break;
182
+ case 'lastCreated':
183
+ default:
184
+ posts = posts.sort(sortByLastCreated);
185
+ break;
186
+ }
187
+
188
+ return posts;
189
+ }
190
+ }
@@ -0,0 +1,45 @@
1
+ import { PaginationController } from '~/core/liveCollection/PaginationController';
2
+ import { COLLECTION_DEFAULT_PAGINATION_LIMIT } from '~/utils/constants';
3
+ import { inferIsDeleted } from '~/utils/inferIsDeleted';
4
+
5
+ export class PostPaginationController extends PaginationController<
6
+ 'post',
7
+ Amity.PostLiveCollection
8
+ > {
9
+ async getRequest(queryParams: Amity.PostLiveCollection, token: string | undefined) {
10
+ const {
11
+ limit = COLLECTION_DEFAULT_PAGINATION_LIMIT,
12
+ includeDeleted,
13
+ matchingOnlyParentPost,
14
+ ...params
15
+ } = queryParams;
16
+
17
+ const { dataTypes } = params;
18
+
19
+ const baseOptions = {
20
+ type: params.sortBy || queryParams.limit ? 'pagination' : undefined,
21
+ };
22
+
23
+ const options = token ? { ...baseOptions, token } : { ...baseOptions, limit };
24
+
25
+ const { data: queryResponse } = await this.http.get<Amity.PostPayload & Amity.Pagination>(
26
+ `/api/v4/posts`,
27
+ {
28
+ params: {
29
+ ...params,
30
+ isDeleted: inferIsDeleted(includeDeleted),
31
+ /*
32
+ * when creating post like image, file, video BE will create 2 posts
33
+ * 1. parent post to store text with dataType=text
34
+ * 2. child post to store dataTypes post data
35
+ *
36
+ * By default, BE queries only parent post
37
+ */
38
+ matchingOnlyParentPost: matchingOnlyParentPost ?? !dataTypes?.length,
39
+ options,
40
+ },
41
+ },
42
+ );
43
+ return queryResponse;
44
+ }
45
+ }
@@ -0,0 +1,102 @@
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 { EnumPostActions } from './enums';
7
+
8
+ export class PostQueryStreamController extends QueryStreamController<
9
+ Amity.PostPayload,
10
+ Amity.PostLiveCollection
11
+ > {
12
+ private notifyChange: (params: Amity.LiveCollectionNotifyParams) => void;
13
+
14
+ private preparePayload: (response: Amity.PostPayload) => Amity.ProcessedPostPayload;
15
+
16
+ constructor(
17
+ query: Amity.PostLiveCollection,
18
+ cacheKey: string[],
19
+ notifyChange: (params: Amity.LiveCollectionNotifyParams) => void,
20
+ preparePayload: (response: Amity.PostPayload) => Amity.ProcessedPostPayload,
21
+ ) {
22
+ super(query, cacheKey);
23
+ this.notifyChange = notifyChange;
24
+ this.preparePayload = preparePayload;
25
+ }
26
+
27
+ async saveToMainDB(response: Amity.PostPayload) {
28
+ const processedPayload = await this.preparePayload(response);
29
+
30
+ const client = getActiveClient();
31
+ const cachedAt = client.cache && Date.now();
32
+
33
+ if (client.cache) {
34
+ ingestInCache(processedPayload, { cachedAt });
35
+ }
36
+ }
37
+
38
+ appendToQueryStream(
39
+ response: Amity.PostPayload & Partial<Amity.Pagination>,
40
+ direction: Amity.LiveCollectionPageDirection,
41
+ refresh = false,
42
+ ) {
43
+ if (refresh) {
44
+ pushToCache(this.cacheKey, {
45
+ data: response.posts.map(getResolver('post')),
46
+ });
47
+ } else {
48
+ const collection = pullFromCache<Amity.CommunityLiveCollectionCache>(this.cacheKey)?.data;
49
+
50
+ const posts = collection?.data ?? [];
51
+
52
+ pushToCache(this.cacheKey, {
53
+ ...collection,
54
+ data: [...new Set([...posts, ...response.posts.map(getResolver('post'))])],
55
+ });
56
+ }
57
+ }
58
+
59
+ reactor(action: EnumPostActions) {
60
+ return (post: Amity.InternalPost) => {
61
+ const collection = pullFromCache<Amity.PostLiveCollectionCache>(this.cacheKey)?.data;
62
+
63
+ if (!collection) return;
64
+
65
+ if (post.parentPostId && post.isDeleted) {
66
+ const parentPost = pullFromCache<Amity.InternalPost>([
67
+ 'post',
68
+ 'get',
69
+ post.parentPostId,
70
+ ])?.data;
71
+
72
+ if (!parentPost || parentPost?.targetId !== this.query.targetId) return;
73
+
74
+ parentPost.children = parentPost.children.filter(childId => childId !== post.postId);
75
+ pushToCache(['post', 'get', parentPost.postId], parentPost);
76
+ } else {
77
+ if (this.query.targetId !== post.targetId) return;
78
+ if (this.query.targetType !== post.targetType) return;
79
+ }
80
+
81
+ if (action === EnumPostActions.OnPostDeclined) {
82
+ collection.data = collection.data.filter(postId => postId !== post.postId);
83
+ }
84
+
85
+ if (action === EnumPostActions.OnPostCreated || action === EnumPostActions.OnPostApproved) {
86
+ collection.data = [...new Set([post.postId, ...collection.data])];
87
+ }
88
+
89
+ pushToCache(this.cacheKey, collection);
90
+ this.notifyChange({ origin: Amity.LiveDataOrigin.EVENT, loading: false });
91
+ };
92
+ }
93
+
94
+ subscribeRTE(
95
+ createSubscriber: {
96
+ fn: (reactor: (post: Amity.InternalPost) => void) => Amity.Unsubscriber;
97
+ action: EnumPostActions;
98
+ }[],
99
+ ) {
100
+ return createSubscriber.map(subscriber => subscriber.fn(this.reactor(subscriber.action)));
101
+ }
102
+ }
@@ -0,0 +1,11 @@
1
+ export enum EnumPostActions {
2
+ OnPostCreated = 'onPostCreated',
3
+ OnPostUpdated = 'onPostUpdated',
4
+ OnPostDeleted = 'onPostDeleted',
5
+ OnPostFlagged = 'onPostFlagged',
6
+ OnPostUnflagged = 'onPostUnflagged',
7
+ OnPostReactionAdded = 'onPostReactionAdded',
8
+ OnPostReactionRemoved = 'onPostReactionRemoved',
9
+ OnPostApproved = 'onPostApproved',
10
+ OnPostDeclined = 'onPostDeclined',
11
+ }