Skip to content

Commit

Permalink
Merge pull request #27227 from margelo/feat/##23230-highlight-linked-…
Browse files Browse the repository at this point in the history
…comment

Highlight linked comment
  • Loading branch information
Gonals authored Oct 2, 2023
2 parents 9c15943 + 534ffba commit f17a6ec
Show file tree
Hide file tree
Showing 6 changed files with 75 additions and 7 deletions.
5 changes: 5 additions & 0 deletions src/libs/Navigation/Navigation.js
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -268,6 +272,7 @@ export default {
setIsNavigationReady,
getTopmostReportId,
getRouteNameFromStateEvent,
getTopmostReportActionId,
};

export {navigationRef};
42 changes: 42 additions & 0 deletions src/libs/Navigation/getTopmostReportActionID.js
Original file line number Diff line number Diff line change
@@ -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;
15 changes: 10 additions & 5 deletions src/pages/home/report/ReportActionItem.js
Original file line number Diff line number Diff line change
@@ -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';
Expand Down Expand Up @@ -61,12 +61,13 @@ import * as Session from '../../../libs/actions/Session';
import MoneyRequestView from '../../../components/ReportActionItem/MoneyRequestView';
import {hideContextMenu} from './ContextMenu/ReportActionContextMenu';
import * as PersonalDetailsUtils from '../../../libs/PersonalDetailsUtils';
import ReportActionItemBasicMessage from './ReportActionItemBasicMessage';
import * as store from '../../../libs/actions/ReimbursementAccount/store';
import * as BankAccounts from '../../../libs/actions/BankAccounts';
import {ReactionListContext} from '../ReportScreenContext';
import usePrevious from '../../../hooks/usePrevious';
import Permissions from '../../../libs/Permissions';
import themeColors from '../../../styles/themes/default';
import ReportActionItemBasicMessage from './ReportActionItemBasicMessage';
import RenderHTML from '../../../components/RenderHTML';
import ReportAttachmentsContext from './ReportAttachmentsContext';

Expand Down Expand Up @@ -138,6 +139,9 @@ 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 isReportActionLinked = props.linkedReportActionID === props.action.reportActionID;

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);
Expand Down Expand Up @@ -594,7 +598,7 @@ function ReportActionItem(props) {
disabled={Boolean(props.draftMessage)}
>
{(hovered) => (
<View>
<View style={highlightedBackgroundColorIfNeeded}>
{props.shouldDisplayNewMarker && <UnreadActionIndicator reportActionID={props.action.reportActionID} />}
<MiniReportActionContextMenu
reportID={props.report.reportID}
Expand Down Expand Up @@ -638,7 +642,7 @@ function ReportActionItem(props) {
/>
</View>
)}
{renderReportActionItem(hovered, isWhisper, hasErrors)}
{renderReportActionItem(hovered || isReportActionLinked, isWhisper, hasErrors)}
</OfflineWithFeedback>
</View>
</View>
Expand Down Expand Up @@ -711,6 +715,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,
),
);
7 changes: 6 additions & 1 deletion src/pages/home/report/ReportActionsList.js
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand Down Expand Up @@ -117,13 +119,15 @@ 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);
const scrollingVerticalOffset = useRef(0);
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
Expand Down Expand Up @@ -303,6 +307,7 @@ function ReportActionsList({
reportAction={reportAction}
index={index}
report={report}
linkedReportActionID={linkedReportActionID}
hasOutstandingIOU={hasOutstandingIOU}
sortedReportActions={sortedReportActions}
mostRecentIOUReportActionID={mostRecentIOUReportActionID}
Expand All @@ -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.
Expand Down
6 changes: 6 additions & 0 deletions src/pages/home/report/ReportActionsListItemRenderer.js
Original file line number Diff line number Diff line change
Expand Up @@ -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({
Expand All @@ -49,6 +53,7 @@ function ReportActionsListItemRenderer({
mostRecentIOUReportActionID,
shouldHideThreadDividerLine,
shouldDisplayNewMarker,
linkedReportActionID,
}) {
const shouldDisplayParentAction =
reportAction.actionName === CONST.REPORT.ACTIONS.TYPE.CREATED &&
Expand All @@ -67,6 +72,7 @@ function ReportActionsListItemRenderer({
shouldHideThreadDividerLine={shouldHideThreadDividerLine}
report={report}
action={reportAction}
linkedReportActionID={linkedReportActionID}
displayAsGroup={ReportActionsUtils.isConsecutiveActionMadeByPreviousActor(sortedReportActions, index)}
shouldDisplayNewMarker={shouldDisplayNewMarker}
shouldShowSubscriptAvatar={
Expand Down
7 changes: 6 additions & 1 deletion src/pages/home/sidebar/SidebarLinks.js
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,12 @@ class SidebarLinks extends React.PureComponent {
// or when clicking the active LHN row on large screens
// or when continuously clicking different LHNs, only apply to small screen
// since getTopmostReportId always returns on other devices
if (this.props.isCreateMenuOpen || option.reportID === Navigation.getTopmostReportId() || (this.props.isSmallScreenWidth && this.props.isActiveReport(option.reportID))) {
const reportActionID = Navigation.getTopmostReportActionId();
if (
this.props.isCreateMenuOpen ||
(option.reportID === Navigation.getTopmostReportId() && !reportActionID) ||
(this.props.isSmallScreenWidth && this.props.isActiveReport(option.reportID) && !reportActionID)
) {
return;
}
Navigation.navigate(ROUTES.REPORT_WITH_ID.getRoute(option.reportID));
Expand Down

0 comments on commit f17a6ec

Please sign in to comment.