diff --git a/src/components/Composer/index.tsx b/src/components/Composer/index.tsx index 5d01b05bb51f..69cc6b208652 100755 --- a/src/components/Composer/index.tsx +++ b/src/components/Composer/index.tsx @@ -388,13 +388,20 @@ function Composer( disabled={isDisabled} onKeyPress={handleKeyPress} onFocus={(e) => { - ReportActionComposeFocusManager.onComposerFocus(() => { - if (!textInput.current) { - return; - } - - textInput.current.focus(); - }); + if (isReportActionCompose) { + ReportActionComposeFocusManager.onComposerFocus(null); + } else { + // While a user edits a comment, if they open the LHN menu, we want to ensure that + // the focus returns to the message edit composer after they click on a menu item (e.g. mark as read). + // To achieve this, we re-assign the focus callback here. + ReportActionComposeFocusManager.onComposerFocus(() => { + if (!textInput.current) { + return; + } + + textInput.current.focus(); + }); + } props.onFocus?.(e); }} diff --git a/src/libs/ReportActionComposeFocusManager.ts b/src/libs/ReportActionComposeFocusManager.ts index 123d97987e14..11c1fd04329f 100644 --- a/src/libs/ReportActionComposeFocusManager.ts +++ b/src/libs/ReportActionComposeFocusManager.ts @@ -3,7 +3,7 @@ import type {TextInput} from 'react-native'; import ROUTES from '@src/ROUTES'; import Navigation from './Navigation/Navigation'; -type FocusCallback = () => void; +type FocusCallback = (shouldFocusForNonBlurInputOnTapOutside?: boolean) => void; const composerRef = React.createRef(); const editComposerRef = React.createRef(); @@ -18,7 +18,7 @@ let mainComposerFocusCallback: FocusCallback | null = null; * * @param callback callback to register */ -function onComposerFocus(callback: FocusCallback, isMainComposer = false) { +function onComposerFocus(callback: FocusCallback | null, isMainComposer = false) { if (isMainComposer) { mainComposerFocusCallback = callback; } else { @@ -29,7 +29,7 @@ function onComposerFocus(callback: FocusCallback, isMainComposer = false) { /** * Request focus on the ReportActionComposer */ -function focus() { +function focus(shouldFocusForNonBlurInputOnTapOutside?: boolean) { /** Do not trigger the refocusing when the active route is not the report route, */ if (!Navigation.isActiveRoute(ROUTES.REPORT_WITH_ID.getRoute(Navigation.getTopmostReportId() ?? ''))) { return; @@ -40,7 +40,7 @@ function focus() { return; } - mainComposerFocusCallback(); + mainComposerFocusCallback(shouldFocusForNonBlurInputOnTapOutside); return; } diff --git a/src/pages/home/report/ContextMenu/ContextMenuActions.tsx b/src/pages/home/report/ContextMenu/ContextMenuActions.tsx index c8e0b64cc434..4aba9e43b1c0 100644 --- a/src/pages/home/report/ContextMenu/ContextMenuActions.tsx +++ b/src/pages/home/report/ContextMenu/ContextMenuActions.tsx @@ -1,6 +1,7 @@ import ExpensiMark from 'expensify-common/lib/ExpensiMark'; import type {MutableRefObject} from 'react'; import React from 'react'; +import {InteractionManager} from 'react-native'; // eslint-disable-next-line no-restricted-imports import type {GestureResponderEvent, Text, View} from 'react-native'; import type {OnyxEntry} from 'react-native-onyx'; @@ -200,7 +201,11 @@ const ContextMenuActions: ContextMenuAction[] = [ onPress: (closePopover, {reportAction, reportID}) => { if (closePopover) { hideContextMenu(false, () => { - ReportActionComposeFocusManager.focus(); + InteractionManager.runAfterInteractions(() => { + // Normally the focus callback of the main composer doesn't focus when willBlurTextInputOnTapOutside + // is false, so we need to pass true here to override this condition. + ReportActionComposeFocusManager.focus(true); + }); Report.navigateToAndOpenChildReport(reportAction?.childReportID ?? '0', reportAction, reportID); }); return; diff --git a/src/pages/home/report/ReportActionCompose/ComposerWithSuggestions/ComposerWithSuggestions.tsx b/src/pages/home/report/ReportActionCompose/ComposerWithSuggestions/ComposerWithSuggestions.tsx index bfcef66e7c54..f8147dfda81d 100644 --- a/src/pages/home/report/ReportActionCompose/ComposerWithSuggestions/ComposerWithSuggestions.tsx +++ b/src/pages/home/report/ReportActionCompose/ComposerWithSuggestions/ComposerWithSuggestions.tsx @@ -591,8 +591,8 @@ function ComposerWithSuggestions( const setUpComposeFocusManager = useCallback(() => { // This callback is used in the contextMenuActions to manage giving focus back to the compose input. - ReportActionComposeFocusManager.onComposerFocus(() => { - if (!willBlurTextInputOnTapOutside || !isFocused) { + ReportActionComposeFocusManager.onComposerFocus((shouldFocusForNonBlurInputOnTapOutside = false) => { + if ((!willBlurTextInputOnTapOutside && !shouldFocusForNonBlurInputOnTapOutside) || !isFocused) { return; }