Skip to content

Commit

Permalink
Merge pull request #51516 from bernhardoj/fix/50962-exit-survey-page-…
Browse files Browse the repository at this point in the history
…auto-validate-when-open

Fix exit survey response page validation runs when open
  • Loading branch information
neil-marcellini authored Oct 28, 2024
2 parents ba1482e + 55fd597 commit 1f7366a
Show file tree
Hide file tree
Showing 5 changed files with 42 additions and 14 deletions.
11 changes: 9 additions & 2 deletions src/hooks/useAutoFocusInput.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import {useCallback, useEffect, useRef, useState} from 'react';
import type {RefObject} from 'react';
import type {TextInput} from 'react-native';
import {InteractionManager} from 'react-native';
import {moveSelectionToEnd, scrollToBottom} from '@libs/InputUtils';
import CONST from '@src/CONST';
import {useSplashScreenStateContext} from '@src/SplashScreenStateContext';

Expand All @@ -11,7 +12,7 @@ type UseAutoFocusInput = {
inputRef: RefObject<TextInput | null>;
};

export default function useAutoFocusInput(): UseAutoFocusInput {
export default function useAutoFocusInput(isMultiline = false): UseAutoFocusInput {
const [isInputInitialized, setIsInputInitialized] = useState(false);
const [isScreenTransitionEnded, setIsScreenTransitionEnded] = useState(false);

Expand All @@ -25,14 +26,17 @@ export default function useAutoFocusInput(): UseAutoFocusInput {
return;
}
const focusTaskHandle = InteractionManager.runAfterInteractions(() => {
if (inputRef.current && isMultiline) {
moveSelectionToEnd(inputRef.current);
}
inputRef.current?.focus();
setIsScreenTransitionEnded(false);
});

return () => {
focusTaskHandle.cancel();
};
}, [isScreenTransitionEnded, isInputInitialized, splashScreenState]);
}, [isMultiline, isScreenTransitionEnded, isInputInitialized, splashScreenState]);

useFocusEffect(
useCallback(() => {
Expand All @@ -54,6 +58,9 @@ export default function useAutoFocusInput(): UseAutoFocusInput {
if (isInputInitialized) {
return;
}
if (ref && isMultiline) {
scrollToBottom(ref);
}
setIsInputInitialized(true);
};

Expand Down
6 changes: 6 additions & 0 deletions src/libs/InputUtils/index.native.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import type {MoveSelectiontoEnd, ScrollToBottom} from './types';

const scrollToBottom: ScrollToBottom = () => {};
const moveSelectionToEnd: MoveSelectiontoEnd = () => {};

export {scrollToBottom, moveSelectionToEnd};
19 changes: 19 additions & 0 deletions src/libs/InputUtils/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import type {MoveSelectiontoEnd, ScrollToBottom} from './types';

const scrollToBottom: ScrollToBottom = (input) => {
if (!('scrollTop' in input)) {
return;
}
// eslint-disable-next-line no-param-reassign
input.scrollTop = input.scrollHeight;
};

const moveSelectionToEnd: MoveSelectiontoEnd = (input) => {
if (!('setSelectionRange' in input)) {
return;
}
const length = input.value.length;
input.setSelectionRange(length, length);
};

export {scrollToBottom, moveSelectionToEnd};
6 changes: 6 additions & 0 deletions src/libs/InputUtils/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import type {TextInput} from 'react-native';

type ScrollToBottom = (input: HTMLInputElement | TextInput) => void;
type MoveSelectiontoEnd = (input: HTMLInputElement | TextInput) => void;

export type {ScrollToBottom, MoveSelectiontoEnd};
14 changes: 2 additions & 12 deletions src/pages/settings/ExitSurvey/ExitSurveyResponsePage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import {useOnyx} from 'react-native-onyx';
import FormProvider from '@components/Form/FormProvider';
import InputWrapper from '@components/Form/InputWrapper';
import HeaderWithBackButton from '@components/HeaderWithBackButton';
import type {AnimatedTextInputRef} from '@components/RNTextInput';
import ScreenWrapper from '@components/ScreenWrapper';
import Text from '@components/Text';
import TextInput from '@components/TextInput';
Expand All @@ -18,7 +17,6 @@ import useStyleUtils from '@hooks/useStyleUtils';
import useThemeStyles from '@hooks/useThemeStyles';
import useWindowDimensions from '@hooks/useWindowDimensions';
import StatusBar from '@libs/StatusBar';
import updateMultilineInputRange from '@libs/updateMultilineInputRange';
import Navigation from '@navigation/Navigation';
import type {SettingsNavigatorParamList} from '@navigation/types';
import variables from '@styles/variables';
Expand All @@ -40,7 +38,7 @@ function ExitSurveyResponsePage({route, navigation}: ExitSurveyResponsePageProps
const StyleUtils = useStyleUtils();
const {keyboardHeight} = useKeyboardState();
const {windowHeight} = useWindowDimensions();
const {inputCallbackRef, inputRef} = useAutoFocusInput();
const {inputCallbackRef} = useAutoFocusInput(true);

// Device safe area top and bottom insets.
// When the keyboard is shown, the bottom inset doesn't affect the height, so we take it out from the calculation.
Expand Down Expand Up @@ -120,15 +118,7 @@ function ExitSurveyResponsePage({route, navigation}: ExitSurveyResponsePageProps
autoGrowHeight
maxAutoGrowHeight={variables.textInputAutoGrowMaxHeight}
maxLength={CONST.MAX_COMMENT_LENGTH}
ref={(el: AnimatedTextInputRef) => {
if (!el) {
return;
}
if (!inputRef.current) {
updateMultilineInputRange(el);
}
inputCallbackRef(el);
}}
ref={inputCallbackRef}
containerStyles={[baseResponseInputContainerStyle]}
shouldSaveDraft
shouldSubmitForm
Expand Down

0 comments on commit 1f7366a

Please sign in to comment.