From 994fd6f7cf778509afb35212bdfd60be55b89e72 Mon Sep 17 00:00:00 2001 From: tienifr Date: Tue, 8 Aug 2023 18:59:57 +0700 Subject: [PATCH 01/13] fix: 23898 --- src/components/Composer/index.js | 15 +++++++++++ src/libs/ReportActionComposeFocusManager.js | 28 +++++++++++++++++--- src/pages/home/report/ReportActionCompose.js | 4 +-- 3 files changed, 41 insertions(+), 6 deletions(-) diff --git a/src/components/Composer/index.js b/src/components/Composer/index.js index 4b4601247008..442e14dd49c1 100755 --- a/src/components/Composer/index.js +++ b/src/components/Composer/index.js @@ -17,6 +17,8 @@ import Text from '../Text'; import isEnterWhileComposition from '../../libs/KeyboardShortcut/isEnterWhileComposition'; import CONST from '../../CONST'; import withNavigation from '../withNavigation'; +import ReportActionComposeFocusManager from '../../libs/ReportActionComposeFocusManager'; +import willBlurTextInputOnTapOutside from '../../libs/willBlurTextInputOnTapOutside'; const propTypes = { /** Maximum number of lines in the text input */ @@ -140,6 +142,7 @@ class Composer extends React.Component { this.textRef = React.createRef(null); this.unsubscribeBlur = () => null; this.unsubscribeFocus = () => null; + this.willBlurTextInputOnTapOutside = willBlurTextInputOnTapOutside(); } componentDidMount() { @@ -458,6 +461,18 @@ class Composer extends React.Component { numberOfLines={this.state.numberOfLines} disabled={this.props.isDisabled} onKeyPress={this.handleKeyPress} + onFocus={(e) => { + ReportActionComposeFocusManager.onComposerFocus(() => { + if (!this.willBlurTextInputOnTapOutside) { + return; + } + + this.textInput.focus(); + }); + if (this.props.onFocus) { + this.props.onFocus(e); + } + }} /> {this.props.shouldCalculateCaretPosition && renderElementForCaretPosition} diff --git a/src/libs/ReportActionComposeFocusManager.js b/src/libs/ReportActionComposeFocusManager.js index 2acbfadf98a8..9d8831427c2b 100644 --- a/src/libs/ReportActionComposeFocusManager.js +++ b/src/libs/ReportActionComposeFocusManager.js @@ -3,6 +3,7 @@ import React from 'react'; const composerRef = React.createRef(); let focusCallback = null; +let mainComposerFocusCallback = null; /** * Register a callback to be called when focus is requested. @@ -10,8 +11,13 @@ let focusCallback = null; * * @param {Function} callback callback to register */ -function onComposerFocus(callback) { - focusCallback = callback; +function onComposerFocus(callback, isMainComposer = false) { + if (isMainComposer) { + console.log('registering mainComposerFocusCallback') + mainComposerFocusCallback = callback; + } else { + focusCallback = callback; + } } /** @@ -19,10 +25,20 @@ function onComposerFocus(callback) { * */ function focus() { + console.log('calling focussss') if (!_.isFunction(focusCallback)) { + if (!_.isFunction(mainComposerFocusCallback)) { + console.log('mainComposerFocusCallbackkkk', mainComposerFocusCallback) + return; + } + + console.log('mainComposerFocusCallback'); + mainComposerFocusCallback(); return; } + console.log('calling focusCallback') + focusCallback(); } @@ -30,8 +46,12 @@ function focus() { * Clear the registered focus callback * */ -function clear() { - focusCallback = null; +function clear(isMainComposer = false) { + if (isMainComposer) { + mainComposerFocusCallback = null; + } else { + focusCallback = null; + } } /** diff --git a/src/pages/home/report/ReportActionCompose.js b/src/pages/home/report/ReportActionCompose.js index 48173754c3be..95b83a02ec5f 100644 --- a/src/pages/home/report/ReportActionCompose.js +++ b/src/pages/home/report/ReportActionCompose.js @@ -291,7 +291,7 @@ class ReportActionCompose extends React.Component { } componentWillUnmount() { - ReportActionComposeFocusManager.clear(); + ReportActionComposeFocusManager.clear(true); KeyDownListener.removeKeyDownPressListner(this.focusComposerOnKeyPress); this.unsubscribeNavigationBlur(); @@ -320,7 +320,7 @@ class ReportActionCompose extends React.Component { } this.focus(false); - }); + }, true); } getDefaultSuggestionsValues() { From 9480a6ceb74f3e2facf081b6bb68a257c0803e22 Mon Sep 17 00:00:00 2001 From: tienifr Date: Sat, 12 Aug 2023 18:35:09 +0700 Subject: [PATCH 02/13] add comment and remove logs --- src/components/Composer/index.js | 12 ++++++------ src/libs/ReportActionComposeFocusManager.js | 9 +++------ 2 files changed, 9 insertions(+), 12 deletions(-) diff --git a/src/components/Composer/index.js b/src/components/Composer/index.js index 442e14dd49c1..31a0245a9c87 100755 --- a/src/components/Composer/index.js +++ b/src/components/Composer/index.js @@ -462,13 +462,13 @@ class Composer extends React.Component { disabled={this.props.isDisabled} onKeyPress={this.handleKeyPress} onFocus={(e) => { - ReportActionComposeFocusManager.onComposerFocus(() => { - if (!this.willBlurTextInputOnTapOutside) { - return; - } - + ReportActionComposeFocusManager.onComposerFocus(() => { + if (!this.willBlurTextInputOnTapOutside) { + return; + } + this.textInput.focus(); - }); + }); if (this.props.onFocus) { this.props.onFocus(e); } diff --git a/src/libs/ReportActionComposeFocusManager.js b/src/libs/ReportActionComposeFocusManager.js index 9d8831427c2b..e90435652187 100644 --- a/src/libs/ReportActionComposeFocusManager.js +++ b/src/libs/ReportActionComposeFocusManager.js @@ -2,6 +2,7 @@ import _ from 'underscore'; import React from 'react'; const composerRef = React.createRef(); +// There are two types of composer: general composer (edit composer) and main composer let focusCallback = null; let mainComposerFocusCallback = null; @@ -10,10 +11,10 @@ let mainComposerFocusCallback = null; * Typical uses of this would be call the focus on the ReportActionComposer. * * @param {Function} callback callback to register + * @param {Boolean} isMainComposer */ function onComposerFocus(callback, isMainComposer = false) { if (isMainComposer) { - console.log('registering mainComposerFocusCallback') mainComposerFocusCallback = callback; } else { focusCallback = callback; @@ -25,26 +26,22 @@ function onComposerFocus(callback, isMainComposer = false) { * */ function focus() { - console.log('calling focussss') if (!_.isFunction(focusCallback)) { if (!_.isFunction(mainComposerFocusCallback)) { - console.log('mainComposerFocusCallbackkkk', mainComposerFocusCallback) return; } - console.log('mainComposerFocusCallback'); mainComposerFocusCallback(); return; } - console.log('calling focusCallback') - focusCallback(); } /** * Clear the registered focus callback * + * @param {Boolean} isMainComposer */ function clear(isMainComposer = false) { if (isMainComposer) { From 39b39025abe30174e4d120f2b58635c4d1e25b67 Mon Sep 17 00:00:00 2001 From: tienifr Date: Sat, 12 Aug 2023 23:13:13 +0700 Subject: [PATCH 03/13] add null check --- src/components/Composer/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/Composer/index.js b/src/components/Composer/index.js index 31a0245a9c87..5de8c4db0005 100755 --- a/src/components/Composer/index.js +++ b/src/components/Composer/index.js @@ -463,7 +463,7 @@ class Composer extends React.Component { onKeyPress={this.handleKeyPress} onFocus={(e) => { ReportActionComposeFocusManager.onComposerFocus(() => { - if (!this.willBlurTextInputOnTapOutside) { + if (!this.willBlurTextInputOnTapOutside || !this.textInput) { return; } From d3ec5e41ba662a3df289cc814a43b9e901502302 Mon Sep 17 00:00:00 2001 From: tienifr Date: Sun, 13 Aug 2023 00:56:15 +0700 Subject: [PATCH 04/13] clear callback when exit draft mode --- src/pages/home/report/ReportActionItemMessageEdit.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/pages/home/report/ReportActionItemMessageEdit.js b/src/pages/home/report/ReportActionItemMessageEdit.js index cb03d12b4caf..9a4b800d1213 100644 --- a/src/pages/home/report/ReportActionItemMessageEdit.js +++ b/src/pages/home/report/ReportActionItemMessageEdit.js @@ -204,6 +204,7 @@ function ReportActionItemMessageEdit(props) { debouncedSaveDraft.cancel(); Report.saveReportActionDraft(props.reportID, props.action.reportActionID, ''); ComposerActions.setShouldShowComposeInput(true); + ReportActionComposeFocusManager.clear(); ReportActionComposeFocusManager.focus(); // Scroll to the last comment after editing to make sure the whole comment is clearly visible in the report. From 76c3710e69fd2a3a8ec0fde727ef3ee8ba7b344f Mon Sep 17 00:00:00 2001 From: tienifr Date: Fri, 18 Aug 2023 17:28:29 +0700 Subject: [PATCH 05/13] clear callback on unmount --- src/components/Composer/index.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/components/Composer/index.js b/src/components/Composer/index.js index 76b77844fa58..0ff451116a98 100755 --- a/src/components/Composer/index.js +++ b/src/components/Composer/index.js @@ -356,6 +356,11 @@ function Composer({ updateNumberOfLines(); }, [updateNumberOfLines]); + useEffect(() => () => { + ReportActionComposeFocusManager.clear(); + ReportActionComposeFocusManager.focus(); + }, []); + useEffect(() => { // we need to handle listeners on navigation focus/blur as Composer is not unmounting // when navigating away to different report From 3a64c6ecc6ca866747c0e4ab66246788982d6729 Mon Sep 17 00:00:00 2001 From: tienifr Date: Sun, 20 Aug 2023 10:44:20 +0700 Subject: [PATCH 06/13] move to existing cleanup func --- src/components/Composer/index.js | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/src/components/Composer/index.js b/src/components/Composer/index.js index 976a59c2908e..63c8287b7a4a 100755 --- a/src/components/Composer/index.js +++ b/src/components/Composer/index.js @@ -18,8 +18,8 @@ import Text from '../Text'; import isEnterWhileComposition from '../../libs/KeyboardShortcut/isEnterWhileComposition'; import CONST from '../../CONST'; import withNavigation from '../withNavigation'; -import ReportActionComposeFocusManager from "../../libs/ReportActionComposeFocusManager"; -import willBlurTextInputOnTapOutside from "../../libs/willBlurTextInputOnTapOutside"; +import ReportActionComposeFocusManager from '../../libs/ReportActionComposeFocusManager'; +import willBlurTextInputOnTapOutside from '../../libs/willBlurTextInputOnTapOutside'; const propTypes = { /** Maximum number of lines in the text input */ @@ -161,7 +161,7 @@ function Composer({ }) { const textRef = useRef(null); const textInput = useRef(null); - const willBlurTextInputOnTapOutsideRef= useRef(); + const willBlurTextInputOnTapOutsideRef = useRef(); willBlurTextInputOnTapOutsideRef.current = willBlurTextInputOnTapOutside(); const initialValue = defaultValue ? `${defaultValue}` : `${value || ''}`; const [numberOfLines, setNumberOfLines] = useState(numberOfLinesProp); @@ -358,10 +358,13 @@ function Composer({ updateNumberOfLines(); }, [updateNumberOfLines]); - useEffect(() => () => { - ReportActionComposeFocusManager.clear(); - ReportActionComposeFocusManager.focus(); - }, []); + useEffect( + () => () => { + ReportActionComposeFocusManager.clear(); + ReportActionComposeFocusManager.focus(); + }, + [], + ); useEffect(() => { // we need to handle listeners on navigation focus/blur as Composer is not unmounting @@ -379,6 +382,8 @@ function Composer({ } return () => { + ReportActionComposeFocusManager.clear(); + ReportActionComposeFocusManager.focus(); unsubscribeFocus(); unsubscribeBlur(); document.removeEventListener('paste', handlePaste); From 56ceb26dddfd0017f7c4f9346881b8e8cb696376 Mon Sep 17 00:00:00 2001 From: tienifr Date: Sun, 20 Aug 2023 19:02:27 +0700 Subject: [PATCH 07/13] remove redundant cleanup --- src/components/Composer/index.js | 8 -------- 1 file changed, 8 deletions(-) diff --git a/src/components/Composer/index.js b/src/components/Composer/index.js index 63c8287b7a4a..54df0cc4b068 100755 --- a/src/components/Composer/index.js +++ b/src/components/Composer/index.js @@ -358,14 +358,6 @@ function Composer({ updateNumberOfLines(); }, [updateNumberOfLines]); - useEffect( - () => () => { - ReportActionComposeFocusManager.clear(); - ReportActionComposeFocusManager.focus(); - }, - [], - ); - useEffect(() => { // we need to handle listeners on navigation focus/blur as Composer is not unmounting // when navigating away to different report From 0f744e4a1240d0f8da14a323ca8e8c563a8d682f Mon Sep 17 00:00:00 2001 From: tienifr Date: Sun, 20 Aug 2023 19:22:50 +0700 Subject: [PATCH 08/13] do not re-focus on unmount --- src/components/Composer/index.js | 1 - 1 file changed, 1 deletion(-) diff --git a/src/components/Composer/index.js b/src/components/Composer/index.js index 54df0cc4b068..43ac1e13a678 100755 --- a/src/components/Composer/index.js +++ b/src/components/Composer/index.js @@ -375,7 +375,6 @@ function Composer({ return () => { ReportActionComposeFocusManager.clear(); - ReportActionComposeFocusManager.focus(); unsubscribeFocus(); unsubscribeBlur(); document.removeEventListener('paste', handlePaste); From fafeeaf96c9d581496e3f40d3909274d2d3c492b Mon Sep 17 00:00:00 2001 From: tienifr Date: Sun, 20 Aug 2023 23:07:42 +0700 Subject: [PATCH 09/13] remove ref --- src/components/Composer/index.js | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/components/Composer/index.js b/src/components/Composer/index.js index 43ac1e13a678..df4e2c2a7ee1 100755 --- a/src/components/Composer/index.js +++ b/src/components/Composer/index.js @@ -161,8 +161,6 @@ function Composer({ }) { const textRef = useRef(null); const textInput = useRef(null); - const willBlurTextInputOnTapOutsideRef = useRef(); - willBlurTextInputOnTapOutsideRef.current = willBlurTextInputOnTapOutside(); const initialValue = defaultValue ? `${defaultValue}` : `${value || ''}`; const [numberOfLines, setNumberOfLines] = useState(numberOfLinesProp); const [selection, setSelection] = useState({ @@ -455,7 +453,7 @@ function Composer({ onKeyPress={handleKeyPress} onFocus={(e) => { ReportActionComposeFocusManager.onComposerFocus(() => { - if (!willBlurTextInputOnTapOutsideRef.current || !textInput.current) { + if (!willBlurTextInputOnTapOutside() || !textInput.current) { return; } From 9b8f5634eedfb0e6e3f98875c013404273cf0f79 Mon Sep 17 00:00:00 2001 From: tienifr Date: Mon, 21 Aug 2023 01:39:38 +0700 Subject: [PATCH 10/13] remove redundant check --- src/components/Composer/index.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/components/Composer/index.js b/src/components/Composer/index.js index df4e2c2a7ee1..aad965ff536b 100755 --- a/src/components/Composer/index.js +++ b/src/components/Composer/index.js @@ -19,7 +19,6 @@ import isEnterWhileComposition from '../../libs/KeyboardShortcut/isEnterWhileCom import CONST from '../../CONST'; import withNavigation from '../withNavigation'; import ReportActionComposeFocusManager from '../../libs/ReportActionComposeFocusManager'; -import willBlurTextInputOnTapOutside from '../../libs/willBlurTextInputOnTapOutside'; const propTypes = { /** Maximum number of lines in the text input */ @@ -453,7 +452,7 @@ function Composer({ onKeyPress={handleKeyPress} onFocus={(e) => { ReportActionComposeFocusManager.onComposerFocus(() => { - if (!willBlurTextInputOnTapOutside() || !textInput.current) { + if (!textInput.current) { return; } From a623c7d86aa43b11c1e125530d6df61b134cc8d7 Mon Sep 17 00:00:00 2001 From: tienifr Date: Mon, 21 Aug 2023 17:28:25 +0700 Subject: [PATCH 11/13] modify comment --- src/libs/ReportActionComposeFocusManager.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/libs/ReportActionComposeFocusManager.js b/src/libs/ReportActionComposeFocusManager.js index e90435652187..7f31b17aaa57 100644 --- a/src/libs/ReportActionComposeFocusManager.js +++ b/src/libs/ReportActionComposeFocusManager.js @@ -2,7 +2,8 @@ import _ from 'underscore'; import React from 'react'; const composerRef = React.createRef(); -// There are two types of composer: general composer (edit composer) and main composer +// There are two types of composer: general composer (edit composer) and main composer. +// The general composer callback will take priority if it exists. let focusCallback = null; let mainComposerFocusCallback = null; From 9add8d11589643a973b3eb3d44376d9c00c3f2a2 Mon Sep 17 00:00:00 2001 From: tienifr Date: Tue, 22 Aug 2023 00:21:18 +0700 Subject: [PATCH 12/13] clear focus callback only in case of edit compose --- src/libs/ReportActionComposeFocusManager.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libs/ReportActionComposeFocusManager.js b/src/libs/ReportActionComposeFocusManager.js index 7f31b17aaa57..025a46ade894 100644 --- a/src/libs/ReportActionComposeFocusManager.js +++ b/src/libs/ReportActionComposeFocusManager.js @@ -47,7 +47,7 @@ function focus() { function clear(isMainComposer = false) { if (isMainComposer) { mainComposerFocusCallback = null; - } else { + } else if (mainComposerFocusCallback) { focusCallback = null; } } From 9005a8a3faa69cebbc472b6512df67a7b85eadbe Mon Sep 17 00:00:00 2001 From: tienifr Date: Tue, 22 Aug 2023 01:42:27 +0700 Subject: [PATCH 13/13] only clear in case of edit composer --- src/components/Composer/index.js | 9 ++++++++- src/libs/ReportActionComposeFocusManager.js | 2 +- src/pages/home/report/ReportActionCompose.js | 1 + 3 files changed, 10 insertions(+), 2 deletions(-) diff --git a/src/components/Composer/index.js b/src/components/Composer/index.js index aad965ff536b..dc9b5ba4ac67 100755 --- a/src/components/Composer/index.js +++ b/src/components/Composer/index.js @@ -80,6 +80,9 @@ const propTypes = { /** Function to check whether composer is covered up or not */ checkComposerVisibility: PropTypes.func, + /** Whether this is the report action compose */ + isReportActionCompose: PropTypes.bool, + ...withLocalizePropTypes, ...windowDimensionsPropTypes, @@ -107,6 +110,7 @@ const defaultProps = { setIsFullComposerAvailable: () => {}, shouldCalculateCaretPosition: false, checkComposerVisibility: () => false, + isReportActionCompose: false, }; /** @@ -156,6 +160,7 @@ function Composer({ setIsFullComposerAvailable, checkComposerVisibility, selection: selectionProp, + isReportActionCompose, ...props }) { const textRef = useRef(null); @@ -371,7 +376,9 @@ function Composer({ } return () => { - ReportActionComposeFocusManager.clear(); + if (!isReportActionCompose) { + ReportActionComposeFocusManager.clear(); + } unsubscribeFocus(); unsubscribeBlur(); document.removeEventListener('paste', handlePaste); diff --git a/src/libs/ReportActionComposeFocusManager.js b/src/libs/ReportActionComposeFocusManager.js index 025a46ade894..7f31b17aaa57 100644 --- a/src/libs/ReportActionComposeFocusManager.js +++ b/src/libs/ReportActionComposeFocusManager.js @@ -47,7 +47,7 @@ function focus() { function clear(isMainComposer = false) { if (isMainComposer) { mainComposerFocusCallback = null; - } else if (mainComposerFocusCallback) { + } else { focusCallback = null; } } diff --git a/src/pages/home/report/ReportActionCompose.js b/src/pages/home/report/ReportActionCompose.js index a388b75efad5..675fab95ff28 100644 --- a/src/pages/home/report/ReportActionCompose.js +++ b/src/pages/home/report/ReportActionCompose.js @@ -1197,6 +1197,7 @@ function ReportActionCompose({ shouldClear={textInputShouldClear} onClear={() => setTextInputShouldClear(false)} isDisabled={isBlockedFromConcierge || disabled} + isReportActionCompose selection={selection} onSelectionChange={onSelectionChange} isFullComposerAvailable={isFullSizeComposerAvailable}