From 783b4b6b9b7225fcffb03f5847beeacbc7cb7054 Mon Sep 17 00:00:00 2001 From: Daniel Gale-Rosen Date: Tue, 23 May 2023 12:44:56 -0400 Subject: [PATCH 01/14] basic framework --- src/pages/home/report/ReportActionItem.js | 46 +++++++++++++++++++ .../home/report/ReportActionItemMessage.js | 7 ++- 2 files changed, 51 insertions(+), 2 deletions(-) diff --git a/src/pages/home/report/ReportActionItem.js b/src/pages/home/report/ReportActionItem.js index a318d181e460..a722f793246a 100644 --- a/src/pages/home/report/ReportActionItem.js +++ b/src/pages/home/report/ReportActionItem.js @@ -10,6 +10,7 @@ import reportActionPropTypes from './reportActionPropTypes'; import * as StyleUtils from '../../../styles/StyleUtils'; import PressableWithSecondaryInteraction from '../../../components/PressableWithSecondaryInteraction'; import Hoverable from '../../../components/Hoverable'; +import Button from '../../../components/Button'; import ReportActionItemSingle from './ReportActionItemSingle'; import ReportActionItemGrouped from './ReportActionItemGrouped'; import MoneyRequestAction from '../../../components/ReportActionItem/MoneyRequestAction'; @@ -105,6 +106,8 @@ const defaultProps = { function ReportActionItem(props) { const [isContextMenuActive, setIsContextMenuActive] = useState(ReportActionContextMenu.isActiveReportAction(props.action.reportActionID)); + const [isHidden, setIsHidden] = useState(true); + const [moderationDecision, setModerationDecision] = useState('approved'); const textInputRef = useRef(); const popoverAnchorRef = useRef(); @@ -120,6 +123,40 @@ function ReportActionItem(props) { focusTextInputAfterAnimation(textInputRef.current, 100); }, [isDraftEmpty]); + // hide the message if it is being moderated + useEffect(() => { + if (!props.action.moderationDecisions || _.isEmpty(props.action.moderationDecisions)) { + return; + } + + const decisions = props.action.moderationDecisions; + let lastDecision; + + decisions.foreach((decision) => { + // removed will always take precedence - there's no going back from that currently + if (decision.decision === 'removed') { + setModerationDecision(decision.decision); + setIsHidden(true); + return; + } + + // pending will always be the most recent if it exists + if (decision.decision === 'pending') { + setModerationDecision(decision.decision); + setIsHidden(true); + return; + } + + if (!lastDecision || lastDecision.timestamp < decision.timestamp) { + lastDecision = decision; + } + }) + + setModerationDecision(lastDecision.decision); + setIsHidden(moderationDecision === 'pending' || moderationDecision === 'hidden'); + + }, [props.action, moderationDecision]) + const toggleContextMenuFromActiveReportAction = useCallback(() => { setIsContextMenuActive(ReportActionContextMenu.isActiveReportAction(props.action.reportActionID)); }, [props.action.reportActionID]); @@ -243,6 +280,7 @@ function ReportActionItem(props) { {!props.draftMessage ? ( )} + {moderationDecision === 'approved' && + + } + ) : ( )} - {moderationDecision === 'approved' && + {!props.displayAsGroup && moderationDecision !== 'approved' && } ); @@ -368,6 +380,7 @@ function ReportActionItem(props) { wrapperStyles={[styles.chatItem, isWhisper ? styles.pt1 : {}]} shouldShowSubscriptAvatar={props.shouldShowSubscriptAvatar} report={props.report} + isHidden={isHidden} > {content} diff --git a/src/pages/home/report/ReportActionItemMessage.js b/src/pages/home/report/ReportActionItemMessage.js index c6ad45968bbd..057795079a63 100644 --- a/src/pages/home/report/ReportActionItemMessage.js +++ b/src/pages/home/report/ReportActionItemMessage.js @@ -1,5 +1,5 @@ import React from 'react'; -import {View} from 'react-native'; +import {View, Text} from 'react-native'; import PropTypes from 'prop-types'; import _ from 'underscore'; import lodashGet from 'lodash/get'; @@ -39,7 +39,7 @@ const ReportActionItemMessage = (props) => ( loading={props.action.isLoading} style={props.style} /> - )) : 'hi'} + )) : This message has been flagged as violating our community rules and the content has been hidden.} ); diff --git a/src/pages/home/report/ReportActionItemSingle.js b/src/pages/home/report/ReportActionItemSingle.js index f388faf1b5a4..ceb248dfb0ea 100644 --- a/src/pages/home/report/ReportActionItemSingle.js +++ b/src/pages/home/report/ReportActionItemSingle.js @@ -127,7 +127,9 @@ const ReportActionItemSingle = (props) => { ) : null} - {props.children} + + {props.children} + ); diff --git a/src/styles/styles.js b/src/styles/styles.js index 5d7f0952a627..7ef46639a694 100644 --- a/src/styles/styles.js +++ b/src/styles/styles.js @@ -1018,6 +1018,10 @@ const styles = { lineHeight: 16, }, + lh20: { + lineHeight: 20, + }, + lh140Percent: { lineHeight: '140%', }, From f831821c19322b6b5d43d0d1f3656a0e9f47cc29 Mon Sep 17 00:00:00 2001 From: Daniel Gale-Rosen Date: Tue, 23 May 2023 14:51:23 -0400 Subject: [PATCH 03/14] cleanup --- src/pages/home/report/ReportActionItem.js | 7 ++++--- src/pages/home/report/ReportActionItemSingle.js | 2 +- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/pages/home/report/ReportActionItem.js b/src/pages/home/report/ReportActionItem.js index c23fc3b79ed4..957f135e9533 100644 --- a/src/pages/home/report/ReportActionItem.js +++ b/src/pages/home/report/ReportActionItem.js @@ -267,6 +267,7 @@ function ReportActionItem(props) { ); } else { const message = _.last(lodashGet(props.action, 'message', [{}])); + const hasBeenFlagged = moderationDecision !== 'approved'; const isAttachment = _.has(props.action, 'isAttachment') ? props.action.isAttachment : ReportUtils.isReportMessageAttachment(message); children = ( {!props.draftMessage ? ( - + - {props.displayAsGroup && moderationDecision !== 'approved' && + {props.displayAsGroup && hasBeenFlagged && } diff --git a/src/pages/home/report/ReportActionItemMessage.js b/src/pages/home/report/ReportActionItemMessage.js index 057795079a63..8b93cd1668d3 100644 --- a/src/pages/home/report/ReportActionItemMessage.js +++ b/src/pages/home/report/ReportActionItemMessage.js @@ -39,7 +39,7 @@ const ReportActionItemMessage = (props) => ( loading={props.action.isLoading} style={props.style} /> - )) : This message has been flagged as violating our community rules and the content has been hidden.} + )) : {props.translate('moderation.flaggedContent')}} ); From f49a93eabed5980d4a42df74e775f3a6df8da3d7 Mon Sep 17 00:00:00 2001 From: Daniel Gale-Rosen Date: Thu, 25 May 2023 21:17:27 -0400 Subject: [PATCH 08/14] use constants for decisions --- src/CONST.js | 2 ++ src/pages/home/report/ReportActionItem.js | 8 ++++---- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/CONST.js b/src/CONST.js index 182548b4d99e..b89af0a998bb 100755 --- a/src/CONST.js +++ b/src/CONST.js @@ -2432,6 +2432,8 @@ const CONST = { MODERATION: { MODERATOR_DECISION_PENDING: 'pending', MODERATOR_DECISION_PENDING_HIDE: 'pendingHide', + MODERATOR_DECISION_APPROVED: 'approved', + MODERATOR_DECISION: 'hidden', FLAG_SEVERITY_SPAM: 'spam', FLAG_SEVERITY_INCONSIDERATE: 'inconsiderate', }, diff --git a/src/pages/home/report/ReportActionItem.js b/src/pages/home/report/ReportActionItem.js index 0093a0e15f5c..f2faeffcf2ec 100644 --- a/src/pages/home/report/ReportActionItem.js +++ b/src/pages/home/report/ReportActionItem.js @@ -107,7 +107,7 @@ const defaultProps = { function ReportActionItem(props) { const [isContextMenuActive, setIsContextMenuActive] = useState(ReportActionContextMenu.isActiveReportAction(props.action.reportActionID)); const [isHidden, setIsHidden] = useState(false); - const [moderationDecision, setModerationDecision] = useState('approved'); + const [moderationDecision, setModerationDecision] = useState(CONST.MODERATION.MODERATOR_DECISION_APPROVED); const textInputRef = useRef(); const popoverAnchorRef = useRef(); @@ -129,7 +129,7 @@ function ReportActionItem(props) { // Right now we are only sending the latest moderationDecision to the frontend even though it is an array const latestDecision = props.action.moderationDecisions[0]; - if (latestDecision.decision === 'pendingHide' || latestDecision.decision === 'hidden') { + if (latestDecision.decision === CONST.MODERATION.MODERATOR_DECISION_PENDING_HIDE || latestDecision.decision === CONST.MODERATION.MODERATOR_DECISION_HIDDEN) { setIsHidden(true); } setModerationDecision(latestDecision.decision); @@ -245,7 +245,7 @@ function ReportActionItem(props) { ); } else { const message = _.last(lodashGet(props.action, 'message', [{}])); - const hasBeenFlagged = moderationDecision !== 'approved'; + const hasBeenFlagged = moderationDecision !== CONST.MODERATION.MODERATOR_DECISION_APPROVED; const isAttachment = _.has(props.action, 'isAttachment') ? props.action.isAttachment : ReportUtils.isReportMessageAttachment(message); children = ( {content} From b5083eef6571d7f735f674c73432bf547d3fda3d Mon Sep 17 00:00:00 2001 From: Daniel Gale-Rosen Date: Thu, 25 May 2023 21:19:36 -0400 Subject: [PATCH 09/14] fix constant and prettier --- src/CONST.js | 2 +- src/pages/home/report/ReportActionItem.js | 28 +++++++++++++------ .../home/report/ReportActionItemMessage.js | 28 +++++++++++-------- .../home/report/ReportActionItemSingle.js | 4 +-- 4 files changed, 38 insertions(+), 24 deletions(-) diff --git a/src/CONST.js b/src/CONST.js index b89af0a998bb..969f451bc2ba 100755 --- a/src/CONST.js +++ b/src/CONST.js @@ -2433,7 +2433,7 @@ const CONST = { MODERATOR_DECISION_PENDING: 'pending', MODERATOR_DECISION_PENDING_HIDE: 'pendingHide', MODERATOR_DECISION_APPROVED: 'approved', - MODERATOR_DECISION: 'hidden', + MODERATOR_DECISION_HIDDEN: 'hidden', FLAG_SEVERITY_SPAM: 'spam', FLAG_SEVERITY_INCONSIDERATE: 'inconsiderate', }, diff --git a/src/pages/home/report/ReportActionItem.js b/src/pages/home/report/ReportActionItem.js index f2faeffcf2ec..febe993320a4 100644 --- a/src/pages/home/report/ReportActionItem.js +++ b/src/pages/home/report/ReportActionItem.js @@ -133,7 +133,7 @@ function ReportActionItem(props) { setIsHidden(true); } setModerationDecision(latestDecision.decision); - }, [props.action, moderationDecision]) + }, [props.action, moderationDecision]); const toggleContextMenuFromActiveReportAction = useCallback(() => { setIsContextMenuActive(ReportActionContextMenu.isActiveReportAction(props.action.reportActionID)); @@ -263,18 +263,25 @@ function ReportActionItem(props) { isHidden={isHidden} style={[ !props.displayAsGroup && isAttachment ? styles.mt2 : undefined, - _.contains([..._.values(CONST.REPORT.ACTIONS.TYPE.POLICYCHANGELOG), CONST.REPORT.ACTIONS.TYPE.IOU], props.action.actionName) ? styles.colorMuted : undefined, + _.contains([..._.values(CONST.REPORT.ACTIONS.TYPE.POLICYCHANGELOG), CONST.REPORT.ACTIONS.TYPE.IOU], props.action.actionName) + ? styles.colorMuted + : undefined, ]} /> - {props.displayAsGroup && hasBeenFlagged && + {props.displayAsGroup && hasBeenFlagged && ( - } + )} ) : ( )} - {!props.displayAsGroup && hasBeenFlagged && + {!props.displayAsGroup && hasBeenFlagged && ( - } + )} ); } diff --git a/src/pages/home/report/ReportActionItemMessage.js b/src/pages/home/report/ReportActionItemMessage.js index 8b93cd1668d3..4d6c0b8dfb30 100644 --- a/src/pages/home/report/ReportActionItemMessage.js +++ b/src/pages/home/report/ReportActionItemMessage.js @@ -28,18 +28,22 @@ const defaultProps = { const ReportActionItemMessage = (props) => ( - {!props.isHidden ? _.map(_.compact(props.action.previousMessage || props.action.message), (fragment, index) => ( - - )) : {props.translate('moderation.flaggedContent')}} + {!props.isHidden ? ( + _.map(_.compact(props.action.previousMessage || props.action.message), (fragment, index) => ( + + )) + ) : ( + {props.translate('moderation.flaggedContent')} + )} ); diff --git a/src/pages/home/report/ReportActionItemSingle.js b/src/pages/home/report/ReportActionItemSingle.js index 69e342e2aa08..5dac6fdb1cb3 100644 --- a/src/pages/home/report/ReportActionItemSingle.js +++ b/src/pages/home/report/ReportActionItemSingle.js @@ -133,9 +133,7 @@ const ReportActionItemSingle = (props) => { ) : null} - - {props.children} - + {props.children} ); From b104d9b78ab96f85f2b1dba86bdf753e9b11eafd Mon Sep 17 00:00:00 2001 From: Daniel Gale-Rosen Date: Thu, 25 May 2023 21:27:59 -0400 Subject: [PATCH 10/14] act normal for pending --- src/pages/home/report/ReportActionItem.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/pages/home/report/ReportActionItem.js b/src/pages/home/report/ReportActionItem.js index febe993320a4..679d75df801a 100644 --- a/src/pages/home/report/ReportActionItem.js +++ b/src/pages/home/report/ReportActionItem.js @@ -245,7 +245,7 @@ function ReportActionItem(props) { ); } else { const message = _.last(lodashGet(props.action, 'message', [{}])); - const hasBeenFlagged = moderationDecision !== CONST.MODERATION.MODERATOR_DECISION_APPROVED; + const hasBeenFlagged = moderationDecision !== CONST.MODERATION.MODERATOR_DECISION_APPROVED && moderationDecision !== CONST.MODERATION.MODERATOR_DECISION_PENDING; const isAttachment = _.has(props.action, 'isAttachment') ? props.action.isAttachment : ReportUtils.isReportMessageAttachment(message); children = ( {content} From 5e9a8c85b9a8613dad132bf350221f6b1a64ecbd Mon Sep 17 00:00:00 2001 From: Daniel Gale-Rosen Date: Thu, 25 May 2023 21:48:50 -0400 Subject: [PATCH 11/14] remove unnecessary conditional --- src/pages/home/report/ReportActionItem.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/home/report/ReportActionItem.js b/src/pages/home/report/ReportActionItem.js index 679d75df801a..1423ceab7773 100644 --- a/src/pages/home/report/ReportActionItem.js +++ b/src/pages/home/report/ReportActionItem.js @@ -123,7 +123,7 @@ function ReportActionItem(props) { // Hide the message if it is being moderated for a higher offense, or is hidden by a moderator // Removed messages should not be shown anyway and should not need this flow useEffect(() => { - if (!props.action.moderationDecisions || _.isEmpty(props.action.moderationDecisions)) { + if (_.isEmpty(props.action.moderationDecisions)) { return; } From e97ac5d2c1b665350e25540ade1ba525542a3164 Mon Sep 17 00:00:00 2001 From: Daniel Gale-Rosen Date: Thu, 25 May 2023 22:10:24 -0400 Subject: [PATCH 12/14] add proptype comment --- src/pages/home/report/ReportActionItemMessage.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/pages/home/report/ReportActionItemMessage.js b/src/pages/home/report/ReportActionItemMessage.js index 4d6c0b8dfb30..a764eafb84b7 100644 --- a/src/pages/home/report/ReportActionItemMessage.js +++ b/src/pages/home/report/ReportActionItemMessage.js @@ -15,6 +15,7 @@ const propTypes = { /** Additional styles to add after local styles. */ style: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.object), PropTypes.object]), + /** Whether or not the message is hidden by moderation */ isHidden: PropTypes.bool, /** localization props */ From 097ad8af24bf38c5b5dd17a648efe7add2595496 Mon Sep 17 00:00:00 2001 From: Daniel Gale-Rosen Date: Fri, 26 May 2023 16:26:34 -0400 Subject: [PATCH 13/14] address comments --- src/pages/home/report/ReportActionItem.js | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/pages/home/report/ReportActionItem.js b/src/pages/home/report/ReportActionItem.js index 1423ceab7773..d4a10fa8a985 100644 --- a/src/pages/home/report/ReportActionItem.js +++ b/src/pages/home/report/ReportActionItem.js @@ -123,17 +123,17 @@ function ReportActionItem(props) { // Hide the message if it is being moderated for a higher offense, or is hidden by a moderator // Removed messages should not be shown anyway and should not need this flow useEffect(() => { - if (_.isEmpty(props.action.moderationDecisions)) { + if (!props.action.actionName === CONST.REPORT.ACTIONS.TYPE.ADDCOMMENT || _.isEmpty(props.action.message[0].moderationDecisions)) { return; } // Right now we are only sending the latest moderationDecision to the frontend even though it is an array - const latestDecision = props.action.moderationDecisions[0]; + const latestDecision = props.action.message[0].moderationDecisions[0]; if (latestDecision.decision === CONST.MODERATION.MODERATOR_DECISION_PENDING_HIDE || latestDecision.decision === CONST.MODERATION.MODERATOR_DECISION_HIDDEN) { setIsHidden(true); } setModerationDecision(latestDecision.decision); - }, [props.action, moderationDecision]); + }, [props.action.message, props.action.actionName]); const toggleContextMenuFromActiveReportAction = useCallback(() => { setIsContextMenuActive(ReportActionContextMenu.isActiveReportAction(props.action.reportActionID)); @@ -245,8 +245,7 @@ function ReportActionItem(props) { ); } else { const message = _.last(lodashGet(props.action, 'message', [{}])); - const hasBeenFlagged = moderationDecision !== CONST.MODERATION.MODERATOR_DECISION_APPROVED && moderationDecision !== CONST.MODERATION.MODERATOR_DECISION_PENDING; - const isAttachment = _.has(props.action, 'isAttachment') ? props.action.isAttachment : ReportUtils.isReportMessageAttachment(message); + const hasBeenFlagged = !_.contains([CONST.MODERATION.MODERATOR_DECISION_APPROVED, CONST.MODERATION.MODERATOR_DECISION_PENDING], moderationDecision); const isAttachment = _.has(props.action, 'isAttachment') ? props.action.isAttachment : ReportUtils.isReportMessageAttachment(message); children = ( Date: Fri, 26 May 2023 17:01:51 -0400 Subject: [PATCH 14/14] prettier seriously? --- src/pages/home/report/ReportActionItem.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/pages/home/report/ReportActionItem.js b/src/pages/home/report/ReportActionItem.js index d4a10fa8a985..d40b0a4e2cc6 100644 --- a/src/pages/home/report/ReportActionItem.js +++ b/src/pages/home/report/ReportActionItem.js @@ -245,7 +245,8 @@ function ReportActionItem(props) { ); } else { const message = _.last(lodashGet(props.action, 'message', [{}])); - const hasBeenFlagged = !_.contains([CONST.MODERATION.MODERATOR_DECISION_APPROVED, CONST.MODERATION.MODERATOR_DECISION_PENDING], moderationDecision); const isAttachment = _.has(props.action, 'isAttachment') ? props.action.isAttachment : ReportUtils.isReportMessageAttachment(message); + const hasBeenFlagged = !_.contains([CONST.MODERATION.MODERATOR_DECISION_APPROVED, CONST.MODERATION.MODERATOR_DECISION_PENDING], moderationDecision); + const isAttachment = _.has(props.action, 'isAttachment') ? props.action.isAttachment : ReportUtils.isReportMessageAttachment(message); children = (