@amityco/ts-sdk 7.1.1-e887d15f.0 → 7.2.1-3663404.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/dist/@types/core/events.d.ts +4 -0
- package/dist/@types/core/events.d.ts.map +1 -1
- package/dist/@types/core/model.d.ts +4 -0
- package/dist/@types/core/model.d.ts.map +1 -1
- package/dist/@types/core/payload.d.ts +45 -1
- package/dist/@types/core/payload.d.ts.map +1 -1
- package/dist/@types/domains/channel.d.ts +2 -2
- package/dist/@types/domains/channel.d.ts.map +1 -1
- package/dist/@types/domains/client.d.ts +1 -0
- package/dist/@types/domains/client.d.ts.map +1 -1
- package/dist/@types/domains/file.d.ts +1 -20
- package/dist/@types/domains/file.d.ts.map +1 -1
- package/dist/@types/domains/notification.d.ts +78 -0
- package/dist/@types/domains/notification.d.ts.map +1 -0
- package/dist/@types/domains/post.d.ts +4 -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/channelRepository/events/onChannelDeleted.d.ts.map +1 -1
- package/dist/channelRepository/internalApi/getTotalChannelsUnread.d.ts +11 -0
- package/dist/channelRepository/internalApi/getTotalChannelsUnread.d.ts.map +1 -0
- package/dist/channelRepository/observers/getTotalChannelsUnread.d.ts +20 -0
- package/dist/channelRepository/observers/getTotalChannelsUnread.d.ts.map +1 -0
- package/dist/channelRepository/observers/index.d.ts +1 -0
- package/dist/channelRepository/observers/index.d.ts.map +1 -1
- package/dist/channelRepository/utils/prepareChannelPayload.d.ts.map +1 -1
- package/dist/client/api/createClient.d.ts +1 -0
- package/dist/client/api/createClient.d.ts.map +1 -1
- package/dist/client/utils/ReadReceiptSync/readReceiptSyncEngine.d.ts.map +1 -1
- package/dist/client/utils/endpoints.d.ts +1 -0
- package/dist/client/utils/endpoints.d.ts.map +1 -1
- package/dist/client/utils/setClientToken.d.ts.map +1 -1
- package/dist/commentRepository/events/utils.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/model/idResolvers.d.ts.map +1 -1
- package/dist/core/model/index.d.ts.map +1 -1
- package/dist/fileRepository/api/index.d.ts +1 -0
- package/dist/fileRepository/api/index.d.ts.map +1 -1
- package/dist/fileRepository/api/updateAltText.d.ts +17 -0
- package/dist/fileRepository/api/updateAltText.d.ts.map +1 -0
- package/dist/fileRepository/api/uploadImage.d.ts +2 -1
- package/dist/fileRepository/api/uploadImage.d.ts.map +1 -1
- package/dist/index.cjs.js +748 -73
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.esm.js +731 -57
- package/dist/index.umd.js +4 -4
- package/dist/messageRepository/events/onMessageCreated.d.ts.map +1 -1
- package/dist/messageRepository/observers/getMessage.d.ts.map +1 -1
- package/dist/notificationTray/api/index.d.ts +3 -0
- package/dist/notificationTray/api/index.d.ts.map +1 -0
- package/dist/notificationTray/api/markItemsSeen.d.ts +16 -0
- package/dist/notificationTray/api/markItemsSeen.d.ts.map +1 -0
- package/dist/notificationTray/api/markTraySeen.d.ts +19 -0
- package/dist/notificationTray/api/markTraySeen.d.ts.map +1 -0
- package/dist/notificationTray/events/index.d.ts +2 -0
- package/dist/notificationTray/events/index.d.ts.map +1 -0
- package/dist/notificationTray/events/onNotificationTraySeenUpdated.d.ts +17 -0
- package/dist/notificationTray/events/onNotificationTraySeenUpdated.d.ts.map +1 -0
- package/dist/notificationTray/index.d.ts +4 -0
- package/dist/notificationTray/index.d.ts.map +1 -0
- package/dist/notificationTray/internalApi/getNotificationTraySeen.d.ts +30 -0
- package/dist/notificationTray/internalApi/getNotificationTraySeen.d.ts.map +1 -0
- package/dist/notificationTray/observers/getNotificationTrayItems/NotificationTrayItemsLiveCollectionController.d.ts +13 -0
- package/dist/notificationTray/observers/getNotificationTrayItems/NotificationTrayItemsLiveCollectionController.d.ts.map +1 -0
- package/dist/notificationTray/observers/getNotificationTrayItems/NotificationTrayItemsPaginationController.d.ts +9 -0
- package/dist/notificationTray/observers/getNotificationTrayItems/NotificationTrayItemsPaginationController.d.ts.map +1 -0
- package/dist/notificationTray/observers/getNotificationTrayItems/NotificationTrayItemsQuerystreamController.d.ts +9 -0
- package/dist/notificationTray/observers/getNotificationTrayItems/NotificationTrayItemsQuerystreamController.d.ts.map +1 -0
- package/dist/notificationTray/observers/getNotificationTrayItems.d.ts +12 -0
- package/dist/notificationTray/observers/getNotificationTrayItems.d.ts.map +1 -0
- package/dist/notificationTray/observers/getNotificationTraySeen.d.ts +20 -0
- package/dist/notificationTray/observers/getNotificationTraySeen.d.ts.map +1 -0
- package/dist/notificationTray/observers/index.d.ts +3 -0
- package/dist/notificationTray/observers/index.d.ts.map +1 -0
- package/dist/notificationTray/utils/prepareNotificationTrayItemsPayload.d.ts +2 -0
- package/dist/notificationTray/utils/prepareNotificationTrayItemsPayload.d.ts.map +1 -0
- package/dist/utils/linkedObject/index.d.ts +1 -0
- package/dist/utils/linkedObject/index.d.ts.map +1 -1
- package/dist/utils/linkedObject/notificationTrayLinkedObject.d.ts +2 -0
- package/dist/utils/linkedObject/notificationTrayLinkedObject.d.ts.map +1 -0
- package/dist/utils/linkedObject/postLinkedObject.d.ts.map +1 -1
- package/dist/utils/postTypePredicate.d.ts +4 -0
- package/dist/utils/postTypePredicate.d.ts.map +1 -0
- package/package.json +1 -1
- package/src/@types/core/events.ts +5 -0
- package/src/@types/core/model.ts +6 -0
- package/src/@types/core/payload.ts +52 -1
- package/src/@types/domains/channel.ts +2 -2
- package/src/@types/domains/client.ts +1 -0
- package/src/@types/domains/file.ts +1 -21
- package/src/@types/domains/notification.ts +94 -0
- package/src/@types/domains/post.ts +4 -0
- package/src/@types/index.ts +1 -0
- package/src/channelRepository/events/onChannelDeleted.ts +9 -2
- package/src/channelRepository/internalApi/getTotalChannelsUnread.ts +38 -0
- package/src/channelRepository/observers/getTotalChannelsUnread.ts +129 -0
- package/src/channelRepository/observers/index.ts +1 -0
- package/src/channelRepository/utils/prepareChannelPayload.ts +21 -10
- package/src/client/api/createClient.ts +4 -1
- package/src/client/utils/ReadReceiptSync/readReceiptSyncEngine.ts +5 -1
- package/src/client/utils/endpoints.ts +1 -0
- package/src/client/utils/setClientToken.ts +8 -0
- package/src/commentRepository/events/utils.ts +73 -0
- package/src/core/model/idResolvers.ts +3 -0
- package/src/core/model/index.ts +2 -0
- package/src/fileRepository/api/index.ts +1 -0
- package/src/fileRepository/api/updateAltText.ts +39 -0
- package/src/fileRepository/api/uploadFile.ts +1 -1
- package/src/fileRepository/api/uploadImage.ts +23 -4
- package/src/fileRepository/api/uploadVideo.ts +1 -1
- package/src/index.ts +2 -0
- package/src/messageRepository/events/onMessageCreated.ts +19 -9
- package/src/messageRepository/observers/getMessage.ts +0 -1
- package/src/notificationTray/api/index.ts +2 -0
- package/src/notificationTray/api/markItemsSeen.ts +62 -0
- package/src/notificationTray/api/markTraySeen.ts +65 -0
- package/src/notificationTray/events/index.ts +1 -0
- package/src/notificationTray/events/onNotificationTraySeenUpdated.ts +36 -0
- package/src/notificationTray/index.ts +3 -0
- package/src/notificationTray/internalApi/getNotificationTraySeen.ts +80 -0
- package/src/notificationTray/observers/getNotificationTrayItems/NotificationTrayItemsLiveCollectionController.ts +96 -0
- package/src/notificationTray/observers/getNotificationTrayItems/NotificationTrayItemsPaginationController.ts +31 -0
- package/src/notificationTray/observers/getNotificationTrayItems/NotificationTrayItemsQuerystreamController.ts +68 -0
- package/src/notificationTray/observers/getNotificationTrayItems.ts +44 -0
- package/src/notificationTray/observers/getNotificationTraySeen.ts +60 -0
- package/src/notificationTray/observers/index.ts +2 -0
- package/src/notificationTray/utils/prepareNotificationTrayItemsPayload.ts +12 -0
- package/src/utils/linkedObject/index.ts +2 -0
- package/src/utils/linkedObject/notificationTrayLinkedObject.ts +19 -0
- package/src/utils/linkedObject/postLinkedObject.ts +29 -0
- package/src/utils/postTypePredicate.ts +27 -0
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
import { getActiveUser } from '~/client/api/activeUser';
|
|
2
|
+
import { getTotalChannelsUnread as _getTotalChannelsUnread } from '../internalApi/getTotalChannelsUnread';
|
|
3
|
+
import { onChannelUnreadUpdatedLocal } from '../events/onChannelUnreadUpdatedLocal';
|
|
4
|
+
import { ASCApiError, ASCError } from '~/core/errors';
|
|
5
|
+
import { getActiveClient } from '~/client';
|
|
6
|
+
import { convertGetterPropsToStatic } from '~/utils/object';
|
|
7
|
+
import { createQuery, runQuery } from '~/core/query';
|
|
8
|
+
import {
|
|
9
|
+
UNSYNCED_OBJECT_CACHED_AT_MESSAGE,
|
|
10
|
+
UNSYNCED_OBJECT_CACHED_AT_VALUE,
|
|
11
|
+
} from '~/utils/constants';
|
|
12
|
+
import { isEqual } from '~/utils/isEqual';
|
|
13
|
+
|
|
14
|
+
/* begin_public_function
|
|
15
|
+
id: totalChannelsUnread.get
|
|
16
|
+
*/
|
|
17
|
+
/**
|
|
18
|
+
* ```js
|
|
19
|
+
* import { ChannelRepository } from '@amityco/ts-sdk';
|
|
20
|
+
*
|
|
21
|
+
* let totalChannelsUnread;
|
|
22
|
+
*
|
|
23
|
+
* const unsubscribe = ChannelRepository.getTotalChannelsUnread(response => {
|
|
24
|
+
* unread = response.data;
|
|
25
|
+
* });
|
|
26
|
+
* ```
|
|
27
|
+
*
|
|
28
|
+
* Observe all mutation on a given {@link Amity.UserUnread}
|
|
29
|
+
*
|
|
30
|
+
* @returns An {@link Amity.UserUnread} function to run when willing to stop observing the message
|
|
31
|
+
*
|
|
32
|
+
* @category User Unread Live Object
|
|
33
|
+
*
|
|
34
|
+
*/
|
|
35
|
+
|
|
36
|
+
export const getTotalChannelsUnread = (
|
|
37
|
+
callback: Amity.LiveObjectCallback<Amity.UserUnread | undefined>,
|
|
38
|
+
): Amity.Unsubscriber => {
|
|
39
|
+
const { _id: userId } = getActiveUser();
|
|
40
|
+
|
|
41
|
+
if (!userId)
|
|
42
|
+
throw new ASCError(
|
|
43
|
+
'The _id has not been defined in ActiveUser',
|
|
44
|
+
Amity.ClientError.UNKNOWN_ERROR,
|
|
45
|
+
Amity.ErrorLevel.ERROR,
|
|
46
|
+
);
|
|
47
|
+
|
|
48
|
+
const { log, cache } = getActiveClient();
|
|
49
|
+
|
|
50
|
+
if (!cache) {
|
|
51
|
+
console.log('For using Live Object feature you need to enable Cache!');
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
const timestamp = Date.now();
|
|
55
|
+
log(`liveTotalChannelsUnread(tmpid: ${timestamp}) > listen`);
|
|
56
|
+
|
|
57
|
+
const disposers: Amity.Unsubscriber[] = [];
|
|
58
|
+
|
|
59
|
+
let isUnsyncedModel = false; // for messages
|
|
60
|
+
|
|
61
|
+
let model: Amity.UserUnread | undefined;
|
|
62
|
+
|
|
63
|
+
const dispatcher = (data: Amity.LiveObject<Amity.UserUnread | undefined>) => {
|
|
64
|
+
const { data: userUnread } = data;
|
|
65
|
+
|
|
66
|
+
const callbackModel = userUnread
|
|
67
|
+
? {
|
|
68
|
+
unreadCount: userUnread.unreadCount,
|
|
69
|
+
isMentioned: userUnread.isMentioned,
|
|
70
|
+
}
|
|
71
|
+
: undefined;
|
|
72
|
+
|
|
73
|
+
model = callbackModel ? convertGetterPropsToStatic(callbackModel) : callbackModel;
|
|
74
|
+
|
|
75
|
+
callback({
|
|
76
|
+
data: callbackModel
|
|
77
|
+
? { ...callbackModel, isMentioned: callbackModel.isMentioned }
|
|
78
|
+
: callbackModel,
|
|
79
|
+
|
|
80
|
+
loading: data.loading,
|
|
81
|
+
error: data.error,
|
|
82
|
+
});
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
const realtimeRouter = (userUnread: Amity.UserUnread) => {
|
|
86
|
+
if (isEqual(model, userUnread)) return;
|
|
87
|
+
|
|
88
|
+
dispatcher({
|
|
89
|
+
loading: false,
|
|
90
|
+
data: userUnread,
|
|
91
|
+
});
|
|
92
|
+
};
|
|
93
|
+
|
|
94
|
+
const onFetch = () => {
|
|
95
|
+
const query = createQuery(async () => _getTotalChannelsUnread());
|
|
96
|
+
|
|
97
|
+
runQuery(query, ({ error, data, loading, origin, cachedAt }) => {
|
|
98
|
+
if (cachedAt === UNSYNCED_OBJECT_CACHED_AT_VALUE) {
|
|
99
|
+
dispatcher({
|
|
100
|
+
data,
|
|
101
|
+
origin,
|
|
102
|
+
loading: false,
|
|
103
|
+
error: new ASCApiError(
|
|
104
|
+
UNSYNCED_OBJECT_CACHED_AT_MESSAGE,
|
|
105
|
+
Amity.ClientError.DISALOOW_UNSYNCED_OBJECT,
|
|
106
|
+
Amity.ErrorLevel.ERROR,
|
|
107
|
+
),
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
isUnsyncedModel = true;
|
|
111
|
+
disposers.forEach(fn => fn());
|
|
112
|
+
} else if (!isUnsyncedModel) {
|
|
113
|
+
dispatcher({ loading, data, origin, error });
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
if (error) {
|
|
117
|
+
disposers.forEach(fn => fn());
|
|
118
|
+
}
|
|
119
|
+
});
|
|
120
|
+
};
|
|
121
|
+
|
|
122
|
+
disposers.push(onChannelUnreadUpdatedLocal(realtimeRouter));
|
|
123
|
+
|
|
124
|
+
onFetch();
|
|
125
|
+
|
|
126
|
+
return () => {
|
|
127
|
+
disposers.forEach(fn => fn());
|
|
128
|
+
};
|
|
129
|
+
};
|
|
@@ -58,23 +58,34 @@ const updateChannelUnread = ({
|
|
|
58
58
|
}) => {
|
|
59
59
|
for (let i = 0; i < channels.length; i += 1) {
|
|
60
60
|
const cacheKey = ['channelUnread', 'get', channels[i].channelId];
|
|
61
|
-
const
|
|
61
|
+
const channelUser = channelUsers.find(
|
|
62
62
|
channelUser =>
|
|
63
63
|
channelUser.channelId === channels[i].channelId && channelUser.userId === currentUserId,
|
|
64
|
-
)
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
64
|
+
);
|
|
65
|
+
|
|
66
|
+
let unreadCount = 0;
|
|
67
|
+
let readToSegment = null;
|
|
68
|
+
let lastMentionedSegment = null;
|
|
69
|
+
let isMentioned = false;
|
|
70
|
+
|
|
71
|
+
if (channelUser) {
|
|
72
|
+
readToSegment = channelUser.readToSegment;
|
|
73
|
+
lastMentionedSegment = channelUser.lastMentionedSegment;
|
|
74
|
+
unreadCount = Math.max(channels[i].messageCount - readToSegment, 0);
|
|
75
|
+
isMentioned = lastMentionedSegment > readToSegment;
|
|
76
|
+
}
|
|
68
77
|
|
|
69
|
-
|
|
78
|
+
const cacheChannelUnread: Amity.ChannelUnread = {
|
|
70
79
|
channelId: channels[i].channelId,
|
|
71
80
|
lastSegment: channels[i].messageCount,
|
|
72
81
|
readToSegment,
|
|
73
82
|
lastMentionedSegment,
|
|
74
|
-
unreadCount
|
|
75
|
-
isMentioned
|
|
76
|
-
isDeleted: channels[i].isDeleted,
|
|
77
|
-
}
|
|
83
|
+
unreadCount,
|
|
84
|
+
isMentioned,
|
|
85
|
+
isDeleted: channels[i].isDeleted || false,
|
|
86
|
+
};
|
|
87
|
+
|
|
88
|
+
pushToCache(cacheKey, cacheChannelUnread);
|
|
78
89
|
}
|
|
79
90
|
};
|
|
80
91
|
|
|
@@ -50,7 +50,7 @@ export const createClient = (
|
|
|
50
50
|
rteEnabled = true,
|
|
51
51
|
}: {
|
|
52
52
|
debugSession?: string;
|
|
53
|
-
apiEndpoint?: { http?: string; mqtt?: string };
|
|
53
|
+
apiEndpoint?: { http?: string; mqtt?: string; upload?: string };
|
|
54
54
|
prefixDeviceIdKey?: string;
|
|
55
55
|
rteEnabled?: boolean;
|
|
56
56
|
} = {},
|
|
@@ -63,9 +63,11 @@ export const createClient = (
|
|
|
63
63
|
});
|
|
64
64
|
|
|
65
65
|
const httpEndpoint = apiEndpoint?.http ?? computeUrl('http', apiRegion);
|
|
66
|
+
const uploadEndpoint = apiEndpoint?.upload ?? computeUrl('upload', apiRegion);
|
|
66
67
|
const mqttEndpoint = apiEndpoint?.mqtt ?? computeUrl('mqtt', apiRegion);
|
|
67
68
|
|
|
68
69
|
const http = createHttpTransport(httpEndpoint);
|
|
70
|
+
const upload = createHttpTransport(uploadEndpoint);
|
|
69
71
|
|
|
70
72
|
let ws;
|
|
71
73
|
let mqtt;
|
|
@@ -105,6 +107,7 @@ export const createClient = (
|
|
|
105
107
|
http,
|
|
106
108
|
ws,
|
|
107
109
|
mqtt,
|
|
110
|
+
upload,
|
|
108
111
|
emitter,
|
|
109
112
|
|
|
110
113
|
/*
|
|
@@ -158,7 +158,11 @@ export class MessageReadReceiptSyncEngine {
|
|
|
158
158
|
const cacheKey = ['channelUnread', 'get', channelId];
|
|
159
159
|
const channelUnread = pullFromCache<Amity.ChannelUnread>(cacheKey)?.data;
|
|
160
160
|
|
|
161
|
-
if (
|
|
161
|
+
if (
|
|
162
|
+
typeof channelUnread?.readToSegment === 'number' &&
|
|
163
|
+
channelUnread &&
|
|
164
|
+
segment > channelUnread.readToSegment
|
|
165
|
+
) {
|
|
162
166
|
channelUnread.readToSegment = segment;
|
|
163
167
|
channelUnread.unreadCount = Math.max(channelUnread.lastSegment - segment, 0);
|
|
164
168
|
|
|
@@ -30,6 +30,14 @@ export const setClientToken = async (params: Parameters<typeof getToken>[0]) =>
|
|
|
30
30
|
isUserDeleted: false,
|
|
31
31
|
};
|
|
32
32
|
|
|
33
|
+
client.upload.defaults.headers.common.Authorization = `Bearer ${accessToken}`;
|
|
34
|
+
|
|
35
|
+
client.upload.defaults.metadata = {
|
|
36
|
+
tokenExpiry: expiresAt,
|
|
37
|
+
isGlobalBanned: false,
|
|
38
|
+
isUserDeleted: false,
|
|
39
|
+
};
|
|
40
|
+
|
|
33
41
|
// manually setup the token for ws transport
|
|
34
42
|
if (client.ws) client.ws.io.opts.query = { token: accessToken };
|
|
35
43
|
|
|
@@ -53,6 +53,36 @@ export const createCommentEventSubscriber = (
|
|
|
53
53
|
}
|
|
54
54
|
}
|
|
55
55
|
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
if (['comment.deleted'].includes(event)) {
|
|
59
|
+
// NOTE: skip deleting comment to parent comment children if it's the same user since we use the local event to update instead.
|
|
60
|
+
if (event === 'comment.deleted' && comment.data.userId === client.userId) return;
|
|
61
|
+
|
|
62
|
+
if (comments[0].parentId) {
|
|
63
|
+
const parentComment = pullFromCache<Amity.InternalComment>([
|
|
64
|
+
'comment',
|
|
65
|
+
'get',
|
|
66
|
+
comments[0].parentId,
|
|
67
|
+
]);
|
|
68
|
+
|
|
69
|
+
if (parentComment?.data) {
|
|
70
|
+
// Remove deleted comment in parent childComment if still exists
|
|
71
|
+
if (parentComment.data.children.includes(comments[0].commentId)) {
|
|
72
|
+
const newParentComment = {
|
|
73
|
+
...parentComment.data,
|
|
74
|
+
childrenNumber: parentComment.data.childrenNumber - 1,
|
|
75
|
+
children: [
|
|
76
|
+
...new Set([
|
|
77
|
+
...parentComment.data.children.filter(id => id !== comments[0].commentId),
|
|
78
|
+
]),
|
|
79
|
+
],
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
pushToCache(['comment', 'get', comments[0].parentId], newParentComment);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
}
|
|
56
86
|
|
|
57
87
|
const queries = queryCache<Amity.InternalComment[]>(['comment', 'query'])?.filter(
|
|
58
88
|
({ key }) => (key[2] as Amity.QueryComments)?.referenceId === comment.data.referenceId,
|
|
@@ -135,6 +165,49 @@ export const createLocalCommentEventSubscriber = (
|
|
|
135
165
|
queries?.map(({ key, data }) => upsertInCache(key, data as any, { cachedAt: -1 }));
|
|
136
166
|
}
|
|
137
167
|
|
|
168
|
+
if (['local.comment.deleted'].includes(event)) {
|
|
169
|
+
if (comments[0].parentId) {
|
|
170
|
+
const parentComment = pullFromCache<Amity.InternalComment>([
|
|
171
|
+
'comment',
|
|
172
|
+
'get',
|
|
173
|
+
comments[0].parentId,
|
|
174
|
+
]);
|
|
175
|
+
|
|
176
|
+
if (parentComment?.data) {
|
|
177
|
+
// Remove deleted comment in parent childComment if still exists
|
|
178
|
+
if (parentComment.data.children.includes(comments[0].commentId)) {
|
|
179
|
+
const newParentComment = {
|
|
180
|
+
...parentComment.data,
|
|
181
|
+
childrenNumber: parentComment.data.childrenNumber - 1,
|
|
182
|
+
children: [
|
|
183
|
+
...new Set([
|
|
184
|
+
...parentComment.data.children.filter(id => id !== comments[0].commentId),
|
|
185
|
+
]),
|
|
186
|
+
],
|
|
187
|
+
};
|
|
188
|
+
pushToCache(['comment', 'get', comments[0].parentId], newParentComment);
|
|
189
|
+
|
|
190
|
+
setTimeout(() => {
|
|
191
|
+
// NOTE: This is workaround solution for emitting event not work properly.
|
|
192
|
+
fireEvent('comment.updated', {
|
|
193
|
+
comments: [newParentComment],
|
|
194
|
+
commentChildren: [],
|
|
195
|
+
files: [],
|
|
196
|
+
users: [],
|
|
197
|
+
communityUsers: [],
|
|
198
|
+
});
|
|
199
|
+
}, 200);
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
const queries = queryCache<Amity.InternalComment[]>(['comment', 'query'])?.filter(
|
|
205
|
+
({ key }) => (key[2] as Amity.QueryComments)?.referenceId === comment.data.referenceId,
|
|
206
|
+
);
|
|
207
|
+
|
|
208
|
+
queries?.map(({ key, data }) => upsertInCache(key, data as any, { cachedAt: -1 }));
|
|
209
|
+
}
|
|
210
|
+
|
|
138
211
|
callback(LinkedObject.comment(comment.data));
|
|
139
212
|
}
|
|
140
213
|
}
|
|
@@ -61,6 +61,9 @@ const idResolvers: Resolvers = {
|
|
|
61
61
|
|
|
62
62
|
pin: ({ placement, referenceId }) => `${placement}#${referenceId}`,
|
|
63
63
|
pinTarget: ({ targetId }) => targetId,
|
|
64
|
+
|
|
65
|
+
notificationTrayItem: ({ _id }) => _id,
|
|
66
|
+
notificationTraySeen: ({ userId }) => userId,
|
|
64
67
|
};
|
|
65
68
|
|
|
66
69
|
/**
|
package/src/core/model/index.ts
CHANGED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { ingestInCache } from '~/cache/api/ingestInCache';
|
|
2
|
+
import { getActiveClient } from '~/client';
|
|
3
|
+
|
|
4
|
+
/* begin_public_function
|
|
5
|
+
id: file.update.altText
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* ```js
|
|
9
|
+
* import { FileRepository } from '@amityco/ts-sdk'
|
|
10
|
+
* const updated = await FileRepository.updateAltText(fileId, altText)
|
|
11
|
+
* ```
|
|
12
|
+
*
|
|
13
|
+
* Updates an {@link Amity.File<'image'>['altText']}.
|
|
14
|
+
*
|
|
15
|
+
* @param fileId The ID of the {@link Amity.File<'image'>} to edit
|
|
16
|
+
* @param altText The new alt text for the {@link Amity.File<'image'>}
|
|
17
|
+
* @returns the updated {@link Amity.File<'image'>} object
|
|
18
|
+
*
|
|
19
|
+
* @category File API
|
|
20
|
+
* @async
|
|
21
|
+
*/
|
|
22
|
+
export const updateAltText = async (
|
|
23
|
+
fileId: Amity.File['fileId'],
|
|
24
|
+
altText: string,
|
|
25
|
+
): Promise<boolean> => {
|
|
26
|
+
const client = getActiveClient();
|
|
27
|
+
client.log('file/updateAltText', altText);
|
|
28
|
+
|
|
29
|
+
const { data } = await client.http.put<Amity.FilePayload<'image'>>(`/api/v3/files/${fileId}`, {
|
|
30
|
+
altText,
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
const cachedAt = client.cache && Date.now();
|
|
34
|
+
|
|
35
|
+
if (client.cache) ingestInCache({ files: [data] }, { cachedAt });
|
|
36
|
+
|
|
37
|
+
return true;
|
|
38
|
+
};
|
|
39
|
+
/* end_public_function */
|
|
@@ -42,7 +42,7 @@ export const uploadFile = async <T extends Amity.FileType = any>(
|
|
|
42
42
|
? (formData as any).getHeaders()
|
|
43
43
|
: { 'content-type': 'multipart/form-data' };
|
|
44
44
|
|
|
45
|
-
const { data } = await client.
|
|
45
|
+
const { data } = await client.upload.post<Amity.CreateFilePayload<T>>('/api/v4/files', formData, {
|
|
46
46
|
headers,
|
|
47
47
|
onUploadProgress({ loaded, total = 100 }) {
|
|
48
48
|
onProgress && onProgress(Math.round((loaded * 100) / total));
|
|
@@ -16,33 +16,52 @@ import GlobalFileAccessType from '~/client/utils/GlobalFileAccessType';
|
|
|
16
16
|
*
|
|
17
17
|
* @param formData The data necessary to create a new {@link Amity.File<'image'>}
|
|
18
18
|
* @param onProgress The callback to track the upload progress
|
|
19
|
+
* @param altText The alt text for the image
|
|
19
20
|
* @returns The newly created {@link Amity.File<'image'>}
|
|
20
21
|
*
|
|
21
22
|
* @category File API
|
|
22
23
|
* @async
|
|
23
24
|
*/
|
|
25
|
+
|
|
24
26
|
export const uploadImage = async (
|
|
25
27
|
formData: FormData,
|
|
26
28
|
onProgress?: (percent: number) => void,
|
|
29
|
+
altText?: string,
|
|
27
30
|
): Promise<Amity.Cached<Amity.File<'image'>[]>> => {
|
|
28
31
|
const client = getActiveClient();
|
|
29
32
|
client.log('file/uploadImage', formData);
|
|
30
33
|
|
|
31
34
|
const files = formData.getAll('files');
|
|
32
35
|
|
|
33
|
-
if (
|
|
36
|
+
if (files?.length) {
|
|
37
|
+
console.warn('Deprecation Warning: `files` is deprecated, please use `file` instead.');
|
|
38
|
+
|
|
39
|
+
formData.append('preferredFilename', (files[0] as File).name);
|
|
40
|
+
} else {
|
|
41
|
+
const file = formData.get('file') as File;
|
|
42
|
+
|
|
43
|
+
if (!file) {
|
|
44
|
+
throw new Error('The formData object must have a `file` or `files` key');
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
formData.append('preferredFilename', file.name);
|
|
48
|
+
|
|
49
|
+
// alt is for single image
|
|
50
|
+
if (altText) {
|
|
51
|
+
formData.append('altText', altText);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
34
54
|
|
|
35
55
|
const accessType = GlobalFileAccessType.getInstance().getFileAccessType();
|
|
36
|
-
formData.append('accessType', accessType);
|
|
37
56
|
|
|
38
|
-
formData.append('
|
|
57
|
+
formData.append('accessType', accessType);
|
|
39
58
|
|
|
40
59
|
const headers =
|
|
41
60
|
'getHeaders' in formData
|
|
42
61
|
? (formData as any).getHeaders()
|
|
43
62
|
: { 'content-type': 'multipart/form-data' };
|
|
44
63
|
|
|
45
|
-
const { data } = await client.
|
|
64
|
+
const { data } = await client.upload.post<Amity.CreateFilePayload<'image'>>(
|
|
46
65
|
'/api/v4/images',
|
|
47
66
|
formData,
|
|
48
67
|
{
|
|
@@ -48,7 +48,7 @@ export const uploadVideo = async (
|
|
|
48
48
|
? (formData as any).getHeaders()
|
|
49
49
|
: { 'content-type': 'multipart/form-data' };
|
|
50
50
|
|
|
51
|
-
const { data } = await client.
|
|
51
|
+
const { data } = await client.upload.post<Amity.CreateFilePayload<'video'>>(
|
|
52
52
|
'/api/v4/videos',
|
|
53
53
|
formData,
|
|
54
54
|
{
|
package/src/index.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { getActiveClient } from '~/client/api/activeClient';
|
|
2
|
-
import { createEventSubscriber } from '~/core/events';
|
|
2
|
+
import { createEventSubscriber, fireEvent } from '~/core/events';
|
|
3
3
|
import { ingestInCache } from '~/cache/api/ingestInCache';
|
|
4
4
|
import { updateSubChannelUnreadFromMessage } from '~/marker/utils/updateSubChannelUnreadFromMessage';
|
|
5
5
|
import { reCalculateChannelUnreadInfo } from '~/marker/utils/reCalculateChannelUnreadInfo';
|
|
@@ -48,7 +48,14 @@ export const onMessageCreatedMqtt = (
|
|
|
48
48
|
'get',
|
|
49
49
|
message.channelId,
|
|
50
50
|
])?.data;
|
|
51
|
-
|
|
51
|
+
|
|
52
|
+
if (
|
|
53
|
+
!channelUnread ||
|
|
54
|
+
channelUnread.lastSegment >= message.segment ||
|
|
55
|
+
typeof channelUnread.readToSegment !== 'number' ||
|
|
56
|
+
typeof channelUnread.lastMentionedSegment !== 'number'
|
|
57
|
+
)
|
|
58
|
+
return;
|
|
52
59
|
|
|
53
60
|
const lastSegment = message.segment;
|
|
54
61
|
const isMentionedInMessage = message.mentionedUsers?.some(mention => {
|
|
@@ -60,17 +67,20 @@ export const onMessageCreatedMqtt = (
|
|
|
60
67
|
);
|
|
61
68
|
});
|
|
62
69
|
|
|
63
|
-
const
|
|
70
|
+
const lastMentionedSegment = isMentionedInMessage
|
|
64
71
|
? message.segment
|
|
65
|
-
: channelUnread.
|
|
72
|
+
: channelUnread.lastMentionedSegment;
|
|
66
73
|
|
|
67
|
-
|
|
74
|
+
const updatedChannelUnread: Amity.ChannelUnread = {
|
|
68
75
|
...channelUnread,
|
|
69
76
|
lastSegment,
|
|
70
|
-
unreadCount: lastSegment - channelUnread.readToSegment,
|
|
71
|
-
|
|
72
|
-
isMentioned: !(channelUnread.readToSegment >=
|
|
73
|
-
}
|
|
77
|
+
unreadCount: Math.max(lastSegment - channelUnread.readToSegment, 0),
|
|
78
|
+
lastMentionedSegment,
|
|
79
|
+
isMentioned: !(channelUnread.readToSegment >= lastMentionedSegment),
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
pushToCache(['channelUnread', 'get', message.channelId], updatedChannelUnread);
|
|
83
|
+
fireEvent('local.channelUnread.updated', updatedChannelUnread);
|
|
74
84
|
});
|
|
75
85
|
}
|
|
76
86
|
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { getActiveClient } from '~/client/api/activeClient';
|
|
2
|
+
import { fireEvent } from '~/core/events';
|
|
3
|
+
import { pullFromCache, pushToCache } from '~/cache/api';
|
|
4
|
+
|
|
5
|
+
/* begin_public_function
|
|
6
|
+
id: notificationTrayItem.markSeen
|
|
7
|
+
*/
|
|
8
|
+
/**
|
|
9
|
+
* ```js
|
|
10
|
+
* import { notificationTray } from '@amityco/ts-sdk'
|
|
11
|
+
* const updated = await notificationTray.markItemsSeen()
|
|
12
|
+
* ```
|
|
13
|
+
*
|
|
14
|
+
* Updates an {@link Amity.NotificationItemSeen}
|
|
15
|
+
*
|
|
16
|
+
* @param trayItems[] that include id and lastTraySeenAt, The ID of the {@link Amity.NotificationItemSeen} to edit
|
|
17
|
+
* @returns the updated {@link Amity.NotificationItemSeen} object
|
|
18
|
+
*
|
|
19
|
+
* @category NotificationItemSeen API
|
|
20
|
+
* @async
|
|
21
|
+
*/
|
|
22
|
+
export const markItemsSeen = async (trayItems: Amity.QueryNotificationItemSeen[]) => {
|
|
23
|
+
const client = getActiveClient();
|
|
24
|
+
client.log('notificationTray/markItemsSeen', {});
|
|
25
|
+
|
|
26
|
+
const { data: payload } = await client.http.post<Amity.NotificationItemSeenPayload>(
|
|
27
|
+
`api/v1/notification-tray/items/seen`,
|
|
28
|
+
{
|
|
29
|
+
trayItems: trayItems.map(item => ({
|
|
30
|
+
id: item.id,
|
|
31
|
+
lastSeenAt: item.lastSeenAt,
|
|
32
|
+
})),
|
|
33
|
+
},
|
|
34
|
+
);
|
|
35
|
+
|
|
36
|
+
const updatedData = trayItems
|
|
37
|
+
.map(patchItem => {
|
|
38
|
+
const cacheData = pullFromCache<Amity.InternalNotificationTrayItem>([
|
|
39
|
+
'notificationTrayItem',
|
|
40
|
+
'get',
|
|
41
|
+
patchItem.id,
|
|
42
|
+
])?.data;
|
|
43
|
+
|
|
44
|
+
if (!cacheData) return;
|
|
45
|
+
|
|
46
|
+
const data = {
|
|
47
|
+
...cacheData,
|
|
48
|
+
...payload,
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
if (client.cache) {
|
|
52
|
+
const cachedAt = Date.now();
|
|
53
|
+
pushToCache(['notificationTrayItem', 'get'], data, { cachedAt });
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
return data;
|
|
57
|
+
})
|
|
58
|
+
.filter(Boolean) as Amity.InternalNotificationTrayItem[];
|
|
59
|
+
|
|
60
|
+
fireEvent('local.notificationTrayItem.updated', { notificationTrayItems: updatedData });
|
|
61
|
+
};
|
|
62
|
+
/* end_public_function */
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { getActiveClient } from '~/client/api';
|
|
2
|
+
import { fireEvent } from '~/core/events';
|
|
3
|
+
import { pullFromCache, pushToCache } from '~/cache/api';
|
|
4
|
+
|
|
5
|
+
/* begin_public_function
|
|
6
|
+
id: notificationTray.markSeen
|
|
7
|
+
*/
|
|
8
|
+
/**
|
|
9
|
+
* ```js
|
|
10
|
+
* import { notificationTray } from '@amityco/ts-sdk'
|
|
11
|
+
* const updated = await notificationTray.markTraySeen({
|
|
12
|
+
* lastSeenAt: Amity.timestamp,
|
|
13
|
+
* })
|
|
14
|
+
* ```
|
|
15
|
+
*
|
|
16
|
+
* Updates an {@link Amity.NotificationTraySeen}
|
|
17
|
+
*
|
|
18
|
+
* @param userId The ID of the {@link Amity.NotificationTraySeen} to edit
|
|
19
|
+
* @param lastSeenAt The patch data to apply
|
|
20
|
+
* @returns the updated {@link Amity.NotificationTraySeen} object
|
|
21
|
+
*
|
|
22
|
+
* @category Post API
|
|
23
|
+
* @async
|
|
24
|
+
*/
|
|
25
|
+
export const markTraySeen = async (
|
|
26
|
+
lastSeenAt: Amity.timestamp,
|
|
27
|
+
): Promise<Amity.Cached<Amity.NotificationTraySeenUpdatedPayload>> => {
|
|
28
|
+
const client = getActiveClient();
|
|
29
|
+
client.log('notificationTray/markTraySeen', {});
|
|
30
|
+
|
|
31
|
+
const { data: payload } = await client.http.post<Amity.NotificationTraySeenUpdatedPayload>(
|
|
32
|
+
`api/v1/notification-tray/tray/seen`,
|
|
33
|
+
{
|
|
34
|
+
lastSeenAt,
|
|
35
|
+
},
|
|
36
|
+
);
|
|
37
|
+
|
|
38
|
+
const cacheData = pullFromCache<Amity.InternalNotificationTraySeen>([
|
|
39
|
+
'notificationTraySeen',
|
|
40
|
+
'get',
|
|
41
|
+
])?.data;
|
|
42
|
+
|
|
43
|
+
const data = {
|
|
44
|
+
userId: client.userId!,
|
|
45
|
+
lastTraySeenAt: payload.lastSeenAt,
|
|
46
|
+
} as Amity.InternalNotificationTraySeen;
|
|
47
|
+
|
|
48
|
+
const updateCacheData = {
|
|
49
|
+
...cacheData,
|
|
50
|
+
...data,
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
const cachedAt = client.cache && Date.now();
|
|
54
|
+
|
|
55
|
+
if (client.cache)
|
|
56
|
+
pushToCache(['notificationTraySeen', 'get', client.userId!], updateCacheData, { cachedAt });
|
|
57
|
+
|
|
58
|
+
fireEvent('local.notificationTraySeen.updated', data);
|
|
59
|
+
|
|
60
|
+
return {
|
|
61
|
+
data: payload,
|
|
62
|
+
cachedAt,
|
|
63
|
+
};
|
|
64
|
+
};
|
|
65
|
+
/* end_public_function */
|