From cb999869528220bccb3d4eb85b81cc4c23101fa8 Mon Sep 17 00:00:00 2001 From: Taras Perun Date: Tue, 12 Sep 2023 11:50:51 +0200 Subject: [PATCH 01/19] create withRoute --- src/components/withRoute.js | 40 +++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) create mode 100644 src/components/withRoute.js diff --git a/src/components/withRoute.js b/src/components/withRoute.js new file mode 100644 index 000000000000..a50aa79f45c4 --- /dev/null +++ b/src/components/withRoute.js @@ -0,0 +1,40 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import {useRoute} from '@react-navigation/native'; +import getComponentDisplayName from '../libs/getComponentDisplayName'; +import refPropTypes from './refPropTypes'; + +const withRoutePropTypes = { + route: PropTypes.object.isRequired, +}; + +export default function withRoute(WrappedComponent) { + function WithRoute(props) { + const route = useRoute(); + return ( + + ); + } + + WithRoute.displayName = `withRoute(${getComponentDisplayName(WrappedComponent)})`; + WithRoute.propTypes = { + forwardedRef: refPropTypes, + }; + WithRoute.defaultProps = { + forwardedRef: () => {}, + }; + return React.forwardRef((props, ref) => ( + + )); +} + +export {withRoutePropTypes}; From 9ae049cbce074a0cd29c442719bb9a068a3a7f91 Mon Sep 17 00:00:00 2001 From: Taras Perun Date: Tue, 12 Sep 2023 11:53:24 +0200 Subject: [PATCH 02/19] highlight background color If needed --- src/pages/home/report/ReportActionItem.js | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/pages/home/report/ReportActionItem.js b/src/pages/home/report/ReportActionItem.js index 8425f78a3a10..dc78d8b777e1 100644 --- a/src/pages/home/report/ReportActionItem.js +++ b/src/pages/home/report/ReportActionItem.js @@ -1,6 +1,6 @@ import _ from 'underscore'; import lodashGet from 'lodash/get'; -import React, {useState, useRef, useEffect, memo, useCallback, useContext} from 'react'; +import React, {useState, useRef, useEffect, memo, useCallback, useContext, useMemo} from 'react'; import {InteractionManager, View} from 'react-native'; import PropTypes from 'prop-types'; import {withOnyx} from 'react-native-onyx'; @@ -67,6 +67,8 @@ import * as BankAccounts from '../../../libs/actions/BankAccounts'; import usePrevious from '../../../hooks/usePrevious'; import ReportScreenContext from '../ReportScreenContext'; import Permissions from '../../../libs/Permissions'; +import themeColors from '../../../styles/themes/default'; +import withRoute from '../../../components/withRoute'; const propTypes = { ...windowDimensionsPropTypes, @@ -135,6 +137,11 @@ function ReportActionItem(props) { const prevDraftMessage = usePrevious(props.draftMessage); const originalReportID = ReportUtils.getOriginalReportID(props.report.reportID, props.action); const originalReport = props.report.reportID === originalReportID ? props.report : ReportUtils.getReport(originalReportID); + const reportActionID = lodashGet(props.route, 'params.reportActionID'); + + const highlightedBackgroundColorIfNeeded = useMemo(() => { + return reportActionID === props.action.reportActionID ? {backgroundColor: themeColors.highlightBG} : {}; + }, [reportActionID]); useEffect( () => () => { @@ -557,7 +564,7 @@ function ReportActionItem(props) { > {(hovered) => ( - + {props.shouldDisplayNewMarker && } `${ONYXKEYS.COLLECTION.REPORT_ACTIONS_REACTIONS}${action.reportActionID}`, }, }), + withRoute, )( memo( ReportActionItem, From 8d34f8799b90c11c9cfd9b4d89c088c2c162c80c Mon Sep 17 00:00:00 2001 From: Taras Perun Date: Tue, 12 Sep 2023 14:05:27 +0200 Subject: [PATCH 03/19] lint --- src/pages/home/report/ReportActionItem.js | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/pages/home/report/ReportActionItem.js b/src/pages/home/report/ReportActionItem.js index dc78d8b777e1..7a04ed55801d 100644 --- a/src/pages/home/report/ReportActionItem.js +++ b/src/pages/home/report/ReportActionItem.js @@ -139,9 +139,7 @@ function ReportActionItem(props) { const originalReport = props.report.reportID === originalReportID ? props.report : ReportUtils.getReport(originalReportID); const reportActionID = lodashGet(props.route, 'params.reportActionID'); - const highlightedBackgroundColorIfNeeded = useMemo(() => { - return reportActionID === props.action.reportActionID ? {backgroundColor: themeColors.highlightBG} : {}; - }, [reportActionID]); + const highlightedBackgroundColorIfNeeded = useMemo(() => (reportActionID === props.action.reportActionID ? {backgroundColor: themeColors.highlightBG} : {}), [reportActionID]); useEffect( () => () => { From 58dbaf317cc5bf7154200d006ce73f62cfcbc405 Mon Sep 17 00:00:00 2001 From: Taras Perun Date: Tue, 12 Sep 2023 14:16:05 +0200 Subject: [PATCH 04/19] add dependency --- src/pages/home/report/ReportActionItem.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/pages/home/report/ReportActionItem.js b/src/pages/home/report/ReportActionItem.js index 7a04ed55801d..077568f26e6f 100644 --- a/src/pages/home/report/ReportActionItem.js +++ b/src/pages/home/report/ReportActionItem.js @@ -139,7 +139,10 @@ function ReportActionItem(props) { const originalReport = props.report.reportID === originalReportID ? props.report : ReportUtils.getReport(originalReportID); const reportActionID = lodashGet(props.route, 'params.reportActionID'); - const highlightedBackgroundColorIfNeeded = useMemo(() => (reportActionID === props.action.reportActionID ? {backgroundColor: themeColors.highlightBG} : {}), [reportActionID]); + const highlightedBackgroundColorIfNeeded = useMemo( + () => (reportActionID === props.action.reportActionID ? {backgroundColor: themeColors.highlightBG} : {}), + [reportActionID, props.action.reportActionID], + ); useEffect( () => () => { From 43a586c887c18d1ef45707e5b08564ab1f978fe8 Mon Sep 17 00:00:00 2001 From: Taras Perun Date: Tue, 19 Sep 2023 17:30:21 +0200 Subject: [PATCH 05/19] use hook instead of hoc --- src/components/withRoute.js | 40 ----------------------- src/pages/home/report/ReportActionItem.js | 6 ++-- 2 files changed, 3 insertions(+), 43 deletions(-) delete mode 100644 src/components/withRoute.js diff --git a/src/components/withRoute.js b/src/components/withRoute.js deleted file mode 100644 index a50aa79f45c4..000000000000 --- a/src/components/withRoute.js +++ /dev/null @@ -1,40 +0,0 @@ -import React from 'react'; -import PropTypes from 'prop-types'; -import {useRoute} from '@react-navigation/native'; -import getComponentDisplayName from '../libs/getComponentDisplayName'; -import refPropTypes from './refPropTypes'; - -const withRoutePropTypes = { - route: PropTypes.object.isRequired, -}; - -export default function withRoute(WrappedComponent) { - function WithRoute(props) { - const route = useRoute(); - return ( - - ); - } - - WithRoute.displayName = `withRoute(${getComponentDisplayName(WrappedComponent)})`; - WithRoute.propTypes = { - forwardedRef: refPropTypes, - }; - WithRoute.defaultProps = { - forwardedRef: () => {}, - }; - return React.forwardRef((props, ref) => ( - - )); -} - -export {withRoutePropTypes}; diff --git a/src/pages/home/report/ReportActionItem.js b/src/pages/home/report/ReportActionItem.js index 55ff1a4a79ff..9cd253a5502f 100644 --- a/src/pages/home/report/ReportActionItem.js +++ b/src/pages/home/report/ReportActionItem.js @@ -4,6 +4,7 @@ import React, {useState, useRef, useEffect, memo, useCallback, useContext, useMe import {InteractionManager, View} from 'react-native'; import PropTypes from 'prop-types'; import {withOnyx} from 'react-native-onyx'; +import {useRoute} from '@react-navigation/native'; import CONST from '../../../CONST'; import ONYXKEYS from '../../../ONYXKEYS'; import reportActionPropTypes from './reportActionPropTypes'; @@ -67,7 +68,6 @@ import usePrevious from '../../../hooks/usePrevious'; import ReportScreenContext from '../ReportScreenContext'; import Permissions from '../../../libs/Permissions'; import themeColors from '../../../styles/themes/default'; -import withRoute from '../../../components/withRoute'; import ReportActionItemBasicMessage from './ReportActionItemBasicMessage'; import RenderHTML from '../../../components/RenderHTML'; import ReportAttachmentsContext from './ReportAttachmentsContext'; @@ -129,6 +129,7 @@ const defaultProps = { }; function ReportActionItem(props) { + const route = useRoute(); const [isContextMenuActive, setIsContextMenuActive] = useState(ReportActionContextMenu.isActiveReportAction(props.action.reportActionID)); const [isHidden, setIsHidden] = useState(false); const [moderationDecision, setModerationDecision] = useState(CONST.MODERATION.MODERATOR_DECISION_APPROVED); @@ -140,7 +141,7 @@ function ReportActionItem(props) { const prevDraftMessage = usePrevious(props.draftMessage); const originalReportID = ReportUtils.getOriginalReportID(props.report.reportID, props.action); const originalReport = props.report.reportID === originalReportID ? props.report : ReportUtils.getReport(originalReportID); - const reportActionID = lodashGet(props.route, 'params.reportActionID'); + const reportActionID = lodashGet(route, 'params.reportActionID'); const highlightedBackgroundColorIfNeeded = useMemo( () => (reportActionID === props.action.reportActionID ? {backgroundColor: themeColors.highlightBG} : {}), @@ -695,7 +696,6 @@ export default compose( key: ({action}) => `${ONYXKEYS.COLLECTION.REPORT_ACTIONS_REACTIONS}${action.reportActionID}`, }, }), - withRoute, )( memo( ReportActionItem, From a080732ecfda883e4987973c8a5e6157e13a874b Mon Sep 17 00:00:00 2001 From: Taras Perun Date: Fri, 22 Sep 2023 17:34:41 +0200 Subject: [PATCH 06/19] use getBackgroundColorStyle --- 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 9cd253a5502f..d9d003660a39 100644 --- a/src/pages/home/report/ReportActionItem.js +++ b/src/pages/home/report/ReportActionItem.js @@ -144,7 +144,7 @@ function ReportActionItem(props) { const reportActionID = lodashGet(route, 'params.reportActionID'); const highlightedBackgroundColorIfNeeded = useMemo( - () => (reportActionID === props.action.reportActionID ? {backgroundColor: themeColors.highlightBG} : {}), + () => (reportActionID === props.action.reportActionID ? StyleUtils.getBackgroundColorStyle(themeColors.highlightBG) : {}), [reportActionID, props.action.reportActionID], ); From 836e394e17ae3c6f03d72fd317edfeff0a04d477 Mon Sep 17 00:00:00 2001 From: Taras Perun Date: Sat, 23 Sep 2023 11:14:38 +0200 Subject: [PATCH 07/19] highlighting money request --- src/pages/home/report/ReportActionItem.js | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/pages/home/report/ReportActionItem.js b/src/pages/home/report/ReportActionItem.js index 8ae9673575e2..77f8192e3f30 100644 --- a/src/pages/home/report/ReportActionItem.js +++ b/src/pages/home/report/ReportActionItem.js @@ -142,10 +142,11 @@ function ReportActionItem(props) { const originalReportID = ReportUtils.getOriginalReportID(props.report.reportID, props.action); const originalReport = props.report.reportID === originalReportID ? props.report : ReportUtils.getReport(originalReportID); const reportActionID = lodashGet(route, 'params.reportActionID'); + const isReportActionLinked = reportActionID === props.action.reportActionID; const highlightedBackgroundColorIfNeeded = useMemo( - () => (reportActionID === props.action.reportActionID ? StyleUtils.getBackgroundColorStyle(themeColors.highlightBG) : {}), - [reportActionID, props.action.reportActionID], + () => (isReportActionLinked ? StyleUtils.getBackgroundColorStyle(themeColors.highlightBG) : {}), + [reportActionID, props.action.reportActionID, isReportActionLinked], ); // When active action changes, we need to update the `isContextMenuActive` state @@ -656,7 +657,7 @@ function ReportActionItem(props) { /> )} - {renderReportActionItem(hovered, isWhisper, hasErrors)} + {renderReportActionItem(hovered || isReportActionLinked, isWhisper, hasErrors)} From 2fdb1cbc94e8c1d69c13d0b54993712839cdfb3e Mon Sep 17 00:00:00 2001 From: Taras Perun Date: Sat, 23 Sep 2023 11:17:22 +0200 Subject: [PATCH 08/19] change link when click active report in LHN --- src/libs/Navigation/Navigation.js | 5 +++ .../Navigation/getTopmostReportActionID.js | 42 +++++++++++++++++++ src/pages/home/sidebar/SidebarLinks.js | 2 +- 3 files changed, 48 insertions(+), 1 deletion(-) create mode 100644 src/libs/Navigation/getTopmostReportActionID.js diff --git a/src/libs/Navigation/Navigation.js b/src/libs/Navigation/Navigation.js index 1264ec777b28..edc6725f6211 100644 --- a/src/libs/Navigation/Navigation.js +++ b/src/libs/Navigation/Navigation.js @@ -10,6 +10,7 @@ import linkingConfig from './linkingConfig'; import navigationRef from './navigationRef'; import NAVIGATORS from '../../NAVIGATORS'; import originalGetTopmostReportId from './getTopmostReportId'; +import originalGetTopmostReportActionId from './getTopmostReportActionID'; import getStateFromPath from './getStateFromPath'; import SCREENS from '../../SCREENS'; import CONST from '../../CONST'; @@ -46,6 +47,9 @@ function canNavigate(methodName, params = {}) { // Re-exporting the getTopmostReportId here to fill in default value for state. The getTopmostReportId isn't defined in this file to avoid cyclic dependencies. const getTopmostReportId = (state = navigationRef.getState()) => originalGetTopmostReportId(state); +// Re-exporting the getTopmostReportActionID here to fill in default value for state. The getTopmostReportActionID isn't defined in this file to avoid cyclic dependencies. +const getTopmostReportActionId = (state = navigationRef.getState()) => originalGetTopmostReportActionId(state); + /** * Method for finding on which index in stack we are. * @param {Object} route @@ -268,6 +272,7 @@ export default { setIsNavigationReady, getTopmostReportId, getRouteNameFromStateEvent, + getTopmostReportActionId, }; export {navigationRef}; diff --git a/src/libs/Navigation/getTopmostReportActionID.js b/src/libs/Navigation/getTopmostReportActionID.js new file mode 100644 index 000000000000..a4480931cda0 --- /dev/null +++ b/src/libs/Navigation/getTopmostReportActionID.js @@ -0,0 +1,42 @@ +import lodashFindLast from 'lodash/findLast'; +import lodashGet from 'lodash/get'; + +// This function is in a separate file than Navigation.js to avoid cyclic dependency. + +/** + * Find the last visited report screen in the navigation state and get the linked reportActionID of it. + * + * @param {Object} state - The react-navigation state + * @returns {String | undefined} - It's possible that there is no report screen + */ +function getTopmostReportActionID(state) { + if (!state) { + return; + } + const topmostCentralPane = lodashFindLast(state.routes, (route) => route.name === 'CentralPaneNavigator'); + + if (!topmostCentralPane) { + return; + } + + const directReportActionIDParam = lodashGet(topmostCentralPane, 'params.params.reportActionID'); + + if (!topmostCentralPane.state && !directReportActionIDParam) { + return; + } + + if (directReportActionIDParam) { + return directReportActionIDParam; + } + + const topmostReport = lodashFindLast(topmostCentralPane.state.routes, (route) => route.name === 'Report'); + if (!topmostReport) { + return; + } + + const topmostReportActionID = lodashGet(topmostReport, 'params.reportActionID'); + + return topmostReportActionID; +} + +export default getTopmostReportActionID; diff --git a/src/pages/home/sidebar/SidebarLinks.js b/src/pages/home/sidebar/SidebarLinks.js index c38ac9e01ccb..6fe446601868 100644 --- a/src/pages/home/sidebar/SidebarLinks.js +++ b/src/pages/home/sidebar/SidebarLinks.js @@ -136,7 +136,7 @@ class SidebarLinks extends React.PureComponent { // since getTopmostReportId always returns on other devices if ( this.props.isCreateMenuOpen || - (!this.props.isSmallScreenWidth && this.props.isActiveReport(option.reportID)) || + (!this.props.isSmallScreenWidth && this.props.isActiveReport(option.reportID) && !Navigation.getTopmostReportActionId()) || (this.props.isSmallScreenWidth && Navigation.getTopmostReportId()) ) { return; From 2dea92ddff6d130a29df27429d1a759bf7e78ef7 Mon Sep 17 00:00:00 2001 From: Taras Perun Date: Sat, 23 Sep 2023 13:04:53 +0200 Subject: [PATCH 09/19] clean --- 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 77f8192e3f30..444c15745790 100644 --- a/src/pages/home/report/ReportActionItem.js +++ b/src/pages/home/report/ReportActionItem.js @@ -146,7 +146,7 @@ function ReportActionItem(props) { const highlightedBackgroundColorIfNeeded = useMemo( () => (isReportActionLinked ? StyleUtils.getBackgroundColorStyle(themeColors.highlightBG) : {}), - [reportActionID, props.action.reportActionID, isReportActionLinked], + [isReportActionLinked], ); // When active action changes, we need to update the `isContextMenuActive` state From 7b7e985f1d2282a9db9045f2d591b2a99c226082 Mon Sep 17 00:00:00 2001 From: Taras Perun Date: Sat, 23 Sep 2023 13:34:24 +0200 Subject: [PATCH 10/19] trying to remove weird 'iou' error --- src/pages/home/report/ReportActionItem.js | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/pages/home/report/ReportActionItem.js b/src/pages/home/report/ReportActionItem.js index 444c15745790..c3d52ff377a8 100644 --- a/src/pages/home/report/ReportActionItem.js +++ b/src/pages/home/report/ReportActionItem.js @@ -144,10 +144,7 @@ function ReportActionItem(props) { const reportActionID = lodashGet(route, 'params.reportActionID'); const isReportActionLinked = reportActionID === props.action.reportActionID; - const highlightedBackgroundColorIfNeeded = useMemo( - () => (isReportActionLinked ? StyleUtils.getBackgroundColorStyle(themeColors.highlightBG) : {}), - [isReportActionLinked], - ); + const highlightedBackgroundColorIfNeeded = useMemo(() => (isReportActionLinked ? StyleUtils.getBackgroundColorStyle(themeColors.highlightBG) : {}), [isReportActionLinked]); // When active action changes, we need to update the `isContextMenuActive` state const isActiveReportActionForMenu = ReportActionContextMenu.isActiveReportAction(props.action.reportActionID); From 29c077d4ac2a9e40b90da398c7870e658adf0c57 Mon Sep 17 00:00:00 2001 From: Taras Perun Date: Sat, 23 Sep 2023 13:45:40 +0200 Subject: [PATCH 11/19] trying to remove weird 'iou' error --- 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 c3d52ff377a8..e36615463645 100644 --- a/src/pages/home/report/ReportActionItem.js +++ b/src/pages/home/report/ReportActionItem.js @@ -654,7 +654,7 @@ function ReportActionItem(props) { /> )} - {renderReportActionItem(hovered || isReportActionLinked, isWhisper, hasErrors)} + {renderReportActionItem(hovered, isWhisper, hasErrors)} From 9e44fc3220447a88209176368d1ffd7175d0ada1 Mon Sep 17 00:00:00 2001 From: Taras Perun Date: Sat, 23 Sep 2023 13:55:31 +0200 Subject: [PATCH 12/19] trying to remove weird 'iou' error II --- src/pages/home/sidebar/SidebarLinks.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/home/sidebar/SidebarLinks.js b/src/pages/home/sidebar/SidebarLinks.js index 6fe446601868..c38ac9e01ccb 100644 --- a/src/pages/home/sidebar/SidebarLinks.js +++ b/src/pages/home/sidebar/SidebarLinks.js @@ -136,7 +136,7 @@ class SidebarLinks extends React.PureComponent { // since getTopmostReportId always returns on other devices if ( this.props.isCreateMenuOpen || - (!this.props.isSmallScreenWidth && this.props.isActiveReport(option.reportID) && !Navigation.getTopmostReportActionId()) || + (!this.props.isSmallScreenWidth && this.props.isActiveReport(option.reportID)) || (this.props.isSmallScreenWidth && Navigation.getTopmostReportId()) ) { return; From c9e5fa5126d83768ff72e860a9bc150a8c50d8d6 Mon Sep 17 00:00:00 2001 From: Taras Perun Date: Sat, 23 Sep 2023 14:08:52 +0200 Subject: [PATCH 13/19] restore to state before iou error --- src/libs/Navigation/Navigation.js | 5 --- .../Navigation/getTopmostReportActionID.js | 42 ------------------- 2 files changed, 47 deletions(-) delete mode 100644 src/libs/Navigation/getTopmostReportActionID.js diff --git a/src/libs/Navigation/Navigation.js b/src/libs/Navigation/Navigation.js index edc6725f6211..1264ec777b28 100644 --- a/src/libs/Navigation/Navigation.js +++ b/src/libs/Navigation/Navigation.js @@ -10,7 +10,6 @@ import linkingConfig from './linkingConfig'; import navigationRef from './navigationRef'; import NAVIGATORS from '../../NAVIGATORS'; import originalGetTopmostReportId from './getTopmostReportId'; -import originalGetTopmostReportActionId from './getTopmostReportActionID'; import getStateFromPath from './getStateFromPath'; import SCREENS from '../../SCREENS'; import CONST from '../../CONST'; @@ -47,9 +46,6 @@ function canNavigate(methodName, params = {}) { // Re-exporting the getTopmostReportId here to fill in default value for state. The getTopmostReportId isn't defined in this file to avoid cyclic dependencies. const getTopmostReportId = (state = navigationRef.getState()) => originalGetTopmostReportId(state); -// Re-exporting the getTopmostReportActionID here to fill in default value for state. The getTopmostReportActionID isn't defined in this file to avoid cyclic dependencies. -const getTopmostReportActionId = (state = navigationRef.getState()) => originalGetTopmostReportActionId(state); - /** * Method for finding on which index in stack we are. * @param {Object} route @@ -272,7 +268,6 @@ export default { setIsNavigationReady, getTopmostReportId, getRouteNameFromStateEvent, - getTopmostReportActionId, }; export {navigationRef}; diff --git a/src/libs/Navigation/getTopmostReportActionID.js b/src/libs/Navigation/getTopmostReportActionID.js deleted file mode 100644 index a4480931cda0..000000000000 --- a/src/libs/Navigation/getTopmostReportActionID.js +++ /dev/null @@ -1,42 +0,0 @@ -import lodashFindLast from 'lodash/findLast'; -import lodashGet from 'lodash/get'; - -// This function is in a separate file than Navigation.js to avoid cyclic dependency. - -/** - * Find the last visited report screen in the navigation state and get the linked reportActionID of it. - * - * @param {Object} state - The react-navigation state - * @returns {String | undefined} - It's possible that there is no report screen - */ -function getTopmostReportActionID(state) { - if (!state) { - return; - } - const topmostCentralPane = lodashFindLast(state.routes, (route) => route.name === 'CentralPaneNavigator'); - - if (!topmostCentralPane) { - return; - } - - const directReportActionIDParam = lodashGet(topmostCentralPane, 'params.params.reportActionID'); - - if (!topmostCentralPane.state && !directReportActionIDParam) { - return; - } - - if (directReportActionIDParam) { - return directReportActionIDParam; - } - - const topmostReport = lodashFindLast(topmostCentralPane.state.routes, (route) => route.name === 'Report'); - if (!topmostReport) { - return; - } - - const topmostReportActionID = lodashGet(topmostReport, 'params.reportActionID'); - - return topmostReportActionID; -} - -export default getTopmostReportActionID; From a98f4076182e309b6e750caf27dfa3fa127750db Mon Sep 17 00:00:00 2001 From: Taras Perun Date: Sat, 23 Sep 2023 14:15:39 +0200 Subject: [PATCH 14/19] test highlightedBackgroundColorIfNeeded --- 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 e36615463645..bd987251512e 100644 --- a/src/pages/home/report/ReportActionItem.js +++ b/src/pages/home/report/ReportActionItem.js @@ -144,7 +144,7 @@ function ReportActionItem(props) { const reportActionID = lodashGet(route, 'params.reportActionID'); const isReportActionLinked = reportActionID === props.action.reportActionID; - const highlightedBackgroundColorIfNeeded = useMemo(() => (isReportActionLinked ? StyleUtils.getBackgroundColorStyle(themeColors.highlightBG) : {}), [isReportActionLinked]); + const highlightedBackgroundColorIfNeeded = useMemo(() => (isReportActionLinked ? {backgroundColor: themeColors.highlightBG} : {}), [isReportActionLinked]); // When active action changes, we need to update the `isContextMenuActive` state const isActiveReportActionForMenu = ReportActionContextMenu.isActiveReportAction(props.action.reportActionID); From ea94621be4666725acbd81bef8c927fa18f80240 Mon Sep 17 00:00:00 2001 From: Taras Perun Date: Mon, 25 Sep 2023 10:11:44 +0200 Subject: [PATCH 15/19] return highlighting money request --- 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 bd987251512e..c3d52ff377a8 100644 --- a/src/pages/home/report/ReportActionItem.js +++ b/src/pages/home/report/ReportActionItem.js @@ -144,7 +144,7 @@ function ReportActionItem(props) { const reportActionID = lodashGet(route, 'params.reportActionID'); const isReportActionLinked = reportActionID === props.action.reportActionID; - const highlightedBackgroundColorIfNeeded = useMemo(() => (isReportActionLinked ? {backgroundColor: themeColors.highlightBG} : {}), [isReportActionLinked]); + const highlightedBackgroundColorIfNeeded = useMemo(() => (isReportActionLinked ? StyleUtils.getBackgroundColorStyle(themeColors.highlightBG) : {}), [isReportActionLinked]); // When active action changes, we need to update the `isContextMenuActive` state const isActiveReportActionForMenu = ReportActionContextMenu.isActiveReportAction(props.action.reportActionID); @@ -654,7 +654,7 @@ function ReportActionItem(props) { /> )} - {renderReportActionItem(hovered, isWhisper, hasErrors)} + {renderReportActionItem(hovered || isReportActionLinked, isWhisper, hasErrors)} From 0c164d1512b4efb3d319e64db1fbd6b634b02a55 Mon Sep 17 00:00:00 2001 From: Taras Perun Date: Mon, 25 Sep 2023 10:24:35 +0200 Subject: [PATCH 16/19] getTopmostReportActionID --- src/libs/Navigation/Navigation.js | 5 +++ .../Navigation/getTopmostReportActionID.js | 42 +++++++++++++++++++ src/pages/home/sidebar/SidebarLinks.js | 2 +- 3 files changed, 48 insertions(+), 1 deletion(-) create mode 100644 src/libs/Navigation/getTopmostReportActionID.js diff --git a/src/libs/Navigation/Navigation.js b/src/libs/Navigation/Navigation.js index dc4f35a59cba..de6162685079 100644 --- a/src/libs/Navigation/Navigation.js +++ b/src/libs/Navigation/Navigation.js @@ -10,6 +10,7 @@ import linkingConfig from './linkingConfig'; import navigationRef from './navigationRef'; import NAVIGATORS from '../../NAVIGATORS'; import originalGetTopmostReportId from './getTopmostReportId'; +import originalGetTopmostReportActionId from './getTopmostReportActionID'; import getStateFromPath from './getStateFromPath'; import SCREENS from '../../SCREENS'; import CONST from '../../CONST'; @@ -46,6 +47,9 @@ function canNavigate(methodName, params = {}) { // Re-exporting the getTopmostReportId here to fill in default value for state. The getTopmostReportId isn't defined in this file to avoid cyclic dependencies. const getTopmostReportId = (state = navigationRef.getState()) => originalGetTopmostReportId(state); +// Re-exporting the getTopmostReportActionID here to fill in default value for state. The getTopmostReportActionID isn't defined in this file to avoid cyclic dependencies. +const getTopmostReportActionId = (state = navigationRef.getState()) => originalGetTopmostReportActionId(state); + /** * Method for finding on which index in stack we are. * @param {Object} route @@ -268,6 +272,7 @@ export default { setIsNavigationReady, getTopmostReportId, getRouteNameFromStateEvent, + getTopmostReportActionId, }; export {navigationRef}; diff --git a/src/libs/Navigation/getTopmostReportActionID.js b/src/libs/Navigation/getTopmostReportActionID.js new file mode 100644 index 000000000000..7e61ae8e7698 --- /dev/null +++ b/src/libs/Navigation/getTopmostReportActionID.js @@ -0,0 +1,42 @@ +import lodashFindLast from 'lodash/findLast'; +import lodashGet from 'lodash/get'; + +// This function is in a separate file than Navigation.js to avoid cyclic dependency. + +/** + * Find the last visited report screen in the navigation state and get the linked reportActionID of it. + * + * @param {Object} state - The react-navigation state + * @returns {String | undefined} - It's possible that there is no report screen + */ +function getTopmostReportActionID(state) { + if (!state) { + return; + } + const topmostCentralPane = lodashFindLast(state.routes, (route) => route.name === 'CentralPaneNavigator'); + + if (!topmostCentralPane) { + return; + } + + const directReportActionIDParam = lodashGet(topmostCentralPane, 'params.params.reportActionID'); + + if (!topmostCentralPane.state && !directReportActionIDParam) { + return; + } + + if (directReportActionIDParam) { + return directReportActionIDParam; + } + + const topmostReport = lodashFindLast(topmostCentralPane.state.routes, (route) => route.name === 'Report'); + if (!topmostReport) { + return; + } + + const topmostReportActionID = lodashGet(topmostReport, 'params.reportActionID'); + + return topmostReportActionID; +} + +export default getTopmostReportActionID; \ No newline at end of file diff --git a/src/pages/home/sidebar/SidebarLinks.js b/src/pages/home/sidebar/SidebarLinks.js index 9ff9cc261af4..37be5967f997 100644 --- a/src/pages/home/sidebar/SidebarLinks.js +++ b/src/pages/home/sidebar/SidebarLinks.js @@ -136,7 +136,7 @@ class SidebarLinks extends React.PureComponent { // since getTopmostReportId always returns on other devices if ( this.props.isCreateMenuOpen || - (!this.props.isSmallScreenWidth && this.props.isActiveReport(option.reportID)) || + (!this.props.isSmallScreenWidth && this.props.isActiveReport(option.reportID) && !Navigation.getTopmostReportActionId()) || (this.props.isSmallScreenWidth && Navigation.getTopmostReportId()) ) { return; From 97d6dd449bfbd2725433811cf3f52f48e5c990ad Mon Sep 17 00:00:00 2001 From: Taras Perun Date: Mon, 25 Sep 2023 10:34:04 +0200 Subject: [PATCH 17/19] lint --- src/libs/Navigation/getTopmostReportActionID.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libs/Navigation/getTopmostReportActionID.js b/src/libs/Navigation/getTopmostReportActionID.js index 7e61ae8e7698..a4480931cda0 100644 --- a/src/libs/Navigation/getTopmostReportActionID.js +++ b/src/libs/Navigation/getTopmostReportActionID.js @@ -39,4 +39,4 @@ function getTopmostReportActionID(state) { return topmostReportActionID; } -export default getTopmostReportActionID; \ No newline at end of file +export default getTopmostReportActionID; From 91384f53b84ececde644b56aa9d52f357e1141e7 Mon Sep 17 00:00:00 2001 From: Taras Perun Date: Fri, 29 Sep 2023 12:11:52 +0200 Subject: [PATCH 18/19] move isReportActionLinked to props --- src/pages/home/report/ReportActionItem.js | 8 +++----- src/pages/home/report/ReportActionsList.js | 7 ++++++- src/pages/home/report/ReportActionsListItemRenderer.js | 6 ++++++ 3 files changed, 15 insertions(+), 6 deletions(-) diff --git a/src/pages/home/report/ReportActionItem.js b/src/pages/home/report/ReportActionItem.js index 028af06d1349..b21fa501990a 100644 --- a/src/pages/home/report/ReportActionItem.js +++ b/src/pages/home/report/ReportActionItem.js @@ -4,7 +4,6 @@ import React, {useState, useRef, useEffect, memo, useCallback, useContext, useMe import {InteractionManager, View} from 'react-native'; import PropTypes from 'prop-types'; import {withOnyx} from 'react-native-onyx'; -import {useRoute} from '@react-navigation/native'; import CONST from '../../../CONST'; import ONYXKEYS from '../../../ONYXKEYS'; import reportActionPropTypes from './reportActionPropTypes'; @@ -129,7 +128,6 @@ const defaultProps = { }; function ReportActionItem(props) { - const route = useRoute(); const [isContextMenuActive, setIsContextMenuActive] = useState(ReportActionContextMenu.isActiveReportAction(props.action.reportActionID)); const [isHidden, setIsHidden] = useState(false); const [moderationDecision, setModerationDecision] = useState(CONST.MODERATION.MODERATOR_DECISION_APPROVED); @@ -141,8 +139,7 @@ function ReportActionItem(props) { const prevDraftMessage = usePrevious(props.draftMessage); const originalReportID = ReportUtils.getOriginalReportID(props.report.reportID, props.action); const originalReport = props.report.reportID === originalReportID ? props.report : ReportUtils.getReport(originalReportID); - const reportActionID = lodashGet(route, 'params.reportActionID'); - const isReportActionLinked = reportActionID === props.action.reportActionID; + const isReportActionLinked = props.linkedReportActionID === props.action.reportActionID; const highlightedBackgroundColorIfNeeded = useMemo(() => (isReportActionLinked ? StyleUtils.getBackgroundColorStyle(themeColors.highlightBG) : {}), [isReportActionLinked]); @@ -723,6 +720,7 @@ export default compose( prevProps.report.managerID === nextProps.report.managerID && prevProps.report.managerEmail === nextProps.report.managerEmail && prevProps.shouldHideThreadDividerLine === nextProps.shouldHideThreadDividerLine && - lodashGet(prevProps.report, 'total', 0) === lodashGet(nextProps.report, 'total', 0), + lodashGet(prevProps.report, 'total', 0) === lodashGet(nextProps.report, 'total', 0) && + prevProps.linkedReportActionID === nextProps.linkedReportActionID, ), ); diff --git a/src/pages/home/report/ReportActionsList.js b/src/pages/home/report/ReportActionsList.js index 0163a7ff2b4f..e391646251f2 100644 --- a/src/pages/home/report/ReportActionsList.js +++ b/src/pages/home/report/ReportActionsList.js @@ -2,6 +2,8 @@ import PropTypes from 'prop-types'; import React, {useCallback, useEffect, useMemo, useRef, useState} from 'react'; import Animated, {useAnimatedStyle, useSharedValue, withTiming} from 'react-native-reanimated'; import _ from 'underscore'; +import { useRoute } from '@react-navigation/native'; +import lodashGet from 'lodash/get'; import CONST from '../../../CONST'; import InvertedFlatList from '../../../components/InvertedFlatList'; import {withPersonalDetails} from '../../../components/OnyxProvider'; @@ -117,6 +119,7 @@ function ReportActionsList({ const reportScrollManager = useReportScrollManager(); const {translate} = useLocalize(); const {isOffline} = useNetwork(); + const route = useRoute(); const opacity = useSharedValue(0); const userActiveSince = useRef(null); const [currentUnreadMarker, setCurrentUnreadMarker] = useState(null); @@ -124,6 +127,7 @@ function ReportActionsList({ const readActionSkipped = useRef(false); const reportActionSize = useRef(sortedReportActions.length); const firstRenderRef = useRef(true); + const linkedReportActionID = lodashGet(route, 'params.reportActionID', ''); // This state is used to force a re-render when the user manually marks a message as unread // by using a timestamp you can force re-renders without having to worry about if another message was marked as unread before @@ -303,6 +307,7 @@ function ReportActionsList({ reportAction={reportAction} index={index} report={report} + linkedReportActionID={linkedReportActionID} hasOutstandingIOU={hasOutstandingIOU} sortedReportActions={sortedReportActions} mostRecentIOUReportActionID={mostRecentIOUReportActionID} @@ -311,7 +316,7 @@ function ReportActionsList({ /> ); }, - [report, hasOutstandingIOU, sortedReportActions, mostRecentIOUReportActionID, messageManuallyMarkedUnread, shouldHideThreadDividerLine, currentUnreadMarker], + [report, linkedReportActionID, hasOutstandingIOU, sortedReportActions, mostRecentIOUReportActionID, messageManuallyMarkedUnread, shouldHideThreadDividerLine, currentUnreadMarker], ); // Native mobile does not render updates flatlist the changes even though component did update called. diff --git a/src/pages/home/report/ReportActionsListItemRenderer.js b/src/pages/home/report/ReportActionsListItemRenderer.js index f70714076ad2..e297641cc885 100644 --- a/src/pages/home/report/ReportActionsListItemRenderer.js +++ b/src/pages/home/report/ReportActionsListItemRenderer.js @@ -33,11 +33,15 @@ const propTypes = { /** Should we display the new marker on top of the comment? */ shouldDisplayNewMarker: PropTypes.bool.isRequired, + + /** Linked report action ID */ + linkedReportActionID: PropTypes.string, }; const defaultProps = { mostRecentIOUReportActionID: '', hasOutstandingIOU: false, + linkedReportActionID: '', }; function ReportActionsListItemRenderer({ @@ -49,6 +53,7 @@ function ReportActionsListItemRenderer({ mostRecentIOUReportActionID, shouldHideThreadDividerLine, shouldDisplayNewMarker, + linkedReportActionID, }) { const shouldDisplayParentAction = reportAction.actionName === CONST.REPORT.ACTIONS.TYPE.CREATED && @@ -67,6 +72,7 @@ function ReportActionsListItemRenderer({ shouldHideThreadDividerLine={shouldHideThreadDividerLine} report={report} action={reportAction} + linkedReportActionID={linkedReportActionID} displayAsGroup={ReportActionsUtils.isConsecutiveActionMadeByPreviousActor(sortedReportActions, index)} shouldDisplayNewMarker={shouldDisplayNewMarker} shouldShowSubscriptAvatar={ From 534ffba214058841b628835d030f23acbeaebd18 Mon Sep 17 00:00:00 2001 From: Taras Perun Date: Fri, 29 Sep 2023 12:12:22 +0200 Subject: [PATCH 19/19] spacing --- src/pages/home/report/ReportActionsList.js | 2 +- src/pages/home/report/ReportActionsListItemRenderer.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/pages/home/report/ReportActionsList.js b/src/pages/home/report/ReportActionsList.js index e391646251f2..438b6e9b68d5 100644 --- a/src/pages/home/report/ReportActionsList.js +++ b/src/pages/home/report/ReportActionsList.js @@ -2,7 +2,7 @@ import PropTypes from 'prop-types'; import React, {useCallback, useEffect, useMemo, useRef, useState} from 'react'; import Animated, {useAnimatedStyle, useSharedValue, withTiming} from 'react-native-reanimated'; import _ from 'underscore'; -import { useRoute } from '@react-navigation/native'; +import {useRoute} from '@react-navigation/native'; import lodashGet from 'lodash/get'; import CONST from '../../../CONST'; import InvertedFlatList from '../../../components/InvertedFlatList'; diff --git a/src/pages/home/report/ReportActionsListItemRenderer.js b/src/pages/home/report/ReportActionsListItemRenderer.js index e297641cc885..40b9ee9142b7 100644 --- a/src/pages/home/report/ReportActionsListItemRenderer.js +++ b/src/pages/home/report/ReportActionsListItemRenderer.js @@ -33,7 +33,7 @@ const propTypes = { /** Should we display the new marker on top of the comment? */ shouldDisplayNewMarker: PropTypes.bool.isRequired, - + /** Linked report action ID */ linkedReportActionID: PropTypes.string, };