diff --git a/background.html b/background.html
index a65bbc589..47c2897bd 100644
--- a/background.html
+++ b/background.html
@@ -36,7 +36,6 @@
-
diff --git a/js/read_receipts.js b/js/read_receipts.js
deleted file mode 100644
index 43e9cb371..000000000
--- a/js/read_receipts.js
+++ /dev/null
@@ -1,108 +0,0 @@
-/* global
- Whisper,
- Backbone,
- _,
- window
-*/
-
-/* eslint-disable more/no-then */
-
-// eslint-disable-next-line func-names
-(function() {
- 'use strict';
-
- window.Whisper = window.Whisper || {};
- Whisper.ReadReceipts = new (Backbone.Collection.extend({
- forMessage(conversation, message) {
- if (!message.isOutgoing()) {
- return [];
- }
- let ids = [];
- if (conversation.isPrivate()) {
- ids = [conversation.id];
- } else {
- ids = conversation.get('members');
- }
- const receipts = this.filter(
- receipt =>
- receipt.get('timestamp') === message.get('sent_at') &&
- _.contains(ids, receipt.get('reader'))
- );
- if (receipts.length) {
- window.log.info('Found early read receipts for message');
- this.remove(receipts);
- }
- return receipts;
- },
- async getTargetMessage(reader, messages) {
- if (messages.length === 0) {
- return null;
- }
- const message = messages.find(
- item => item.isOutgoing() && reader === item.get('conversationId')
- );
- if (message) {
- return message;
- }
-
- const groups = await window.Signal.Data.getAllGroupsInvolvingId(reader);
- const ids = groups.pluck('id');
- ids.push(reader);
-
- const target = messages.find(
- item => item.isOutgoing() && _.contains(ids, item.get('conversationId'))
- );
- if (!target) {
- return null;
- }
-
- return target;
- },
- async onReceipt(receipt) {
- try {
- const messages = await window.Signal.Data.getMessagesBySentAt(receipt.get('timestamp'));
-
- const message = await this.getTargetMessage(receipt.get('reader'), messages);
-
- if (!message) {
- window.log.info(
- 'No message for read receipt',
- receipt.get('reader'),
- receipt.get('timestamp')
- );
- return;
- }
-
- const readBy = message.get('read_by') || [];
- const expirationStartTimestamp = message.get('expirationStartTimestamp');
-
- readBy.push(receipt.get('reader'));
- message.set({
- read_by: readBy,
- expirationStartTimestamp: expirationStartTimestamp || Date.now(),
- sent: true,
- });
-
- if (message.isExpiring() && !expirationStartTimestamp) {
- // This will save the message for us while starting the timer
- await message.setToExpire();
- } else {
- await message.commit();
- }
-
- // notify frontend listeners
- const conversation = window.getConversationController().get(message.get('conversationId'));
- if (conversation) {
- conversation.updateLastMessage();
- }
-
- this.remove(receipt);
- } catch (error) {
- window.log.error(
- 'ReadReceipts.onReceipt error:',
- error && error.stack ? error.stack : error
- );
- }
- },
- }))();
-})();
diff --git a/ts/receiver/contentMessage.ts b/ts/receiver/contentMessage.ts
index d23fc9fb1..90a8adb71 100644
--- a/ts/receiver/contentMessage.ts
+++ b/ts/receiver/contentMessage.ts
@@ -19,6 +19,7 @@ import { getAllCachedECKeyPair } from './closedGroups';
import { handleCallMessage } from './callMessage';
import { SettingsKey } from '../data/settings-key';
import { ConversationTypeEnum } from '../models/conversation';
+import { ReadReceipts } from '../util/readReceipts';
export async function handleSwarmContentMessage(envelope: EnvelopePlus, messageHash: string) {
try {
@@ -439,23 +440,21 @@ export async function innerHandleSwarmContentMessage(
}
}
-function onReadReceipt(readAt: any, timestamp: any, reader: any) {
- const { storage, Whisper } = window;
+function onReadReceipt(readAt: number, timestamp: number, source: string) {
+ const { storage } = window;
- window?.log?.info('read receipt', reader, timestamp);
+ window?.log?.info('read receipt', source, timestamp);
if (!storage.get(SettingsKey.settingsReadReceipt)) {
return;
}
- const receipt = Whisper.ReadReceipts.add({
- reader,
+ // Calling this directly so we can wait for completion
+ return ReadReceipts.onReadReceipt({
+ source,
timestamp,
- read_at: readAt,
+ readAt,
});
-
- // Calling this directly so we can wait for completion
- return Whisper.ReadReceipts.onReceipt(receipt);
}
async function handleReceiptMessage(
diff --git a/ts/util/readReceipts.ts b/ts/util/readReceipts.ts
new file mode 100644
index 000000000..c0510cb17
--- /dev/null
+++ b/ts/util/readReceipts.ts
@@ -0,0 +1,60 @@
+import _ from 'lodash';
+import { MessageCollection } from '../models/message';
+
+import * as Data from '../data/data';
+import { getConversationController } from '../session/conversations';
+
+async function getTargetMessage(reader: string, messages: MessageCollection) {
+ if (messages.length === 0) {
+ return null;
+ }
+ const message = messages.find(msg => msg.isOutgoing() && reader === msg.get('conversationId'));
+ if (message) {
+ return message;
+ }
+
+ // we do not support read messages for groups
+ return null;
+}
+
+async function onReadReceipt(receipt: { source: string; timestamp: number; readAt: number }) {
+ try {
+ const messages = await Data.getMessagesBySentAt(receipt.timestamp);
+
+ const message = await getTargetMessage(receipt.source, messages);
+
+ if (!message) {
+ window.log.info('No message for read receipt', receipt.source, receipt.timestamp);
+ return;
+ }
+
+ const readBy = message.get('read_by') || [];
+ const expirationStartTimestamp = message.get('expirationStartTimestamp');
+
+ if (!readBy.includes(receipt.source)) {
+ readBy.push(receipt.source);
+ }
+ message.set({
+ read_by: readBy,
+ expirationStartTimestamp: expirationStartTimestamp || Date.now(),
+ sent: true,
+ });
+
+ if (message.isExpiring() && !expirationStartTimestamp) {
+ // This will save the message for us while starting the timer
+ await message.setToExpire();
+ } else {
+ await message.commit();
+ }
+
+ // notify frontend listeners
+ const conversation = getConversationController().get(message.get('conversationId'));
+ if (conversation) {
+ conversation.updateLastMessage();
+ }
+ } catch (error) {
+ window.log.error('ReadReceipts.onReceipt error:', error && error.stack ? error.stack : error);
+ }
+}
+
+export const ReadReceipts = { onReadReceipt };