session-desktop/ts/util/readReceipts.ts

79 lines
2.4 KiB
TypeScript

import { MessageCollection } from '../models/message';
import { 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 convoId = message.get('conversationId'); // this might be a group and we don't want to handle them
if (
!convoId ||
!getConversationController().get(convoId) ||
!getConversationController()
.get(convoId)
.isPrivate()
) {
window.log.info(
'Convo is undefined or not a private chat for read receipt in convo',
convoId
);
return;
}
// readBy is only used for private conversations
// we do not care of who read it. If the length is > 0 , it is read and false otherwise
let readBy = message.get('read_by') || [];
const expirationStartTimestamp = message.get('expirationStartTimestamp');
if (!readBy.length) {
readBy.push(receipt.source);
}
if (readBy.length > 1) {
readBy = readBy.slice(0, 1);
}
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 };