@amityco/ts-sdk 6.26.3 → 6.27.1-061592b.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.env +26 -26
- package/dist/@types/core/model.d.ts +5 -5
- package/dist/@types/core/model.d.ts.map +1 -1
- package/dist/@types/core/payload.d.ts +1 -1
- package/dist/@types/core/payload.d.ts.map +1 -1
- package/dist/@types/domains/ad.d.ts +14 -2
- package/dist/@types/domains/ad.d.ts.map +1 -1
- package/dist/@types/domains/file.d.ts +6 -0
- package/dist/@types/domains/file.d.ts.map +1 -1
- package/dist/@types/domains/message.d.ts +4 -1
- package/dist/@types/domains/message.d.ts.map +1 -1
- package/dist/@types/domains/post.d.ts +3 -3
- package/dist/@types/domains/post.d.ts.map +1 -1
- package/dist/adRepository/api/getNetworkAds.d.ts.map +1 -1
- package/dist/analytic/service/analytic/AnalyticsEngine.d.ts +2 -2
- package/dist/analytic/service/analytic/AnalyticsEngine.d.ts.map +1 -1
- package/dist/analytic/service/analytic/AnalyticsEventCapturer.d.ts +11 -5
- package/dist/analytic/service/analytic/AnalyticsEventCapturer.d.ts.map +1 -1
- package/dist/client/api/getToken.d.ts +10 -5
- package/dist/client/api/getToken.d.ts.map +1 -1
- package/dist/client/api/index.d.ts +1 -0
- package/dist/client/api/index.d.ts.map +1 -1
- package/dist/client/api/login.d.ts.map +1 -1
- package/dist/client/api/logout.d.ts.map +1 -1
- package/dist/client/api/renewal.d.ts.map +1 -1
- package/dist/client/api/setUploadedFileAccessType.d.ts +2 -0
- package/dist/client/api/setUploadedFileAccessType.d.ts.map +1 -0
- package/dist/client/events/index.d.ts +1 -0
- package/dist/client/events/index.d.ts.map +1 -1
- package/dist/client/events/onNetworkActivities.d.ts +11 -0
- package/dist/client/events/onNetworkActivities.d.ts.map +1 -0
- package/dist/client/utils/GlobalFileAccessType.d.ts +10 -0
- package/dist/client/utils/GlobalFileAccessType.d.ts.map +1 -0
- package/dist/client/utils/NetworkActivitiesWatcher.d.ts +12 -0
- package/dist/client/utils/NetworkActivitiesWatcher.d.ts.map +1 -0
- package/dist/commentRepository/observers/getComments.d.ts +1 -1
- package/dist/commentRepository/observers/getComments.d.ts.map +1 -1
- package/dist/communityRepository/utils/payload.d.ts +7 -0
- package/dist/communityRepository/utils/payload.d.ts.map +1 -1
- package/dist/core/transports/http.d.ts.map +1 -1
- package/dist/fileRepository/api/createFile.d.ts.map +1 -1
- package/dist/fileRepository/api/createImage.d.ts.map +1 -1
- package/dist/fileRepository/api/createVideo.d.ts.map +1 -1
- package/dist/fileRepository/api/uploadFile.d.ts.map +1 -1
- package/dist/fileRepository/api/uploadImage.d.ts.map +1 -1
- package/dist/fileRepository/api/uploadVideo.d.ts.map +1 -1
- package/dist/index.cjs.js +898 -688
- package/dist/index.esm.js +729 -517
- package/dist/index.umd.js +4 -4
- package/dist/messageRepository/api/createMessage.d.ts +7 -25
- package/dist/messageRepository/api/createMessage.d.ts.map +1 -1
- package/dist/messageRepository/events/onMessageCreated.d.ts.map +1 -1
- package/dist/messageRepository/observers/getMessages/MessageLiveCollectionController.d.ts +4 -4
- package/dist/messageRepository/observers/getMessages/MessageLiveCollectionController.d.ts.map +1 -1
- package/dist/messageRepository/observers/getMessages/MessageQueryStreamController.d.ts.map +1 -1
- package/dist/messageRepository/utils/prepareMessagePayload.d.ts.map +1 -1
- package/dist/postRepository/api/editPost.d.ts +1 -1
- package/dist/postRepository/api/editPost.d.ts.map +1 -1
- package/dist/postRepository/api/updatePost.d.ts +1 -1
- package/dist/postRepository/api/updatePost.d.ts.map +1 -1
- package/dist/postRepository/internalApi/getPost.d.ts +5 -0
- package/dist/postRepository/internalApi/getPost.d.ts.map +1 -0
- package/dist/postRepository/internalApi/index.d.ts +13 -0
- package/dist/postRepository/internalApi/index.d.ts.map +1 -0
- package/dist/postRepository/observers/getPost.d.ts.map +1 -1
- package/dist/postRepository/observers/getPosts/PostLiveCollectionController.d.ts +14 -0
- package/dist/postRepository/observers/getPosts/PostLiveCollectionController.d.ts.map +1 -0
- package/dist/postRepository/observers/getPosts/PostPaginationController.d.ts +5 -0
- package/dist/postRepository/observers/getPosts/PostPaginationController.d.ts.map +1 -0
- package/dist/postRepository/observers/getPosts/PostQueryStreamController.d.ts +15 -0
- package/dist/postRepository/observers/getPosts/PostQueryStreamController.d.ts.map +1 -0
- package/dist/postRepository/observers/getPosts/enums.d.ts +12 -0
- package/dist/postRepository/observers/getPosts/enums.d.ts.map +1 -0
- package/dist/postRepository/observers/getPosts.d.ts.map +1 -1
- package/dist/postRepository/utils/payload.d.ts +2 -0
- package/dist/postRepository/utils/payload.d.ts.map +1 -0
- package/dist/utils/linkedObject/adLinkedObject.d.ts +1 -1
- package/dist/utils/linkedObject/adLinkedObject.d.ts.map +1 -1
- package/dist/utils/linkedObject/categoryLinkedObject.d.ts.map +1 -1
- package/dist/utils/linkedObject/index.d.ts +1 -1
- package/dist/utils/linkedObject/userLinkedObject.d.ts.map +1 -1
- package/dist/utils/tests/dummy/post.d.ts +3 -3
- package/package.json +1 -1
- package/src/@types/core/model.ts +5 -5
- package/src/@types/core/payload.ts +1 -1
- package/src/@types/domains/ad.ts +17 -6
- package/src/@types/domains/file.ts +8 -0
- package/src/@types/domains/message.ts +6 -1
- package/src/@types/domains/post.ts +3 -4
- package/src/adRepository/api/getNetworkAds.ts +22 -8
- package/src/analytic/service/analytic/AnalyticsEngine.ts +2 -2
- package/src/analytic/service/analytic/AnalyticsEventCapturer.ts +45 -27
- package/src/client/api/getToken.ts +15 -7
- package/src/client/api/index.ts +2 -0
- package/src/client/api/login.ts +11 -7
- package/src/client/api/logout.ts +4 -0
- package/src/client/api/renewal.ts +6 -1
- package/src/client/api/setUploadedFileAccessType.ts +5 -0
- package/src/client/api/tests/getToken.test.ts +3 -3
- package/src/client/events/index.ts +2 -0
- package/src/client/events/onNetworkActivities.ts +14 -0
- package/src/client/utils/GlobalFileAccessType.ts +23 -0
- package/src/client/utils/NetworkActivitiesWatcher.ts +31 -0
- package/src/commentRepository/observers/getComments.ts +1 -1
- package/src/communityRepository/utils/payload.ts +19 -3
- package/src/core/model/idResolvers.ts +1 -1
- package/src/core/transports/http.ts +25 -1
- package/src/fileRepository/api/createFile.ts +4 -0
- package/src/fileRepository/api/createImage.ts +4 -0
- package/src/fileRepository/api/createVideo.ts +4 -0
- package/src/fileRepository/api/uploadFile.ts +4 -0
- package/src/fileRepository/api/uploadImage.ts +4 -0
- package/src/fileRepository/api/uploadVideo.ts +4 -0
- package/src/messageRepository/api/createMessage.ts +83 -98
- package/src/messageRepository/events/onMessageCreated.ts +12 -6
- package/src/messageRepository/observers/getMessages/MessageLiveCollectionController.ts +26 -24
- package/src/messageRepository/observers/getMessages/MessageQueryStreamController.ts +3 -2
- package/src/messageRepository/observers/observeMessages.ts +3 -3
- package/src/messageRepository/utils/prepareMessagePayload.ts +1 -1
- package/src/postRepository/internalApi/getPost.ts +65 -0
- package/src/postRepository/internalApi/index.ts +16 -0
- package/src/postRepository/observers/getPost.ts +8 -1
- package/src/postRepository/observers/getPosts/PostLiveCollectionController.ts +190 -0
- package/src/postRepository/observers/getPosts/PostPaginationController.ts +45 -0
- package/src/postRepository/observers/getPosts/PostQueryStreamController.ts +102 -0
- package/src/postRepository/observers/getPosts/enums.ts +11 -0
- package/src/postRepository/observers/getPosts.ts +6 -197
- package/src/postRepository/utils/payload.ts +17 -0
- package/src/utils/linkedObject/adLinkedObject.ts +11 -11
- package/src/utils/linkedObject/categoryLinkedObject.ts +6 -28
- package/src/utils/linkedObject/userLinkedObject.ts +8 -27
|
@@ -3,10 +3,10 @@ import { fireEvent } from '~/core/events';
|
|
|
3
3
|
import { getActiveClient, getActiveUser } from '~/client/api';
|
|
4
4
|
import { ingestInCache } from '~/cache/api/ingestInCache';
|
|
5
5
|
import { UNSYNCED_OBJECT_CACHED_AT_VALUE } from '~/utils/constants';
|
|
6
|
-
import {
|
|
6
|
+
import { dropFromCache, pullFromCache, pushToCache, upsertInCache } from '~/cache/api';
|
|
7
7
|
|
|
8
|
-
import { convertParams, prepareMessagePayload } from '../utils';
|
|
9
8
|
import { LinkedObject } from '~/utils/linkedObject';
|
|
9
|
+
import { convertParams, prepareMessagePayload } from '../utils';
|
|
10
10
|
|
|
11
11
|
const getLocalId = () => `LOCAL_${uuid()}`;
|
|
12
12
|
|
|
@@ -16,109 +16,32 @@ let uniqueId: string | undefined;
|
|
|
16
16
|
/* begin_public_function
|
|
17
17
|
id: message.create.text_message, message.create.image_message, message.create.file_message, message.create.video_message, message.create.audio_message, message.create.custom_message
|
|
18
18
|
*/
|
|
19
|
-
/**
|
|
20
|
-
* ```js
|
|
21
|
-
* import { createMessage, createQuery, runQuery } from '@amityco/ts-sdk'
|
|
22
|
-
*
|
|
23
|
-
* const query = createQuery(createMessage, {
|
|
24
|
-
* subChannelId: 'foobar',
|
|
25
|
-
* data: { text: 'hello world' },
|
|
26
|
-
* });
|
|
27
|
-
*
|
|
28
|
-
* runQuery(query, ({ data: message, loading }) => {
|
|
29
|
-
* console.log(message);
|
|
30
|
-
* });
|
|
31
|
-
* ```
|
|
32
|
-
*
|
|
33
|
-
* Creates an {@link Amity.Message}
|
|
34
|
-
*
|
|
35
|
-
* @param bundle The data necessary to create a new {@link Amity.Message}
|
|
36
|
-
* @returns The newly created {@link Amity.Message}
|
|
37
|
-
*
|
|
38
|
-
* @category Message API
|
|
39
|
-
* @async
|
|
40
|
-
*/
|
|
41
|
-
export const createMessage = async <T extends Amity.MessageContentType>(
|
|
42
|
-
bundle: Pick<
|
|
43
|
-
Amity.Message<T>,
|
|
44
|
-
'subChannelId' | 'parentId' | 'dataType' | 'tags' | 'metadata' | 'mentionees'
|
|
45
|
-
> & {
|
|
46
|
-
data?: Amity.Message<T>['data'];
|
|
47
|
-
fileId?: Amity.File['fileId'];
|
|
48
|
-
// Custom referenceId is a workaround for the case:
|
|
49
|
-
// User wants to create an image message. He should
|
|
50
|
-
// - create and show dummy message in ui
|
|
51
|
-
// - upload image to get fileId, while uploading show a spinner in dummy message in ui
|
|
52
|
-
// - call createMessage and pass fileId
|
|
53
|
-
// - replace dummy message with the actual message received from backend
|
|
54
|
-
// Custom referenceId is needed to make relation between dummy message and actual message.
|
|
55
|
-
// TODO: passing file src into createMessage so that sdk uploads files itself,
|
|
56
|
-
// returns the dummy message bound with the file to eliminate the need to create
|
|
57
|
-
// the dummy message on the user side,
|
|
58
|
-
referenceId?: string;
|
|
59
|
-
},
|
|
60
|
-
): Promise<Amity.Cached<Amity.Message>> => {
|
|
61
|
-
const client = getActiveClient();
|
|
62
|
-
client.log('message/createMessage', bundle);
|
|
63
|
-
|
|
64
|
-
const referenceId = bundle.referenceId || uniqueId || getLocalId();
|
|
65
|
-
uniqueId = undefined;
|
|
66
|
-
|
|
67
|
-
const { data: payload } = await client.http.post<Amity.MessagePayload>('/api/v5/messages', {
|
|
68
|
-
...convertParams(bundle),
|
|
69
|
-
referenceId,
|
|
70
|
-
});
|
|
71
|
-
|
|
72
|
-
const data = await prepareMessagePayload(payload);
|
|
73
|
-
const { messages } = data;
|
|
74
|
-
|
|
75
|
-
const cachedAt = client.cache && Date.now();
|
|
76
|
-
if (client.cache) {
|
|
77
|
-
dropFromCache(['message', 'get', referenceId]);
|
|
78
|
-
ingestInCache(data, { cachedAt });
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
fireEvent('local.message.created', { messages });
|
|
82
19
|
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
20
|
+
type createMessageParam<T extends Amity.MessageContentType> = Pick<
|
|
21
|
+
Amity.Message<T>,
|
|
22
|
+
'subChannelId' | 'parentId' | 'dataType' | 'tags' | 'metadata' | 'mentionees'
|
|
23
|
+
> & {
|
|
24
|
+
data?: Amity.Message<T>['data'];
|
|
25
|
+
fileId?: Amity.File['fileId'];
|
|
26
|
+
referenceId?: string;
|
|
87
27
|
};
|
|
88
28
|
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
*
|
|
93
|
-
* const created = createMessage.optimistically({
|
|
94
|
-
* channelId: 'foobar',
|
|
95
|
-
* data: { text: 'hello world' }
|
|
96
|
-
* })
|
|
97
|
-
* ```
|
|
98
|
-
*
|
|
99
|
-
* Creates an {@link Amity.Message} in cache
|
|
100
|
-
*
|
|
101
|
-
* @param bundle The data necessary to create a new {@link Amity.Message}
|
|
102
|
-
* @returns The newly created {@link Amity.Message}
|
|
103
|
-
*
|
|
104
|
-
* @category Message API
|
|
105
|
-
*/
|
|
106
|
-
createMessage.optimistically = ({
|
|
107
|
-
referenceId,
|
|
108
|
-
...bundle
|
|
109
|
-
}: Parameters<typeof createMessage>[0]): Amity.Cached<Amity.Message> | undefined => {
|
|
29
|
+
const createMessageOptimistic = <T extends Amity.MessageContentType>(
|
|
30
|
+
bundle: createMessageParam<T>,
|
|
31
|
+
): Amity.InternalMessage | undefined => {
|
|
110
32
|
const client = getActiveClient();
|
|
111
33
|
|
|
112
34
|
if (!client.cache) return;
|
|
113
35
|
|
|
114
36
|
/*
|
|
115
|
-
*
|
|
116
|
-
* client, created a new variable
|
|
37
|
+
* When creating messages optimistically a messageId needs to be added by the
|
|
38
|
+
* client, created a new variable to allow backward compatibility of API
|
|
117
39
|
*
|
|
118
40
|
* Updated to handle client requirement to add messageId while uploading
|
|
119
|
-
* message with image.
|
|
41
|
+
* a message with image.
|
|
42
|
+
* Temporary!
|
|
120
43
|
*/
|
|
121
|
-
uniqueId = referenceId || getLocalId();
|
|
44
|
+
uniqueId = bundle.referenceId || getLocalId();
|
|
122
45
|
const bundleWithMessageId = { messageId: uniqueId, uniqueId, ...bundle };
|
|
123
46
|
|
|
124
47
|
client.log('message/createMessage.optimistically', bundleWithMessageId);
|
|
@@ -153,6 +76,8 @@ createMessage.optimistically = ({
|
|
|
153
76
|
childrenNumber: 0,
|
|
154
77
|
createdAt: createdTime,
|
|
155
78
|
updatedAt: createdTime,
|
|
79
|
+
syncState: Amity.SyncState.Syncing,
|
|
80
|
+
isDeleted: false,
|
|
156
81
|
...bundleWithMessageId,
|
|
157
82
|
} as Amity.InternalMessage;
|
|
158
83
|
|
|
@@ -161,9 +86,69 @@ createMessage.optimistically = ({
|
|
|
161
86
|
pushToCache(['message', 'get', message.messageId], message, { cachedAt });
|
|
162
87
|
fireEvent('local.message.created', { messages: [message] });
|
|
163
88
|
|
|
164
|
-
return
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
89
|
+
return message;
|
|
90
|
+
};
|
|
91
|
+
/**
|
|
92
|
+
* ```js
|
|
93
|
+
* import { createMessage, createQuery, runQuery } from '@amityco/ts-sdk'
|
|
94
|
+
*
|
|
95
|
+
* const query = createQuery(createMessage, {
|
|
96
|
+
* subChannelId: 'foobar',
|
|
97
|
+
* data: { text: 'hello world' },
|
|
98
|
+
* });
|
|
99
|
+
*
|
|
100
|
+
* runQuery(query, ({ data: message, loading }) => {
|
|
101
|
+
* console.log(message);
|
|
102
|
+
* });
|
|
103
|
+
* ```
|
|
104
|
+
*
|
|
105
|
+
* Creates an {@link Amity.Message}
|
|
106
|
+
*
|
|
107
|
+
* @param bundle The data necessary to create a new {@link Amity.Message}
|
|
108
|
+
* @returns The newly created {@link Amity.Message}
|
|
109
|
+
*
|
|
110
|
+
* @category Message API
|
|
111
|
+
* @async
|
|
112
|
+
*/
|
|
113
|
+
export const createMessage = async <T extends Amity.MessageContentType>(
|
|
114
|
+
bundle: createMessageParam<T>,
|
|
115
|
+
): Promise<Amity.Cached<Amity.Message>> => {
|
|
116
|
+
const client = getActiveClient();
|
|
117
|
+
client.log('message/createMessage', bundle);
|
|
118
|
+
|
|
119
|
+
const optimisticData = createMessageOptimistic<T>(bundle);
|
|
120
|
+
|
|
121
|
+
const referenceId = bundle.referenceId || uniqueId || getLocalId();
|
|
122
|
+
uniqueId = undefined;
|
|
123
|
+
|
|
124
|
+
try {
|
|
125
|
+
const { data: payload } = await client.http.post<Amity.MessagePayload>('/api/v5/messages', {
|
|
126
|
+
...convertParams(bundle),
|
|
127
|
+
referenceId,
|
|
128
|
+
});
|
|
129
|
+
|
|
130
|
+
const data = await prepareMessagePayload(payload);
|
|
131
|
+
const { messages } = data;
|
|
132
|
+
|
|
133
|
+
const cachedAt = client.cache && Date.now();
|
|
134
|
+
if (client.cache) {
|
|
135
|
+
ingestInCache(data, { cachedAt });
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
fireEvent('local.message.created', {
|
|
139
|
+
messages: [{ ...messages[0], syncState: Amity.SyncState.Synced }],
|
|
140
|
+
});
|
|
141
|
+
|
|
142
|
+
return {
|
|
143
|
+
data: LinkedObject.message(messages[0]),
|
|
144
|
+
cachedAt,
|
|
145
|
+
};
|
|
146
|
+
} catch (e) {
|
|
147
|
+
fireEvent('local.message.created', {
|
|
148
|
+
messages: [{ ...optimisticData, syncState: Amity.SyncState.Error } as Amity.InternalMessage],
|
|
149
|
+
});
|
|
150
|
+
|
|
151
|
+
throw e;
|
|
152
|
+
}
|
|
168
153
|
};
|
|
169
154
|
/* end_public_function */
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { getActiveClient } from '~/client/api/activeClient';
|
|
2
2
|
import { createEventSubscriber } from '~/core/events';
|
|
3
3
|
import { ingestInCache } from '~/cache/api/ingestInCache';
|
|
4
|
-
import { prepareMessagePayload } from '../utils';
|
|
5
4
|
import { updateSubChannelUnreadFromMessage } from '~/marker/utils/updateSubChannelUnreadFromMessage';
|
|
6
5
|
import { reCalculateChannelUnreadInfo } from '~/marker/utils/reCalculateChannelUnreadInfo';
|
|
7
|
-
import { markReadMessage } from '../utils/markReadMessage';
|
|
8
6
|
import { getActiveUser } from '~/client/api/activeUser';
|
|
7
|
+
import { markReadMessage } from '../utils/markReadMessage';
|
|
8
|
+
import { prepareMessagePayload } from '../utils';
|
|
9
9
|
|
|
10
10
|
/**
|
|
11
11
|
* ```js
|
|
@@ -64,10 +64,16 @@ export const onMessageCreatedLocal = (
|
|
|
64
64
|
const client = getActiveClient();
|
|
65
65
|
|
|
66
66
|
const disposers = [
|
|
67
|
-
createEventSubscriber(
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
67
|
+
createEventSubscriber(
|
|
68
|
+
client,
|
|
69
|
+
'message/onMessageCreated',
|
|
70
|
+
'local.message.created',
|
|
71
|
+
async payload => {
|
|
72
|
+
ingestInCache(payload);
|
|
73
|
+
return payload.messages.forEach(message => {
|
|
74
|
+
callback(message);
|
|
75
|
+
});
|
|
76
|
+
},
|
|
71
77
|
),
|
|
72
78
|
];
|
|
73
79
|
|
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
import hash from 'object-hash';
|
|
2
2
|
import { pullFromCache, pushToCache } from '~/cache/api';
|
|
3
|
-
import { MessagePaginationController } from './MessagePaginationController';
|
|
4
|
-
import { MessageQueryStreamController } from './MessageQueryStreamController';
|
|
5
3
|
import {
|
|
4
|
+
onMessageCreatedLocal,
|
|
6
5
|
onMessageCreatedMqtt,
|
|
7
6
|
onMessageDeleted,
|
|
8
7
|
onMessageFlagCleared,
|
|
@@ -18,6 +17,8 @@ import { onMessageMarked, onMessageMarkerFetched } from '~/marker/events';
|
|
|
18
17
|
import { filterByPropEquality } from '~/core/query';
|
|
19
18
|
import { prepareMessagePayload } from '~/messageRepository/utils';
|
|
20
19
|
import { LinkedObject } from '~/utils/linkedObject';
|
|
20
|
+
import { MessageQueryStreamController } from './MessageQueryStreamController';
|
|
21
|
+
import { MessagePaginationController } from './MessagePaginationController';
|
|
21
22
|
|
|
22
23
|
export class MessageLiveCollectionController extends LiveCollectionController<
|
|
23
24
|
'message',
|
|
@@ -52,31 +53,10 @@ export class MessageLiveCollectionController extends LiveCollectionController<
|
|
|
52
53
|
this.loadPage({ initial: true });
|
|
53
54
|
}
|
|
54
55
|
|
|
55
|
-
protected setup() {
|
|
56
|
-
const collection = pullFromCache<Amity.MessageLiveCollectionCache>(this.cacheKey)?.data;
|
|
57
|
-
if (!collection) {
|
|
58
|
-
pushToCache(this.cacheKey, {
|
|
59
|
-
data: [],
|
|
60
|
-
query: this.query,
|
|
61
|
-
});
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
protected async persistModel(response: Amity.MessagePayload & Amity.Pagination) {
|
|
66
|
-
await this.queryStreamController.saveToMainDB(response);
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
protected persistQueryStream({
|
|
70
|
-
response,
|
|
71
|
-
direction,
|
|
72
|
-
refresh,
|
|
73
|
-
}: Amity.LiveCollectionPersistQueryStreamParams<'message'>) {
|
|
74
|
-
this.queryStreamController.appendToQueryStream(response, direction, refresh);
|
|
75
|
-
}
|
|
76
|
-
|
|
77
56
|
startSubscription() {
|
|
78
57
|
return this.queryStreamController.subscribeRTE([
|
|
79
58
|
{ fn: onMessageCreatedMqtt, action: 'onCreate' },
|
|
59
|
+
{ fn: onMessageCreatedLocal, action: 'onCreate' },
|
|
80
60
|
{ fn: onMessageDeleted, action: 'onDelete' },
|
|
81
61
|
{ fn: onMessageUpdated, action: 'onUpdate' },
|
|
82
62
|
{ fn: onMessageFlagged, action: 'onFlagged' },
|
|
@@ -160,4 +140,26 @@ export class MessageLiveCollectionController extends LiveCollectionController<
|
|
|
160
140
|
|
|
161
141
|
return messages;
|
|
162
142
|
}
|
|
143
|
+
|
|
144
|
+
protected setup() {
|
|
145
|
+
const collection = pullFromCache<Amity.MessageLiveCollectionCache>(this.cacheKey)?.data;
|
|
146
|
+
if (!collection) {
|
|
147
|
+
pushToCache(this.cacheKey, {
|
|
148
|
+
data: [],
|
|
149
|
+
query: this.query,
|
|
150
|
+
});
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
protected async persistModel(response: Amity.MessagePayload & Amity.Pagination) {
|
|
155
|
+
await this.queryStreamController.saveToMainDB(response);
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
protected persistQueryStream({
|
|
159
|
+
response,
|
|
160
|
+
direction,
|
|
161
|
+
refresh,
|
|
162
|
+
}: Amity.LiveCollectionPersistQueryStreamParams<'message'>) {
|
|
163
|
+
this.queryStreamController.appendToQueryStream(response, direction, refresh);
|
|
164
|
+
}
|
|
163
165
|
}
|
|
@@ -72,6 +72,7 @@ export class MessageQueryStreamController extends QueryStreamController<
|
|
|
72
72
|
return (payload: Amity.InternalMessage) => {
|
|
73
73
|
if (action === 'onCreate') {
|
|
74
74
|
const collection = pullFromCache<Amity.MessageLiveCollectionCache>(this.cacheKey)?.data;
|
|
75
|
+
const { referenceId } = payload;
|
|
75
76
|
|
|
76
77
|
if (!collection) return;
|
|
77
78
|
if (this.query.subChannelId !== payload?.subChannelId || !collection) return;
|
|
@@ -115,11 +116,11 @@ export class MessageQueryStreamController extends QueryStreamController<
|
|
|
115
116
|
(!this.query.sortBy || this.query.sortBy === 'segmentDesc') &&
|
|
116
117
|
!this.paginationController.getPrevToken()
|
|
117
118
|
) {
|
|
118
|
-
collection.data = [...new Set([payload.messageId, ...collection.data])];
|
|
119
|
+
collection.data = [...new Set([referenceId ?? payload.messageId, ...collection.data])];
|
|
119
120
|
}
|
|
120
121
|
|
|
121
122
|
if (this.query.sortBy === 'segmentAsc' && !this.paginationController.getNextToken()) {
|
|
122
|
-
collection.data = [...new Set([...collection.data, payload.messageId])];
|
|
123
|
+
collection.data = [...new Set([...collection.data, referenceId ?? payload.messageId])];
|
|
123
124
|
}
|
|
124
125
|
|
|
125
126
|
pushToCache(this.cacheKey, collection);
|
|
@@ -2,13 +2,13 @@ import { getActiveClient } from '~/client/api';
|
|
|
2
2
|
import { onMessageMarked, onMessageMarkerFetched } from '~/marker/events';
|
|
3
3
|
import { convertEventPayload } from '~/utils/event';
|
|
4
4
|
|
|
5
|
+
import { LinkedObject } from '~/utils/linkedObject';
|
|
5
6
|
import {
|
|
7
|
+
onMessageCreatedLocal,
|
|
6
8
|
onMessageCreatedMqtt,
|
|
7
|
-
onMessageUpdated,
|
|
8
9
|
onMessageDeleted,
|
|
9
|
-
|
|
10
|
+
onMessageUpdated,
|
|
10
11
|
} from '../events';
|
|
11
|
-
import { LinkedObject } from '~/utils/linkedObject';
|
|
12
12
|
|
|
13
13
|
/**
|
|
14
14
|
* ```js
|
|
@@ -8,7 +8,6 @@ import { MessageContentType } from '~/@types';
|
|
|
8
8
|
import { convertFromRaw as convertSubChannelFromRaw } from '~/subChannelRepository/utils/convertSubChannelFromRaw';
|
|
9
9
|
import { updateSubChannelCache } from '~/subChannelRepository/utils/updateSubChannelCache';
|
|
10
10
|
import { COLLECTION_DEFAULT_PAGINATION_LIMIT } from '~/utils/constants';
|
|
11
|
-
import { getMessageReadCount } from './getMessageReadCount';
|
|
12
11
|
|
|
13
12
|
export function convertFromRaw(
|
|
14
13
|
message: Amity.RawMessage,
|
|
@@ -62,6 +61,7 @@ export function convertFromRaw(
|
|
|
62
61
|
subChannelId: messageFeedId,
|
|
63
62
|
uniqueId: cache ? cache.data.uniqueId : messageId,
|
|
64
63
|
referenceId,
|
|
64
|
+
syncState: Amity.SyncState.Synced,
|
|
65
65
|
};
|
|
66
66
|
|
|
67
67
|
if (mentionedUsers) {
|
|
@@ -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';
|
|
@@ -42,7 +42,14 @@ export const getPost = (
|
|
|
42
42
|
postId: Amity.Post['postId'],
|
|
43
43
|
callback: Amity.LiveObjectCallback<Amity.Post>,
|
|
44
44
|
): Amity.Unsubscriber => {
|
|
45
|
-
|
|
45
|
+
const responder: Amity.LiveObjectCallback<Amity.InternalPost> = (
|
|
46
|
+
snapshot: Amity.LiveObject<Amity.InternalPost>,
|
|
47
|
+
) => {
|
|
48
|
+
const { data } = snapshot;
|
|
49
|
+
callback({ ...snapshot, data: data ? LinkedObject.post(snapshot.data) : data });
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
return liveObject(postId, responder, 'postId', _getPost, [
|
|
46
53
|
onPostApproved,
|
|
47
54
|
onPostDeclined,
|
|
48
55
|
(callback: Amity.Listener<Amity.InternalPost>) => {
|
|
@@ -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
|
+
}
|