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