@amityco/ts-sdk-react-native 6.32.7-289cad7.0 → 6.32.7-686c44c.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 (96) hide show
  1. package/dist/@types/core/events.d.ts +16 -2
  2. package/dist/@types/core/events.d.ts.map +1 -1
  3. package/dist/@types/core/payload.d.ts +3 -0
  4. package/dist/@types/core/payload.d.ts.map +1 -1
  5. package/dist/@types/domains/message.d.ts +1 -0
  6. package/dist/@types/domains/message.d.ts.map +1 -1
  7. package/dist/@types/domains/pinnedPost.d.ts +1 -0
  8. package/dist/@types/domains/pinnedPost.d.ts.map +1 -1
  9. package/dist/@types/domains/reaction.d.ts +8 -2
  10. package/dist/@types/domains/reaction.d.ts.map +1 -1
  11. package/dist/@types/domains/user.d.ts +4 -0
  12. package/dist/@types/domains/user.d.ts.map +1 -1
  13. package/dist/communityRepository/communityMembership/events/utils.d.ts.map +1 -1
  14. package/dist/communityRepository/utils/communityWithMembership.d.ts.map +1 -1
  15. package/dist/feedRepository/api/queryGlobalFeed.d.ts.map +1 -1
  16. package/dist/index.cjs.js +919 -570
  17. package/dist/index.esm.js +919 -570
  18. package/dist/index.umd.js +3 -3
  19. package/dist/postRepository/observers/getGlobalPinnedPosts/GlobalPinnedPostLiveCollectionController.d.ts +13 -0
  20. package/dist/postRepository/observers/getGlobalPinnedPosts/GlobalPinnedPostLiveCollectionController.d.ts.map +1 -0
  21. package/dist/postRepository/observers/getGlobalPinnedPosts/GlobalPinnedPostPaginationController.d.ts +13 -0
  22. package/dist/postRepository/observers/getGlobalPinnedPosts/GlobalPinnedPostPaginationController.d.ts.map +1 -0
  23. package/dist/postRepository/observers/getGlobalPinnedPosts/GlobalPinnedPostQueryStreamController.d.ts +15 -0
  24. package/dist/postRepository/observers/getGlobalPinnedPosts/GlobalPinnedPostQueryStreamController.d.ts.map +1 -0
  25. package/dist/postRepository/observers/getGlobalPinnedPosts.d.ts +10 -0
  26. package/dist/postRepository/observers/getGlobalPinnedPosts.d.ts.map +1 -0
  27. package/dist/postRepository/observers/index.d.ts +1 -0
  28. package/dist/postRepository/observers/index.d.ts.map +1 -1
  29. package/dist/reactionRepository/api/addReaction.d.ts.map +1 -1
  30. package/dist/reactionRepository/api/removeReaction.d.ts.map +1 -1
  31. package/dist/reactionRepository/events/onReactorAddedLocal.d.ts +19 -0
  32. package/dist/reactionRepository/events/onReactorAddedLocal.d.ts.map +1 -0
  33. package/dist/reactionRepository/events/onReactorRemovedLocal.d.ts +19 -0
  34. package/dist/reactionRepository/events/onReactorRemovedLocal.d.ts.map +1 -0
  35. package/dist/reactionRepository/observers/getReactions/ReactionLiveCollectionController.d.ts +13 -0
  36. package/dist/reactionRepository/observers/getReactions/ReactionLiveCollectionController.d.ts.map +1 -0
  37. package/dist/reactionRepository/observers/getReactions/ReactionPaginationController.d.ts +5 -0
  38. package/dist/reactionRepository/observers/getReactions/ReactionPaginationController.d.ts.map +1 -0
  39. package/dist/reactionRepository/observers/getReactions/ReactionQueryStreamController.d.ts +14 -0
  40. package/dist/reactionRepository/observers/getReactions/ReactionQueryStreamController.d.ts.map +1 -0
  41. package/dist/reactionRepository/observers/{getReactions.d.ts → getReactions/getReactions.d.ts} +1 -1
  42. package/dist/reactionRepository/observers/getReactions/getReactions.d.ts.map +1 -0
  43. package/dist/reactionRepository/observers/getReactions/index.d.ts +2 -0
  44. package/dist/reactionRepository/observers/getReactions/index.d.ts.map +1 -0
  45. package/dist/reactionRepository/observers/index.d.ts +1 -1
  46. package/dist/reactionRepository/observers/index.d.ts.map +1 -1
  47. package/dist/storyRepository/observers/getGlobalStoryTargets/GlobalStoryLiveCollectionController.d.ts.map +1 -1
  48. package/dist/storyRepository/observers/getGlobalStoryTargets/GlobalStoryQueryStreamController.d.ts +1 -1
  49. package/dist/storyRepository/observers/getGlobalStoryTargets/GlobalStoryQueryStreamController.d.ts.map +1 -1
  50. package/dist/userRepository/constants/index.d.ts +5 -0
  51. package/dist/userRepository/constants/index.d.ts.map +1 -0
  52. package/dist/userRepository/index.d.ts +1 -0
  53. package/dist/userRepository/index.d.ts.map +1 -1
  54. package/dist/userRepository/observers/getBlockedUsers/BlockedUserLiveCollectionController.d.ts.map +1 -1
  55. package/dist/userRepository/observers/getBlockedUsers/BlockedUserQueryStreamController.d.ts +3 -2
  56. package/dist/userRepository/observers/getBlockedUsers/BlockedUserQueryStreamController.d.ts.map +1 -1
  57. package/dist/utils/linkedObject/messageLinkedObject.d.ts.map +1 -1
  58. package/package.json +1 -1
  59. package/src/@types/core/events.ts +18 -6
  60. package/src/@types/core/payload.ts +4 -0
  61. package/src/@types/domains/message.ts +1 -0
  62. package/src/@types/domains/pin.ts +1 -1
  63. package/src/@types/domains/pinnedPost.ts +2 -0
  64. package/src/@types/domains/reaction.ts +9 -3
  65. package/src/@types/domains/user.ts +6 -0
  66. package/src/communityRepository/communityMembership/events/utils.ts +4 -2
  67. package/src/communityRepository/utils/communityWithMembership.ts +15 -8
  68. package/src/feedRepository/api/queryGlobalFeed.ts +4 -1
  69. package/src/postRepository/observers/getGlobalPinnedPosts/GlobalPinnedPostLiveCollectionController.ts +96 -0
  70. package/src/postRepository/observers/getGlobalPinnedPosts/GlobalPinnedPostPaginationController.ts +19 -0
  71. package/src/postRepository/observers/getGlobalPinnedPosts/GlobalPinnedPostQueryStreamController.ts +88 -0
  72. package/src/postRepository/observers/getGlobalPinnedPosts.ts +42 -0
  73. package/src/postRepository/observers/index.ts +1 -0
  74. package/src/reactionRepository/api/addReaction.ts +23 -1
  75. package/src/reactionRepository/api/removeReaction.ts +25 -2
  76. package/src/reactionRepository/events/onReactorAddedLocal.ts +95 -0
  77. package/src/reactionRepository/events/onReactorRemovedLocal.ts +94 -0
  78. package/src/reactionRepository/observers/getReactions/ReactionLiveCollectionController.ts +111 -0
  79. package/src/reactionRepository/observers/getReactions/ReactionPaginationController.ts +30 -0
  80. package/src/reactionRepository/observers/getReactions/ReactionQueryStreamController.ts +92 -0
  81. package/src/reactionRepository/observers/getReactions/getReactions.ts +57 -0
  82. package/src/reactionRepository/observers/getReactions/index.ts +1 -0
  83. package/src/reactionRepository/observers/index.ts +1 -1
  84. package/src/storyRepository/events/onStoryReactionAdded.ts +3 -3
  85. package/src/storyRepository/events/onStoryReactionRemoved.ts +3 -3
  86. package/src/storyRepository/observers/getGlobalStoryTargets/GlobalStoryLiveCollectionController.ts +5 -0
  87. package/src/storyRepository/observers/getGlobalStoryTargets/GlobalStoryQueryStreamController.ts +5 -2
  88. package/src/userRepository/constants/index.ts +4 -0
  89. package/src/userRepository/index.ts +1 -0
  90. package/src/userRepository/observers/getBlockedUsers/BlockedUserLiveCollectionController.ts +12 -1
  91. package/src/userRepository/observers/getBlockedUsers/BlockedUserQueryStreamController.ts +13 -5
  92. package/src/userRepository/relationship/follow/observers/getFollowers/FollowerLiveCollectionController.ts +1 -1
  93. package/src/userRepository/relationship/follow/observers/getFollowings/FollowingLiveCollectionController.ts +1 -1
  94. package/src/utils/linkedObject/messageLinkedObject.ts +4 -0
  95. package/dist/reactionRepository/observers/getReactions.d.ts.map +0 -1
  96. package/src/reactionRepository/observers/getReactions.ts +0 -146
@@ -0,0 +1,96 @@
1
+ import hash from 'object-hash';
2
+ import { pullFromCache, pushToCache } from '~/cache/api';
3
+ import { GlobalPinnedPostPaginationController } from './GlobalPinnedPostPaginationController';
4
+ import { GlobalPinnedPostQueryStreamController } from './GlobalPinnedPostQueryStreamController';
5
+ import { LiveCollectionController } from '~/core/liveCollection/LiveCollectionController';
6
+ import { isNonNullable } from '~/utils';
7
+ import { LinkedObject } from '~/utils/linkedObject';
8
+ import { onPostDeleted } from '~/postRepository/events';
9
+ import { EnumPostActions } from '../enums';
10
+ import { onLocalPostDeleted } from '~/postRepository/events/onLocalPostDeleted';
11
+
12
+ export class GlobalPinnedPostLiveCollectionController extends LiveCollectionController<
13
+ 'pinnedPost',
14
+ Amity.GlobalPinnedPostLiveCollection,
15
+ Amity.PinnedPost,
16
+ GlobalPinnedPostPaginationController
17
+ > {
18
+ private queryStreamController: GlobalPinnedPostQueryStreamController;
19
+
20
+ private query: Amity.GlobalPinnedPostLiveCollection;
21
+
22
+ constructor(
23
+ query: Amity.GlobalPinnedPostLiveCollection,
24
+ callback: Amity.LiveCollectionCallback<Amity.PinnedPost>,
25
+ ) {
26
+ const queryStreamId = hash(query);
27
+ const cacheKey = ['pinnedPosts', 'collection', queryStreamId];
28
+ const paginationController = new GlobalPinnedPostPaginationController(query);
29
+
30
+ super(paginationController, queryStreamId, cacheKey, callback);
31
+
32
+ this.query = query;
33
+ this.queryStreamController = new GlobalPinnedPostQueryStreamController(
34
+ this.query,
35
+ this.cacheKey,
36
+ this.notifyChange.bind(this),
37
+ response => response,
38
+ );
39
+
40
+ this.callback = callback.bind(this);
41
+ this.loadPage({ initial: true });
42
+ }
43
+
44
+ protected setup() {
45
+ const collection = pullFromCache<Amity.PostLiveCollectionCache>(this.cacheKey)?.data;
46
+ if (!collection) {
47
+ pushToCache(this.cacheKey, {
48
+ data: [],
49
+ params: {},
50
+ });
51
+ }
52
+ }
53
+
54
+ protected async persistModel(queryPayload: Amity.PinnedPostPayload & Amity.Pagination) {
55
+ await this.queryStreamController.saveToMainDB(queryPayload);
56
+ }
57
+
58
+ protected persistQueryStream({
59
+ response,
60
+ direction,
61
+ refresh,
62
+ }: Amity.LiveCollectionPersistQueryStreamParams<'pinnedPost'>) {
63
+ this.queryStreamController.appendToQueryStream(response, direction, refresh);
64
+ }
65
+
66
+ // eslint-disable-next-line class-methods-use-this
67
+ startSubscription() {
68
+ return this.queryStreamController.subscribeRTE([
69
+ { fn: onLocalPostDeleted, action: EnumPostActions.OnPostDeleted },
70
+ {
71
+ fn: onPostDeleted,
72
+ action: EnumPostActions.OnPostDeleted,
73
+ },
74
+ ]);
75
+ }
76
+
77
+ notifyChange({ origin, loading, error }: Amity.LiveCollectionNotifyParams) {
78
+ const collection = pullFromCache<Amity.PinnedPostLiveCollectionCache>(this.cacheKey)?.data;
79
+ if (!collection) return;
80
+
81
+ const data = (
82
+ collection.data
83
+ .map(id => pullFromCache<Amity.InternalPin>(['pin', 'get', id])!)
84
+ .filter(isNonNullable)
85
+ .map(({ data }) => data) ?? []
86
+ ).map(LinkedObject.pinnedPost);
87
+
88
+ if (!this.shouldNotify(data) && origin === 'event') return;
89
+
90
+ this.callback({
91
+ data,
92
+ loading,
93
+ error,
94
+ });
95
+ }
96
+ }
@@ -0,0 +1,19 @@
1
+ import { PaginationController } from '~/core/liveCollection/PaginationController';
2
+ import { COLLECTION_DEFAULT_PAGINATION_LIMIT } from '~/utils/constants';
3
+
4
+ export class GlobalPinnedPostPaginationController extends PaginationController<
5
+ 'pinnedPost',
6
+ Amity.GlobalPinnedPostLiveCollection
7
+ > {
8
+ async getRequest(queryParams: Amity.GlobalPinnedPostLiveCollection, token: string | undefined) {
9
+ const { limit = COLLECTION_DEFAULT_PAGINATION_LIMIT, ...params } = queryParams;
10
+
11
+ const path = '/api/v1/pinned-posts/global';
12
+
13
+ const { data: queryResponse } = await this.http.get<Amity.PinnedPostPayload & Amity.Pagination>(
14
+ path,
15
+ );
16
+
17
+ return queryResponse;
18
+ }
19
+ }
@@ -0,0 +1,88 @@
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 GlobalPinnedPostQueryStreamController extends QueryStreamController<
9
+ Amity.PinnedPostPayload,
10
+ Amity.GlobalPinnedPostLiveCollection
11
+ > {
12
+ private notifyChange: (params: Amity.LiveCollectionNotifyParams) => void;
13
+
14
+ private preparePayload: (response: Amity.PinnedPostPayload) => Amity.ProcessedPostPayload;
15
+
16
+ constructor(
17
+ query: Amity.GlobalPinnedPostLiveCollection,
18
+ cacheKey: string[],
19
+ notifyChange: (params: Amity.LiveCollectionNotifyParams) => void,
20
+ preparePayload: (response: Amity.PinnedPostPayload) => Amity.ProcessedPostPayload,
21
+ ) {
22
+ super(query, cacheKey);
23
+ this.notifyChange = notifyChange;
24
+ this.preparePayload = preparePayload;
25
+ }
26
+
27
+ // eslint-disable-next-line class-methods-use-this
28
+ async saveToMainDB(response: Amity.PinnedPostPayload) {
29
+ const client = getActiveClient();
30
+ const cachedAt = client.cache && Date.now();
31
+
32
+ if (client.cache) {
33
+ ingestInCache(response, { cachedAt });
34
+ }
35
+ }
36
+
37
+ appendToQueryStream(
38
+ response: Amity.PinnedPostPayload & Partial<Amity.Pagination>,
39
+ direction: Amity.LiveCollectionPageDirection,
40
+ refresh = false,
41
+ ) {
42
+ if (refresh) {
43
+ pushToCache(this.cacheKey, {
44
+ data: response.pins.map(getResolver('pin')),
45
+ });
46
+ } else {
47
+ const collection = pullFromCache<Amity.PinnedPostLiveCollectionCache>(this.cacheKey)?.data;
48
+
49
+ const pinnedPosts = collection?.data ?? [];
50
+
51
+ pushToCache(this.cacheKey, {
52
+ ...collection,
53
+ data: [...new Set([...pinnedPosts, ...response.pins.map(getResolver('pin'))])],
54
+ });
55
+
56
+ this.notifyChange({
57
+ origin: Amity.LiveDataOrigin.SERVER,
58
+ loading: false,
59
+ });
60
+ }
61
+ }
62
+
63
+ reactor(action: EnumPostActions) {
64
+ return (post: Amity.InternalPost) => {
65
+ const collection = pullFromCache<Amity.PostLiveCollectionCache>(this.cacheKey)?.data;
66
+
67
+ if (!collection) return;
68
+
69
+ if (action === EnumPostActions.OnPostDeleted) {
70
+ collection.data = collection.data.filter(
71
+ referenceId => referenceId !== `global#${post.postId}`,
72
+ );
73
+ }
74
+
75
+ pushToCache(this.cacheKey, collection);
76
+ this.notifyChange({ origin: Amity.LiveDataOrigin.EVENT, loading: false });
77
+ };
78
+ }
79
+
80
+ subscribeRTE(
81
+ createSubscriber: {
82
+ fn: (reactor: (post: Amity.InternalPost) => void) => Amity.Unsubscriber;
83
+ action: EnumPostActions;
84
+ }[],
85
+ ) {
86
+ return createSubscriber.map(subscriber => subscriber.fn(this.reactor(subscriber.action)));
87
+ }
88
+ }
@@ -0,0 +1,42 @@
1
+ import { getActiveClient } from '~/client/api';
2
+ import { dropFromCache } from '~/cache/api';
3
+ import { ENABLE_CACHE_MESSAGE } from '~/utils/constants';
4
+ import { GlobalPinnedPostLiveCollectionController } from './getGlobalPinnedPosts/GlobalPinnedPostLiveCollectionController';
5
+
6
+ /**
7
+ * Get global pinned posts
8
+ *
9
+ * @returns the global pinned post(s)
10
+ *
11
+ * @category Pined Posts Live Collection
12
+ *
13
+ */
14
+ export const getGlobalPinnedPosts = (
15
+ params: Amity.LiveCollectionParams<Amity.GlobalPinnedPostLiveCollection>,
16
+ callback: Amity.LiveCollectionCallback<Amity.PinnedPost>,
17
+ config?: Amity.LiveCollectionConfig,
18
+ ) => {
19
+ const { log, cache } = getActiveClient();
20
+
21
+ // if (!cache) {
22
+ // console.log(ENABLE_CACHE_MESSAGE);
23
+ // }
24
+
25
+ const timestamp = Date.now();
26
+ log(`getGlobalPinnedPosts(tmpid: ${timestamp}) > listen`);
27
+
28
+ const globalPinnedPostLiveCollection = new GlobalPinnedPostLiveCollectionController(
29
+ params,
30
+ callback,
31
+ );
32
+ const disposers = globalPinnedPostLiveCollection.startSubscription();
33
+
34
+ const cacheKey = globalPinnedPostLiveCollection.getCacheKey();
35
+
36
+ disposers.push(() => dropFromCache(cacheKey));
37
+
38
+ return () => {
39
+ log(`getGlobalPinnedPosts(tmpid: ${timestamp}) > dispose`);
40
+ disposers.forEach(fn => fn());
41
+ };
42
+ };
@@ -3,4 +3,5 @@ export * from './observePost';
3
3
  export * from './getPost';
4
4
  export * from './getPosts';
5
5
  export * from './getPinnedPosts';
6
+ export * from './getGlobalPinnedPosts';
6
7
  export * from './semanticSearchPosts';
@@ -37,7 +37,7 @@ export const addReaction = async (
37
37
  reactionName,
38
38
  });
39
39
 
40
- await client.http.post<{ addedId: 'string' }>('/api/v2/reactions', {
40
+ const { data } = await client.http.post<{ addedId: 'string' }>('/api/v2/reactions', {
41
41
  referenceId,
42
42
  referenceType,
43
43
  reactionName,
@@ -66,6 +66,11 @@ export const addReaction = async (
66
66
  if (referenceType === 'comment') {
67
67
  fireEvent('local.comment.addReaction', {
68
68
  comment: updatedModel as Amity.InternalComment,
69
+ reactor: {
70
+ userId: client.userId!,
71
+ reactionName,
72
+ reactionId: data.addedId,
73
+ },
69
74
  });
70
75
 
71
76
  return true;
@@ -73,6 +78,23 @@ export const addReaction = async (
73
78
  if (referenceType === 'post') {
74
79
  fireEvent('local.post.addReaction', {
75
80
  post: updatedModel as Amity.InternalPost,
81
+ reactor: {
82
+ userId: client.userId!,
83
+ reactionName,
84
+ reactionId: data.addedId,
85
+ },
86
+ });
87
+
88
+ return true;
89
+ }
90
+ if (referenceType === 'story') {
91
+ fireEvent('local.story.reactionAdded', {
92
+ story: updatedModel as Amity.InternalStory,
93
+ reactor: {
94
+ userId: client.userId!,
95
+ reactionName,
96
+ reactionId: data.addedId,
97
+ },
76
98
  });
77
99
 
78
100
  return true;
@@ -38,7 +38,7 @@ export const removeReaction = async (
38
38
  reactionName,
39
39
  });
40
40
 
41
- await client.http.delete<{ removedId: string }>(`/api/v2/reactions`, {
41
+ const { data } = await client.http.delete<{ removedId: string }>(`/api/v2/reactions`, {
42
42
  data: {
43
43
  referenceId,
44
44
  referenceType,
@@ -69,6 +69,11 @@ export const removeReaction = async (
69
69
  if (referenceType === 'comment') {
70
70
  fireEvent('local.comment.removeReaction', {
71
71
  comment: updatedModel as Amity.InternalComment,
72
+ reactor: {
73
+ reactionId: data.removedId,
74
+ reactionName,
75
+ userId: client.userId!,
76
+ },
72
77
  });
73
78
 
74
79
  return true;
@@ -76,6 +81,24 @@ export const removeReaction = async (
76
81
  if (referenceType === 'post') {
77
82
  fireEvent('local.post.removeReaction', {
78
83
  post: updatedModel as Amity.InternalPost,
84
+ reactor: {
85
+ reactionId: data.removedId,
86
+ reactionName,
87
+ userId: client.userId!,
88
+ },
89
+ });
90
+
91
+ return true;
92
+ }
93
+
94
+ if (referenceType === 'story') {
95
+ fireEvent('local.story.reactionAdded', {
96
+ story: updatedModel as Amity.InternalStory,
97
+ reactor: {
98
+ userId: client.userId!,
99
+ reactionName,
100
+ reactionId: data.removedId,
101
+ },
79
102
  });
80
103
 
81
104
  return true;
@@ -139,5 +162,5 @@ removeReaction.optimistically = (
139
162
 
140
163
  dispatchReactable(referenceType, reaction);
141
164
 
142
- return !reaction?.myReactions?.includes(reactionName) ?? false;
165
+ return !reaction?.myReactions?.includes(reactionName);
143
166
  };
@@ -0,0 +1,95 @@
1
+ import { getActiveClient } from '~/client/api';
2
+ import { ingestInCache } from '~/cache/api/ingestInCache';
3
+ import { createEventSubscriber } from '~/core/events';
4
+ import { prepareMessagePayload } from '~/messageRepository/utils';
5
+
6
+ /**
7
+ * ```js
8
+ * import { onReactorAddedLocal } from '@amityco/ts-sdk'
9
+ * const dispose = onReactorAdded('post', postId, reactor => {
10
+ * // ...
11
+ * })
12
+ * ```
13
+ *
14
+ * Fired when an {@link Amity.InternalReactor} has been added
15
+ *
16
+ * @param {@link Amity.ReactableType} referenceType
17
+ * @param {string} referenceId
18
+ * @param callback The function to call when the event was fired
19
+ * @returns an {@link Amity.Unsubscriber} function to stop listening
20
+ *
21
+ * @category Events
22
+ * */
23
+ export const onReactorAddedLocal = (
24
+ referenceType: Amity.ReactableType,
25
+ referenceId: Amity.Reaction['referenceId'],
26
+ callback: Amity.Listener<Amity.InternalReactor>,
27
+ ): Amity.Unsubscriber => {
28
+ const client = getActiveClient();
29
+
30
+ const callbackWrapper = (
31
+ referenceType_: Amity.ReactableType,
32
+ referenceId_: Amity.Reaction['referenceId'],
33
+ reaction: Amity.InternalReactor,
34
+ ) => {
35
+ if (referenceType_ === referenceType && referenceId_ === referenceId) {
36
+ callback(reaction);
37
+ }
38
+ };
39
+
40
+ if (referenceType === 'message') {
41
+ const filter = async (rawPayload: Amity.MessagePayload) => {
42
+ const payload = await prepareMessagePayload(rawPayload);
43
+ if (!payload.reactions[0]) return;
44
+
45
+ ingestInCache(payload);
46
+ ingestInCache({ reactors: payload.reactions });
47
+
48
+ callbackWrapper('message', payload.messages[0].messageId, payload.reactions[0]);
49
+ };
50
+
51
+ return createEventSubscriber(
52
+ client,
53
+ 'reaction/onReactorAdded',
54
+ 'message.reactionAdded',
55
+ filter,
56
+ );
57
+ }
58
+
59
+ if (referenceType === 'post') {
60
+ const filter = (payload: Amity.LocalEvents['local.post.addReaction']) => {
61
+ callbackWrapper('post', payload.post.postId, payload.reactor);
62
+ };
63
+
64
+ return createEventSubscriber(
65
+ client,
66
+ 'local.post.addReaction',
67
+ 'local.post.addReaction',
68
+ filter,
69
+ );
70
+ }
71
+
72
+ if (referenceType === 'story') {
73
+ const filter = (payload: Amity.StoryReactionPayload) => {
74
+ const { reactions, ...rest } = payload;
75
+ ingestInCache(rest as Amity.StoryPayload);
76
+ ingestInCache({ reactors: reactions });
77
+
78
+ if (payload.stories.length === 0 || payload.reactions.length === 0) return;
79
+ callbackWrapper('story', payload.stories[0].storyId, payload.reactions[0]);
80
+ };
81
+
82
+ return createEventSubscriber(client, 'story.reactionAdded', 'story.reactionAdded', filter);
83
+ }
84
+
85
+ const filter = (payload: Amity.LocalEvents['local.comment.addReaction']) => {
86
+ callbackWrapper('comment', payload.comment.commentId, payload.reactor);
87
+ };
88
+
89
+ return createEventSubscriber(
90
+ client,
91
+ 'local.comment.addReaction',
92
+ 'local.comment.addReaction',
93
+ filter,
94
+ );
95
+ };
@@ -0,0 +1,94 @@
1
+ import { getActiveClient } from '~/client/api';
2
+ import { ingestInCache } from '~/cache/api/ingestInCache';
3
+ import { createEventSubscriber } from '~/core/events';
4
+ import { prepareMessagePayload } from '~/messageRepository/utils';
5
+
6
+ /**
7
+ * ```js
8
+ * import { onReactorRemovedLocal } from '@amityco/ts-sdk'
9
+ * const dispose = onReactorRemoved('post', postId, reactor => {
10
+ * // ...
11
+ * })
12
+ * ```
13
+ *
14
+ * Fired when an {@link Amity.InternalReactor} has been removed
15
+ *
16
+ * @param {@link Amity.ReactableType} referenceType
17
+ * @param {string} referenceId
18
+ * @param callback The function to call when the event was fired
19
+ * @returns an {@link Amity.Unsubscriber} function to stop listening
20
+ *
21
+ * @category Events
22
+ * */
23
+ export const onReactorRemovedLocal = (
24
+ referenceType: Amity.ReactableType,
25
+ referenceId: Amity.Reaction['referenceId'],
26
+ callback: Amity.Listener<Amity.InternalReactor>,
27
+ ): Amity.Unsubscriber => {
28
+ const client = getActiveClient();
29
+
30
+ const callbackWrapper = (
31
+ referenceType_: Amity.ReactableType,
32
+ referenceId_: Amity.Reaction['referenceId'],
33
+ reaction: Amity.InternalReactor,
34
+ ) => {
35
+ if (referenceType_ === referenceType && referenceId_ === referenceId) {
36
+ callback(reaction);
37
+ }
38
+ };
39
+
40
+ if (referenceType === 'message') {
41
+ const filter = async (rawPayload: Amity.MessagePayload) => {
42
+ const payload = await prepareMessagePayload(rawPayload);
43
+ if (!payload.reactions[0]) return;
44
+
45
+ ingestInCache(payload);
46
+
47
+ callbackWrapper('message', payload.messages[0].messageId, payload.reactions[0]);
48
+ };
49
+
50
+ return createEventSubscriber(
51
+ client,
52
+ 'reaction/onReactorRemoved',
53
+ 'message.reactionRemoved',
54
+ filter,
55
+ );
56
+ }
57
+
58
+ if (referenceType === 'post') {
59
+ const filter = (payload: Amity.LocalEvents['local.post.removeReaction']) => {
60
+ callbackWrapper('post', payload.post.postId, payload.reactor);
61
+ };
62
+
63
+ return createEventSubscriber(
64
+ client,
65
+ 'local.post.removeReaction',
66
+ 'local.post.removeReaction',
67
+ filter,
68
+ );
69
+ }
70
+
71
+ if (referenceType === 'story') {
72
+ const filter = (payload: Amity.StoryReactionPayload) => {
73
+ const { reactions, ...rest } = payload;
74
+ ingestInCache(rest as Amity.StoryPayload);
75
+ ingestInCache({ reactors: reactions });
76
+
77
+ if (payload.stories.length === 0 || payload.reactions.length === 0) return;
78
+ callbackWrapper('story', payload.stories[0].storyId, payload.reactions[0]);
79
+ };
80
+
81
+ return createEventSubscriber(client, 'story.reactionRemoved', 'story.reactionRemoved', filter);
82
+ }
83
+
84
+ const filter = (payload: Amity.LocalEvents['local.comment.removeReaction']) => {
85
+ callbackWrapper('comment', payload.comment.commentId, payload.reactor);
86
+ };
87
+
88
+ return createEventSubscriber(
89
+ client,
90
+ 'local.comment.removeReaction',
91
+ 'local.comment.removeReaction',
92
+ filter,
93
+ );
94
+ };
@@ -0,0 +1,111 @@
1
+ import hash from 'object-hash';
2
+ import { pullFromCache, pushToCache } from '~/cache/api';
3
+ import { ReactionPaginationController } from './ReactionPaginationController';
4
+ import { ReactionQueryStreamController } from './ReactionQueryStreamController';
5
+ import { LiveCollectionController } from '~/core/liveCollection/LiveCollectionController';
6
+
7
+ import { onReactorAdded, onReactorRemoved } from '../../events';
8
+
9
+ import { LinkedObject } from '~/utils/linkedObject';
10
+ import { onReactorRemovedLocal } from '~/reactionRepository/events/onReactorRemovedLocal';
11
+ import { onReactorAddedLocal } from '~/reactionRepository/events/onReactorAddedLocal';
12
+
13
+ export class ReactionLiveCollectionController extends LiveCollectionController<
14
+ 'reaction',
15
+ Amity.ReactionLiveCollection,
16
+ Amity.Reactor,
17
+ ReactionPaginationController
18
+ > {
19
+ private queryStreamController: ReactionQueryStreamController;
20
+
21
+ private query: Amity.ReactionLiveCollection;
22
+
23
+ constructor(
24
+ query: Amity.ReactionLiveCollection,
25
+ callback: Amity.LiveCollectionCallback<Amity.Reactor>,
26
+ ) {
27
+ const queryStreamId = hash(query);
28
+ const cacheKey = ['reaction', 'collection', queryStreamId];
29
+ const paginationController = new ReactionPaginationController(query);
30
+
31
+ super(paginationController, queryStreamId, cacheKey, callback);
32
+
33
+ this.query = query;
34
+ this.queryStreamController = new ReactionQueryStreamController(
35
+ this.query,
36
+ this.cacheKey,
37
+ this.notifyChange.bind(this),
38
+ payload => payload,
39
+ );
40
+
41
+ this.callback = callback.bind(this);
42
+ this.loadPage({ initial: true });
43
+ }
44
+
45
+ protected setup() {
46
+ const collection = pullFromCache<Amity.ReactionLiveCollectionCache>(this.cacheKey)?.data;
47
+ if (!collection) {
48
+ pushToCache(this.cacheKey, {
49
+ data: [],
50
+ params: {},
51
+ });
52
+ }
53
+ }
54
+
55
+ protected async persistModel(queryPayload: Amity.ReactionPayload & Amity.Pagination) {
56
+ await this.queryStreamController.saveToMainDB(queryPayload);
57
+ }
58
+
59
+ protected persistQueryStream({
60
+ response,
61
+ direction,
62
+ refresh,
63
+ }: Amity.LiveCollectionPersistQueryStreamParams<'reaction'>) {
64
+ this.queryStreamController.appendToQueryStream(response, direction, refresh);
65
+ }
66
+
67
+ startSubscription() {
68
+ return this.queryStreamController.subscribeRTE([
69
+ {
70
+ fn: callback => onReactorAdded(this.query.referenceType, this.query.referenceId, callback),
71
+ action: Amity.ReactionActionTypeEnum.OnAdded,
72
+ },
73
+ {
74
+ fn: callback =>
75
+ onReactorRemoved(this.query.referenceType, this.query.referenceId, callback),
76
+ action: Amity.ReactionActionTypeEnum.OnRemoved,
77
+ },
78
+ {
79
+ fn: callback =>
80
+ onReactorRemovedLocal(this.query.referenceType, this.query.referenceId, callback),
81
+ action: Amity.ReactionActionTypeEnum.OnRemoved,
82
+ },
83
+ {
84
+ fn: callback =>
85
+ onReactorAddedLocal(this.query.referenceType, this.query.referenceId, callback),
86
+ action: Amity.ReactionActionTypeEnum.OnRemoved,
87
+ },
88
+ ]);
89
+ }
90
+
91
+ notifyChange({ origin, loading, error }: Amity.LiveCollectionNotifyParams) {
92
+ const collection = pullFromCache<Amity.ReactionLiveCollectionCache>(this.cacheKey)?.data;
93
+ if (!collection) return;
94
+
95
+ const data =
96
+ collection.data
97
+ .map(reactorId => pullFromCache<Amity.InternalReactor>(['reactor', 'get', reactorId])!)
98
+ .filter(Boolean)
99
+ .map(({ data }) => LinkedObject.reactor(data)) ?? [];
100
+
101
+ if (!this.shouldNotify(data) && origin === 'event') return;
102
+
103
+ this.callback({
104
+ onNextPage: () => this.loadPage({ direction: Amity.LiveCollectionPageDirection.NEXT }),
105
+ data,
106
+ hasNextPage: !!this.paginationController.getNextToken(),
107
+ loading,
108
+ error,
109
+ });
110
+ }
111
+ }
@@ -0,0 +1,30 @@
1
+ import { getActiveClient } from '~/client';
2
+ import { PaginationController } from '~/core/liveCollection/PaginationController';
3
+ import { COLLECTION_DEFAULT_PAGINATION_LIMIT } from '~/utils/constants';
4
+ import { REFERENCE_API_V5 } from '~/reactionRepository/api/constants';
5
+
6
+ export class ReactionPaginationController extends PaginationController<
7
+ 'reaction',
8
+ Amity.ReactionLiveCollection
9
+ > {
10
+ async getRequest(queryParams: Amity.ReactionLiveCollection, token: string | undefined) {
11
+ const { limit = COLLECTION_DEFAULT_PAGINATION_LIMIT, ...params } = queryParams;
12
+ const options = token ? { token } : { limit };
13
+ const client = getActiveClient();
14
+ client.log('reaction/queryReactions', queryParams);
15
+
16
+ const path = '/api/v3/reactions';
17
+
18
+ const { data: queryResponse } = await this.http.get<Amity.ReactionPayload & Amity.Pagination>(
19
+ path,
20
+ {
21
+ params: {
22
+ ...params,
23
+ referenceVersion: REFERENCE_API_V5, // Need to put this param to make it can query reaction for message in sub-channel
24
+ options,
25
+ },
26
+ },
27
+ );
28
+ return queryResponse;
29
+ }
30
+ }