-
Notifications
You must be signed in to change notification settings - Fork 3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fix: 10731 Focus composer without showing keyboard when users go to chats #32711
Changes from 15 commits
d8eb426
07fdad0
a5f99b7
f764d66
f6e2e28
4b19bdf
7e930b8
96e924d
8edc49a
5dc6922
b6647b4
432e67e
e6bfa42
eb79042
aec542a
802f37d
d036e24
dd50857
b008b05
025fa15
c48bb63
726154d
5e13e27
69bc468
c037b05
3e60d1e
7ba9d60
958e9df
ca23e24
c59d44f
fb798c0
fcac742
18055ae
381fdff
e08d442
2282bf6
1245315
33e093e
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -27,7 +27,6 @@ import useTheme from '@hooks/useTheme'; | |
import useThemeStyles from '@hooks/useThemeStyles'; | ||
import useWindowDimensions from '@hooks/useWindowDimensions'; | ||
import * as Browser from '@libs/Browser'; | ||
import canFocusInputOnScreenFocus from '@libs/canFocusInputOnScreenFocus'; | ||
import * as ComposerUtils from '@libs/ComposerUtils'; | ||
import convertToLTRForComposer from '@libs/convertToLTRForComposer'; | ||
import {getDraftComment} from '@libs/DraftCommentUtils'; | ||
|
@@ -36,7 +35,6 @@ import focusComposerWithDelay from '@libs/focusComposerWithDelay'; | |
import getPlatform from '@libs/getPlatform'; | ||
import * as KeyDownListener from '@libs/KeyboardShortcut/KeyDownPressListener'; | ||
import ReportActionComposeFocusManager from '@libs/ReportActionComposeFocusManager'; | ||
import * as ReportActionsUtils from '@libs/ReportActionsUtils'; | ||
import * as ReportUtils from '@libs/ReportUtils'; | ||
import * as SuggestionUtils from '@libs/SuggestionUtils'; | ||
import updateMultilineInputRange from '@libs/updateMultilineInputRange'; | ||
|
@@ -66,9 +64,6 @@ type ComposerWithSuggestionsOnyxProps = { | |
/** The number of lines the comment should take up */ | ||
numberOfLines: OnyxEntry<number>; | ||
|
||
/** The parent report actions for the report */ | ||
parentReportActions: OnyxEntry<OnyxTypes.ReportActions>; | ||
|
||
/** The modal state */ | ||
modal: OnyxEntry<OnyxTypes.Modal>; | ||
|
||
|
@@ -156,22 +151,12 @@ type ComposerWithSuggestionsProps = ComposerWithSuggestionsOnyxProps & | |
/** Whether the edit is focused */ | ||
editFocused: boolean; | ||
|
||
/** Wheater chat is empty */ | ||
isEmptyChat?: boolean; | ||
|
||
/** The last report action */ | ||
lastReportAction?: OnyxEntry<OnyxTypes.ReportAction>; | ||
|
||
/** Whether to include chronos */ | ||
includeChronos?: boolean; | ||
|
||
/** The parent report action ID */ | ||
parentReportActionID?: string; | ||
|
||
/** The parent report ID */ | ||
// eslint-disable-next-line react/no-unused-prop-types -- its used in the withOnyx HOC | ||
parentReportID: string | undefined; | ||
|
||
/** Whether report is from group policy */ | ||
isGroupPolicyReport: boolean; | ||
|
||
|
@@ -199,10 +184,6 @@ const debouncedBroadcastUserIsTyping = lodashDebounce( | |
|
||
const willBlurTextInputOnTapOutside = willBlurTextInputOnTapOutsideFunc(); | ||
|
||
// We want consistent auto focus behavior on input between native and mWeb so we have some auto focus management code that will | ||
// prevent auto focus on existing chat for mobile device | ||
const shouldFocusInputOnScreenFocus = canFocusInputOnScreenFocus(); | ||
|
||
/** | ||
* This component holds the value and selection state. | ||
* If a component really needs access to these state values it should be put here. | ||
|
@@ -214,15 +195,12 @@ function ComposerWithSuggestions( | |
// Onyx | ||
modal, | ||
preferredSkinTone = CONST.EMOJI_DEFAULT_SKIN_TONE, | ||
parentReportActions, | ||
numberOfLines, | ||
|
||
// Props: Report | ||
reportID, | ||
includeChronos, | ||
isEmptyChat, | ||
lastReportAction, | ||
parentReportActionID, | ||
isGroupPolicyReport, | ||
policyID, | ||
|
||
|
@@ -282,19 +260,21 @@ function ComposerWithSuggestions( | |
const {isSmallScreenWidth} = useWindowDimensions(); | ||
const maxComposerLines = isSmallScreenWidth ? CONST.COMPOSER.MAX_LINES_SMALL_SCREEN : CONST.COMPOSER.MAX_LINES; | ||
|
||
const parentReportAction = parentReportActions?.[parentReportActionID ?? ''] ?? null; | ||
const shouldAutoFocus = | ||
!modal?.isVisible && isFocused && (shouldFocusInputOnScreenFocus || (isEmptyChat && !ReportActionsUtils.isTransactionThread(parentReportAction))) && shouldShowComposeInput; | ||
const shouldAutoFocus = !modal?.isVisible && shouldShowComposeInput; | ||
|
||
const valueRef = useRef(value); | ||
valueRef.current = value; | ||
|
||
const [showSoftInputOnFocus, setShowSoftInputOnFocus] = useState(false); | ||
|
||
const [selection, setSelection] = useState(() => ({start: 0, end: 0})); | ||
|
||
const [composerHeight, setComposerHeight] = useState(0); | ||
|
||
const textInputRef = useRef<TextInput | null>(null); | ||
const insertedEmojisRef = useRef<Emoji[]>([]); | ||
const shouldInitFocus = useRef<boolean>(true); | ||
const isFocusedWhileChangingInputMode = useRef<boolean>(false); | ||
|
||
const syncSelectionWithOnChangeTextRef = useRef<SyncSelection | null>(null); | ||
|
||
|
@@ -678,7 +658,15 @@ function ComposerWithSuggestions( | |
// We want to focus or refocus the input when a modal has been closed or the underlying screen is refocused. | ||
// We avoid doing this on native platforms since the software keyboard popping | ||
// open creates a jarring and broken UX. | ||
if (!((willBlurTextInputOnTapOutside || shouldAutoFocus) && !isNextModalWillOpenRef.current && !modal?.isVisible && isFocused && (!!prevIsModalVisible || !prevIsFocused))) { | ||
if ( | ||
!( | ||
(willBlurTextInputOnTapOutside || shouldAutoFocus) && | ||
!isNextModalWillOpenRef.current && | ||
!modal?.isVisible && | ||
isFocused && | ||
(!!prevIsModalVisible || !prevIsFocused || shouldInitFocus.current) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. why would we need There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. btw @christianwen? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @christianwen Bump on this one. If possible, please rewrite this condition for more readable |
||
) | ||
) { | ||
return; | ||
} | ||
|
||
|
@@ -687,6 +675,9 @@ function ComposerWithSuggestions( | |
return; | ||
} | ||
focus(true); | ||
if (shouldInitFocus.current) { | ||
shouldInitFocus.current = false; | ||
} | ||
}, [focus, prevIsFocused, editFocused, prevIsModalVisible, isFocused, modal?.isVisible, isNextModalWillOpenRef, shouldAutoFocus]); | ||
|
||
useEffect(() => { | ||
|
@@ -730,6 +721,16 @@ function ComposerWithSuggestions( | |
// eslint-disable-next-line react-hooks/exhaustive-deps | ||
}, []); | ||
|
||
useEffect(() => { | ||
if (!showSoftInputOnFocus || !isFocusedWhileChangingInputMode.current) { | ||
return; | ||
} | ||
// On Safari when changing inputMode from none to text, the keyboard will cover the view | ||
// We need to re-focus to trigger the keyboard to open below the view | ||
isFocusedWhileChangingInputMode.current = false; | ||
textInputRef.current?.focus(); | ||
}, [showSoftInputOnFocus]); | ||
|
||
return ( | ||
<> | ||
<View style={[StyleUtils.getContainerComposeStyles(), styles.textInputComposeBorder]}> | ||
|
@@ -746,7 +747,12 @@ function ComposerWithSuggestions( | |
style={[styles.textInputCompose, isComposerFullSize ? styles.textInputFullCompose : styles.textInputCollapseCompose]} | ||
maxLines={maxComposerLines} | ||
onFocus={onFocus} | ||
onBlur={onBlur} | ||
onBlur={(e) => { | ||
if (isFocusedWhileChangingInputMode.current) { | ||
return; | ||
} | ||
onBlur(e); | ||
}} | ||
onClick={setShouldBlockSuggestionCalcToFalse} | ||
onPasteFile={displayFileInModal} | ||
shouldClear={textInputShouldClear} | ||
|
@@ -765,6 +771,18 @@ function ComposerWithSuggestions( | |
shouldCalculateCaretPosition | ||
onLayout={onLayout} | ||
onScroll={hideSuggestionMenu} | ||
showSoftInputOnFocus={showSoftInputOnFocus} | ||
onTouchStart={() => { | ||
if (showSoftInputOnFocus) { | ||
return; | ||
} | ||
if (Browser.isMobileSafari()) { | ||
isFocusedWhileChangingInputMode.current = true; | ||
textInputRef.current?.blur(); | ||
} | ||
|
||
setShowSoftInputOnFocus(true); | ||
}} | ||
shouldContainScroll={Browser.isMobileSafari()} | ||
/> | ||
</View> | ||
|
@@ -824,11 +842,6 @@ export default withOnyx<ComposerWithSuggestionsProps & RefAttributes<ComposerRef | |
editFocused: { | ||
key: ONYXKEYS.INPUT_FOCUSED, | ||
}, | ||
parentReportActions: { | ||
key: ({parentReportID}) => `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${parentReportID}`, | ||
canEvict: false, | ||
initWithStoredValues: false, | ||
}, | ||
})(memo(ComposerWithSuggestionsWithRef)); | ||
|
||
export type {ComposerWithSuggestionsProps}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why this was deleted?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same question.
After rechecking. This is added #18699 and now we change the expectation. So this should be removed to align with new expect