@amityco/ts-sdk 0.0.1-beta.23 → 0.0.1-beta.26
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/.eslintrc.json +4 -1
- package/dist/@types/core/events.d.ts +5 -1
- package/dist/@types/core/events.d.ts.map +1 -1
- package/dist/@types/core/live.d.ts +23 -0
- package/dist/@types/core/live.d.ts.map +1 -0
- package/dist/@types/core/paging.d.ts +1 -1
- package/dist/@types/core/paging.d.ts.map +1 -1
- package/dist/@types/domains/channel.d.ts +1 -2
- package/dist/@types/domains/channel.d.ts.map +1 -1
- package/dist/@types/domains/comment.d.ts +14 -0
- package/dist/@types/domains/comment.d.ts.map +1 -1
- package/dist/@types/domains/post.d.ts +17 -0
- package/dist/@types/domains/post.d.ts.map +1 -1
- package/dist/@types/index.d.ts +1 -0
- package/dist/@types/index.d.ts.map +1 -1
- package/dist/cache/api/ingestInCache.d.ts +1 -1
- package/dist/cache/api/ingestInCache.d.ts.map +1 -1
- package/dist/cache/api/mergeInCache.d.ts +1 -1
- package/dist/cache/api/mergeInCache.d.ts.map +1 -1
- package/dist/category/api/queryCategories.d.ts +3 -3
- package/dist/category/api/queryCategories.d.ts.map +1 -1
- package/dist/channel/api/queryChannels.d.ts +6 -6
- package/dist/channel/api/queryChannels.d.ts.map +1 -1
- package/dist/channel/api/updateChannel.d.ts +1 -1
- package/dist/channel/api/updateChannel.d.ts.map +1 -1
- package/dist/client/api/connectClient.d.ts +1 -1
- package/dist/client/api/connectClient.d.ts.map +1 -1
- package/dist/client/api/createClient.d.ts +1 -1
- package/dist/client/api/createClient.d.ts.map +1 -1
- package/dist/comment/api/queryComments.d.ts +1 -9
- package/dist/comment/api/queryComments.d.ts.map +1 -1
- package/dist/comment/observers/index.d.ts +1 -0
- package/dist/comment/observers/index.d.ts.map +1 -1
- package/dist/comment/observers/liveComments.d.ts +22 -0
- package/dist/comment/observers/liveComments.d.ts.map +1 -0
- package/dist/comment/observers/observeComments.d.ts.map +1 -1
- package/dist/community/api/getRecommendedCommunities.d.ts +1 -1
- package/dist/community/api/getRecommendedCommunities.d.ts.map +1 -1
- package/dist/community/api/getTopTrendingCommunities.d.ts +1 -1
- package/dist/community/api/getTopTrendingCommunities.d.ts.map +1 -1
- package/dist/community/api/queryCommunities.d.ts +7 -7
- package/dist/community/api/queryCommunities.d.ts.map +1 -1
- package/dist/core/debug.d.ts +1 -1
- package/dist/core/debug.d.ts.map +1 -1
- package/dist/core/events.d.ts +3 -3
- package/dist/core/events.d.ts.map +1 -1
- package/dist/core/query/paging.d.ts +2 -2
- package/dist/core/query/paging.d.ts.map +1 -1
- package/dist/core/query/query.d.ts +1 -1
- package/dist/core/query/query.d.ts.map +1 -1
- package/dist/core/tests/query/filtering.test.d.ts +2 -0
- package/dist/core/tests/query/filtering.test.d.ts.map +1 -0
- package/dist/core/tests/query/query.test.d.ts +2 -0
- package/dist/core/tests/query/query.test.d.ts.map +1 -0
- package/dist/core/transports/ws.d.ts +1 -1
- package/dist/core/transports/ws.d.ts.map +1 -1
- package/dist/external/api/createUserToken.d.ts +1 -1
- package/dist/external/api/createUserToken.d.ts.map +1 -1
- package/dist/feed/api/queryGlobalFeed.d.ts +4 -4
- package/dist/feed/api/queryGlobalFeed.d.ts.map +1 -1
- package/dist/index.cjs.js +17981 -17588
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.esm.js +17975 -17589
- package/dist/index.umd.js +4 -19
- package/dist/poll/api/closePoll.d.ts.map +1 -1
- package/dist/poll/api/deletePoll.d.ts.map +1 -1
- package/dist/poll/api/votePoll.d.ts.map +1 -1
- package/dist/poll/events/index.d.ts +3 -0
- package/dist/poll/events/index.d.ts.map +1 -0
- package/dist/poll/events/onPollDeleted.d.ts +17 -0
- package/dist/poll/events/onPollDeleted.d.ts.map +1 -0
- package/dist/poll/events/onPollUpdated.d.ts +17 -0
- package/dist/poll/events/onPollUpdated.d.ts.map +1 -0
- package/dist/poll/observers/index.d.ts +2 -0
- package/dist/poll/observers/index.d.ts.map +1 -0
- package/dist/poll/observers/observePoll.d.ts +18 -0
- package/dist/poll/observers/observePoll.d.ts.map +1 -0
- package/dist/post/api/approvePost.d.ts +17 -0
- package/dist/post/api/approvePost.d.ts.map +1 -0
- package/dist/post/api/declinePost.d.ts +17 -0
- package/dist/post/api/declinePost.d.ts.map +1 -0
- package/dist/post/api/index.d.ts +2 -0
- package/dist/post/api/index.d.ts.map +1 -1
- package/dist/post/api/queryPosts.d.ts +1 -12
- package/dist/post/api/queryPosts.d.ts.map +1 -1
- package/dist/post/observers/index.d.ts +1 -0
- package/dist/post/observers/index.d.ts.map +1 -1
- package/dist/post/observers/livePosts.d.ts +22 -0
- package/dist/post/observers/livePosts.d.ts.map +1 -0
- package/dist/post/observers/observePosts.d.ts.map +1 -1
- package/dist/post/tests/api/getPost.test.d.ts +2 -0
- package/dist/post/tests/api/getPost.test.d.ts.map +1 -0
- package/dist/post/tests/api/queryPosts.test.d.ts +2 -0
- package/dist/post/tests/api/queryPosts.test.d.ts.map +1 -0
- package/dist/reaction/api/queryReactions.d.ts +2 -2
- package/dist/reaction/api/queryReactions.d.ts.map +1 -1
- package/dist/report/api/createReport.d.ts.map +1 -1
- package/dist/report/api/deleteReport.d.ts.map +1 -1
- package/dist/role/api/queryRoles.d.ts +4 -4
- package/dist/role/api/queryRoles.d.ts.map +1 -1
- package/dist/stream/api/queryStreams.d.ts +6 -6
- package/dist/stream/api/queryStreams.d.ts.map +1 -1
- package/dist/utils/constants.d.ts +3 -0
- package/dist/utils/constants.d.ts.map +1 -0
- package/dist/utils/tests/client.d.ts +3 -0
- package/dist/utils/tests/client.d.ts.map +1 -0
- package/dist/utils/tests/dummy.d.ts +8 -0
- package/dist/utils/tests/dummy.d.ts.map +1 -0
- package/dist/utils/tests/index.d.ts +3 -0
- package/dist/utils/tests/index.d.ts.map +1 -0
- package/jest.config.ts +15 -0
- package/package.json +21 -16
- package/src/@types/core/events.ts +6 -1
- package/src/@types/core/live.ts +28 -0
- package/src/@types/core/paging.ts +1 -1
- package/src/@types/domains/channel.ts +1 -2
- package/src/@types/domains/comment.ts +31 -0
- package/src/@types/domains/post.ts +37 -0
- package/src/@types/index.ts +1 -0
- package/src/channel/api/updateChannel.ts +1 -1
- package/src/comment/api/queryComments.ts +3 -9
- package/src/comment/observers/index.ts +1 -0
- package/src/comment/observers/liveComments.ts +169 -0
- package/src/comment/observers/observeComments.ts +1 -11
- package/src/core/query/query.ts +15 -2
- package/src/core/tests/query/filtering.test.ts +11 -0
- package/src/core/tests/query/query.test.ts +19 -0
- package/src/index.ts +2 -0
- package/src/message/api/createMessage.ts +4 -1
- package/src/poll/api/closePoll.ts +3 -0
- package/src/poll/api/deletePoll.ts +3 -0
- package/src/poll/api/votePoll.ts +3 -0
- package/src/poll/events/index.ts +2 -0
- package/src/poll/events/onPollDeleted.ts +31 -0
- package/src/poll/events/onPollUpdated.ts +31 -0
- package/src/poll/observers/index.ts +1 -0
- package/src/poll/observers/observePoll.ts +67 -0
- package/src/post/api/approvePost.ts +48 -0
- package/src/post/api/declinePost.ts +48 -0
- package/src/post/api/index.ts +3 -0
- package/src/post/api/queryPosts.ts +3 -12
- package/src/post/observers/index.ts +1 -0
- package/src/post/observers/livePosts.ts +170 -0
- package/src/post/observers/observePosts.ts +1 -13
- package/src/post/tests/api/getPost.test.ts +88 -0
- package/src/post/tests/api/queryPosts.test.ts +23 -0
- package/src/reaction/api/queryReactions.ts +10 -10
- package/src/report/api/createReport.ts +7 -1
- package/src/report/api/deleteReport.ts +7 -1
- package/src/utils/constants.ts +2 -0
- package/src/utils/tests/client.ts +5 -0
- package/src/utils/tests/dummy.ts +7 -0
- package/src/utils/tests/index.ts +2 -0
- package/tsconfig.json +23 -22
|
@@ -19,7 +19,7 @@ import { ingestInCache } from '~/cache/api/ingestInCache';
|
|
|
19
19
|
*/
|
|
20
20
|
export const updateChannel = async (
|
|
21
21
|
channelId: Amity.Channel['channelId'],
|
|
22
|
-
patch: Patch<Amity.Channel, 'displayName' | '
|
|
22
|
+
patch: Patch<Amity.Channel, 'displayName' | 'avatarFileId' | 'tags' | 'metadata'>,
|
|
23
23
|
): Promise<Amity.Cached<Amity.Channel>> => {
|
|
24
24
|
const client = getActiveClient();
|
|
25
25
|
client.log('channel/updateChannel', channelId, patch);
|
|
@@ -19,15 +19,9 @@ import { getResolver } from '~/core/model';
|
|
|
19
19
|
* @category Comment API
|
|
20
20
|
* @async
|
|
21
21
|
*/
|
|
22
|
-
export const queryComments = async (
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
sortBy?: 'lastCreated' | 'firstCreated' | 'lastUpdated' | 'firstUpdated';
|
|
26
|
-
parentId?: Amity.Comment['commentId'] | null;
|
|
27
|
-
hasFlag?: boolean;
|
|
28
|
-
isDeleted?: Amity.Comment['isDeleted'];
|
|
29
|
-
page?: Amity.Page;
|
|
30
|
-
}): Promise<Amity.Cached<Amity.Paged<Amity.Comment>>> => {
|
|
22
|
+
export const queryComments = async (
|
|
23
|
+
query: Amity.QueryComments,
|
|
24
|
+
): Promise<Amity.Cached<Amity.Paged<Amity.Comment>>> => {
|
|
31
25
|
const client = getActiveClient();
|
|
32
26
|
client.log('comment/queryComments', query);
|
|
33
27
|
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
/* eslint-disable no-use-before-define */
|
|
2
|
+
import { getResolver } from '~/core/model';
|
|
3
|
+
import { getActiveClient } from '~/client/api';
|
|
4
|
+
import { pushToCache, pullFromCache } from '~/cache/api';
|
|
5
|
+
import {
|
|
6
|
+
createQuery,
|
|
7
|
+
runQuery,
|
|
8
|
+
queryOptions,
|
|
9
|
+
filterByPropEquality,
|
|
10
|
+
sortByFirstCreated,
|
|
11
|
+
sortByLastCreated,
|
|
12
|
+
} from '~/core/query';
|
|
13
|
+
|
|
14
|
+
import {
|
|
15
|
+
COLLECTION_DEFAULT_CACHING_POLICY,
|
|
16
|
+
COLLECTION_DEFAULT_PAGINATION_LIMIT,
|
|
17
|
+
} from '~/utils/constants';
|
|
18
|
+
|
|
19
|
+
import {
|
|
20
|
+
onCommentCreated,
|
|
21
|
+
onCommentUpdated,
|
|
22
|
+
onCommentDeleted,
|
|
23
|
+
onCommentFlagged,
|
|
24
|
+
onCommentUnflagged,
|
|
25
|
+
onCommentReactionAdded,
|
|
26
|
+
onCommentReactionRemoved,
|
|
27
|
+
} from '../events';
|
|
28
|
+
import { queryComments } from '../api';
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* ```js
|
|
32
|
+
* import { liveComments } from '@amityco/ts-sdk'
|
|
33
|
+
*
|
|
34
|
+
* let comments = []
|
|
35
|
+
* const unsub = liveComments({
|
|
36
|
+
* referenceType: Amity.Comment['referenceType'];
|
|
37
|
+
* referenceId: Amity.Comment['referenceId'];
|
|
38
|
+
* }, response => merge(comments, response.data))
|
|
39
|
+
* ```
|
|
40
|
+
*
|
|
41
|
+
* Observe all mutations on a list of {@link Amity.Comment} for a given target object
|
|
42
|
+
*
|
|
43
|
+
* @param referenceType the type of the target
|
|
44
|
+
* @param referenceId the ID of the target
|
|
45
|
+
* @param callback the function to call when new data are available
|
|
46
|
+
* @returns An {@link Amity.Unsubscriber} function to run when willing to stop observing the messages
|
|
47
|
+
*
|
|
48
|
+
* @category Comments Live Collection
|
|
49
|
+
*/
|
|
50
|
+
export const liveComments = (
|
|
51
|
+
params: Amity.CommentLiveCollection,
|
|
52
|
+
callback: Amity.LiveCollectionCallback<Amity.Comment>,
|
|
53
|
+
config?: Amity.LiveCollectionConfig,
|
|
54
|
+
): Amity.Unsubscriber => {
|
|
55
|
+
const { log, cache } = getActiveClient();
|
|
56
|
+
|
|
57
|
+
if (!cache) {
|
|
58
|
+
console.log('For using Live Collection feature you need to enable Cache!');
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
const timestamp = Date.now();
|
|
62
|
+
log(`liveComments(tmpid: ${timestamp}) > listen`);
|
|
63
|
+
|
|
64
|
+
const { limit: queryLimit, ...queryParams } = params;
|
|
65
|
+
|
|
66
|
+
const limit = queryLimit ?? COLLECTION_DEFAULT_PAGINATION_LIMIT;
|
|
67
|
+
const { policy = COLLECTION_DEFAULT_CACHING_POLICY } = config ?? {};
|
|
68
|
+
|
|
69
|
+
const disposers: Amity.Unsubscriber[] = [];
|
|
70
|
+
const cacheKey = [
|
|
71
|
+
'comment',
|
|
72
|
+
'collection',
|
|
73
|
+
{ referenceId: params.referenceType, referenceType: params.referenceId },
|
|
74
|
+
];
|
|
75
|
+
|
|
76
|
+
const responder = (data: Amity.CommentLiveCollectionCache) => {
|
|
77
|
+
let comments: Amity.Comment[] =
|
|
78
|
+
data.data
|
|
79
|
+
.map(commentId => pullFromCache<Amity.Comment>(['comment', 'get', commentId])!)
|
|
80
|
+
.filter(Boolean)
|
|
81
|
+
.map(({ data }) => data) ?? [];
|
|
82
|
+
|
|
83
|
+
comments = filterByPropEquality(comments, 'isDeleted', params.isDeleted);
|
|
84
|
+
|
|
85
|
+
const sortBy = params.sortBy ? params.sortBy : 'lastCreated';
|
|
86
|
+
|
|
87
|
+
comments = comments.sort(sortBy === 'lastCreated' ? sortByLastCreated : sortByFirstCreated);
|
|
88
|
+
|
|
89
|
+
callback({
|
|
90
|
+
onNextPage: onFetch,
|
|
91
|
+
data: comments,
|
|
92
|
+
hasNextPage: !!data.params?.page,
|
|
93
|
+
loading: data.loading,
|
|
94
|
+
error: data.error,
|
|
95
|
+
});
|
|
96
|
+
};
|
|
97
|
+
|
|
98
|
+
const realtimeRouter = (comment: Amity.Comment, action: Amity.CommentActionType) => {
|
|
99
|
+
const collection = pullFromCache<Amity.CommentLiveCollectionCache>(cacheKey)?.data;
|
|
100
|
+
|
|
101
|
+
if (
|
|
102
|
+
params.referenceId !== comment.referenceId ||
|
|
103
|
+
params.referenceType !== comment.referenceType ||
|
|
104
|
+
!collection
|
|
105
|
+
)
|
|
106
|
+
return;
|
|
107
|
+
|
|
108
|
+
if (action === 'onCreate') {
|
|
109
|
+
collection.data = [...new Set([comment.commentId, ...collection.data])];
|
|
110
|
+
} else if (action === 'onDelete') {
|
|
111
|
+
collection.data = collection.data.filter(p => p !== comment.commentId);
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
pushToCache(cacheKey, collection);
|
|
115
|
+
|
|
116
|
+
responder(collection);
|
|
117
|
+
};
|
|
118
|
+
|
|
119
|
+
const onFetch = () => {
|
|
120
|
+
const collection = pullFromCache<Amity.CommentLiveCollectionCache>(cacheKey)?.data;
|
|
121
|
+
|
|
122
|
+
const comments = collection?.data ?? [];
|
|
123
|
+
|
|
124
|
+
if (comments.length > 0 && !collection?.params?.page) return;
|
|
125
|
+
|
|
126
|
+
const query = createQuery(queryComments, {
|
|
127
|
+
...queryParams,
|
|
128
|
+
page: collection?.params?.page ?? { limit },
|
|
129
|
+
});
|
|
130
|
+
|
|
131
|
+
runQuery(
|
|
132
|
+
query,
|
|
133
|
+
({ data: result, error, loading, prevPage: page }) => {
|
|
134
|
+
const data = {
|
|
135
|
+
loading,
|
|
136
|
+
error,
|
|
137
|
+
params: { page },
|
|
138
|
+
data: comments,
|
|
139
|
+
};
|
|
140
|
+
|
|
141
|
+
if (result) {
|
|
142
|
+
data.data = [...new Set([...comments, ...result.map(getResolver('comment'))])];
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
pushToCache(cacheKey, data);
|
|
146
|
+
|
|
147
|
+
responder(data);
|
|
148
|
+
},
|
|
149
|
+
queryOptions(policy),
|
|
150
|
+
);
|
|
151
|
+
};
|
|
152
|
+
|
|
153
|
+
disposers.push(
|
|
154
|
+
onCommentCreated(comment => realtimeRouter(comment, 'onCreate')),
|
|
155
|
+
onCommentUpdated(comment => realtimeRouter(comment, 'onUpdate')),
|
|
156
|
+
onCommentDeleted(comment => realtimeRouter(comment, 'onDelete')),
|
|
157
|
+
onCommentFlagged(comment => realtimeRouter(comment, 'onFlagged')),
|
|
158
|
+
onCommentUnflagged(comment => realtimeRouter(comment, 'onUnflagged')),
|
|
159
|
+
onCommentReactionAdded(comment => realtimeRouter(comment, 'onReactionAdded')),
|
|
160
|
+
onCommentReactionRemoved(comment => realtimeRouter(comment, 'onReactionRemoved')),
|
|
161
|
+
);
|
|
162
|
+
|
|
163
|
+
onFetch();
|
|
164
|
+
|
|
165
|
+
return () => {
|
|
166
|
+
log(`liveComments(tmpid: ${timestamp}) > dispose`);
|
|
167
|
+
disposers.forEach(fn => fn());
|
|
168
|
+
};
|
|
169
|
+
};
|
|
@@ -48,17 +48,7 @@ export const observeComments = (
|
|
|
48
48
|
|
|
49
49
|
const disposers: Amity.Unsubscriber[] = [];
|
|
50
50
|
|
|
51
|
-
const router = (
|
|
52
|
-
comment: Amity.Comment,
|
|
53
|
-
action:
|
|
54
|
-
| 'onCreate'
|
|
55
|
-
| 'onUpdate'
|
|
56
|
-
| 'onDelete'
|
|
57
|
-
| 'onFlagged'
|
|
58
|
-
| 'onUnflagged'
|
|
59
|
-
| 'onReactionAdded'
|
|
60
|
-
| 'onReactionRemoved',
|
|
61
|
-
) => {
|
|
51
|
+
const router = (comment: Amity.Comment, action: Exclude<Amity.CommentActionType, 'onFetch'>) => {
|
|
62
52
|
if (comment.referenceId !== postId) return;
|
|
63
53
|
|
|
64
54
|
if (callback instanceof Function) return callback(comment);
|
package/src/core/query/query.ts
CHANGED
|
@@ -215,8 +215,21 @@ export const runQuery = <Args extends any[], Returned extends any>(
|
|
|
215
215
|
if (isMutator(func)) {
|
|
216
216
|
// @ts-ignore
|
|
217
217
|
const modelKey = local && local.data && identifyModelKey(local.data);
|
|
218
|
-
|
|
219
|
-
|
|
218
|
+
if (modelKey) {
|
|
219
|
+
/*
|
|
220
|
+
* modal key is only required for create as update and delete queries pass
|
|
221
|
+
* the modal key in the param itself
|
|
222
|
+
* For update & delete the first argument is always an id which is of type
|
|
223
|
+
* string, whereas for create the first and only argument is the param object
|
|
224
|
+
*
|
|
225
|
+
* When creating an AmityObject optimistically we need to pass the modal key
|
|
226
|
+
* on to the server. ex: for create message modal key will be 'messageId`
|
|
227
|
+
*/
|
|
228
|
+
if (typeof args[0] !== 'string') {
|
|
229
|
+
// @ts-ignore
|
|
230
|
+
optimisticArgs = [{ ...args[0], [modelKey]: local.data[modelKey] }];
|
|
231
|
+
}
|
|
232
|
+
}
|
|
220
233
|
}
|
|
221
234
|
|
|
222
235
|
func(...optimisticArgs)
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { filterByPropEquality } from '~/core/query';
|
|
2
|
+
|
|
3
|
+
describe('Core/Query/Filtering', () => {
|
|
4
|
+
test('check filterByPropEquality', () => {
|
|
5
|
+
const prop = 'prop';
|
|
6
|
+
const collection = [{ [prop]: 'value' }];
|
|
7
|
+
|
|
8
|
+
expect(filterByPropEquality(collection, prop, 'value')).toStrictEqual(collection);
|
|
9
|
+
expect(filterByPropEquality(collection, prop, 'otherValue')).toStrictEqual([]);
|
|
10
|
+
});
|
|
11
|
+
});
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { isFetcher } from '~/core/query';
|
|
2
|
+
|
|
3
|
+
type isFetcherMockType = jest.Mock<any, any> & {
|
|
4
|
+
locally?: jest.Mock<any, any>;
|
|
5
|
+
};
|
|
6
|
+
|
|
7
|
+
describe('Core/Query/Query', () => {
|
|
8
|
+
const isFetcherMock: isFetcherMockType = jest.fn();
|
|
9
|
+
|
|
10
|
+
test('isFetcher without locally', () => {
|
|
11
|
+
expect(isFetcher(isFetcherMock)).toBe(false);
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
test('isFetcher with locally', () => {
|
|
15
|
+
isFetcherMock.locally = jest.fn();
|
|
16
|
+
|
|
17
|
+
expect(isFetcher(isFetcherMock)).toBe(true);
|
|
18
|
+
});
|
|
19
|
+
});
|
package/src/index.ts
CHANGED
|
@@ -75,8 +75,11 @@ createMessage.optimistically = (
|
|
|
75
75
|
/*
|
|
76
76
|
* when creating messages optimistically a messageId needs to be added by the
|
|
77
77
|
* client, created a new variable so as to allow backward compatibility of API
|
|
78
|
+
*
|
|
79
|
+
* Updated to handle client requirement to add messageId while uploading
|
|
80
|
+
* message with image. Temporary!
|
|
78
81
|
*/
|
|
79
|
-
const bundleWithMessageId = {
|
|
82
|
+
const bundleWithMessageId = { messageId: uuid(), ...bundle };
|
|
80
83
|
|
|
81
84
|
// only log if cache is enabled
|
|
82
85
|
client.log('user/createMessage.locally', bundleWithMessageId);
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { fireEvent } from '~/core/events';
|
|
1
2
|
import { getActiveClient } from '~/client/api';
|
|
2
3
|
|
|
3
4
|
import { ingestInCache } from '~/cache/api/ingestInCache';
|
|
@@ -30,6 +31,8 @@ export const closePoll = async (
|
|
|
30
31
|
const cachedAt = client.cache && Date.now();
|
|
31
32
|
if (client.cache) ingestInCache(data, { cachedAt });
|
|
32
33
|
|
|
34
|
+
fireEvent('poll.updated', data);
|
|
35
|
+
|
|
33
36
|
const { polls } = data;
|
|
34
37
|
|
|
35
38
|
return {
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { fireEvent } from '~/core/events';
|
|
1
2
|
import { getActiveClient } from '~/client/api';
|
|
2
3
|
|
|
3
4
|
import { upsertInCache } from '~/cache/api';
|
|
@@ -32,5 +33,7 @@ export const deletePoll = async (pollId: Amity.Poll['pollId']): Promise<boolean>
|
|
|
32
33
|
|
|
33
34
|
upsertInCache(['poll', 'get', pollId], deleted);
|
|
34
35
|
|
|
36
|
+
fireEvent('poll.deleted', { polls: [deleted], users: [] });
|
|
37
|
+
|
|
35
38
|
return success;
|
|
36
39
|
};
|
package/src/poll/api/votePoll.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { fireEvent } from '~/core/events';
|
|
1
2
|
import { getActiveClient } from '~/client/api';
|
|
2
3
|
|
|
3
4
|
import { ingestInCache } from '~/cache/api/ingestInCache';
|
|
@@ -34,6 +35,8 @@ export const votePoll = async (
|
|
|
34
35
|
|
|
35
36
|
const { polls } = data;
|
|
36
37
|
|
|
38
|
+
fireEvent('poll.updated', data);
|
|
39
|
+
|
|
37
40
|
return {
|
|
38
41
|
data: polls.find(poll => poll.pollId === pollId)!,
|
|
39
42
|
cachedAt,
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { getActiveClient } from '~/client/api';
|
|
2
|
+
import { createEventSubscriber } from '~/core/events';
|
|
3
|
+
|
|
4
|
+
import { ingestInCache } from '~/cache/api/ingestInCache';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* ```js
|
|
8
|
+
* import { onPollDeleted } from '@amityco/ts-sdk'
|
|
9
|
+
* const dispose = onPollDeleted(poll => {
|
|
10
|
+
* // ...
|
|
11
|
+
* })
|
|
12
|
+
* ```
|
|
13
|
+
*
|
|
14
|
+
* Fired when an {@link Amity.Poll} has been deleted
|
|
15
|
+
*
|
|
16
|
+
* @param callback The function to call when the event was fired
|
|
17
|
+
* @returns an {@link Amity.Unsubscriber} function to stop listening
|
|
18
|
+
*
|
|
19
|
+
* @category Poll Events
|
|
20
|
+
*/
|
|
21
|
+
export const onPollDeleted = (callback: Amity.Listener<Amity.Poll>): Amity.Unsubscriber => {
|
|
22
|
+
const client = getActiveClient();
|
|
23
|
+
|
|
24
|
+
const filter = (payload: Amity.PollPayload) => {
|
|
25
|
+
if (client.cache) ingestInCache(payload);
|
|
26
|
+
|
|
27
|
+
callback(payload.polls[0]);
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
return createEventSubscriber(client, 'poll/onPollDeleted', 'poll.deleted', filter);
|
|
31
|
+
};
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { getActiveClient } from '~/client/api';
|
|
2
|
+
import { createEventSubscriber } from '~/core/events';
|
|
3
|
+
|
|
4
|
+
import { ingestInCache } from '~/cache/api/ingestInCache';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* ```js
|
|
8
|
+
* import { onPollUpdated } from '@amityco/ts-sdk'
|
|
9
|
+
* const dispose = onPollUpdated(poll => {
|
|
10
|
+
* // ...
|
|
11
|
+
* })
|
|
12
|
+
* ```
|
|
13
|
+
*
|
|
14
|
+
* Fired when an {@link Amity.Poll} has been updated
|
|
15
|
+
*
|
|
16
|
+
* @param callback The function to call when the event was fired
|
|
17
|
+
* @returns an {@link Amity.Unsubscriber} function to stop listening
|
|
18
|
+
*
|
|
19
|
+
* @category Poll Events
|
|
20
|
+
*/
|
|
21
|
+
export const onPollUpdated = (callback: Amity.Listener<Amity.Poll>): Amity.Unsubscriber => {
|
|
22
|
+
const client = getActiveClient();
|
|
23
|
+
|
|
24
|
+
const filter = (payload: Amity.PollPayload) => {
|
|
25
|
+
if (client.cache) ingestInCache(payload);
|
|
26
|
+
|
|
27
|
+
callback(payload.polls[0]);
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
return createEventSubscriber(client, 'poll/onPollUpdated', 'poll.updated', filter);
|
|
31
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './observePoll';
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { getActiveClient } from '~/client/api';
|
|
2
|
+
|
|
3
|
+
import { createQuery, runQuery, queryOptions } from '~/core/query';
|
|
4
|
+
|
|
5
|
+
import { getPoll } from '../api';
|
|
6
|
+
|
|
7
|
+
import { onPollUpdated, onPollDeleted } from '../events';
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* ```js
|
|
11
|
+
* import { observePoll } from '@amityco/ts-sdk'
|
|
12
|
+
*
|
|
13
|
+
* let poll = {}
|
|
14
|
+
* const dispose = observePoll(pollId, updated => poll = updated)
|
|
15
|
+
* ```
|
|
16
|
+
*
|
|
17
|
+
* Observe all mutation on a given {@link Amity.Poll}
|
|
18
|
+
*
|
|
19
|
+
* @param pollId the ID of the poll to observe
|
|
20
|
+
* @param callback the function to call when new data are available
|
|
21
|
+
* @returns An {@link Amity.Unsubscriber} function to run when willing to stop observing the poll
|
|
22
|
+
*
|
|
23
|
+
* @category Poll Observer
|
|
24
|
+
*/
|
|
25
|
+
export const observePoll = <Events extends ['onFetch', 'onUpdate', 'onDelete']>(
|
|
26
|
+
pollId: string,
|
|
27
|
+
callback: Amity.ObjectListener<Amity.Snapshot<Amity.Poll | undefined>, Events>,
|
|
28
|
+
policy: Amity.QueryPolicy = 'cache_then_server',
|
|
29
|
+
): Amity.Unsubscriber => {
|
|
30
|
+
const { log } = getActiveClient();
|
|
31
|
+
|
|
32
|
+
const timestamp = Date.now();
|
|
33
|
+
log(`observePoll(tmpid: ${timestamp}) > listen`);
|
|
34
|
+
|
|
35
|
+
// wrapper function to make sure
|
|
36
|
+
const router = (result: Amity.Snapshot<Amity.Poll | undefined>, action: Events[number]) => {
|
|
37
|
+
if (callback instanceof Function) return callback(result);
|
|
38
|
+
|
|
39
|
+
if (action !== 'onFetch') callback.onEvent?.(action, result);
|
|
40
|
+
|
|
41
|
+
callback[action]?.(result);
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
const realtimeRouter = (result: Amity.Snapshot<Amity.Poll>, action: Events[number]) => {
|
|
45
|
+
if (result.data?.pollId !== pollId) return;
|
|
46
|
+
|
|
47
|
+
router(result, action);
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
const disposers: Amity.Unsubscriber[] = [];
|
|
51
|
+
|
|
52
|
+
disposers.push(
|
|
53
|
+
onPollUpdated(data => realtimeRouter({ data, loading: false, origin: 'event' }, 'onUpdate')),
|
|
54
|
+
onPollDeleted(data => realtimeRouter({ data, loading: false, origin: 'event' }, 'onDelete')),
|
|
55
|
+
);
|
|
56
|
+
|
|
57
|
+
runQuery(
|
|
58
|
+
createQuery(getPoll, pollId),
|
|
59
|
+
result => (result.data || result.error) && router(result, 'onFetch'),
|
|
60
|
+
queryOptions(policy),
|
|
61
|
+
);
|
|
62
|
+
|
|
63
|
+
return () => {
|
|
64
|
+
log(`observePoll(tmpid: ${timestamp}) > dispose`);
|
|
65
|
+
disposers.forEach(fn => fn());
|
|
66
|
+
};
|
|
67
|
+
};
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { getActiveClient } from '~/client/api';
|
|
2
|
+
|
|
3
|
+
import { ingestInCache } from '~/cache/api/ingestInCache';
|
|
4
|
+
import { fireEvent } from '~/core/events';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* ```js
|
|
8
|
+
* import { approvePost } from '@amityco/ts-sdk'
|
|
9
|
+
*
|
|
10
|
+
* const { data: post } = await approvePost('postId')
|
|
11
|
+
* ```
|
|
12
|
+
*
|
|
13
|
+
* Approves a {@link Amity.Post}
|
|
14
|
+
*
|
|
15
|
+
* @param postId The {@link Amity.Post} ID to be approved
|
|
16
|
+
* @return A {@link Amity.Post} that was approved
|
|
17
|
+
*
|
|
18
|
+
* @category Post API
|
|
19
|
+
* @async
|
|
20
|
+
*/
|
|
21
|
+
export const approvePost = async (
|
|
22
|
+
postId: Amity.Post['postId'],
|
|
23
|
+
): Promise<Amity.Cached<Amity.Post>> => {
|
|
24
|
+
const client = getActiveClient();
|
|
25
|
+
client.log('post/approvePost', postId);
|
|
26
|
+
|
|
27
|
+
const { data: approved } = await client.http.post<Amity.PostPayload>(
|
|
28
|
+
`/api/v3/posts/${encodeURIComponent(postId)}/approve`,
|
|
29
|
+
);
|
|
30
|
+
|
|
31
|
+
const cachedAt = client.cache && Date.now();
|
|
32
|
+
if (client.cache) ingestInCache(approved, { cachedAt });
|
|
33
|
+
|
|
34
|
+
// fire virtual event for community update
|
|
35
|
+
if (approved.posts[0].targetType === 'community') {
|
|
36
|
+
const community = approved.communities?.[0];
|
|
37
|
+
|
|
38
|
+
// @ts-ignore as communities is optional currently in PostPayload
|
|
39
|
+
fireEvent('community.updated', { communities: [community] });
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
fireEvent('post.approved', { posts: [approved.posts[0]] });
|
|
43
|
+
|
|
44
|
+
return {
|
|
45
|
+
data: approved.posts.find(post => post.postId === postId)!,
|
|
46
|
+
cachedAt,
|
|
47
|
+
};
|
|
48
|
+
};
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { getActiveClient } from '~/client/api';
|
|
2
|
+
|
|
3
|
+
import { ingestInCache } from '~/cache/api/ingestInCache';
|
|
4
|
+
import { fireEvent } from '~/core/events';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* ```js
|
|
8
|
+
* import { declinePost } from '@amityco/ts-sdk'
|
|
9
|
+
*
|
|
10
|
+
* const {data: post} = await declinePost('postId')
|
|
11
|
+
* ```
|
|
12
|
+
*
|
|
13
|
+
* Declines a {@link Amity.Post}
|
|
14
|
+
*
|
|
15
|
+
* @param postId The {@link Amity.Post} ID to be declined
|
|
16
|
+
* @return A {@link Amity.Post} that was declined
|
|
17
|
+
*
|
|
18
|
+
* @category Post API
|
|
19
|
+
* @async
|
|
20
|
+
*/
|
|
21
|
+
export const declinePost = async (
|
|
22
|
+
postId: Amity.Post['postId'],
|
|
23
|
+
): Promise<Amity.Cached<Amity.Post>> => {
|
|
24
|
+
const client = getActiveClient();
|
|
25
|
+
client.log('post/declinePost', postId);
|
|
26
|
+
|
|
27
|
+
const { data: declined } = await client.http.post<Amity.PostPayload>(
|
|
28
|
+
`/api/v3/posts/${encodeURIComponent(postId)}/decline`,
|
|
29
|
+
);
|
|
30
|
+
|
|
31
|
+
const cachedAt = client.cache && Date.now();
|
|
32
|
+
if (client.cache) ingestInCache(declined, { cachedAt });
|
|
33
|
+
|
|
34
|
+
// fire virtual event
|
|
35
|
+
if (declined.posts[0].targetType === 'community') {
|
|
36
|
+
const community = declined.communities?.[0];
|
|
37
|
+
|
|
38
|
+
// @ts-ignore as communities is optional currently in PostPayload
|
|
39
|
+
fireEvent('community.updated', { communities: [community] });
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
fireEvent('post.declined', { posts: [declined.posts[0]] });
|
|
43
|
+
|
|
44
|
+
return {
|
|
45
|
+
data: declined.posts.find(post => post.postId === postId)!,
|
|
46
|
+
cachedAt,
|
|
47
|
+
};
|
|
48
|
+
};
|
package/src/post/api/index.ts
CHANGED
|
@@ -20,18 +20,9 @@ import { getResolver } from '~/core/model';
|
|
|
20
20
|
* @category Post API
|
|
21
21
|
* @async
|
|
22
22
|
*/
|
|
23
|
-
export const queryPosts = async (
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
sortBy?: 'lastCreated' | 'firstCreated' | 'lastUpdated' | 'firstUpdated';
|
|
27
|
-
dataType?: string;
|
|
28
|
-
isDeleted?: Amity.Post['isDeleted'];
|
|
29
|
-
hasFlag?: boolean;
|
|
30
|
-
feedType?: 'reviewing' | 'published';
|
|
31
|
-
tags?: Amity.Taggable['tags'];
|
|
32
|
-
matchingOnlyParentPost?: boolean;
|
|
33
|
-
page?: Amity.PageRaw;
|
|
34
|
-
}): Promise<Amity.Cached<Amity.Paged<Amity.Post, Amity.PageRaw>>> => {
|
|
23
|
+
export const queryPosts = async (
|
|
24
|
+
query: Amity.QueryPosts,
|
|
25
|
+
): Promise<Amity.Cached<Amity.Paged<Amity.Post, Amity.PageRaw>>> => {
|
|
35
26
|
const client = getActiveClient();
|
|
36
27
|
client.log('post/queryPosts', query);
|
|
37
28
|
|