From 1a80a9ea4d7b279118fe52d96effe5cbcec57963 Mon Sep 17 00:00:00 2001 From: Akinwale Ariwodola Date: Mon, 2 Oct 2023 19:58:30 +0100 Subject: [PATCH 1/4] implement a hook to delay auto focus on text inputs --- src/CONST.ts | 1 + src/hooks/useDelayedInputFocus.js | 25 +++++++++++++++++++++ src/pages/workspace/WorkspaceNewRoomPage.js | 7 +++++- 3 files changed, 32 insertions(+), 1 deletion(-) create mode 100644 src/hooks/useDelayedInputFocus.js diff --git a/src/CONST.ts b/src/CONST.ts index 0a262d868de9..1ce7a2dc4994 100755 --- a/src/CONST.ts +++ b/src/CONST.ts @@ -43,6 +43,7 @@ const CONST = { OUT: 'out', }, ARROW_HIDE_DELAY: 3000, + INPUT_FOCUS_DELAY: 600, API_ATTACHMENT_VALIDATIONS: { // 24 megabytes in bytes, this is limit set on servers, do not update without wider internal discussion diff --git a/src/hooks/useDelayedInputFocus.js b/src/hooks/useDelayedInputFocus.js new file mode 100644 index 000000000000..974b37c96dbd --- /dev/null +++ b/src/hooks/useDelayedInputFocus.js @@ -0,0 +1,25 @@ +import {useCallback, useRef} from 'react'; +import {useFocusEffect} from '@react-navigation/native'; +import CONST from '../CONST'; + +/** + * Focus a text input when a screen is navigated to, after the specified time delay has elapsed. + * + * @param {Object} inputRef + * @param {Number} [delay] + */ +export default function useDelayedInputFocus(inputRef, delay = CONST.INPUT_FOCUS_DELAY) { + const timeoutRef = useRef(null); + + useFocusEffect( + useCallback(() => { + timeoutRef.current = setTimeout(() => inputRef.current && inputRef.current.focus(), delay); + return () => { + if (!timeoutRef.current) { + return; + } + clearTimeout(timeoutRef.current); + }; + }, [delay, inputRef]), + ); +} diff --git a/src/pages/workspace/WorkspaceNewRoomPage.js b/src/pages/workspace/WorkspaceNewRoomPage.js index d6f58a1b66ad..47ae0fb34cff 100644 --- a/src/pages/workspace/WorkspaceNewRoomPage.js +++ b/src/pages/workspace/WorkspaceNewRoomPage.js @@ -1,4 +1,4 @@ -import React, {useState, useCallback, useMemo} from 'react'; +import React, {useState, useCallback, useMemo, useRef} from 'react'; import {View} from 'react-native'; import _ from 'underscore'; import {withOnyx} from 'react-native-onyx'; @@ -25,6 +25,7 @@ import policyMemberPropType from '../policyMemberPropType'; import FullPageNotFoundView from '../../components/BlockingViews/FullPageNotFoundView'; import compose from '../../libs/compose'; import variables from '../../styles/variables'; +import useDelayedInputFocus from '../../hooks/useDelayedInputFocus'; const propTypes = { /** All reports shared with the user */ @@ -144,6 +145,9 @@ function WorkspaceNewRoomPage(props) { [translate], ); + const roomNameInputRef = useRef(null); + useDelayedInputFocus(roomNameInputRef); + return ( (roomNameInputRef.current = el)} inputID="roomName" isFocused={props.isFocused} shouldDelayFocus From f7b86594d7c92d57d4ded64804073167f070d8f8 Mon Sep 17 00:00:00 2001 From: Akinwale Ariwodola Date: Wed, 4 Oct 2023 13:31:25 +0100 Subject: [PATCH 2/4] change default delay for the useDelayedInputFocus hook --- src/hooks/useDelayedInputFocus.js | 2 +- src/pages/workspace/WorkspaceNewRoomPage.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/hooks/useDelayedInputFocus.js b/src/hooks/useDelayedInputFocus.js index 974b37c96dbd..2fd94327a588 100644 --- a/src/hooks/useDelayedInputFocus.js +++ b/src/hooks/useDelayedInputFocus.js @@ -8,7 +8,7 @@ import CONST from '../CONST'; * @param {Object} inputRef * @param {Number} [delay] */ -export default function useDelayedInputFocus(inputRef, delay = CONST.INPUT_FOCUS_DELAY) { +export default function useDelayedInputFocus(inputRef, delay = CONST.ANIMATED_TRANSITION) { const timeoutRef = useRef(null); useFocusEffect( diff --git a/src/pages/workspace/WorkspaceNewRoomPage.js b/src/pages/workspace/WorkspaceNewRoomPage.js index 47ae0fb34cff..17f8de4fb912 100644 --- a/src/pages/workspace/WorkspaceNewRoomPage.js +++ b/src/pages/workspace/WorkspaceNewRoomPage.js @@ -146,7 +146,7 @@ function WorkspaceNewRoomPage(props) { ); const roomNameInputRef = useRef(null); - useDelayedInputFocus(roomNameInputRef); + useDelayedInputFocus(roomNameInputRef, CONST.INPUT_FOCUS_DELAY); return ( Date: Wed, 4 Oct 2023 18:49:13 +0100 Subject: [PATCH 3/4] use component-specific delay value for room name input --- src/CONST.ts | 1 - src/pages/workspace/WorkspaceNewRoomPage.js | 5 ++++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/CONST.ts b/src/CONST.ts index 1ce7a2dc4994..0a262d868de9 100755 --- a/src/CONST.ts +++ b/src/CONST.ts @@ -43,7 +43,6 @@ const CONST = { OUT: 'out', }, ARROW_HIDE_DELAY: 3000, - INPUT_FOCUS_DELAY: 600, API_ATTACHMENT_VALIDATIONS: { // 24 megabytes in bytes, this is limit set on servers, do not update without wider internal discussion diff --git a/src/pages/workspace/WorkspaceNewRoomPage.js b/src/pages/workspace/WorkspaceNewRoomPage.js index 46b4d0838952..4a7a36713793 100644 --- a/src/pages/workspace/WorkspaceNewRoomPage.js +++ b/src/pages/workspace/WorkspaceNewRoomPage.js @@ -155,8 +155,11 @@ function WorkspaceNewRoomPage(props) { [translate], ); + // the delay to be used for delayed focus on the room name input field + const inputFocusDelay = 600; + const roomNameInputRef = useRef(null); - useDelayedInputFocus(roomNameInputRef, CONST.INPUT_FOCUS_DELAY); + useDelayedInputFocus(roomNameInputRef, inputFocusDelay); return ( Date: Wed, 4 Oct 2023 19:08:30 +0100 Subject: [PATCH 4/4] parameter cleanup --- src/pages/workspace/WorkspaceNewRoomPage.js | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/pages/workspace/WorkspaceNewRoomPage.js b/src/pages/workspace/WorkspaceNewRoomPage.js index 4a7a36713793..34ec93fe7150 100644 --- a/src/pages/workspace/WorkspaceNewRoomPage.js +++ b/src/pages/workspace/WorkspaceNewRoomPage.js @@ -155,11 +155,10 @@ function WorkspaceNewRoomPage(props) { [translate], ); - // the delay to be used for delayed focus on the room name input field - const inputFocusDelay = 600; - const roomNameInputRef = useRef(null); - useDelayedInputFocus(roomNameInputRef, inputFocusDelay); + + // use a 600ms delay for delayed focus on the room name input field so that it works consistently on native iOS / Android + useDelayedInputFocus(roomNameInputRef, 600); return (