From dde61bb35b91bfffc794e817e6bbc2a0a5b23ab0 Mon Sep 17 00:00:00 2001 From: William Grant Date: Mon, 29 Aug 2022 17:29:10 +1000 Subject: [PATCH] feat: moderator clear all reactions behaviour now uses the cache --- ts/components/dialog/ReactListModal.tsx | 7 +--- .../sogsv3/sogsV3ClearReaction.ts | 37 ++++++++++++++++++- .../sogsv3/sogsV3MutationCache.ts | 30 ++++++++------- 3 files changed, 54 insertions(+), 20 deletions(-) diff --git a/ts/components/dialog/ReactListModal.tsx b/ts/components/dialog/ReactListModal.tsx index 3fb5bdccc..d833bbff2 100644 --- a/ts/components/dialog/ReactListModal.tsx +++ b/ts/components/dialog/ReactListModal.tsx @@ -3,9 +3,8 @@ import React, { ReactElement, useEffect, useState } from 'react'; import { useDispatch } from 'react-redux'; import styled from 'styled-components'; import { Data } from '../../data/data'; -import { useMessageReactsPropsById } from '../../hooks/useParamSelector'; +import { useMessageReactsPropsById, useWeAreModerator } from '../../hooks/useParamSelector'; import { isUsAnySogsFromCache } from '../../session/apis/open_group_api/sogsv3/knownBlindedkeys'; -import { getConversationController } from '../../session/conversations'; import { UserUtils } from '../../session/utils'; import { updateReactClearAllModal, @@ -285,9 +284,7 @@ export const ReactListModal = (props: Props): ReactElement => { const dispatch = useDispatch(); const { convoId, isPublic } = msgProps; - - const convo = getConversationController().get(convoId); - const weAreModerator = convo.getConversationModelProps().weAreModerator; + const weAreModerator = useWeAreModerator(convoId); const handleSelectedReaction = (emoji: string): boolean => { return currentReact === emoji; diff --git a/ts/session/apis/open_group_api/sogsv3/sogsV3ClearReaction.ts b/ts/session/apis/open_group_api/sogsv3/sogsV3ClearReaction.ts index c8f8c41f2..fefa9537d 100644 --- a/ts/session/apis/open_group_api/sogsv3/sogsV3ClearReaction.ts +++ b/ts/session/apis/open_group_api/sogsv3/sogsV3ClearReaction.ts @@ -1,4 +1,5 @@ import AbortController from 'abort-controller'; +import { OpenGroupReactionResponse } from '../../../../types/Reaction'; import { OpenGroupRequestCommonType } from '../opengroupV2/ApiUtil'; import { batchFirstSubIsSuccess, @@ -6,6 +7,12 @@ import { OpenGroupBatchRow, sogsBatchSend, } from './sogsV3BatchPoll'; +import { + addToMutationCache, + ChangeType, + SogsV3Mutation, + updateMutationCache, +} from './sogsV3MutationCache'; import { hasReactionSupport } from './sogsV3SendReaction'; /** @@ -23,6 +30,20 @@ export const clearSogsReactionByServerId = async ( return false; } + const cacheEntry: SogsV3Mutation = { + server: roomInfos.serverUrl, + room: roomInfos.roomId, + changeType: ChangeType.REACTIONS, + seqno: null, + metadata: { + messageId: serverId, + emoji: reaction, + action: 'CLEAR', + }, + }; + + addToMutationCache(cacheEntry); + const options: Array = [ { type: 'deleteReaction', @@ -37,8 +58,22 @@ export const clearSogsReactionByServerId = async ( 'batch' ); + if (!result) { + throw new Error('Could not deleteReaction, res is invalid'); + } + + const rawMessage = (result.body && (result.body[0].body as OpenGroupReactionResponse)) || null; + if (!rawMessage) { + throw new Error('deleteReaction parsing failed'); + } + try { - return batchGlobalIsSuccess(result) && batchFirstSubIsSuccess(result); + if (batchGlobalIsSuccess(result) && batchFirstSubIsSuccess(result)) { + updateMutationCache(cacheEntry, rawMessage.seqno); + return true; + } else { + return false; + } } catch (e) { window?.log?.error("clearSogsReactionByServerId Can't decode JSON body"); } diff --git a/ts/session/apis/open_group_api/sogsv3/sogsV3MutationCache.ts b/ts/session/apis/open_group_api/sogsv3/sogsV3MutationCache.ts index 9cefe2591..90f5d442d 100644 --- a/ts/session/apis/open_group_api/sogsv3/sogsV3MutationCache.ts +++ b/ts/session/apis/open_group_api/sogsv3/sogsV3MutationCache.ts @@ -11,7 +11,7 @@ export enum ChangeType { REACTIONS = 0, } -type ReactionAction = 'ADD' | 'REMOVE'; +type ReactionAction = 'ADD' | 'REMOVE' | 'CLEAR'; type ReactionChange = { messageId: number; // will be serverId of the reacted message @@ -73,16 +73,19 @@ export async function processMessagesUsingCache( message: OpenGroupMessageV4 ) { const updatedReactions = message.reactions; - const matches: Array = filter(sogsMutationCache, { server, room }); + const roomMatches: Array = filter(sogsMutationCache, { server, room }); - if (matches?.length) { - for (const match of matches) { - if (message.seqno && match.seqno && match.seqno <= message.seqno) { - const removedEntry = remove(sogsMutationCache, match); + if (roomMatches?.length) { + for (const roomMatch of roomMatches) { + if (message.seqno && roomMatch.seqno && roomMatch.seqno <= message.seqno) { + const removedEntry = remove(sogsMutationCache, roomMatch); window.log.info('SOGS Mutation Cache: Entry ignored and removed!', removedEntry); - } else if (!message.seqno || (message.seqno && match.seqno && match.seqno > message.seqno)) { + } else if ( + !message.seqno || + (message.seqno && roomMatch.seqno && roomMatch.seqno > message.seqno) + ) { for (const reaction of Object.keys(message.reactions)) { - const _matches = filter(sogsMutationCache, { + const reactionMatches = filter(sogsMutationCache, { server, room, changeType: ChangeType.REACTIONS, @@ -91,9 +94,9 @@ export async function processMessagesUsingCache( emoji: reaction, }, }); - if (_matches?.length) { - for (const match of _matches) { - switch (match.metadata.action) { + if (reactionMatches?.length) { + for (const reactionMatch of reactionMatches) { + switch (reactionMatch.metadata.action) { case 'ADD': updatedReactions[reaction].you = true; updatedReactions[reaction].count += 1; @@ -113,13 +116,12 @@ export async function processMessagesUsingCache( default: window.log.warn( 'SOGS Mutation Cache: Unsupported metadata action in OpenGroupMessageV4', - match + reactionMatch ); - break; } } - const removedMatches = remove(sogsMutationCache, ...matches); + const removedMatches = remove(sogsMutationCache, ...roomMatches); window.log.info( 'SOGS Mutation Cache: Removed processed entries from cache!', removedMatches