diff --git a/js/delivery_receipts.js b/js/delivery_receipts.js index 44be4b5e566f..ea1a2704e685 100644 --- a/js/delivery_receipts.js +++ b/js/delivery_receipts.js @@ -100,9 +100,7 @@ await message.setToExpire(false, { skipSave: true }); } - await window.Signal.Data.saveMessage(message.attributes, { - Message: Whisper.Message, - }); + window.Signal.Util.updateMessageBatcher.add(message.attributes); // notify frontend listeners const conversation = ConversationController.get( diff --git a/js/read_receipts.js b/js/read_receipts.js index 0f1b17328396..30a7f28ceebc 100644 --- a/js/read_receipts.js +++ b/js/read_receipts.js @@ -101,9 +101,7 @@ await message.setToExpire(false, { skipSave: true }); } - await window.Signal.Data.saveMessage(message.attributes, { - Message: Whisper.Message, - }); + window.Signal.Util.updateMessageBatcher.add(message.attributes); // notify frontend listeners const conversation = ConversationController.get( diff --git a/js/read_syncs.js b/js/read_syncs.js index ca76472f5fbc..23296062d08c 100644 --- a/js/read_syncs.js +++ b/js/read_syncs.js @@ -94,9 +94,7 @@ } } - await window.Signal.Data.saveMessage(message.attributes, { - Message: Whisper.Message, - }); + window.Signal.Util.updateMessageBatcher.add(message.attributes); this.remove(receipt); } catch (error) { diff --git a/main.js b/main.js index f77ee550d846..d3554ec26765 100644 --- a/main.js +++ b/main.js @@ -956,7 +956,7 @@ app.on('ready', async () => { // We use this event only a single time to log the startup time of the app // from when it's first ready until the loading screen disappears. ipc.once('signal-app-loaded', () => { - console.log('App has finished loading in:', Date.now() - startTime); + console.log('App loaded - time:', Date.now() - startTime); }); const userDataPath = await getRealPath(app.getPath('userData')); diff --git a/ts/background.ts b/ts/background.ts index 78842ca2d1b5..d01ff44f4b9e 100644 --- a/ts/background.ts +++ b/ts/background.ts @@ -2062,6 +2062,10 @@ export async function startApp(): Promise { interval = null; view.onEmpty(); window.logAppLoadedEvent(); + window.log.info( + 'App loaded - messages:', + messageReceiver.getProcessedCount() + ); const attachmentDownloadQueue = window.attachmentDownloadQueue || []; const THREE_DAYS_AGO = Date.now() - 3600 * 72 * 1000; const MAX_ATTACHMENT_MSGS_TO_DOWNLOAD = 250; diff --git a/ts/models/messages.ts b/ts/models/messages.ts index ee3c30df0436..d690a01f77cc 100644 --- a/ts/models/messages.ts +++ b/ts/models/messages.ts @@ -2595,7 +2595,94 @@ export class MessageModel extends window.Backbone.Model { return this.syncPromise; } + // NOTE: If you're modifying this function then you'll likely also need + // to modify queueAttachmentDownloads since it contains the logic below + hasAttachmentDownloads(): boolean { + const attachments = this.get('attachments') || []; + + const [longMessageAttachments, normalAttachments] = _.partition( + attachments, + attachment => + attachment.contentType === + window.Whisper.Message.LONG_MESSAGE_CONTENT_TYPE + ); + + if (longMessageAttachments.length > 0) { + return true; + } + + const hasNormalAttachments = normalAttachments.some(attachment => { + if (!attachment) { + return false; + } + // We've already downloaded this! + if (attachment.path) { + return false; + } + return true; + }); + if (hasNormalAttachments) { + return true; + } + + const previews = this.get('preview') || []; + const hasPreviews = previews.some(item => { + if (!item.image) { + return false; + } + // We've already downloaded this! + if (item.image.path) { + return false; + } + return true; + }); + if (hasPreviews) { + return true; + } + + const contacts = this.get('contact') || []; + const hasContacts = contacts.some(item => { + if (!item.avatar || !item.avatar.avatar) { + return false; + } + if (item.avatar.avatar.path) { + return false; + } + return true; + }); + if (hasContacts) { + return true; + } + + const quote = this.get('quote'); + const quoteAttachments = + quote && quote.attachments ? quote.attachments : []; + const hasQuoteAttachments = quoteAttachments.some(item => { + if (!item.thumbnail) { + return false; + } + // We've already downloaded this! + if (item.thumbnail.path) { + return false; + } + return true; + }); + if (hasQuoteAttachments) { + return true; + } + + const sticker = this.get('sticker'); + if (sticker) { + return !sticker.data || (sticker.data && !sticker.data.path); + } + + return false; + } + // Receive logic + // NOTE: If you're changing any logic in this function that deals with the + // count then you'll also have to modify the above function + // hasAttachmentDownloads async queueAttachmentDownloads(): Promise { const attachmentsToQueue = this.get('attachments') || []; const messageId = this.id; @@ -3008,7 +3095,12 @@ export class MessageModel extends window.Backbone.Model { const inMemoryMessage = window.MessageController.findBySender( this.getSenderIdentifier() ); - if (!inMemoryMessage) { + if (inMemoryMessage) { + window.log.info( + 'handleDataMessage: cache hit', + this.getSenderIdentifier() + ); + } else { window.log.info( 'handleDataMessage: duplicate check db lookup needed', this.getSenderIdentifier() @@ -3639,6 +3731,7 @@ export class MessageModel extends window.Backbone.Model { (isImage(attachments) || isVideo(attachments)) && isInCall(reduxState); if ( + this.hasAttachmentDownloads() && // eslint-disable-next-line @typescript-eslint/no-non-null-assertion (this.getConversation()!.getAccepted() || message.isOutgoing()) && !shouldHoldOffDownload diff --git a/ts/textsecure/MessageReceiver.ts b/ts/textsecure/MessageReceiver.ts index 899ea1be69ec..344ea1dc8e14 100644 --- a/ts/textsecure/MessageReceiver.ts +++ b/ts/textsecure/MessageReceiver.ts @@ -124,6 +124,8 @@ class MessageReceiverInner extends EventTarget { count: number; + processedCount: number; + deviceId?: number; hasConnected?: boolean; @@ -170,6 +172,7 @@ class MessageReceiverInner extends EventTarget { super(); this.count = 0; + this.processedCount = 0; this.signalingKey = signalingKey; this.username = oldUsername; @@ -784,6 +787,7 @@ class MessageReceiverInner extends EventTarget { removeFromCache(envelope: EnvelopeClass) { const { id } = envelope; this.cacheRemoveBatcher.add(id); + this.processedCount += 1; } // Same as handleEnvelope, just without the decryption step. Necessary for handling @@ -2396,6 +2400,7 @@ export default class MessageReceiver { this.cleanupSessionResets = inner.cleanupSessionResets.bind(inner); inner.connect(); + this.getProcessedCount = () => inner.processedCount; } addEventListener: (name: string, handler: Function) => void; @@ -2420,6 +2425,8 @@ export default class MessageReceiver { cleanupSessionResets: () => void; + getProcessedCount: () => number; + static stringToArrayBuffer = MessageReceiverInner.stringToArrayBuffer; static arrayBufferToString = MessageReceiverInner.arrayBufferToString;