@onyx-p/imlib-web 2.3.2 → 2.3.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.
Files changed (3) hide show
  1. package/index.esm.js +445 -417
  2. package/index.umd.js +445 -417
  3. package/package.json +1 -1
package/index.umd.js CHANGED
@@ -20728,302 +20728,13 @@
20728
20728
  return lastMessageId;
20729
20729
  }
20730
20730
 
20731
- class MessageLoader {
20732
- watcher;
20733
- pullingMsg = false;
20734
- letterbox;
20735
- serverMsgSeqno = Long.ZERO;
20736
- pullOfflineFinished = false;
20737
- intervalTimer;
20738
- retryTimer;
20739
- latestSyncTimestamp = 0;
20740
- started = false;
20741
- constructor(watcher, options) {
20742
- this.watcher = watcher;
20743
- this.letterbox = new Letterbox(options.appkey, accountStore.uid.toString());
20744
- }
20745
- start() {
20746
- this.started = true;
20747
- this.pullOfflineFinished = false;
20748
- this.startPullInterval();
20749
- }
20750
- stop() {
20751
- this.started = false;
20752
- this.stopPullInterval();
20753
- this.cancelRetryTask();
20754
- }
20755
- syncMsg(seqno) {
20756
- this.serverMsgSeqno = seqno;
20757
- this.pullMsg();
20758
- }
20759
- startPullInterval() {
20760
- this.stopPullInterval();
20761
- const d = 3 * 60 * 1000;
20762
- this.intervalTimer = setInterval(() => {
20763
- if (Date.now() - this.latestSyncTimestamp >= d) {
20764
- this.pullMsg();
20765
- }
20766
- }, 30000);
20767
- this.latestSyncTimestamp = Date.now();
20768
- this.pullMsg();
20769
- }
20770
- stopPullInterval() {
20771
- if (this.intervalTimer) {
20772
- clearInterval(this.intervalTimer);
20773
- this.intervalTimer = null;
20774
- }
20775
- }
20776
- try2RePullMsg() {
20777
- this.retryTimer = setTimeout(() => {
20778
- this.retryTimer = null;
20779
- this.pullMsg();
20780
- }, 1000);
20781
- }
20782
- cancelRetryTask() {
20783
- if (this.retryTimer) {
20784
- clearTimeout(this.retryTimer);
20785
- this.retryTimer = null;
20786
- }
20787
- }
20788
- async pullMsg() {
20789
- if (this.pullingMsg) {
20790
- return;
20791
- }
20792
- if (!this.started) {
20793
- return;
20794
- }
20795
- this.cancelRetryTask();
20796
- this.pullingMsg = true;
20797
- const inboxTime = this.letterbox.getInboxOffset();
20798
- logger.info(`pullMsg -> time: ${inboxTime}`);
20799
- this.latestSyncTimestamp = Date.now();
20800
- const {
20801
- code,
20802
- data
20803
- } = await getNewMessages(inboxTime, 60);
20804
- if (code !== exports.ErrorCode.SUCCESS) {
20805
- logger.warn('pullMsg failed -> code:', code);
20806
- this.pullingMsg = false;
20807
- if (LibLoader.loader?.getConnectionStatus() == exports.ConnectionStatus.CONNECTED) {
20808
- this.try2RePullMsg();
20809
- }
20810
- return;
20811
- }
20812
- const {
20813
- offset,
20814
- seqno,
20815
- msg
20816
- } = data;
20817
- const cons = Object.keys(msg).map(dialogId => {
20818
- const conversationType = extractConversationType(Long.fromString(dialogId));
20819
- return {
20820
- conversationType,
20821
- targetId: dialogId
20822
- };
20823
- });
20824
- await ConversationManager$1.get().loadConvsationsIfNotExist(cons);
20825
- serverMessageParser.parse(msg, (done, outputMsgs) => {
20826
- const messages = [];
20827
- const recallMessageIndexes = [];
20828
- const isOffLineMessage = !this.pullOfflineFinished;
20829
- outputMsgs.forEach((l, dialogId) => {
20830
- let messageList = [];
20831
- l.forEach(m => {
20832
- if (m.messageType === MessageTypes.RECALL && RecallMessageStore.has(m.content.messageUId)) {
20833
- RecallMessageStore.remove(m.content.messageUId);
20834
- } else {
20835
- m.isOffLineMessage = isOffLineMessage;
20836
- if (!m.messageId || m.messageId > getCurrentMessageId()) {
20837
- m.messageId = generateNewMessageId();
20838
- }
20839
- ConversationManager$1.get().setConversationCacheByMessage(m);
20840
- messageList.push(m);
20841
- if (m.messageType === MessageTypes.RECALL) {
20842
- recallMessageIndexes.push(messageList.length - 1);
20843
- }
20844
- }
20845
- if ([NotiMessageTypes.PRIVATE_OPEN_BURNAFTERREADING, NotiMessageTypes.GROUP_OPEN_BURNAFTERREADING, NotiMessageTypes.PRIVATE_CLOSE_BURNAFTERREADING, NotiMessageTypes.GROUP_CLOSE_BURNAFTERREADING].includes(m.messageType)) {
20846
- this.handleBurnAfterReadingMessage(m);
20847
- }
20848
- });
20849
- let recallMessageUIds = [];
20850
- let deletedMessageIndexes = [];
20851
- for (let i = recallMessageIndexes.length - 1; i >= 0; i--) {
20852
- const index = recallMessageIndexes[i];
20853
- const recallMessage = messageList[index];
20854
- const recallContent = recallMessage.content;
20855
- const messageIndex = messageList.findIndex(m => m.messageUId === recallContent.messageUId);
20856
- if (messageIndex !== -1) {
20857
- deletedMessageIndexes.push(messageIndex);
20858
- } else {
20859
- recallMessageUIds.push(recallContent.messageUId);
20860
- deletedMessageIndexes.push(index);
20861
- }
20862
- }
20863
- messageList = messageList.filter((m, index) => !deletedMessageIndexes.includes(index));
20864
- messages.push(...messageList);
20865
- if (this.isExistPersistedMessage(messageList)) {
20866
- splitFullDialog(dialogId);
20867
- }
20868
- if (recallMessageUIds.length) {
20869
- this.watcher.onRecall?.(recallMessageUIds);
20870
- }
20871
- });
20872
- let normalMessages = this.handleReceiptMessages(messages);
20873
- if (normalMessages.length) {
20874
- this.watcher.batchMessage?.(normalMessages);
20875
- MessageReceiptManager$1.get()?.sendArrivalReceipts(normalMessages);
20876
- }
20877
- if (done) {
20878
- let seqNo_long;
20879
- if (seqno) {
20880
- if (Long.isLong(seqno)) {
20881
- seqNo_long = seqno;
20882
- } else if (typeof seqno === 'string') {
20883
- seqNo_long = Long.fromString(seqno);
20884
- } else if (typeof seqno === 'number') {
20885
- seqNo_long = Long.fromNumber(seqno);
20886
- }
20887
- }
20888
- if (seqNo_long && Long.isLong(seqNo_long) && seqNo_long.ge(this.serverMsgSeqno)) {
20889
- this.serverMsgSeqno = seqNo_long;
20890
- }
20891
- const isFinished = this.serverMsgSeqno.lessThanOrEqual(offset);
20892
- logger.info(`pullMsg success -> syncTime: ${offset}, finished: ${isFinished}`);
20893
- this.letterbox?.setInboxOffset(offset);
20894
- this.pullingMsg = false;
20895
- if (isFinished && !this.pullOfflineFinished) {
20896
- this.pullOfflineFinished = true;
20897
- this.watcher.pullFinished && this.watcher.pullFinished();
20898
- }
20899
- if (!isFinished) {
20900
- this.pullMsg();
20901
- }
20902
- }
20903
- });
20904
- }
20905
- handleBurnAfterReadingMessage(message) {
20906
- const content = message.content;
20907
- const conversationType = message.conversationType;
20908
- const targetId = message.targetId;
20909
- const {
20910
- templateId,
20911
- burnAfterReadingTime
20912
- } = content;
20913
- const burnAfterReadingFlag = templateId === 60010010 || templateId === 60010011;
20914
- ConversationManager$1.get().addStatus({
20915
- conversationType,
20916
- targetId,
20917
- burnAfterReadingFlag: burnAfterReadingFlag,
20918
- burnAfterReadingTime: burnAfterReadingFlag ? burnAfterReadingTime : null
20919
- }, true);
20920
- }
20921
- handleReceiptMessages(messages) {
20922
- try {
20923
- const normalMessages = [];
20924
- const receiptnotificationMessages = [];
20925
- messages.forEach(msg => {
20926
- if (msg.messageType === NotiMessageTypes.GROUP_ARRIVAL_RECEIPT || msg.messageType === NotiMessageTypes.GROUP_READ_RECEIPT || msg.messageType === NotiMessageTypes.PRIVATE_ARRIVAL_RECEIPT || msg.messageType === NotiMessageTypes.PRIVATE_READ_RECEIPT) {
20927
- receiptnotificationMessages.push(msg);
20928
- } else {
20929
- normalMessages.push(msg);
20930
- }
20931
- });
20932
- const sentMessages = normalMessages.filter(m => m.messageDirection === exports.MessageDirection.SEND);
20933
- receiptnotificationMessages.forEach(notiMsg => {
20934
- const notiContent = notiMsg.content;
20935
- const isArrivalReceipt = notiMsg.messageType === NotiMessageTypes.GROUP_ARRIVAL_RECEIPT || notiMsg.messageType === NotiMessageTypes.PRIVATE_ARRIVAL_RECEIPT;
20936
- sentMessages.forEach(msg => {
20937
- if (notiContent.msgIdList.includes(msg.messageUId)) {
20938
- if (isArrivalReceipt) {
20939
- msg.receivedStatus = exports.ReceivedStatus.RECEIVED;
20940
- } else {
20941
- msg.receivedStatus = exports.ReceivedStatus.READ;
20942
- }
20943
- }
20944
- });
20945
- this.watcher.onReceiptReceived?.({
20946
- conversation: {
20947
- conversationType: notiMsg.conversationType,
20948
- targetId: notiMsg.targetId
20949
- },
20950
- messageUIdList: notiContent.msgIdList.map(id => id.toString())
20951
- }, notiMsg.messageType === NotiMessageTypes.GROUP_ARRIVAL_RECEIPT || notiMsg.messageType === NotiMessageTypes.PRIVATE_ARRIVAL_RECEIPT ? 0 : 1);
20952
- });
20953
- return normalMessages;
20954
- } catch (error) {
20955
- logger.error('handleReceiptMessages error', error);
20956
- return [];
20957
- }
20958
- }
20959
- isExistPersistedMessage(messageList) {
20960
- return messageList.some(m => m.isPersited);
20961
- }
20962
- }
20963
-
20964
- class BaseMessage {
20965
- messageType;
20966
- content;
20967
- isPersited;
20968
- isCounted;
20969
- isStatusMessage;
20970
- constructor(messageType, content, isPersited = true, isCounted = true, isStatusMessage = false) {
20971
- this.messageType = messageType;
20972
- this.content = content;
20973
- if (isStatusMessage) {
20974
- this.isPersited = false;
20975
- this.isCounted = false;
20976
- } else {
20977
- this.isPersited = isPersited;
20978
- this.isCounted = isCounted;
20979
- }
20980
- this.isStatusMessage = isStatusMessage;
20981
- }
20982
- }
20983
- const registerMessageType$1 = (messageType, isPersited, isCounted, isStatusMessage) => {
20984
- const defined = function (content) {
20985
- return new BaseMessage(messageType, content, isPersited, isCounted, isStatusMessage);
20986
- };
20987
- return defined;
20988
- };
20989
-
20990
- const TextMessage = registerMessageType$1(MessageTypes.TEXT, true, true, false);
20991
-
20992
- const ImageMessage = registerMessageType$1(MessageTypes.IMAGE, true, true, false);
20993
-
20994
- const GIFMessage = registerMessageType$1(MessageTypes.GIF, true, true, false);
20995
-
20996
- const VoiceMessage = registerMessageType$1(MessageTypes.AUDIO, true, true, false);
20997
-
20998
- const FileMessage = registerMessageType$1(MessageTypes.FILE, true, true, false);
20999
-
21000
- const VideoMessage = registerMessageType$1(MessageTypes.VIDEO, true, true, false);
21001
-
21002
- let LocationMessage = registerMessageType$1(MessageTypes.LOCATION, true, true, false);
21003
- let ChatRecordMessage = registerMessageType$1(MessageTypes.CHAT_RECORD, true, true, false);
21004
- let ContactMessage = registerMessageType$1(MessageTypes.CONTACT, true, true, false);
21005
- let InvitationMessage = registerMessageType$1(MessageTypes.GROUP_INVITATION, true, true, false);
21006
- let RedEnvelopeMessage = registerMessageType$1(MessageTypes.REDPACKET, true, true, false);
21007
- let TransferMessage = registerMessageType$1(MessageTypes.TRANSFER, true, true, false);
21008
-
21009
- const GroupArrivalReceiptMessage = registerMessageType$1(NotiMessageTypes.GROUP_ARRIVAL_RECEIPT, false, false, true);
21010
- const GroupReadReceiptMessage = registerMessageType$1(NotiMessageTypes.GROUP_READ_RECEIPT, false, false, true);
21011
- const PrivateArrivalReceiptMessage = registerMessageType$1(NotiMessageTypes.PRIVATE_ARRIVAL_RECEIPT, false, false, true);
21012
- const PrivateReadReceiptMessage = registerMessageType$1(NotiMessageTypes.PRIVATE_READ_RECEIPT, false, false, true);
21013
- const PrivateOpenBurnAfterReadingMessage = registerMessageType$1(NotiMessageTypes.PRIVATE_OPEN_BURNAFTERREADING, false, false, true);
21014
- const PrivateCloseBurnAfterReadingMessage = registerMessageType$1(NotiMessageTypes.PRIVATE_CLOSE_BURNAFTERREADING, false, false, true);
21015
- const GroupOpenBurnAfterReadingMessage = registerMessageType$1(NotiMessageTypes.GROUP_OPEN_BURNAFTERREADING, false, false, true);
21016
- const GroupCloseBurnAfterReadingMessage = registerMessageType$1(NotiMessageTypes.GROUP_CLOSE_BURNAFTERREADING, false, false, true);
21017
-
21018
- const RecallCommandMessage = registerMessageType$1(MessageTypes.RECALL, true, false, false);
21019
-
21020
20731
  class MessageCache {
21021
20732
  loadedEndMap = new Map();
21022
20733
  db = null;
21023
20734
  currentAppKey = '';
21024
20735
  currentUserId = '';
21025
20736
  APP_INFO_KEY = 'im_app_info';
21026
- DB_NAME_PREFIX = 'im_message_cache_new';
20737
+ DB_NAME_PREFIX = 'im_message_cache_1';
21027
20738
  DB_VERSION = 2;
21028
20739
  STORE_NAME = 'messages_new';
21029
20740
  DIALOG_STATE_STORE = 'dialogStates_new';
@@ -21086,11 +20797,11 @@
21086
20797
  const dbName = this.getDBName();
21087
20798
  const deleteRequest = indexedDB.deleteDatabase(dbName);
21088
20799
  deleteRequest.onsuccess = () => {
21089
- logger.info(`数据库 ${dbName} 已成功删除`);
20800
+ logger.info(`Database ${dbName} successfully deleted`);
21090
20801
  resolve();
21091
20802
  };
21092
20803
  deleteRequest.onerror = event => {
21093
- logger.error(`删除数据库 ${dbName} 失败`, event);
20804
+ logger.error(`Failed to delete database ${dbName}`, event);
21094
20805
  resolve();
21095
20806
  };
21096
20807
  });
@@ -21103,8 +20814,8 @@
21103
20814
  const dbName = this.getDBName();
21104
20815
  const request = indexedDB.open(dbName, this.DB_VERSION);
21105
20816
  request.onerror = event => {
21106
- logger.error('数据库打开失败', event);
21107
- reject(new Error('数据库打开失败'));
20817
+ logger.error('Failed to open database', event);
20818
+ reject(new Error('Failed to open database'));
21108
20819
  };
21109
20820
  request.onsuccess = event => {
21110
20821
  this.db = event.target.result;
@@ -21209,7 +20920,7 @@
21209
20920
  const decryptedStr = aes256Decrypt(encryptedHex, this.encryptKey);
21210
20921
  return JSON.parse(decryptedStr);
21211
20922
  } catch (error) {
21212
- logger.error('解密消息内容失败', error);
20923
+ logger.error('Failed to decrypt message content', error);
21213
20924
  return null;
21214
20925
  }
21215
20926
  }
@@ -21239,8 +20950,8 @@
21239
20950
  resolve();
21240
20951
  };
21241
20952
  transaction.onerror = event => {
21242
- logger.error('添加消息事务失败', event);
21243
- reject(new Error('添加消息事务失败'));
20953
+ logger.error('Add message transaction failed', event);
20954
+ reject(new Error('Add message transaction failed'));
21244
20955
  };
21245
20956
  });
21246
20957
  }
@@ -21282,7 +20993,7 @@
21282
20993
  try {
21283
20994
  message.content = this.decryptContent(message.content);
21284
20995
  } catch (error) {
21285
- logger.error('解密消息内容失败', error);
20996
+ logger.error('Failed to decrypt message content', error);
21286
20997
  message.content = null;
21287
20998
  }
21288
20999
  }
@@ -21306,8 +21017,8 @@
21306
21017
  };
21307
21018
  };
21308
21019
  transaction.onerror = event => {
21309
- logger.error('获取消息事务失败', event);
21310
- reject(new Error('获取消息事务失败'));
21020
+ logger.error('Get message transaction failed', event);
21021
+ reject(new Error('Get message transaction failed'));
21311
21022
  };
21312
21023
  });
21313
21024
  }
@@ -21411,10 +21122,10 @@
21411
21122
  }
21412
21123
  };
21413
21124
  deleteRequest.onerror = event => {
21414
- logger.error('删除消息失败', id, event);
21125
+ logger.error('Failed to delete message', id, event);
21415
21126
  if (!hasError) {
21416
21127
  hasError = true;
21417
- reject(new Error('删除消息失败'));
21128
+ reject(new Error('Failed to delete message'));
21418
21129
  }
21419
21130
  };
21420
21131
  });
@@ -21424,7 +21135,7 @@
21424
21135
  }
21425
21136
  };
21426
21137
  transaction.onerror = event => {
21427
- reject(new Error('批量删除消息事务失败'));
21138
+ reject(new Error('Batch delete message transaction failed'));
21428
21139
  };
21429
21140
  });
21430
21141
  }
@@ -21517,8 +21228,8 @@
21517
21228
  }
21518
21229
  };
21519
21230
  request.onerror = event => {
21520
- logger.error('清除过期消息失败', event);
21521
- reject(new Error('清除过期消息失败'));
21231
+ logger.error('Failed to clear expired messages', event);
21232
+ reject(new Error('Failed to clear expired messages'));
21522
21233
  };
21523
21234
  });
21524
21235
  }
@@ -21544,108 +21255,451 @@
21544
21255
  try {
21545
21256
  message.content = this.decryptContent(message.content);
21546
21257
  } catch (error) {
21547
- logger.error('解密消息内容失败', error);
21258
+ logger.error('Failed to decrypt message content', error);
21548
21259
  message.content = null;
21549
21260
  }
21550
21261
  }
21551
- resolve(message);
21552
- } else {
21553
- resolve(null);
21262
+ resolve(message);
21263
+ } else {
21264
+ resolve(null);
21265
+ }
21266
+ };
21267
+ cursorRequest.onerror = event => {
21268
+ logger.error('Failed to get latest message', event);
21269
+ resolve(null);
21270
+ };
21271
+ });
21272
+ }
21273
+ async upsertMessage(message) {
21274
+ this.addMessages([message], message);
21275
+ }
21276
+ async getMessageById(messageId) {
21277
+ if (!this.db) {
21278
+ return null;
21279
+ }
21280
+ return new Promise((resolve, reject) => {
21281
+ const transaction = this.db.transaction(this.STORE_NAME, 'readonly');
21282
+ const store = transaction.objectStore(this.STORE_NAME);
21283
+ const request = store.get(messageId);
21284
+ request.onsuccess = () => {
21285
+ const message = request.result;
21286
+ if (message) {
21287
+ const decryptedMessage = {
21288
+ ...message
21289
+ };
21290
+ if (typeof decryptedMessage.content === 'string' && decryptedMessage.content) {
21291
+ try {
21292
+ decryptedMessage.content = this.decryptContent(decryptedMessage.content);
21293
+ } catch (error) {
21294
+ logger.error('解密消息内容失败', error);
21295
+ decryptedMessage.content = null;
21296
+ }
21297
+ }
21298
+ resolve(decryptedMessage);
21299
+ } else {
21300
+ resolve(null);
21301
+ }
21302
+ };
21303
+ request.onerror = event => {
21304
+ logger.error('查询消息失败', event);
21305
+ resolve(null);
21306
+ };
21307
+ });
21308
+ }
21309
+ async getMessageIdRange() {
21310
+ if (!this.db) {
21311
+ return null;
21312
+ }
21313
+ return new Promise((resolve, reject) => {
21314
+ const transaction = this.db.transaction(this.STORE_NAME, 'readonly');
21315
+ const store = transaction.objectStore(this.STORE_NAME);
21316
+ let newest = null;
21317
+ let oldest = null;
21318
+ const oldestRequest = store.openCursor();
21319
+ oldestRequest.onsuccess = event => {
21320
+ const cursor = event.target.result;
21321
+ if (cursor) {
21322
+ oldest = cursor.value.messageId;
21323
+ const newestRequest = store.openCursor(null, 'prev');
21324
+ newestRequest.onsuccess = event => {
21325
+ const cursor = event.target.result;
21326
+ if (cursor) {
21327
+ newest = cursor.value.messageId;
21328
+ if (newest && oldest) {
21329
+ resolve({
21330
+ newest,
21331
+ oldest
21332
+ });
21333
+ } else {
21334
+ resolve(null);
21335
+ }
21336
+ } else {
21337
+ resolve(null);
21338
+ }
21339
+ };
21340
+ } else {
21341
+ resolve(null);
21342
+ }
21343
+ };
21344
+ transaction.onerror = event => {
21345
+ resolve(null);
21346
+ };
21347
+ });
21348
+ }
21349
+ async convertToRecallMessages(messageUIds) {
21350
+ if (!messageUIds || messageUIds.length === 0 || !this.db) {
21351
+ return;
21352
+ }
21353
+ const transaction = this.db.transaction(this.STORE_NAME, 'readwrite');
21354
+ const store = transaction.objectStore(this.STORE_NAME);
21355
+ const index = store.index('messageUId');
21356
+ messageUIds.forEach(messageUId => {
21357
+ const request = index.get(messageUId);
21358
+ request.onsuccess = () => {
21359
+ const message = request.result;
21360
+ if (message) {
21361
+ const recallContent = {
21362
+ messageUId: messageUId
21363
+ };
21364
+ const updatedMessage = {
21365
+ ...message,
21366
+ messageType: MessageTypes.RECALL,
21367
+ content: this.encryptContent(recallContent)
21368
+ };
21369
+ store.put(updatedMessage);
21370
+ }
21371
+ };
21372
+ });
21373
+ }
21374
+ }
21375
+ let cache;
21376
+ var MessageCache$1 = {
21377
+ create(appkey, currentUserId) {
21378
+ cache = new MessageCache(appkey, currentUserId);
21379
+ },
21380
+ get() {
21381
+ return cache;
21382
+ }
21383
+ };
21384
+
21385
+ class MessageLoader {
21386
+ watcher;
21387
+ pullingMsg = false;
21388
+ letterbox;
21389
+ serverMsgSeqno = Long.ZERO;
21390
+ pullOfflineFinished = false;
21391
+ intervalTimer;
21392
+ retryTimer;
21393
+ latestSyncTimestamp = 0;
21394
+ started = false;
21395
+ constructor(watcher, options) {
21396
+ this.watcher = watcher;
21397
+ this.letterbox = new Letterbox(options.appkey, accountStore.uid.toString());
21398
+ }
21399
+ start() {
21400
+ this.started = true;
21401
+ this.pullOfflineFinished = false;
21402
+ this.startPullInterval();
21403
+ }
21404
+ stop() {
21405
+ this.started = false;
21406
+ this.stopPullInterval();
21407
+ this.cancelRetryTask();
21408
+ }
21409
+ syncMsg(seqno) {
21410
+ this.serverMsgSeqno = seqno;
21411
+ this.pullMsg();
21412
+ }
21413
+ startPullInterval() {
21414
+ this.stopPullInterval();
21415
+ const d = 3 * 60 * 1000;
21416
+ this.intervalTimer = setInterval(() => {
21417
+ if (Date.now() - this.latestSyncTimestamp >= d) {
21418
+ this.pullMsg();
21419
+ }
21420
+ }, 30000);
21421
+ this.latestSyncTimestamp = Date.now();
21422
+ this.pullMsg();
21423
+ }
21424
+ stopPullInterval() {
21425
+ if (this.intervalTimer) {
21426
+ clearInterval(this.intervalTimer);
21427
+ this.intervalTimer = null;
21428
+ }
21429
+ }
21430
+ try2RePullMsg() {
21431
+ this.retryTimer = setTimeout(() => {
21432
+ this.retryTimer = null;
21433
+ this.pullMsg();
21434
+ }, 1000);
21435
+ }
21436
+ cancelRetryTask() {
21437
+ if (this.retryTimer) {
21438
+ clearTimeout(this.retryTimer);
21439
+ this.retryTimer = null;
21440
+ }
21441
+ }
21442
+ async pullMsg() {
21443
+ if (this.pullingMsg) {
21444
+ return;
21445
+ }
21446
+ if (!this.started) {
21447
+ return;
21448
+ }
21449
+ this.cancelRetryTask();
21450
+ this.pullingMsg = true;
21451
+ const inboxTime = this.letterbox.getInboxOffset();
21452
+ logger.info(`pullMsg -> time: ${inboxTime}`);
21453
+ this.latestSyncTimestamp = Date.now();
21454
+ const {
21455
+ code,
21456
+ data
21457
+ } = await getNewMessages(inboxTime, 60);
21458
+ if (code !== exports.ErrorCode.SUCCESS) {
21459
+ logger.warn('pullMsg failed -> code:', code);
21460
+ this.pullingMsg = false;
21461
+ if (LibLoader.loader?.getConnectionStatus() == exports.ConnectionStatus.CONNECTED) {
21462
+ this.try2RePullMsg();
21463
+ }
21464
+ return;
21465
+ }
21466
+ const {
21467
+ offset,
21468
+ seqno,
21469
+ msg
21470
+ } = data;
21471
+ const cons = Object.keys(msg).map(dialogId => {
21472
+ const conversationType = extractConversationType(Long.fromString(dialogId));
21473
+ return {
21474
+ conversationType,
21475
+ targetId: dialogId
21476
+ };
21477
+ });
21478
+ await ConversationManager$1.get().loadConvsationsIfNotExist(cons);
21479
+ serverMessageParser.parse(msg, (done, outputMsgs) => {
21480
+ const messages = [];
21481
+ let recallMessageUIds = [];
21482
+ const recallMessageIndexes = [];
21483
+ const isOffLineMessage = !this.pullOfflineFinished;
21484
+ outputMsgs.forEach((l, dialogId) => {
21485
+ let messageList = [];
21486
+ l.forEach(m => {
21487
+ if (m.messageType === MessageTypes.RECALL && RecallMessageStore.has(m.content.messageUId)) {
21488
+ RecallMessageStore.remove(m.content.messageUId);
21489
+ } else {
21490
+ m.isOffLineMessage = isOffLineMessage;
21491
+ if (!m.messageId || m.messageId > getCurrentMessageId()) {
21492
+ m.messageId = generateNewMessageId();
21493
+ }
21494
+ ConversationManager$1.get().setConversationCacheByMessage(m);
21495
+ messageList.push(m);
21496
+ if (m.messageType === MessageTypes.RECALL) {
21497
+ recallMessageIndexes.push(messageList.length - 1);
21498
+ }
21499
+ }
21500
+ if ([NotiMessageTypes.PRIVATE_OPEN_BURNAFTERREADING, NotiMessageTypes.GROUP_OPEN_BURNAFTERREADING, NotiMessageTypes.PRIVATE_CLOSE_BURNAFTERREADING, NotiMessageTypes.GROUP_CLOSE_BURNAFTERREADING].includes(m.messageType)) {
21501
+ this.handleBurnAfterReadingMessage(m);
21502
+ }
21503
+ });
21504
+ let deletedMessageIndexes = [];
21505
+ for (let i = recallMessageIndexes.length - 1; i >= 0; i--) {
21506
+ const index = recallMessageIndexes[i];
21507
+ const recallMessage = messageList[index];
21508
+ const recallContent = recallMessage.content;
21509
+ const messageIndex = messageList.findIndex(m => m.messageUId === recallContent.messageUId);
21510
+ if (messageIndex !== -1) {
21511
+ deletedMessageIndexes.push(messageIndex);
21512
+ } else {
21513
+ recallMessageUIds.push(recallContent.messageUId);
21514
+ deletedMessageIndexes.push(index);
21515
+ }
21554
21516
  }
21555
- };
21556
- cursorRequest.onerror = event => {
21557
- logger.error('获取最新消息失败', event);
21558
- resolve(null);
21559
- };
21517
+ messageList = messageList.filter((m, index) => !deletedMessageIndexes.includes(index));
21518
+ messages.push(...messageList);
21519
+ if (this.isExistPersistedMessage(messageList)) {
21520
+ splitFullDialog(dialogId);
21521
+ }
21522
+ });
21523
+ let normalMessages = this.handleReceiptMessages(messages);
21524
+ if (normalMessages.length) {
21525
+ this.handleBatchMessages(normalMessages);
21526
+ MessageReceiptManager$1.get()?.sendArrivalReceipts(normalMessages);
21527
+ }
21528
+ if (recallMessageUIds.length) {
21529
+ MessageCache$1.get()?.convertToRecallMessages(recallMessageUIds);
21530
+ this.watcher.onRecall?.(recallMessageUIds);
21531
+ }
21532
+ if (done) {
21533
+ let seqNo_long;
21534
+ if (seqno) {
21535
+ if (Long.isLong(seqno)) {
21536
+ seqNo_long = seqno;
21537
+ } else if (typeof seqno === 'string') {
21538
+ seqNo_long = Long.fromString(seqno);
21539
+ } else if (typeof seqno === 'number') {
21540
+ seqNo_long = Long.fromNumber(seqno);
21541
+ }
21542
+ }
21543
+ if (seqNo_long && Long.isLong(seqNo_long) && seqNo_long.ge(this.serverMsgSeqno)) {
21544
+ this.serverMsgSeqno = seqNo_long;
21545
+ }
21546
+ const isFinished = this.serverMsgSeqno.lessThanOrEqual(offset);
21547
+ logger.info(`pullMsg success -> syncTime: ${offset}, finished: ${isFinished}`);
21548
+ this.letterbox?.setInboxOffset(offset);
21549
+ this.pullingMsg = false;
21550
+ if (isFinished && !this.pullOfflineFinished) {
21551
+ this.pullOfflineFinished = true;
21552
+ this.watcher.pullFinished && this.watcher.pullFinished();
21553
+ }
21554
+ if (!isFinished) {
21555
+ this.pullMsg();
21556
+ }
21557
+ }
21560
21558
  });
21561
21559
  }
21562
- async upsertMessage(message) {
21563
- this.addMessages([message], message);
21560
+ handleBurnAfterReadingMessage(message) {
21561
+ const content = message.content;
21562
+ const conversationType = message.conversationType;
21563
+ const targetId = message.targetId;
21564
+ const {
21565
+ templateId,
21566
+ burnAfterReadingTime
21567
+ } = content;
21568
+ const burnAfterReadingFlag = templateId === 60010010 || templateId === 60010011;
21569
+ ConversationManager$1.get().addStatus({
21570
+ conversationType,
21571
+ targetId,
21572
+ burnAfterReadingFlag: burnAfterReadingFlag,
21573
+ burnAfterReadingTime: burnAfterReadingFlag ? burnAfterReadingTime : null
21574
+ }, true);
21564
21575
  }
21565
- async getMessageById(messageId) {
21566
- if (!this.db) {
21567
- return null;
21568
- }
21569
- return new Promise((resolve, reject) => {
21570
- const transaction = this.db.transaction(this.STORE_NAME, 'readonly');
21571
- const store = transaction.objectStore(this.STORE_NAME);
21572
- const request = store.get(messageId);
21573
- request.onsuccess = () => {
21574
- const message = request.result;
21575
- if (message) {
21576
- const decryptedMessage = {
21577
- ...message
21578
- };
21579
- if (typeof decryptedMessage.content === 'string' && decryptedMessage.content) {
21580
- try {
21581
- decryptedMessage.content = this.decryptContent(decryptedMessage.content);
21582
- } catch (error) {
21583
- logger.error('解密消息内容失败', error);
21584
- decryptedMessage.content = null;
21585
- }
21586
- }
21587
- resolve(decryptedMessage);
21576
+ handleReceiptMessages(messages) {
21577
+ try {
21578
+ const normalMessages = [];
21579
+ const receiptnotificationMessages = [];
21580
+ messages.forEach(msg => {
21581
+ if (msg.messageType === NotiMessageTypes.GROUP_ARRIVAL_RECEIPT || msg.messageType === NotiMessageTypes.GROUP_READ_RECEIPT || msg.messageType === NotiMessageTypes.PRIVATE_ARRIVAL_RECEIPT || msg.messageType === NotiMessageTypes.PRIVATE_READ_RECEIPT) {
21582
+ receiptnotificationMessages.push(msg);
21588
21583
  } else {
21589
- resolve(null);
21584
+ normalMessages.push(msg);
21590
21585
  }
21591
- };
21592
- request.onerror = event => {
21593
- logger.error('查询消息失败', event);
21594
- resolve(null);
21595
- };
21596
- });
21597
- }
21598
- async getMessageIdRange() {
21599
- if (!this.db) {
21600
- return null;
21601
- }
21602
- return new Promise((resolve, reject) => {
21603
- const transaction = this.db.transaction(this.STORE_NAME, 'readonly');
21604
- const store = transaction.objectStore(this.STORE_NAME);
21605
- let newest = null;
21606
- let oldest = null;
21607
- const oldestRequest = store.openCursor();
21608
- oldestRequest.onsuccess = event => {
21609
- const cursor = event.target.result;
21610
- if (cursor) {
21611
- oldest = cursor.value.messageId;
21612
- const newestRequest = store.openCursor(null, 'prev');
21613
- newestRequest.onsuccess = event => {
21614
- const cursor = event.target.result;
21615
- if (cursor) {
21616
- newest = cursor.value.messageId;
21617
- if (newest && oldest) {
21618
- resolve({
21619
- newest,
21620
- oldest
21621
- });
21622
- } else {
21623
- resolve(null);
21624
- }
21586
+ });
21587
+ const sentMessages = normalMessages.filter(m => m.messageDirection === exports.MessageDirection.SEND);
21588
+ receiptnotificationMessages.forEach(notiMsg => {
21589
+ const notiContent = notiMsg.content;
21590
+ const isArrivalReceipt = notiMsg.messageType === NotiMessageTypes.GROUP_ARRIVAL_RECEIPT || notiMsg.messageType === NotiMessageTypes.PRIVATE_ARRIVAL_RECEIPT;
21591
+ sentMessages.forEach(msg => {
21592
+ if (notiContent.msgIdList.includes(msg.messageUId)) {
21593
+ if (isArrivalReceipt) {
21594
+ msg.receivedStatus = exports.ReceivedStatus.RECEIVED;
21625
21595
  } else {
21626
- resolve(null);
21596
+ msg.receivedStatus = exports.ReceivedStatus.READ;
21627
21597
  }
21628
- };
21629
- } else {
21630
- resolve(null);
21598
+ }
21599
+ });
21600
+ this.watcher.onReceiptReceived?.({
21601
+ conversation: {
21602
+ conversationType: notiMsg.conversationType,
21603
+ targetId: notiMsg.targetId
21604
+ },
21605
+ messageUIdList: notiContent.msgIdList.map(id => id.toString())
21606
+ }, notiMsg.messageType === NotiMessageTypes.GROUP_ARRIVAL_RECEIPT || notiMsg.messageType === NotiMessageTypes.PRIVATE_ARRIVAL_RECEIPT ? 0 : 1);
21607
+ });
21608
+ return normalMessages;
21609
+ } catch (error) {
21610
+ logger.error('handleReceiptMessages error', error);
21611
+ return [];
21612
+ }
21613
+ }
21614
+ handleBatchMessages(messages) {
21615
+ if (messages.length) {
21616
+ const targetGroups = new Map();
21617
+ messages.forEach(message => {
21618
+ if (!targetGroups.has(message.targetId)) {
21619
+ targetGroups.set(message.targetId, []);
21631
21620
  }
21632
- };
21633
- transaction.onerror = event => {
21634
- resolve(null);
21635
- };
21621
+ targetGroups.get(message.targetId).push(message);
21622
+ });
21623
+ targetGroups.forEach((targetMessages, targetId) => {
21624
+ const conversationType = targetMessages[0].conversationType;
21625
+ MessageCache$1.get()?.addMessages(targetMessages, {
21626
+ conversationType,
21627
+ targetId
21628
+ });
21629
+ });
21630
+ }
21631
+ const filteredMessages = messages.filter(m => {
21632
+ if (m.messageDirection === exports.MessageDirection.SEND && m.messageId && SentMessageStore.has(m.messageId)) {
21633
+ SentMessageStore.remove(m.messageId);
21634
+ return false;
21635
+ }
21636
+ return true;
21636
21637
  });
21638
+ if (filteredMessages.length) {
21639
+ this.watcher.batchMessage?.(filteredMessages);
21640
+ }
21641
+ }
21642
+ isExistPersistedMessage(messageList) {
21643
+ return messageList.some(m => m.isPersited);
21637
21644
  }
21638
21645
  }
21639
- let cache;
21640
- var MessageCache$1 = {
21641
- create(appkey, currentUserId) {
21642
- cache = new MessageCache(appkey, currentUserId);
21643
- },
21644
- get() {
21645
- return cache;
21646
+
21647
+ class BaseMessage {
21648
+ messageType;
21649
+ content;
21650
+ isPersited;
21651
+ isCounted;
21652
+ isStatusMessage;
21653
+ constructor(messageType, content, isPersited = true, isCounted = true, isStatusMessage = false) {
21654
+ this.messageType = messageType;
21655
+ this.content = content;
21656
+ if (isStatusMessage) {
21657
+ this.isPersited = false;
21658
+ this.isCounted = false;
21659
+ } else {
21660
+ this.isPersited = isPersited;
21661
+ this.isCounted = isCounted;
21662
+ }
21663
+ this.isStatusMessage = isStatusMessage;
21646
21664
  }
21665
+ }
21666
+ const registerMessageType$1 = (messageType, isPersited, isCounted, isStatusMessage) => {
21667
+ const defined = function (content) {
21668
+ return new BaseMessage(messageType, content, isPersited, isCounted, isStatusMessage);
21669
+ };
21670
+ return defined;
21647
21671
  };
21648
21672
 
21673
+ const TextMessage = registerMessageType$1(MessageTypes.TEXT, true, true, false);
21674
+
21675
+ const ImageMessage = registerMessageType$1(MessageTypes.IMAGE, true, true, false);
21676
+
21677
+ const GIFMessage = registerMessageType$1(MessageTypes.GIF, true, true, false);
21678
+
21679
+ const VoiceMessage = registerMessageType$1(MessageTypes.AUDIO, true, true, false);
21680
+
21681
+ const FileMessage = registerMessageType$1(MessageTypes.FILE, true, true, false);
21682
+
21683
+ const VideoMessage = registerMessageType$1(MessageTypes.VIDEO, true, true, false);
21684
+
21685
+ let LocationMessage = registerMessageType$1(MessageTypes.LOCATION, true, true, false);
21686
+ let ChatRecordMessage = registerMessageType$1(MessageTypes.CHAT_RECORD, true, true, false);
21687
+ let ContactMessage = registerMessageType$1(MessageTypes.CONTACT, true, true, false);
21688
+ let InvitationMessage = registerMessageType$1(MessageTypes.GROUP_INVITATION, true, true, false);
21689
+ let RedEnvelopeMessage = registerMessageType$1(MessageTypes.REDPACKET, true, true, false);
21690
+ let TransferMessage = registerMessageType$1(MessageTypes.TRANSFER, true, true, false);
21691
+
21692
+ const GroupArrivalReceiptMessage = registerMessageType$1(NotiMessageTypes.GROUP_ARRIVAL_RECEIPT, false, false, true);
21693
+ const GroupReadReceiptMessage = registerMessageType$1(NotiMessageTypes.GROUP_READ_RECEIPT, false, false, true);
21694
+ const PrivateArrivalReceiptMessage = registerMessageType$1(NotiMessageTypes.PRIVATE_ARRIVAL_RECEIPT, false, false, true);
21695
+ const PrivateReadReceiptMessage = registerMessageType$1(NotiMessageTypes.PRIVATE_READ_RECEIPT, false, false, true);
21696
+ const PrivateOpenBurnAfterReadingMessage = registerMessageType$1(NotiMessageTypes.PRIVATE_OPEN_BURNAFTERREADING, false, false, true);
21697
+ const PrivateCloseBurnAfterReadingMessage = registerMessageType$1(NotiMessageTypes.PRIVATE_CLOSE_BURNAFTERREADING, false, false, true);
21698
+ const GroupOpenBurnAfterReadingMessage = registerMessageType$1(NotiMessageTypes.GROUP_OPEN_BURNAFTERREADING, false, false, true);
21699
+ const GroupCloseBurnAfterReadingMessage = registerMessageType$1(NotiMessageTypes.GROUP_CLOSE_BURNAFTERREADING, false, false, true);
21700
+
21701
+ const RecallCommandMessage = registerMessageType$1(MessageTypes.RECALL, true, false, false);
21702
+
21649
21703
  const DEFAULT_SOCKET_URI = 'wss://imweb.mp.net:6443';
21650
21704
  class LibLoader {
21651
21705
  options;
@@ -29156,34 +29210,9 @@
29156
29210
  this.emit(exports.Events.SUSPEND, this.libLoader.getConnectionStatus());
29157
29211
  },
29158
29212
  batchMessage: messages => {
29159
- if (messages.length) {
29160
- const targetGroups = new Map();
29161
- messages.forEach(message => {
29162
- if (!targetGroups.has(message.targetId)) {
29163
- targetGroups.set(message.targetId, []);
29164
- }
29165
- targetGroups.get(message.targetId).push(message);
29166
- });
29167
- targetGroups.forEach((targetMessages, targetId) => {
29168
- const conversationType = targetMessages[0].conversationType;
29169
- MessageCache$1.get()?.addMessages(targetMessages, {
29170
- conversationType,
29171
- targetId
29172
- });
29173
- });
29174
- }
29175
- const filteredMessages = messages.filter(m => {
29176
- if (m.messageDirection === exports.MessageDirection.SEND && m.messageId && SentMessageStore.has(m.messageId)) {
29177
- SentMessageStore.remove(m.messageId);
29178
- return false;
29179
- }
29180
- return true;
29213
+ this.emit(exports.Events.MESSAGES, {
29214
+ messages
29181
29215
  });
29182
- if (filteredMessages.length) {
29183
- this.emit(exports.Events.MESSAGES, {
29184
- messages: filteredMessages
29185
- });
29186
- }
29187
29216
  },
29188
29217
  pullFinished: () => {
29189
29218
  this.emit(exports.Events.PULL_OFFLINE_MESSAGE_FINISHED);
@@ -29200,7 +29229,6 @@
29200
29229
  });
29201
29230
  },
29202
29231
  onRecall: messageUids => {
29203
- MessageCache$1.get()?.removeMessagesByUId(messageUids);
29204
29232
  messageUids.forEach(messageUId => {
29205
29233
  this.emit(exports.Events.RECALL, messageUId);
29206
29234
  });