@onyx-p/imlib-web 3.0.3 → 3.0.4

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/database/main.cjs CHANGED
@@ -66,6 +66,7 @@ const READ_METHOD_NAMES = [
66
66
  'getMessageByUId',
67
67
  'getMessageIdRange',
68
68
  'getMessagesByType',
69
+ 'getPinnedMessages',
69
70
  'searchMessages',
70
71
  'searchTextMessages',
71
72
  'getLegacyMigrationState'
@@ -76,6 +77,8 @@ const WRITE_METHOD_NAMES = [
76
77
  'clearAllCache',
77
78
  'removeMessagesByUId',
78
79
  'updateMessageReceiptStatus',
80
+ 'setMessagePinned',
81
+ 'unpinAllMessages',
79
82
  'clearBurnAfterReadingExpiredMessages',
80
83
  'upsertMessage',
81
84
  'convertToRecallMessages',
@@ -13,6 +13,7 @@ const READ_METHOD_NAMES = [
13
13
  'getMessageByUId',
14
14
  'getMessageIdRange',
15
15
  'getMessagesByType',
16
+ 'getPinnedMessages',
16
17
  'searchMessages',
17
18
  'searchTextMessages',
18
19
  'getLegacyMigrationState'
@@ -23,6 +24,8 @@ const WRITE_METHOD_NAMES = [
23
24
  'clearAllCache',
24
25
  'removeMessagesByUId',
25
26
  'updateMessageReceiptStatus',
27
+ 'setMessagePinned',
28
+ 'unpinAllMessages',
26
29
  'clearBurnAfterReadingExpiredMessages',
27
30
  'upsertMessage',
28
31
  'convertToRecallMessages',
@@ -16,6 +16,7 @@ const READ_METHOD_NAMES = [
16
16
  'getMessageByUId',
17
17
  'getMessageIdRange',
18
18
  'getMessagesByType',
19
+ 'getPinnedMessages',
19
20
  'searchMessages',
20
21
  'searchTextMessages',
21
22
  'getLegacyMigrationState'
@@ -26,6 +27,8 @@ const WRITE_METHOD_NAMES = [
26
27
  'clearAllCache',
27
28
  'removeMessagesByUId',
28
29
  'updateMessageReceiptStatus',
30
+ 'setMessagePinned',
31
+ 'unpinAllMessages',
29
32
  'clearBurnAfterReadingExpiredMessages',
30
33
  'upsertMessage',
31
34
  'convertToRecallMessages',
@@ -143,6 +146,17 @@ const SCHEMA_MIGRATIONS = [
143
146
  ON messages (dialogId, messageType, sentTime DESC, messageId DESC);
144
147
  `);
145
148
  }
149
+ },
150
+ {
151
+ version: 6,
152
+ up(database) {
153
+ database.exec(`
154
+ ALTER TABLE messages ADD COLUMN pinned INTEGER NOT NULL DEFAULT 0;
155
+
156
+ CREATE INDEX messages_by_dialog_pinned_time
157
+ ON messages (dialogId, pinned, sentTime DESC, messageId DESC);
158
+ `);
159
+ }
146
160
  }
147
161
  ];
148
162
  SCHEMA_MIGRATIONS[SCHEMA_MIGRATIONS.length - 1]?.version ?? 0;
@@ -175,7 +189,12 @@ function runMigrations(database, migrations = SCHEMA_MIGRATIONS) {
175
189
 
176
190
  const LEGACY_MIGRATION_KEY = 'legacy_indexeddb_migration';
177
191
  function parseMessage(row) {
178
- return row ? JSON.parse(row.json) : null;
192
+ if (!row) {
193
+ return null;
194
+ }
195
+ const message = JSON.parse(row.json);
196
+ message.pinned = message.pinned ?? false;
197
+ return message;
179
198
  }
180
199
  function extractSearchText(message) {
181
200
  const content = message.content;
@@ -203,10 +222,10 @@ class MessageStore {
203
222
  const upsert = this.database.prepare(`
204
223
  INSERT INTO messages (
205
224
  messageId, messageUId, dialogId, sentTime, receivedStatus,
206
- burnAfterReadingFlag, burnAfterReadingTime, messageType, json, searchText
225
+ burnAfterReadingFlag, burnAfterReadingTime, messageType, pinned, json, searchText
207
226
  ) VALUES (
208
227
  $messageId, $messageUId, $dialogId, $sentTime, $receivedStatus,
209
- $burnAfterReadingFlag, $burnAfterReadingTime, $messageType, $json, $searchText
228
+ $burnAfterReadingFlag, $burnAfterReadingTime, $messageType, $pinned, $json, $searchText
210
229
  )
211
230
  ON CONFLICT(messageId) DO UPDATE SET
212
231
  messageUId = excluded.messageUId,
@@ -216,6 +235,7 @@ class MessageStore {
216
235
  burnAfterReadingFlag = excluded.burnAfterReadingFlag,
217
236
  burnAfterReadingTime = excluded.burnAfterReadingTime,
218
237
  messageType = excluded.messageType,
238
+ pinned = excluded.pinned,
219
239
  json = excluded.json,
220
240
  searchText = excluded.searchText;
221
241
  `);
@@ -235,6 +255,7 @@ class MessageStore {
235
255
  burnAfterReadingFlag: message.burnAfterReadingFlag ? 1 : 0,
236
256
  burnAfterReadingTime: message.burnAfterReadingTime ?? null,
237
257
  messageType: message.messageType ?? null,
258
+ pinned: message.pinned ? 1 : 0,
238
259
  json: JSON.stringify(message),
239
260
  searchText: extractSearchText(message)
240
261
  });
@@ -358,6 +379,23 @@ class MessageStore {
358
379
  .prepare('SELECT json FROM messages WHERE messageUId = $messageUId;')
359
380
  .get({ messageUId }));
360
381
  }
382
+ getPinnedMessages(dialogId, count = 50) {
383
+ const safeCount = Math.max(0, Math.floor(count));
384
+ if (safeCount === 0) {
385
+ return [];
386
+ }
387
+ return this.database
388
+ .prepare(`SELECT json FROM messages
389
+ WHERE dialogId = $dialogId AND pinned = 1
390
+ ORDER BY sentTime DESC, messageId DESC
391
+ LIMIT $limit;`)
392
+ .all({ dialogId, limit: safeCount })
393
+ .map(row => parseMessage(row))
394
+ .sort((left, right) => {
395
+ const byTime = Number(left.sentTime) - Number(right.sentTime);
396
+ return byTime || left.messageId - right.messageId;
397
+ });
398
+ }
361
399
  getMessageIdRange() {
362
400
  const row = this.database
363
401
  .prepare('SELECT MIN(messageId) AS oldest, MAX(messageId) AS newest FROM messages;')
@@ -411,6 +449,48 @@ class MessageStore {
411
449
  }
412
450
  })();
413
451
  }
452
+ setMessagePinned(dialogId, messageUId, pinned) {
453
+ const row = this.database
454
+ .prepare(`SELECT json FROM messages
455
+ WHERE dialogId = $dialogId AND messageUId = $messageUId;`)
456
+ .get({ dialogId, messageUId });
457
+ const message = parseMessage(row);
458
+ if (!message) {
459
+ return;
460
+ }
461
+ message.pinned = pinned;
462
+ this.database
463
+ .prepare(`UPDATE messages SET pinned = $pinned, json = $json
464
+ WHERE dialogId = $dialogId AND messageUId = $messageUId;`)
465
+ .run({
466
+ dialogId,
467
+ messageUId,
468
+ pinned: pinned ? 1 : 0,
469
+ json: JSON.stringify(message)
470
+ });
471
+ }
472
+ unpinAllMessages(dialogId) {
473
+ const rows = this.database
474
+ .prepare(`SELECT messageUId, json FROM messages
475
+ WHERE dialogId = $dialogId AND pinned = 1;`)
476
+ .all({ dialogId });
477
+ const update = this.database.prepare(`UPDATE messages SET pinned = 0, json = $json
478
+ WHERE dialogId = $dialogId AND messageUId = $messageUId;`);
479
+ this.database.transaction(() => {
480
+ for (const row of rows) {
481
+ const message = parseMessage(row);
482
+ if (!message) {
483
+ continue;
484
+ }
485
+ message.pinned = false;
486
+ update.run({
487
+ dialogId,
488
+ messageUId: row.messageUId,
489
+ json: JSON.stringify(message)
490
+ });
491
+ }
492
+ })();
493
+ }
414
494
  clearBurnAfterReadingExpiredMessages(dialogId, now = Date.now()) {
415
495
  const rows = this.database
416
496
  .prepare(`SELECT messageUId FROM messages
@@ -431,7 +511,7 @@ class MessageStore {
431
511
  convertToRecallMessages(messageUIds, recallMessageType) {
432
512
  const select = this.database.prepare('SELECT json FROM messages WHERE messageUId = $messageUId;');
433
513
  const update = this.database.prepare(`
434
- UPDATE messages SET messageType = $messageType, json = $json, searchText = ''
514
+ UPDATE messages SET messageType = $messageType, pinned = 0, json = $json, searchText = ''
435
515
  WHERE messageUId = $messageUId;
436
516
  `);
437
517
  this.database.transaction(() => {
@@ -447,6 +527,7 @@ class MessageStore {
447
527
  message.isCounted = false;
448
528
  message.isMentioned = false;
449
529
  message.disableNotification = true;
530
+ message.pinned = false;
450
531
  update.run({
451
532
  messageUId,
452
533
  messageType: recallMessageType,