diff --git a/ts/data/data.ts b/ts/data/data.ts index bc5b92a1d..8ec5f5e34 100644 --- a/ts/data/data.ts +++ b/ts/data/data.ts @@ -446,10 +446,11 @@ async function getMessageBySenderAndSentAt({ } async function getMessageByServerId( + conversationId: string, serverId: number, skipTimerInit: boolean = false ): Promise { - const message = await channels.getMessageByServerId(serverId); + const message = await channels.getMessageByServerId(conversationId, serverId); if (!message) { return null; } diff --git a/ts/models/conversation.ts b/ts/models/conversation.ts index 820bab980..1969eaf19 100644 --- a/ts/models/conversation.ts +++ b/ts/models/conversation.ts @@ -735,7 +735,6 @@ export class ConversationModel extends Backbone.Model { reaction, sender: UserUtils.getOurPubKeyStrFromCache(), you: true, - isOpenGroup: false, }); return; } @@ -752,7 +751,6 @@ export class ConversationModel extends Backbone.Model { reaction, sender: UserUtils.getOurPubKeyStrFromCache(), you: true, - isOpenGroup: false, }); return; } diff --git a/ts/node/sql.ts b/ts/node/sql.ts index 0f6fd847d..4cf9569e1 100644 --- a/ts/node/sql.ts +++ b/ts/node/sql.ts @@ -1040,10 +1040,14 @@ function getMessageBySenderAndSentAt({ source, sentAt }: { source: string; sentA return map(rows, row => jsonToObject(row.json)); } -function getMessageByServerId(serverId: number) { +// serverIds are not unique so we need the conversationId +function getMessageByServerId(conversationId: string, serverId: number) { const row = assertGlobalInstance() - .prepare(`SELECT * FROM ${MESSAGES_TABLE} WHERE serverId = $serverId;`) + .prepare( + `SELECT * FROM ${MESSAGES_TABLE} WHERE conversationId = $conversationId AND serverId = $serverId;` + ) .get({ + conversationId, serverId, }); diff --git a/ts/receiver/dataMessage.ts b/ts/receiver/dataMessage.ts index 2d4e725eb..ebd86af01 100644 --- a/ts/receiver/dataMessage.ts +++ b/ts/receiver/dataMessage.ts @@ -309,7 +309,6 @@ async function handleSwarmMessage( reaction: rawDataMessage.reaction, sender: msgModel.get('source'), you: isUsFromCache(msgModel.get('source')), - isOpenGroup: false, }); if ( convoToAddMessageTo.isPrivate() && diff --git a/ts/session/apis/open_group_api/sogsv3/sogsV3ClearReaction.ts b/ts/session/apis/open_group_api/sogsv3/sogsV3ClearReaction.ts index eb358757e..292a68811 100644 --- a/ts/session/apis/open_group_api/sogsv3/sogsV3ClearReaction.ts +++ b/ts/session/apis/open_group_api/sogsv3/sogsV3ClearReaction.ts @@ -2,6 +2,7 @@ import AbortController from 'abort-controller'; import { OpenGroupReactionResponse } from '../../../../types/Reaction'; import { Reactions } from '../../../../util/reactions'; import { OpenGroupRequestCommonType } from '../opengroupV2/ApiUtil'; +import { getOpenGroupV2ConversationId } from '../utils/OpenGroupUtils'; import { batchFirstSubIsSuccess, batchGlobalIsSuccess, @@ -26,7 +27,8 @@ export const clearSogsReactionByServerId = async ( serverId: number, roomInfos: OpenGroupRequestCommonType ): Promise => { - const { supported, conversation } = await hasReactionSupport(serverId); + const converationId = getOpenGroupV2ConversationId(roomInfos.serverUrl, roomInfos.roomId); + const { supported, conversation } = await hasReactionSupport(converationId, serverId); if (!supported) { return false; } @@ -51,7 +53,7 @@ export const clearSogsReactionByServerId = async ( addToMutationCache(cacheEntry); // Since responses can take a long time we immediately update the moderators's UI and if there is a problem it is overwritten by handleOpenGroupMessageReactions later. - await Reactions.handleClearReaction(serverId, reaction); + await Reactions.handleClearReaction(converationId, serverId, reaction); const options: Array = [ { diff --git a/ts/session/apis/open_group_api/sogsv3/sogsV3MutationCache.ts b/ts/session/apis/open_group_api/sogsv3/sogsV3MutationCache.ts index b704fd5a0..74c8cd4cf 100644 --- a/ts/session/apis/open_group_api/sogsv3/sogsV3MutationCache.ts +++ b/ts/session/apis/open_group_api/sogsv3/sogsV3MutationCache.ts @@ -6,6 +6,7 @@ import { filter, findIndex, remove } from 'lodash'; import { Reactions } from '../../../../util/reactions'; import { OpenGroupReactionMessageV4 } from '../opengroupV2/OpenGroupServerPoller'; +import { getOpenGroupV2ConversationId } from '../utils/OpenGroupUtils'; export enum ChangeType { REACTIONS = 0, @@ -143,6 +144,10 @@ export async function processMessagesUsingCache( } message.reactions = updatedReactions; - await Reactions.handleOpenGroupMessageReactions(message.reactions, message.id); + await Reactions.handleOpenGroupMessageReactions( + getOpenGroupV2ConversationId(server, room), + message.id, + message.reactions + ); return message; } diff --git a/ts/session/apis/open_group_api/sogsv3/sogsV3SendReaction.ts b/ts/session/apis/open_group_api/sogsv3/sogsV3SendReaction.ts index 4f31e35a6..7a03842e1 100644 --- a/ts/session/apis/open_group_api/sogsv3/sogsV3SendReaction.ts +++ b/ts/session/apis/open_group_api/sogsv3/sogsV3SendReaction.ts @@ -12,19 +12,15 @@ import { Reactions } from '../../../../util/reactions'; import { OnionSending } from '../../../onions/onionSend'; import { ToastUtils, UserUtils } from '../../../utils'; import { OpenGroupPollingUtils } from '../opengroupV2/OpenGroupPollingUtils'; +import { getOpenGroupV2ConversationId } from '../utils/OpenGroupUtils'; import { getUsBlindedInThatServer } from './knownBlindedkeys'; import { batchGlobalIsSuccess, parseBatchGlobalStatusCode } from './sogsV3BatchPoll'; -import { - addToMutationCache, - ChangeType, - SogsV3Mutation, - updateMutationCache, -} from './sogsV3MutationCache'; export const hasReactionSupport = async ( + conversationId: string, serverId: number ): Promise<{ supported: boolean; conversation: ConversationModel | null }> => { - const found = await Data.getMessageByServerId(serverId); + const found = await Data.getMessageByServerId(conversationId, serverId); if (!found) { window.log.warn(`Open Group Message ${serverId} not found in db`); return { supported: false, conversation: null }; @@ -57,7 +53,10 @@ export const sendSogsReactionOnionV4 = async ( throw new Error(`Could not find sogs pubkey of url:${serverUrl}`); } - const { supported, conversation } = await hasReactionSupport(reaction.id); + const { supported, conversation } = await hasReactionSupport( + getOpenGroupV2ConversationId(serverUrl, room), + reaction.id + ); if (!supported) { return false; } @@ -82,27 +81,13 @@ export const sendSogsReactionOnionV4 = async ( const method = reaction.action === Action.REACT ? 'PUT' : 'DELETE'; const serverPubkey = allValidRoomInfos[0].serverPublicKey; - const cacheEntry: SogsV3Mutation = { - server: serverUrl, - room: room, - changeType: ChangeType.REACTIONS, - seqno: null, - metadata: { - messageId: reaction.id, - emoji, - action: reaction.action === Action.REACT ? 'ADD' : 'REMOVE', - }, - }; - - addToMutationCache(cacheEntry); - // Since responses can take a long time we immediately update the sender's UI and if there is a problem it is overwritten by handleOpenGroupMessageReactions later. const me = UserUtils.getOurPubKeyStrFromCache(); await Reactions.handleMessageReaction({ reaction, sender: blinded ? getUsBlindedInThatServer(conversation) || me : me, you: true, - isOpenGroup: true, + openGroupConversationId: getOpenGroupV2ConversationId(serverUrl, room), }); // reaction endpoint requires an empty dict {} @@ -137,9 +122,5 @@ export const sendSogsReactionOnionV4 = async ( const success = Boolean(reaction.action === Action.REACT ? rawMessage.added : rawMessage.removed); - if (success) { - updateMutationCache(cacheEntry, rawMessage.seqno); - } - return success; }; diff --git a/ts/test/session/unit/reactions/ReactionMessage_test.ts b/ts/test/session/unit/reactions/ReactionMessage_test.ts index 8c9574b38..2a53368d9 100644 --- a/ts/test/session/unit/reactions/ReactionMessage_test.ts +++ b/ts/test/session/unit/reactions/ReactionMessage_test.ts @@ -56,7 +56,6 @@ describe('ReactionMessage', () => { reaction: reaction as SignalService.DataMessage.IReaction, sender: ourNumber, you: true, - isOpenGroup: false, }); expect(updatedMessage?.get('reacts'), 'original message should have reacts').to.not.be @@ -89,7 +88,6 @@ describe('ReactionMessage', () => { reaction: reaction as SignalService.DataMessage.IReaction, sender: ourNumber, you: true, - isOpenGroup: false, }); expect(updatedMessage?.get('reacts'), 'original message reacts should be undefined').to.be diff --git a/ts/util/reactions.ts b/ts/util/reactions.ts index 0659c5224..51ff2dab6 100644 --- a/ts/util/reactions.ts +++ b/ts/util/reactions.ts @@ -38,14 +38,14 @@ function hitRateLimit(): boolean { */ const getMessageByReaction = async ( reaction: SignalService.DataMessage.IReaction, - isOpenGroup: boolean + openGroupConversationId?: string ): Promise => { let originalMessage = null; const originalMessageId = Number(reaction.id); const originalMessageAuthor = reaction.author; - if (isOpenGroup) { - originalMessage = await Data.getMessageByServerId(originalMessageId); + if (openGroupConversationId && !isEmpty(openGroupConversationId)) { + originalMessage = await Data.getMessageByServerId(openGroupConversationId, originalMessageId); } else { const collection = await Data.getMessagesBySentAt(originalMessageId); originalMessage = collection.find((item: MessageModel) => { @@ -152,19 +152,19 @@ const handleMessageReaction = async ({ reaction, sender, you, - isOpenGroup, + openGroupConversationId, }: { reaction: SignalService.DataMessage.IReaction; sender: string; you: boolean; - isOpenGroup: boolean; + openGroupConversationId?: string; }) => { if (!reaction.emoji) { window?.log?.warn(`There is no emoji for the reaction ${reaction}.`); return; } - const originalMessage = await getMessageByReaction(reaction, isOpenGroup); + const originalMessage = await getMessageByReaction(reaction, openGroupConversationId); if (!originalMessage) { return; } @@ -240,10 +240,12 @@ const handleMessageReaction = async ({ * Handles updating the UI when clearing all reactions for a certain emoji * Only usable by moderators in opengroups and runs on their client */ -const handleClearReaction = async (serverId: number, emoji: string) => { - const originalMessage = await Data.getMessageByServerId(serverId); +const handleClearReaction = async (conversationId: string, serverId: number, emoji: string) => { + const originalMessage = await Data.getMessageByServerId(conversationId, serverId); if (!originalMessage) { - window?.log?.warn(`Cannot find the original reacted message ${serverId}.`); + window?.log?.warn( + `Cannot find the original reacted message ${serverId} in conversation ${conversationId}.` + ); return; } @@ -265,14 +267,18 @@ const handleClearReaction = async (serverId: number, emoji: string) => { /** * Handles all message reaction updates/responses for opengroups + * serverIds are not unique so we need the conversationId */ const handleOpenGroupMessageReactions = async ( - reactions: OpenGroupReactionList, - serverId: number + conversationId: string, + serverId: number, + reactions: OpenGroupReactionList ) => { - const originalMessage = await Data.getMessageByServerId(serverId); + const originalMessage = await Data.getMessageByServerId(conversationId, serverId); if (!originalMessage) { - window?.log?.warn(`Cannot find the original reacted message ${serverId}.`); + window?.log?.warn( + `Cannot find the original reacted message ${serverId} in conversation ${conversationId}.` + ); return; }