2021-10-29 23:19:44 +00:00
|
|
|
// Copyright 2021 Signal Messenger, LLC
|
|
|
|
// SPDX-License-Identifier: AGPL-3.0-only
|
|
|
|
|
2023-08-21 20:08:27 +00:00
|
|
|
import noop from 'lodash/noop';
|
2024-10-08 03:17:03 +00:00
|
|
|
import { v7 as generateUuid } from 'uuid';
|
2023-08-10 16:43:33 +00:00
|
|
|
|
2024-07-22 18:16:33 +00:00
|
|
|
import { DataWriter } from '../sql/Client';
|
2024-10-08 03:17:03 +00:00
|
|
|
import type { MessageModel } from '../models/messages';
|
2023-08-21 20:08:27 +00:00
|
|
|
import type { ReactionAttributesType } from '../messageModifiers/Reactions';
|
2021-10-29 23:19:44 +00:00
|
|
|
import { ReactionSource } from './ReactionSource';
|
2023-10-04 00:12:57 +00:00
|
|
|
import { __DEPRECATED$getMessageById } from '../messages/getMessageById';
|
2023-08-16 20:54:39 +00:00
|
|
|
import { getSourceServiceId, isStory } from '../messages/helpers';
|
2021-10-29 23:19:44 +00:00
|
|
|
import { strictAssert } from '../util/assert';
|
2023-01-11 22:54:06 +00:00
|
|
|
import { isDirectConversation } from '../util/whatTypeOfConversation';
|
|
|
|
import { incrementMessageCounter } from '../util/incrementMessageCounter';
|
2024-10-08 03:17:03 +00:00
|
|
|
import { generateMessageId } from '../util/generateMessageId';
|
2023-01-11 22:54:06 +00:00
|
|
|
import { repeat, zipObject } from '../util/iterables';
|
2023-05-16 17:37:12 +00:00
|
|
|
import { getMessageSentTimestamp } from '../util/getMessageSentTimestamp';
|
2023-09-14 17:04:48 +00:00
|
|
|
import { isAciString } from '../util/isAciString';
|
2023-01-11 22:54:06 +00:00
|
|
|
import { SendStatus } from '../messages/MessageSendState';
|
2023-05-16 17:37:12 +00:00
|
|
|
import * as log from '../logging/log';
|
2021-10-29 23:19:44 +00:00
|
|
|
|
|
|
|
export async function enqueueReactionForSend({
|
|
|
|
emoji,
|
|
|
|
messageId,
|
|
|
|
remove,
|
|
|
|
}: Readonly<{
|
|
|
|
emoji: string;
|
|
|
|
messageId: string;
|
|
|
|
remove: boolean;
|
|
|
|
}>): Promise<void> {
|
2023-10-04 00:12:57 +00:00
|
|
|
const message = await __DEPRECATED$getMessageById(messageId);
|
2021-10-29 23:19:44 +00:00
|
|
|
strictAssert(message, 'enqueueReactionForSend: no message found');
|
|
|
|
|
2023-08-16 20:54:39 +00:00
|
|
|
const targetAuthorAci = getSourceServiceId(message.attributes);
|
2021-10-29 23:19:44 +00:00
|
|
|
strictAssert(
|
2023-08-16 20:54:39 +00:00
|
|
|
targetAuthorAci,
|
2021-10-29 23:19:44 +00:00
|
|
|
`enqueueReactionForSend: message ${message.idForLogging()} had no source UUID`
|
|
|
|
);
|
2023-08-10 16:43:33 +00:00
|
|
|
strictAssert(
|
2023-08-16 20:54:39 +00:00
|
|
|
isAciString(targetAuthorAci),
|
2023-08-10 16:43:33 +00:00
|
|
|
`enqueueReactionForSend: message ${message.idForLogging()} had no source ACI`
|
|
|
|
);
|
2021-10-29 23:19:44 +00:00
|
|
|
|
2023-05-16 17:37:12 +00:00
|
|
|
const targetTimestamp = getMessageSentTimestamp(message.attributes, {
|
|
|
|
log,
|
|
|
|
});
|
2021-10-29 23:19:44 +00:00
|
|
|
strictAssert(
|
|
|
|
targetTimestamp,
|
|
|
|
`enqueueReactionForSend: message ${message.idForLogging()} had no timestamp`
|
|
|
|
);
|
|
|
|
|
2023-01-11 22:54:06 +00:00
|
|
|
const timestamp = Date.now();
|
|
|
|
const messageConversation = message.getConversation();
|
|
|
|
strictAssert(
|
|
|
|
messageConversation,
|
|
|
|
'enqueueReactionForSend: No conversation extracted from target message'
|
|
|
|
);
|
|
|
|
|
2023-05-10 16:14:00 +00:00
|
|
|
const isMessageAStory = isStory(message.attributes);
|
2023-12-08 02:20:36 +00:00
|
|
|
|
|
|
|
if (
|
|
|
|
!isMessageAStory ||
|
|
|
|
isDirectConversation(messageConversation.attributes)
|
|
|
|
) {
|
|
|
|
log.info('Enabling profile sharing for reaction send');
|
|
|
|
if (!messageConversation.get('profileSharing')) {
|
|
|
|
messageConversation.set('profileSharing', true);
|
2024-07-22 18:16:33 +00:00
|
|
|
await DataWriter.updateConversation(messageConversation.attributes);
|
2023-12-08 02:20:36 +00:00
|
|
|
}
|
|
|
|
await messageConversation.restoreContact();
|
|
|
|
}
|
|
|
|
|
2023-01-11 22:54:06 +00:00
|
|
|
const targetConversation =
|
2023-05-10 16:14:00 +00:00
|
|
|
isMessageAStory && isDirectConversation(messageConversation.attributes)
|
2023-08-16 20:54:39 +00:00
|
|
|
? window.ConversationController.get(targetAuthorAci)
|
2023-01-11 22:54:06 +00:00
|
|
|
: messageConversation;
|
|
|
|
strictAssert(
|
|
|
|
targetConversation,
|
|
|
|
'enqueueReactionForSend: Did not find a targetConversation'
|
|
|
|
);
|
|
|
|
|
2023-05-10 16:14:00 +00:00
|
|
|
const expireTimer =
|
|
|
|
!isMessageAStory || isDirectConversation(targetConversation.attributes)
|
|
|
|
? targetConversation.get('expireTimer')
|
|
|
|
: undefined;
|
2023-01-11 22:54:06 +00:00
|
|
|
const storyMessage = isStory(message.attributes)
|
|
|
|
? message.attributes
|
|
|
|
: undefined;
|
|
|
|
|
|
|
|
// Only used in story scenarios, where we use a whole message to represent the reaction
|
2024-10-08 03:17:03 +00:00
|
|
|
let storyReactionMessage: MessageModel | undefined;
|
|
|
|
if (storyMessage) {
|
|
|
|
storyReactionMessage = new window.Whisper.Message({
|
|
|
|
...generateMessageId(incrementMessageCounter()),
|
|
|
|
type: 'outgoing',
|
|
|
|
conversationId: targetConversation.id,
|
|
|
|
sent_at: timestamp,
|
|
|
|
received_at_ms: timestamp,
|
|
|
|
timestamp,
|
|
|
|
expireTimer,
|
|
|
|
sendStateByConversationId: zipObject(
|
|
|
|
targetConversation.getMemberConversationIds(),
|
|
|
|
repeat({
|
|
|
|
status: SendStatus.Pending,
|
|
|
|
updatedAt: Date.now(),
|
|
|
|
})
|
|
|
|
),
|
|
|
|
storyId: message.id,
|
|
|
|
storyReaction: {
|
|
|
|
emoji,
|
|
|
|
targetAuthorAci,
|
|
|
|
targetTimestamp,
|
|
|
|
},
|
|
|
|
});
|
|
|
|
}
|
2023-01-11 22:54:06 +00:00
|
|
|
|
2023-08-21 20:08:27 +00:00
|
|
|
const reaction: ReactionAttributesType = {
|
|
|
|
envelopeId: generateUuid(),
|
|
|
|
removeFromMessageReceiverCache: noop,
|
2021-10-29 23:19:44 +00:00
|
|
|
emoji,
|
2023-01-11 22:54:06 +00:00
|
|
|
fromId: window.ConversationController.getOurConversationIdOrThrow(),
|
2021-10-29 23:19:44 +00:00
|
|
|
remove,
|
2023-01-11 22:54:06 +00:00
|
|
|
source: ReactionSource.FromThisDevice,
|
2024-04-29 21:20:20 +00:00
|
|
|
generatedMessageForStoryReaction: storyReactionMessage,
|
2023-08-16 20:54:39 +00:00
|
|
|
targetAuthorAci,
|
2021-10-29 23:19:44 +00:00
|
|
|
targetTimestamp,
|
2023-12-08 01:30:20 +00:00
|
|
|
receivedAtDate: timestamp,
|
2023-01-11 22:54:06 +00:00
|
|
|
timestamp,
|
2023-08-21 20:08:27 +00:00
|
|
|
};
|
2021-10-29 23:19:44 +00:00
|
|
|
|
2023-01-11 22:54:06 +00:00
|
|
|
await message.handleReaction(reaction, { storyMessage });
|
2021-10-29 23:19:44 +00:00
|
|
|
}
|