@onyx-p/imlib-web 3.0.4 → 3.0.6
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/README.md +2 -1
- package/database/main.cjs +38 -0
- package/database/preload.cjs +2 -0
- package/database/worker.cjs +385 -39
- package/index.esm.js +4 -4
- package/index.umd.js +4 -4
- package/package.json +1 -1
- package/types/constants/messageTypes.d.ts +6 -0
- package/types/database/contracts.d.ts +5 -2
- package/types/database/legacyMediaReferences.d.ts +21 -0
- package/types/database/main/ipc.d.ts +1 -0
- package/types/database/main/keyStore.d.ts +1 -0
- package/types/database/main/messageStore.d.ts +21 -1
- package/types/database/main/service.d.ts +1 -0
- package/types/database/renderer/legacyIndexedDbMigration.d.ts +15 -2
- package/types/database/renderer/messageRepository.d.ts +22 -2
- package/types/index.d.ts +47 -7
- package/types/model/iReceivedMessage.d.ts +13 -0
- package/types/model/messages/index.d.ts +2 -2
- package/types/model/messages/notificationMessages.d.ts +16 -1
- package/types/model/messages/otherMediaMessages.d.ts +2 -1
- package/types/model/messages/textMessage.d.ts +2 -0
- package/types/types.d.ts +48 -1
package/README.md
CHANGED
|
@@ -106,7 +106,8 @@ already committed batches are safe to repeat.
|
|
|
106
106
|
## 消息搜索
|
|
107
107
|
|
|
108
108
|
单会话搜索接口保持不变。全局搜索使用 Signal 风格的 FTS5 前缀匹配,
|
|
109
|
-
按消息时间倒序返回,默认最多 500
|
|
109
|
+
按消息时间倒序返回,默认最多 500 条。文本消息按正文搜索,
|
|
110
|
+
文件消息按文件名搜索:
|
|
110
111
|
|
|
111
112
|
```js
|
|
112
113
|
const result = await ACIMLib.searchMessages('项目进度')
|
package/database/main.cjs
CHANGED
|
@@ -28,6 +28,14 @@ class DatabaseKeyStore {
|
|
|
28
28
|
this.writeKeys(keys);
|
|
29
29
|
return key;
|
|
30
30
|
}
|
|
31
|
+
remove(accountId) {
|
|
32
|
+
const keys = this.readKeys();
|
|
33
|
+
if (!(accountId in keys)) {
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
delete keys[accountId];
|
|
37
|
+
this.writeKeys(keys);
|
|
38
|
+
}
|
|
31
39
|
readKeys() {
|
|
32
40
|
try {
|
|
33
41
|
const parsed = JSON.parse(node_fs.readFileSync(this.filePath, 'utf8'));
|
|
@@ -69,6 +77,7 @@ const READ_METHOD_NAMES = [
|
|
|
69
77
|
'getPinnedMessages',
|
|
70
78
|
'searchMessages',
|
|
71
79
|
'searchTextMessages',
|
|
80
|
+
'getLegacyMediaReferences',
|
|
72
81
|
'getLegacyMigrationState'
|
|
73
82
|
];
|
|
74
83
|
const WRITE_METHOD_NAMES = [
|
|
@@ -78,6 +87,7 @@ const WRITE_METHOD_NAMES = [
|
|
|
78
87
|
'removeMessagesByUId',
|
|
79
88
|
'updateMessageReceiptStatus',
|
|
80
89
|
'setMessagePinned',
|
|
90
|
+
'setMessageReactions',
|
|
81
91
|
'unpinAllMessages',
|
|
82
92
|
'clearBurnAfterReadingExpiredMessages',
|
|
83
93
|
'upsertMessage',
|
|
@@ -120,6 +130,19 @@ function parseRequest(value) {
|
|
|
120
130
|
if (value.type === 'close') {
|
|
121
131
|
return { type: 'close' };
|
|
122
132
|
}
|
|
133
|
+
if (value.type === 'delete') {
|
|
134
|
+
if (!isRecord(value.options) ||
|
|
135
|
+
typeof value.options.appKey !== 'string' ||
|
|
136
|
+
typeof value.options.userId !== 'string' ||
|
|
137
|
+
!value.options.appKey ||
|
|
138
|
+
!value.options.userId) {
|
|
139
|
+
throw new Error('Invalid database delete options');
|
|
140
|
+
}
|
|
141
|
+
return {
|
|
142
|
+
type: 'delete',
|
|
143
|
+
options: { appKey: value.options.appKey, userId: value.options.userId }
|
|
144
|
+
};
|
|
145
|
+
}
|
|
123
146
|
if (value.type === 'open') {
|
|
124
147
|
if (!isRecord(value.options) ||
|
|
125
148
|
typeof value.options.appKey !== 'string' ||
|
|
@@ -158,6 +181,9 @@ function registerDatabaseIpc({ ipcMain, service, isTrustedEvent = isTopLevelSend
|
|
|
158
181
|
else if (request.type === 'close') {
|
|
159
182
|
result = await service.close();
|
|
160
183
|
}
|
|
184
|
+
else if (request.type === 'delete') {
|
|
185
|
+
result = await service.deleteAccount(request.options);
|
|
186
|
+
}
|
|
161
187
|
else if (request.type === 'read') {
|
|
162
188
|
result = await service.read(request.method, request.args);
|
|
163
189
|
}
|
|
@@ -250,6 +276,18 @@ class MainDatabaseService {
|
|
|
250
276
|
}
|
|
251
277
|
}));
|
|
252
278
|
}
|
|
279
|
+
async deleteAccount(options) {
|
|
280
|
+
await this.close();
|
|
281
|
+
const accountId = node_crypto.createHash('sha256')
|
|
282
|
+
.update(`${options.appKey}:${options.userId}`)
|
|
283
|
+
.digest('hex');
|
|
284
|
+
const sqlDirectory = node_path.join(this.options.userDataPath, 'sql');
|
|
285
|
+
const dbPath = node_path.join(sqlDirectory, `${accountId}.sqlite`);
|
|
286
|
+
for (const path of [dbPath, `${dbPath}-wal`, `${dbPath}-shm`]) {
|
|
287
|
+
node_fs.rmSync(path, { force: true });
|
|
288
|
+
}
|
|
289
|
+
this.options.keyStore.remove(accountId);
|
|
290
|
+
}
|
|
253
291
|
assertOpen() {
|
|
254
292
|
if (!this.accountId || this.pool.length === 0) {
|
|
255
293
|
throw new Error('Database service is not open');
|
package/database/preload.cjs
CHANGED
|
@@ -16,6 +16,7 @@ const READ_METHOD_NAMES = [
|
|
|
16
16
|
'getPinnedMessages',
|
|
17
17
|
'searchMessages',
|
|
18
18
|
'searchTextMessages',
|
|
19
|
+
'getLegacyMediaReferences',
|
|
19
20
|
'getLegacyMigrationState'
|
|
20
21
|
];
|
|
21
22
|
const WRITE_METHOD_NAMES = [
|
|
@@ -25,6 +26,7 @@ const WRITE_METHOD_NAMES = [
|
|
|
25
26
|
'removeMessagesByUId',
|
|
26
27
|
'updateMessageReceiptStatus',
|
|
27
28
|
'setMessagePinned',
|
|
29
|
+
'setMessageReactions',
|
|
28
30
|
'unpinAllMessages',
|
|
29
31
|
'clearBurnAfterReadingExpiredMessages',
|
|
30
32
|
'upsertMessage',
|
package/database/worker.cjs
CHANGED
|
@@ -19,6 +19,7 @@ const READ_METHOD_NAMES = [
|
|
|
19
19
|
'getPinnedMessages',
|
|
20
20
|
'searchMessages',
|
|
21
21
|
'searchTextMessages',
|
|
22
|
+
'getLegacyMediaReferences',
|
|
22
23
|
'getLegacyMigrationState'
|
|
23
24
|
];
|
|
24
25
|
const WRITE_METHOD_NAMES = [
|
|
@@ -28,6 +29,7 @@ const WRITE_METHOD_NAMES = [
|
|
|
28
29
|
'removeMessagesByUId',
|
|
29
30
|
'updateMessageReceiptStatus',
|
|
30
31
|
'setMessagePinned',
|
|
32
|
+
'setMessageReactions',
|
|
31
33
|
'unpinAllMessages',
|
|
32
34
|
'clearBurnAfterReadingExpiredMessages',
|
|
33
35
|
'upsertMessage',
|
|
@@ -52,6 +54,24 @@ function serializeDatabaseError(error) {
|
|
|
52
54
|
};
|
|
53
55
|
}
|
|
54
56
|
|
|
57
|
+
const MessageTypes = {
|
|
58
|
+
TEXT: 0x00000000,
|
|
59
|
+
IMAGE: 0x30001000,
|
|
60
|
+
GIF: 0x3000100B,
|
|
61
|
+
FILE: 0x3000101A,
|
|
62
|
+
AUDIO: 0x30001011,
|
|
63
|
+
VIDEO: 0x30001006,
|
|
64
|
+
RECALL: 0x6001001e,
|
|
65
|
+
STORED_RECALL: 0x6001001d,
|
|
66
|
+
LOCATION: 0x30001005,
|
|
67
|
+
CHAT_RECORD: 0x30001019,
|
|
68
|
+
CONTACT: 0x10001002,
|
|
69
|
+
GROUP_INVITATION: 0x30001003,
|
|
70
|
+
REDPACKET: 0x10001040,
|
|
71
|
+
TRANSFER: 0x10001030,
|
|
72
|
+
LINK: 0x10001004
|
|
73
|
+
};
|
|
74
|
+
|
|
55
75
|
const SCHEMA_MIGRATIONS = [
|
|
56
76
|
{
|
|
57
77
|
version: 1,
|
|
@@ -157,6 +177,20 @@ const SCHEMA_MIGRATIONS = [
|
|
|
157
177
|
ON messages (dialogId, pinned, sentTime DESC, messageId DESC);
|
|
158
178
|
`);
|
|
159
179
|
}
|
|
180
|
+
},
|
|
181
|
+
{
|
|
182
|
+
version: 7,
|
|
183
|
+
up(database) {
|
|
184
|
+
database
|
|
185
|
+
.prepare(`UPDATE messages
|
|
186
|
+
SET searchText = CASE
|
|
187
|
+
WHEN json_type(json, '$.content.title') = 'text'
|
|
188
|
+
THEN json_extract(json, '$.content.title')
|
|
189
|
+
ELSE ''
|
|
190
|
+
END
|
|
191
|
+
WHERE messageType = $fileMessageType;`)
|
|
192
|
+
.run({ fileMessageType: MessageTypes.FILE });
|
|
193
|
+
}
|
|
160
194
|
}
|
|
161
195
|
];
|
|
162
196
|
SCHEMA_MIGRATIONS[SCHEMA_MIGRATIONS.length - 1]?.version ?? 0;
|
|
@@ -187,6 +221,167 @@ function runMigrations(database, migrations = SCHEMA_MIGRATIONS) {
|
|
|
187
221
|
}
|
|
188
222
|
}
|
|
189
223
|
|
|
224
|
+
var ConnectionStatus;
|
|
225
|
+
(function (ConnectionStatus) {
|
|
226
|
+
ConnectionStatus[ConnectionStatus["CONNECTED"] = 0] = "CONNECTED";
|
|
227
|
+
ConnectionStatus[ConnectionStatus["CONNECTING"] = 1] = "CONNECTING";
|
|
228
|
+
ConnectionStatus[ConnectionStatus["DISCONNECTED"] = 2] = "DISCONNECTED";
|
|
229
|
+
ConnectionStatus[ConnectionStatus["NETWORK_UNAVAILABLE"] = 3] = "NETWORK_UNAVAILABLE";
|
|
230
|
+
ConnectionStatus[ConnectionStatus["CONNECTION_CLOSED"] = 4] = "CONNECTION_CLOSED";
|
|
231
|
+
ConnectionStatus[ConnectionStatus["KICKED_OFFLINE_BY_OTHER_CLIENT"] = 6] = "KICKED_OFFLINE_BY_OTHER_CLIENT";
|
|
232
|
+
ConnectionStatus[ConnectionStatus["WEBSOCKET_UNAVAILABLE"] = 7] = "WEBSOCKET_UNAVAILABLE";
|
|
233
|
+
ConnectionStatus[ConnectionStatus["WEBSOCKET_ERROR"] = 8] = "WEBSOCKET_ERROR";
|
|
234
|
+
ConnectionStatus[ConnectionStatus["BLOCKED"] = 9] = "BLOCKED";
|
|
235
|
+
ConnectionStatus[ConnectionStatus["DISCONNECT_BY_SERVER"] = 13] = "DISCONNECT_BY_SERVER";
|
|
236
|
+
})(ConnectionStatus || (ConnectionStatus = {}));
|
|
237
|
+
var ErrorCode;
|
|
238
|
+
(function (ErrorCode) {
|
|
239
|
+
ErrorCode[ErrorCode["TIMEOUT"] = -1] = "TIMEOUT";
|
|
240
|
+
ErrorCode[ErrorCode["UNKNOWN"] = -2] = "UNKNOWN";
|
|
241
|
+
ErrorCode[ErrorCode["PARAMETER_ERROR"] = -3] = "PARAMETER_ERROR";
|
|
242
|
+
ErrorCode[ErrorCode["SUCCESS"] = 0] = "SUCCESS";
|
|
243
|
+
ErrorCode[ErrorCode["NETWORK_ERROR"] = 7] = "NETWORK_ERROR";
|
|
244
|
+
ErrorCode[ErrorCode["MSG_ENCRYPT_ERROR"] = 6001] = "MSG_ENCRYPT_ERROR";
|
|
245
|
+
ErrorCode[ErrorCode["RC_DISCUSSION_GROUP_ID_INVALID"] = 20407] = "RC_DISCUSSION_GROUP_ID_INVALID";
|
|
246
|
+
ErrorCode[ErrorCode["SEND_FREQUENCY_TOO_FAST"] = 20604] = "SEND_FREQUENCY_TOO_FAST";
|
|
247
|
+
ErrorCode[ErrorCode["FORBIDDEN_IN_GROUP"] = 22408] = "FORBIDDEN_IN_GROUP";
|
|
248
|
+
ErrorCode[ErrorCode["RECALL_MESSAGE"] = 25101] = "RECALL_MESSAGE";
|
|
249
|
+
ErrorCode[ErrorCode["NOT_IN_GROUP"] = 22406] = "NOT_IN_GROUP";
|
|
250
|
+
ErrorCode[ErrorCode["SENSITIVE_SHIELD"] = 21501] = "SENSITIVE_SHIELD";
|
|
251
|
+
ErrorCode[ErrorCode["GET_USERINFO_ERROR"] = 23407] = "GET_USERINFO_ERROR";
|
|
252
|
+
ErrorCode[ErrorCode["REJECTED_BY_BLACKLIST"] = 405] = "REJECTED_BY_BLACKLIST";
|
|
253
|
+
ErrorCode[ErrorCode["RC_NET_CHANNEL_INVALID"] = 30001] = "RC_NET_CHANNEL_INVALID";
|
|
254
|
+
ErrorCode[ErrorCode["RC_NET_UNAVAILABLE"] = 30002] = "RC_NET_UNAVAILABLE";
|
|
255
|
+
ErrorCode[ErrorCode["RC_MSG_RESP_TIMEOUT"] = 30003] = "RC_MSG_RESP_TIMEOUT";
|
|
256
|
+
ErrorCode[ErrorCode["RC_SOCKET_NOT_CREATED"] = 30010] = "RC_SOCKET_NOT_CREATED";
|
|
257
|
+
ErrorCode[ErrorCode["RC_SOCKET_DISCONNECTED"] = 30011] = "RC_SOCKET_DISCONNECTED";
|
|
258
|
+
ErrorCode[ErrorCode["RC_PONG_RECV_FAIL"] = 30013] = "RC_PONG_RECV_FAIL";
|
|
259
|
+
ErrorCode[ErrorCode["RC_MSG_SEND_FAIL"] = 30014] = "RC_MSG_SEND_FAIL";
|
|
260
|
+
ErrorCode[ErrorCode["RC_MSG_CONTENT_EXCEED_LIMIT"] = 30016] = "RC_MSG_CONTENT_EXCEED_LIMIT";
|
|
261
|
+
ErrorCode[ErrorCode["RC_CONN_ACK_TIMEOUT"] = 31000] = "RC_CONN_ACK_TIMEOUT";
|
|
262
|
+
ErrorCode[ErrorCode["RC_CONN_ID_REJECT"] = 31002] = "RC_CONN_ID_REJECT";
|
|
263
|
+
ErrorCode[ErrorCode["RC_CONN_SERVER_UNAVAILABLE"] = 31003] = "RC_CONN_SERVER_UNAVAILABLE";
|
|
264
|
+
ErrorCode[ErrorCode["RC_CONN_USER_OR_PASSWD_ERROR"] = 31004] = "RC_CONN_USER_OR_PASSWD_ERROR";
|
|
265
|
+
ErrorCode[ErrorCode["RC_CONN_NOT_AUTHRORIZED"] = 31005] = "RC_CONN_NOT_AUTHRORIZED";
|
|
266
|
+
ErrorCode[ErrorCode["RC_DISCONN_KICK"] = 31010] = "RC_DISCONN_KICK";
|
|
267
|
+
ErrorCode[ErrorCode["RC_DISCONN_SAME_CLIENT_ON_LINE"] = 31023] = "RC_DISCONN_SAME_CLIENT_ON_LINE";
|
|
268
|
+
ErrorCode[ErrorCode["BIZ_ERROR_CLIENT_NOT_INIT"] = 33001] = "BIZ_ERROR_CLIENT_NOT_INIT";
|
|
269
|
+
ErrorCode[ErrorCode["BIZ_ERROR_INVALID_PARAMETER"] = 33003] = "BIZ_ERROR_INVALID_PARAMETER";
|
|
270
|
+
ErrorCode[ErrorCode["BIZ_ERROR_RECONNECT_SUCCESS"] = 33005] = "BIZ_ERROR_RECONNECT_SUCCESS";
|
|
271
|
+
ErrorCode[ErrorCode["BIZ_ERROR_CONNECTING"] = 33006] = "BIZ_ERROR_CONNECTING";
|
|
272
|
+
ErrorCode[ErrorCode["MSG_INSERT_ERROR"] = 33008] = "MSG_INSERT_ERROR";
|
|
273
|
+
ErrorCode[ErrorCode["MSG_DEL_ERROR"] = 33009] = "MSG_DEL_ERROR";
|
|
274
|
+
ErrorCode[ErrorCode["CONVER_REMOVE_ERROR"] = 34001] = "CONVER_REMOVE_ERROR";
|
|
275
|
+
ErrorCode[ErrorCode["CONVER_GETLIST_ERROR"] = 34002] = "CONVER_GETLIST_ERROR";
|
|
276
|
+
ErrorCode[ErrorCode["CONVER_SETOP_ERROR"] = 34003] = "CONVER_SETOP_ERROR";
|
|
277
|
+
ErrorCode[ErrorCode["CONVER_TOTAL_UNREAD_ERROR"] = 34004] = "CONVER_TOTAL_UNREAD_ERROR";
|
|
278
|
+
ErrorCode[ErrorCode["CONVER_TYPE_UNREAD_ERROR"] = 34005] = "CONVER_TYPE_UNREAD_ERROR";
|
|
279
|
+
ErrorCode[ErrorCode["CONVER_ID_TYPE_UNREAD_ERROR"] = 34006] = "CONVER_ID_TYPE_UNREAD_ERROR";
|
|
280
|
+
ErrorCode[ErrorCode["CONVER_OUT_LIMIT_ERROR"] = 34013] = "CONVER_OUT_LIMIT_ERROR";
|
|
281
|
+
ErrorCode[ErrorCode["MEDIA_EXCEPTION"] = 34018] = "MEDIA_EXCEPTION";
|
|
282
|
+
ErrorCode[ErrorCode["CONVER_GET_ERROR"] = 35021] = "CONVER_GET_ERROR";
|
|
283
|
+
ErrorCode[ErrorCode["GROUP_SYNC_ERROR"] = 35001] = "GROUP_SYNC_ERROR";
|
|
284
|
+
ErrorCode[ErrorCode["CAN_NOT_RECONNECT"] = 35007] = "CAN_NOT_RECONNECT";
|
|
285
|
+
ErrorCode[ErrorCode["HAS_OHTER_SAME_CLIENT_ON_LINE"] = 35010] = "HAS_OHTER_SAME_CLIENT_ON_LINE";
|
|
286
|
+
ErrorCode[ErrorCode["METHOD_NOT_AVAILABLE"] = 35011] = "METHOD_NOT_AVAILABLE";
|
|
287
|
+
ErrorCode[ErrorCode["METHOD_NOT_SUPPORT"] = 35012] = "METHOD_NOT_SUPPORT";
|
|
288
|
+
ErrorCode[ErrorCode["MSG_LIMIT_ERROR"] = 35013] = "MSG_LIMIT_ERROR";
|
|
289
|
+
ErrorCode[ErrorCode["METHOD_ONLY_SUPPORT_ULTRA_GROUP"] = 35014] = "METHOD_ONLY_SUPPORT_ULTRA_GROUP";
|
|
290
|
+
ErrorCode[ErrorCode["UPLOAD_FILE_FAILED"] = 35020] = "UPLOAD_FILE_FAILED";
|
|
291
|
+
ErrorCode[ErrorCode["DRAF_GET_ERROR"] = 38001] = "DRAF_GET_ERROR";
|
|
292
|
+
ErrorCode[ErrorCode["DRAF_SAVE_ERROR"] = 38002] = "DRAF_SAVE_ERROR";
|
|
293
|
+
ErrorCode[ErrorCode["DRAF_REMOVE_ERROR"] = 38003] = "DRAF_REMOVE_ERROR";
|
|
294
|
+
ErrorCode[ErrorCode["NOT_SUPPORT"] = 39002] = "NOT_SUPPORT";
|
|
295
|
+
})(ErrorCode || (ErrorCode = {}));
|
|
296
|
+
var ConversationType;
|
|
297
|
+
(function (ConversationType) {
|
|
298
|
+
ConversationType[ConversationType["PRIVATE"] = 1] = "PRIVATE";
|
|
299
|
+
ConversationType[ConversationType["GROUP"] = 3] = "GROUP";
|
|
300
|
+
})(ConversationType || (ConversationType = {}));
|
|
301
|
+
var MentionedType;
|
|
302
|
+
(function (MentionedType) {
|
|
303
|
+
MentionedType[MentionedType["ALL"] = 1] = "ALL";
|
|
304
|
+
MentionedType[MentionedType["SINGAL"] = 2] = "SINGAL";
|
|
305
|
+
})(MentionedType || (MentionedType = {}));
|
|
306
|
+
var NotificationStatus;
|
|
307
|
+
(function (NotificationStatus) {
|
|
308
|
+
NotificationStatus[NotificationStatus["OPEN"] = 1] = "OPEN";
|
|
309
|
+
NotificationStatus[NotificationStatus["CLOSE"] = 2] = "CLOSE";
|
|
310
|
+
})(NotificationStatus || (NotificationStatus = {}));
|
|
311
|
+
var MessageDirection;
|
|
312
|
+
(function (MessageDirection) {
|
|
313
|
+
MessageDirection[MessageDirection["SEND"] = 1] = "SEND";
|
|
314
|
+
MessageDirection[MessageDirection["RECEIVE"] = 2] = "RECEIVE";
|
|
315
|
+
})(MessageDirection || (MessageDirection = {}));
|
|
316
|
+
var SentStatus;
|
|
317
|
+
(function (SentStatus) {
|
|
318
|
+
SentStatus[SentStatus["SENDING"] = 10] = "SENDING";
|
|
319
|
+
SentStatus[SentStatus["FAILED"] = 20] = "FAILED";
|
|
320
|
+
SentStatus[SentStatus["SENT"] = 30] = "SENT";
|
|
321
|
+
})(SentStatus || (SentStatus = {}));
|
|
322
|
+
var ReceivedStatus;
|
|
323
|
+
(function (ReceivedStatus) {
|
|
324
|
+
ReceivedStatus[ReceivedStatus["IDLE"] = 0] = "IDLE";
|
|
325
|
+
ReceivedStatus[ReceivedStatus["RECEIVED"] = 1] = "RECEIVED";
|
|
326
|
+
ReceivedStatus[ReceivedStatus["READ"] = 2] = "READ";
|
|
327
|
+
ReceivedStatus[ReceivedStatus["LISTENED"] = 3] = "LISTENED";
|
|
328
|
+
})(ReceivedStatus || (ReceivedStatus = {}));
|
|
329
|
+
var NotificationLevel;
|
|
330
|
+
(function (NotificationLevel) {
|
|
331
|
+
NotificationLevel[NotificationLevel["ALL_MESSAGE"] = -1] = "ALL_MESSAGE";
|
|
332
|
+
NotificationLevel[NotificationLevel["NOT_SET"] = 0] = "NOT_SET";
|
|
333
|
+
NotificationLevel[NotificationLevel["AT_MESSAGE_NOTIFICATION"] = 1] = "AT_MESSAGE_NOTIFICATION";
|
|
334
|
+
NotificationLevel[NotificationLevel["AT_USER_NOTIFICATION"] = 2] = "AT_USER_NOTIFICATION";
|
|
335
|
+
NotificationLevel[NotificationLevel["AT_GROUP_ALL_USER_NOTIFICATION"] = 4] = "AT_GROUP_ALL_USER_NOTIFICATION";
|
|
336
|
+
NotificationLevel[NotificationLevel["NOT_MESSAGE_NOTIFICATION"] = 5] = "NOT_MESSAGE_NOTIFICATION";
|
|
337
|
+
})(NotificationLevel || (NotificationLevel = {}));
|
|
338
|
+
|
|
339
|
+
function extractLegacyMediaReferences(message) {
|
|
340
|
+
const { messageId, conversationType, targetId } = message;
|
|
341
|
+
if (!Number.isSafeInteger(messageId) ||
|
|
342
|
+
typeof conversationType !== 'number' ||
|
|
343
|
+
!Number.isSafeInteger(conversationType) ||
|
|
344
|
+
typeof targetId !== 'string' ||
|
|
345
|
+
!targetId) {
|
|
346
|
+
return [];
|
|
347
|
+
}
|
|
348
|
+
const result = [];
|
|
349
|
+
const content = message.content ?? {};
|
|
350
|
+
const add = (kind, value) => {
|
|
351
|
+
const objectKey = typeof value === 'string' ? value.trim() : '';
|
|
352
|
+
if (!objectKey) {
|
|
353
|
+
return;
|
|
354
|
+
}
|
|
355
|
+
result.push({
|
|
356
|
+
messageId,
|
|
357
|
+
conversationType,
|
|
358
|
+
targetId,
|
|
359
|
+
objectKey,
|
|
360
|
+
kind
|
|
361
|
+
});
|
|
362
|
+
};
|
|
363
|
+
switch (message.messageType) {
|
|
364
|
+
case MessageTypes.IMAGE:
|
|
365
|
+
add('image', content.originalObjectKey);
|
|
366
|
+
add('image-thumbnail', content.thumbnailObjectKey);
|
|
367
|
+
break;
|
|
368
|
+
case MessageTypes.GIF:
|
|
369
|
+
add('gif', content.originalObjectKey);
|
|
370
|
+
break;
|
|
371
|
+
case MessageTypes.VIDEO:
|
|
372
|
+
add('video', content.videoObjectKey);
|
|
373
|
+
add('video-thumbnail', content.thumbnailObjectKey);
|
|
374
|
+
break;
|
|
375
|
+
case MessageTypes.FILE:
|
|
376
|
+
add('file', content.fileKey);
|
|
377
|
+
break;
|
|
378
|
+
case MessageTypes.AUDIO:
|
|
379
|
+
add('audio', content.audioObjectKey);
|
|
380
|
+
break;
|
|
381
|
+
}
|
|
382
|
+
return result;
|
|
383
|
+
}
|
|
384
|
+
|
|
190
385
|
const LEGACY_MIGRATION_KEY = 'legacy_indexeddb_migration';
|
|
191
386
|
function parseMessage(row) {
|
|
192
387
|
if (!row) {
|
|
@@ -196,8 +391,38 @@ function parseMessage(row) {
|
|
|
196
391
|
message.pinned = message.pinned ?? false;
|
|
197
392
|
return message;
|
|
198
393
|
}
|
|
394
|
+
function mergeStoredReceiptStatus(incoming, existing) {
|
|
395
|
+
if (!existing) {
|
|
396
|
+
return incoming;
|
|
397
|
+
}
|
|
398
|
+
const existingStatus = existing.receivedStatus ?? -1;
|
|
399
|
+
const incomingStatus = incoming.receivedStatus ?? -1;
|
|
400
|
+
const merged = existingStatus <= incomingStatus
|
|
401
|
+
? {
|
|
402
|
+
...incoming,
|
|
403
|
+
messageId: existing.messageId
|
|
404
|
+
}
|
|
405
|
+
: {
|
|
406
|
+
...incoming,
|
|
407
|
+
messageId: existing.messageId,
|
|
408
|
+
receivedStatus: existing.receivedStatus
|
|
409
|
+
};
|
|
410
|
+
if (incoming.reactions == null && existing.reactions != null) {
|
|
411
|
+
merged.reactions = existing.reactions;
|
|
412
|
+
}
|
|
413
|
+
if (incoming.burnAfterReadingStartedAt == null &&
|
|
414
|
+
existing.burnAfterReadingStartedAt != null) {
|
|
415
|
+
merged.burnAfterReadingStartedAt = existing.burnAfterReadingStartedAt;
|
|
416
|
+
}
|
|
417
|
+
return merged;
|
|
418
|
+
}
|
|
199
419
|
function extractSearchText(message) {
|
|
200
420
|
const content = message.content;
|
|
421
|
+
if (message.messageType === MessageTypes.FILE &&
|
|
422
|
+
content &&
|
|
423
|
+
typeof content.title === 'string') {
|
|
424
|
+
return content.title;
|
|
425
|
+
}
|
|
201
426
|
if (typeof content === 'string') {
|
|
202
427
|
return content;
|
|
203
428
|
}
|
|
@@ -213,6 +438,32 @@ function normalizeInteger(value, name) {
|
|
|
213
438
|
}
|
|
214
439
|
return number;
|
|
215
440
|
}
|
|
441
|
+
function isBurnAfterReadingMessageVisible(message, now) {
|
|
442
|
+
if (!message.burnAfterReadingFlag) {
|
|
443
|
+
return true;
|
|
444
|
+
}
|
|
445
|
+
const burnAfterReadingTime = message.burnAfterReadingTime ?? 0;
|
|
446
|
+
const sentTime = Number(message.sentTime);
|
|
447
|
+
if (message.messageDirection === MessageDirection.RECEIVE) {
|
|
448
|
+
if ((message.receivedStatus ?? ReceivedStatus.IDLE) < ReceivedStatus.READ) {
|
|
449
|
+
return true;
|
|
450
|
+
}
|
|
451
|
+
if (burnAfterReadingTime <= 0) {
|
|
452
|
+
return false;
|
|
453
|
+
}
|
|
454
|
+
const startedAt = message.burnAfterReadingStartedAt ?? sentTime;
|
|
455
|
+
return !Number.isFinite(startedAt) || startedAt + burnAfterReadingTime > now;
|
|
456
|
+
}
|
|
457
|
+
if (message.messageDirection === MessageDirection.SEND) {
|
|
458
|
+
if (message.sentStatus !== SentStatus.SENT) {
|
|
459
|
+
return true;
|
|
460
|
+
}
|
|
461
|
+
return (burnAfterReadingTime > 0 &&
|
|
462
|
+
(!Number.isFinite(sentTime) || sentTime + burnAfterReadingTime > now));
|
|
463
|
+
}
|
|
464
|
+
return (burnAfterReadingTime > 0 &&
|
|
465
|
+
(!Number.isFinite(sentTime) || sentTime + burnAfterReadingTime > now));
|
|
466
|
+
}
|
|
216
467
|
class MessageStore {
|
|
217
468
|
database;
|
|
218
469
|
constructor(database) {
|
|
@@ -244,20 +495,24 @@ class MessageStore {
|
|
|
244
495
|
if (message.isPersited === false) {
|
|
245
496
|
continue;
|
|
246
497
|
}
|
|
247
|
-
const
|
|
248
|
-
|
|
498
|
+
const existing = message.messageUId
|
|
499
|
+
? this.getMessageByUId(message.messageUId)
|
|
500
|
+
: this.getMessageById(normalizeInteger(message.messageId, 'messageId'));
|
|
501
|
+
const merged = mergeStoredReceiptStatus(message, existing);
|
|
502
|
+
const messageId = normalizeInteger(merged.messageId, 'messageId');
|
|
503
|
+
const sentTime = normalizeInteger(merged.sentTime, 'sentTime');
|
|
249
504
|
upsert.run({
|
|
250
505
|
messageId,
|
|
251
|
-
messageUId:
|
|
506
|
+
messageUId: merged.messageUId ?? null,
|
|
252
507
|
dialogId,
|
|
253
508
|
sentTime,
|
|
254
|
-
receivedStatus:
|
|
255
|
-
burnAfterReadingFlag:
|
|
256
|
-
burnAfterReadingTime:
|
|
257
|
-
messageType:
|
|
258
|
-
pinned:
|
|
259
|
-
json: JSON.stringify(
|
|
260
|
-
searchText: extractSearchText(
|
|
509
|
+
receivedStatus: merged.receivedStatus ?? null,
|
|
510
|
+
burnAfterReadingFlag: merged.burnAfterReadingFlag ? 1 : 0,
|
|
511
|
+
burnAfterReadingTime: merged.burnAfterReadingTime ?? null,
|
|
512
|
+
messageType: merged.messageType ?? null,
|
|
513
|
+
pinned: merged.pinned ? 1 : 0,
|
|
514
|
+
json: JSON.stringify(merged),
|
|
515
|
+
searchText: extractSearchText(merged)
|
|
261
516
|
});
|
|
262
517
|
}
|
|
263
518
|
if (isEnd !== undefined) {
|
|
@@ -270,33 +525,54 @@ class MessageStore {
|
|
|
270
525
|
}
|
|
271
526
|
getMessages(dialogId, timestamp = '0', count = 20, isForward = true) {
|
|
272
527
|
const safeCount = Math.max(0, Math.floor(count));
|
|
528
|
+
const batchSize = Math.max(safeCount + 1, 50);
|
|
273
529
|
const params = {
|
|
274
530
|
dialogId,
|
|
275
|
-
limit:
|
|
531
|
+
limit: batchSize
|
|
276
532
|
};
|
|
533
|
+
let offset = 0;
|
|
277
534
|
let timeClause = '';
|
|
278
535
|
if (timestamp !== '0') {
|
|
279
536
|
params.timestamp = normalizeInteger(timestamp, 'timestamp');
|
|
280
|
-
timeClause = isForward
|
|
537
|
+
timeClause = isForward
|
|
538
|
+
? 'AND sentTime < $timestamp'
|
|
539
|
+
: 'AND sentTime > $timestamp';
|
|
281
540
|
}
|
|
282
541
|
const direction = isForward ? 'DESC' : 'ASC';
|
|
283
|
-
const
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
542
|
+
const select = this.database.prepare(`SELECT json FROM messages
|
|
543
|
+
WHERE dialogId = $dialogId ${timeClause}
|
|
544
|
+
ORDER BY sentTime ${direction}, messageId ${direction}
|
|
545
|
+
LIMIT $limit OFFSET $offset;`);
|
|
546
|
+
const visibleMessages = [];
|
|
547
|
+
const now = Date.now();
|
|
548
|
+
while (visibleMessages.length <= safeCount) {
|
|
549
|
+
const rows = select.all({ ...params, offset });
|
|
550
|
+
for (const row of rows) {
|
|
551
|
+
const message = parseMessage(row);
|
|
552
|
+
if (message && isBurnAfterReadingMessageVisible(message, now)) {
|
|
553
|
+
visibleMessages.push(message);
|
|
554
|
+
if (visibleMessages.length > safeCount) {
|
|
555
|
+
break;
|
|
556
|
+
}
|
|
557
|
+
}
|
|
558
|
+
}
|
|
559
|
+
if (rows.length < batchSize || visibleMessages.length > safeCount) {
|
|
560
|
+
break;
|
|
561
|
+
}
|
|
562
|
+
offset += rows.length;
|
|
563
|
+
}
|
|
564
|
+
const hasAdditionalMessage = visibleMessages.length > safeCount;
|
|
565
|
+
const messages = visibleMessages
|
|
291
566
|
.slice(0, safeCount)
|
|
292
|
-
.map(row => parseMessage(row))
|
|
293
567
|
.sort((left, right) => {
|
|
294
568
|
const byTime = Number(left.sentTime) - Number(right.sentTime);
|
|
295
569
|
return byTime || left.messageId - right.messageId;
|
|
296
570
|
});
|
|
297
571
|
return {
|
|
298
572
|
messages,
|
|
299
|
-
hasMore:
|
|
573
|
+
hasMore: isForward
|
|
574
|
+
? hasAdditionalMessage || !this.getDialogLoadedState(dialogId)
|
|
575
|
+
: hasAdditionalMessage
|
|
300
576
|
};
|
|
301
577
|
}
|
|
302
578
|
getMessagesByType(dialogId, messageTypes, timestamp = '0', count = 50, isForward = true) {
|
|
@@ -431,7 +707,7 @@ class MessageStore {
|
|
|
431
707
|
}
|
|
432
708
|
})();
|
|
433
709
|
}
|
|
434
|
-
updateMessageReceiptStatus(messageUIds, receivedStatus) {
|
|
710
|
+
updateMessageReceiptStatus(messageUIds, receivedStatus, burnAfterReadingStartedAt) {
|
|
435
711
|
const select = this.database.prepare('SELECT json, receivedStatus FROM messages WHERE messageUId = $messageUId;');
|
|
436
712
|
const update = this.database.prepare(`
|
|
437
713
|
UPDATE messages SET receivedStatus = $receivedStatus, json = $json
|
|
@@ -440,12 +716,31 @@ class MessageStore {
|
|
|
440
716
|
this.database.transaction(() => {
|
|
441
717
|
for (const messageUId of messageUIds) {
|
|
442
718
|
const row = select.get({ messageUId });
|
|
443
|
-
if (!row
|
|
719
|
+
if (!row) {
|
|
444
720
|
continue;
|
|
445
721
|
}
|
|
446
722
|
const message = JSON.parse(row.json);
|
|
447
|
-
|
|
448
|
-
|
|
723
|
+
const shouldAdvanceStatus = (row.receivedStatus ?? -1) < receivedStatus;
|
|
724
|
+
const shouldStartBurn = burnAfterReadingStartedAt != null &&
|
|
725
|
+
receivedStatus === ReceivedStatus.READ &&
|
|
726
|
+
message.messageDirection === MessageDirection.RECEIVE &&
|
|
727
|
+
message.burnAfterReadingFlag === true &&
|
|
728
|
+
message.burnAfterReadingStartedAt == null;
|
|
729
|
+
if (!shouldAdvanceStatus && !shouldStartBurn) {
|
|
730
|
+
continue;
|
|
731
|
+
}
|
|
732
|
+
const nextReceivedStatus = shouldAdvanceStatus
|
|
733
|
+
? receivedStatus
|
|
734
|
+
: row.receivedStatus ?? receivedStatus;
|
|
735
|
+
message.receivedStatus = nextReceivedStatus;
|
|
736
|
+
if (shouldStartBurn) {
|
|
737
|
+
message.burnAfterReadingStartedAt = burnAfterReadingStartedAt;
|
|
738
|
+
}
|
|
739
|
+
update.run({
|
|
740
|
+
messageUId,
|
|
741
|
+
receivedStatus: nextReceivedStatus,
|
|
742
|
+
json: JSON.stringify(message)
|
|
743
|
+
});
|
|
449
744
|
}
|
|
450
745
|
})();
|
|
451
746
|
}
|
|
@@ -469,6 +764,31 @@ class MessageStore {
|
|
|
469
764
|
json: JSON.stringify(message)
|
|
470
765
|
});
|
|
471
766
|
}
|
|
767
|
+
setMessageReactions(dialogId, messageUId, reactions) {
|
|
768
|
+
const row = this.database
|
|
769
|
+
.prepare(`SELECT json FROM messages
|
|
770
|
+
WHERE dialogId = $dialogId AND messageUId = $messageUId;`)
|
|
771
|
+
.get({ dialogId, messageUId });
|
|
772
|
+
const message = parseMessage(row);
|
|
773
|
+
if (!message) {
|
|
774
|
+
return false;
|
|
775
|
+
}
|
|
776
|
+
if (reactions.length) {
|
|
777
|
+
message.reactions = reactions;
|
|
778
|
+
}
|
|
779
|
+
else {
|
|
780
|
+
delete message.reactions;
|
|
781
|
+
}
|
|
782
|
+
this.database
|
|
783
|
+
.prepare(`UPDATE messages SET json = $json
|
|
784
|
+
WHERE dialogId = $dialogId AND messageUId = $messageUId;`)
|
|
785
|
+
.run({
|
|
786
|
+
dialogId,
|
|
787
|
+
messageUId,
|
|
788
|
+
json: JSON.stringify(message)
|
|
789
|
+
});
|
|
790
|
+
return true;
|
|
791
|
+
}
|
|
472
792
|
unpinAllMessages(dialogId) {
|
|
473
793
|
const rows = this.database
|
|
474
794
|
.prepare(`SELECT messageUId, json FROM messages
|
|
@@ -493,20 +813,23 @@ class MessageStore {
|
|
|
493
813
|
}
|
|
494
814
|
clearBurnAfterReadingExpiredMessages(dialogId, now = Date.now()) {
|
|
495
815
|
const rows = this.database
|
|
496
|
-
.prepare(`SELECT messageUId FROM messages
|
|
497
|
-
WHERE dialogId = $dialogId
|
|
498
|
-
AND burnAfterReadingFlag = 1
|
|
499
|
-
AND (burnAfterReadingTime IS NULL OR burnAfterReadingTime = 0
|
|
500
|
-
OR sentTime + burnAfterReadingTime <= $now);`, { pluck: true })
|
|
501
|
-
.all({ dialogId, now });
|
|
502
|
-
this.database
|
|
503
|
-
.prepare(`DELETE FROM messages
|
|
816
|
+
.prepare(`SELECT messageId, messageUId, json FROM messages
|
|
504
817
|
WHERE dialogId = $dialogId
|
|
505
|
-
AND burnAfterReadingFlag = 1
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
818
|
+
AND burnAfterReadingFlag = 1;`)
|
|
819
|
+
.all({
|
|
820
|
+
dialogId
|
|
821
|
+
});
|
|
822
|
+
const expiredRows = rows.filter(row => {
|
|
823
|
+
const message = parseMessage({ json: row.json });
|
|
824
|
+
return message != null && !isBurnAfterReadingMessageVisible(message, now);
|
|
825
|
+
});
|
|
826
|
+
const remove = this.database.prepare('DELETE FROM messages WHERE messageId = $messageId;');
|
|
827
|
+
this.database.transaction(() => {
|
|
828
|
+
for (const row of expiredRows) {
|
|
829
|
+
remove.run({ messageId: row.messageId });
|
|
830
|
+
}
|
|
831
|
+
})();
|
|
832
|
+
return expiredRows.flatMap(row => row.messageUId == null ? [] : [row.messageUId]);
|
|
510
833
|
}
|
|
511
834
|
convertToRecallMessages(messageUIds, recallMessageType) {
|
|
512
835
|
const select = this.database.prepare('SELECT json FROM messages WHERE messageUId = $messageUId;');
|
|
@@ -576,6 +899,29 @@ class MessageStore {
|
|
|
576
899
|
})
|
|
577
900
|
.map(row => parseMessage(row));
|
|
578
901
|
}
|
|
902
|
+
getLegacyMediaReferences(afterMessageId = 0, limit = 500) {
|
|
903
|
+
const safeCursor = Number.isSafeInteger(afterMessageId)
|
|
904
|
+
? afterMessageId
|
|
905
|
+
: 0;
|
|
906
|
+
const safeLimit = Math.min(1000, Math.max(1, Math.floor(limit)));
|
|
907
|
+
const rows = this.database
|
|
908
|
+
.prepare(`SELECT messageId, json
|
|
909
|
+
FROM messages
|
|
910
|
+
WHERE messageId > $afterMessageId
|
|
911
|
+
ORDER BY messageId ASC
|
|
912
|
+
LIMIT $limit;`)
|
|
913
|
+
.all({
|
|
914
|
+
afterMessageId: safeCursor,
|
|
915
|
+
limit: safeLimit
|
|
916
|
+
});
|
|
917
|
+
const nextCursor = rows.length === safeLimit
|
|
918
|
+
? rows[rows.length - 1]?.messageId
|
|
919
|
+
: undefined;
|
|
920
|
+
return {
|
|
921
|
+
items: rows.flatMap(row => extractLegacyMediaReferences(JSON.parse(row.json))),
|
|
922
|
+
...(nextCursor === undefined ? {} : { nextCursor })
|
|
923
|
+
};
|
|
924
|
+
}
|
|
579
925
|
getLegacyMigrationState() {
|
|
580
926
|
const value = this.database
|
|
581
927
|
.prepare('SELECT value FROM metadata WHERE key = $key;', { pluck: true })
|