Send/Receive support for reaction read syncs
This commit is contained in:
parent
82a9705010
commit
e0c324e4ba
23 changed files with 1188 additions and 498 deletions
111
ts/util/markConversationRead.ts
Normal file
111
ts/util/markConversationRead.ts
Normal file
|
@ -0,0 +1,111 @@
|
|||
// Copyright 2021 Signal Messenger, LLC
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
import { ConversationAttributesType } from '../model-types.d';
|
||||
import { handleMessageSend } from './handleMessageSend';
|
||||
import { sendReadReceiptsFor } from './sendReadReceiptsFor';
|
||||
|
||||
export async function markConversationRead(
|
||||
conversationAttrs: ConversationAttributesType,
|
||||
newestUnreadId: number,
|
||||
options: { readAt?: number; sendReadReceipts: boolean } = {
|
||||
sendReadReceipts: true,
|
||||
}
|
||||
): Promise<number> {
|
||||
const { id: conversationId } = conversationAttrs;
|
||||
window.Whisper.Notifications.removeBy({ conversationId });
|
||||
|
||||
const [unreadMessages, unreadReactions] = await Promise.all([
|
||||
window.Signal.Data.getUnreadByConversationAndMarkRead(
|
||||
conversationId,
|
||||
newestUnreadId,
|
||||
options.readAt
|
||||
),
|
||||
window.Signal.Data.getUnreadReactionsAndMarkRead(
|
||||
conversationId,
|
||||
newestUnreadId
|
||||
),
|
||||
]);
|
||||
|
||||
const unreadReactionSyncData = new Map<
|
||||
string,
|
||||
{
|
||||
senderUuid?: string;
|
||||
senderE164?: string;
|
||||
timestamp: number;
|
||||
}
|
||||
>();
|
||||
unreadReactions.forEach(reaction => {
|
||||
const targetKey = `${reaction.targetAuthorUuid}/${reaction.targetTimestamp}`;
|
||||
if (unreadReactionSyncData.has(targetKey)) {
|
||||
return;
|
||||
}
|
||||
unreadReactionSyncData.set(targetKey, {
|
||||
senderE164: undefined,
|
||||
senderUuid: reaction.targetAuthorUuid,
|
||||
timestamp: reaction.targetTimestamp,
|
||||
});
|
||||
});
|
||||
|
||||
const allReadMessagesSync = unreadMessages.map(messageSyncData => {
|
||||
const message = window.MessageController.getById(messageSyncData.id);
|
||||
// we update the in-memory MessageModel with the fresh database call data
|
||||
if (message) {
|
||||
message.set(messageSyncData);
|
||||
}
|
||||
|
||||
return {
|
||||
senderE164: messageSyncData.source,
|
||||
senderUuid: messageSyncData.sourceUuid,
|
||||
senderId: window.ConversationController.ensureContactIds({
|
||||
e164: messageSyncData.source,
|
||||
uuid: messageSyncData.sourceUuid,
|
||||
}),
|
||||
timestamp: messageSyncData.sent_at,
|
||||
hasErrors: message ? message.hasErrors() : false,
|
||||
};
|
||||
});
|
||||
|
||||
// Some messages we're marking read are local notifications with no sender
|
||||
const messagesWithSenderId = allReadMessagesSync.filter(syncMessage =>
|
||||
Boolean(syncMessage.senderId)
|
||||
);
|
||||
const incomingUnreadMessages = unreadMessages.filter(
|
||||
message => message.type === 'incoming'
|
||||
);
|
||||
const unreadCount =
|
||||
incomingUnreadMessages.length - messagesWithSenderId.length;
|
||||
|
||||
// If a message has errors, we don't want to send anything out about it.
|
||||
// read syncs - let's wait for a client that really understands the message
|
||||
// to mark it read. we'll mark our local error read locally, though.
|
||||
// read receipts - here we can run into infinite loops, where each time the
|
||||
// conversation is viewed, another error message shows up for the contact
|
||||
const unreadMessagesSyncData = messagesWithSenderId.filter(
|
||||
item => !item.hasErrors
|
||||
);
|
||||
|
||||
const readSyncs = [
|
||||
...unreadMessagesSyncData,
|
||||
...Array.from(unreadReactionSyncData.values()),
|
||||
];
|
||||
|
||||
if (readSyncs.length && options.sendReadReceipts) {
|
||||
window.log.info(`Sending ${readSyncs.length} read syncs`);
|
||||
// Because syncReadMessages sends to our other devices, and sendReadReceipts goes
|
||||
// to a contact, we need accessKeys for both.
|
||||
const {
|
||||
sendOptions,
|
||||
} = await window.ConversationController.prepareForSend(
|
||||
window.ConversationController.getOurConversationId(),
|
||||
{ syncMessage: true }
|
||||
);
|
||||
|
||||
await handleMessageSend(
|
||||
window.textsecure.messaging.syncReadMessages(readSyncs, sendOptions)
|
||||
);
|
||||
await sendReadReceiptsFor(conversationAttrs, unreadMessagesSyncData);
|
||||
}
|
||||
|
||||
return unreadCount;
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue