MM-62896 Keyboard blocks input (#8646)
* WIP * fix keyboard blocking text input for interactive dialog * do not use extra keyboard and windowSoftInputMode:adjustNothing on Android 10 and under --------- Co-authored-by: Devin Binnie <devin.binnie@mattermost.com>
This commit is contained in:
parent
5231ee6553
commit
1c8770c74d
5 changed files with 144 additions and 9 deletions
|
|
@ -54,6 +54,10 @@ export const ExtraKeyboardProvider = (({children}: {children: React.ReactElement
|
|||
const [isTextInputFocused, setIsTextInputFocused] = useState(false);
|
||||
|
||||
const showExtraKeyboard = useCallback((newComponent: React.ReactElement|null) => {
|
||||
// Do not use ExtraKeyboard on Android versions below 11
|
||||
if (Platform.OS === 'android' && Platform.Version < 30) {
|
||||
return;
|
||||
}
|
||||
setExtraKeyboardVisible(true);
|
||||
setComponent(newComponent);
|
||||
if (Keyboard.isVisible()) {
|
||||
|
|
@ -62,6 +66,10 @@ export const ExtraKeyboardProvider = (({children}: {children: React.ReactElement
|
|||
}, []);
|
||||
|
||||
const hideExtraKeyboard = useCallback(() => {
|
||||
// Do not use ExtraKeyboard on Android versions below 11
|
||||
if (Platform.OS === 'android' && Platform.Version < 30) {
|
||||
return;
|
||||
}
|
||||
setExtraKeyboardVisible(false);
|
||||
setComponent(null);
|
||||
if (Keyboard.isVisible()) {
|
||||
|
|
@ -70,6 +78,11 @@ export const ExtraKeyboardProvider = (({children}: {children: React.ReactElement
|
|||
}, []);
|
||||
|
||||
const registerTextInputFocus = useCallback(() => {
|
||||
// Do not use ExtraKeyboard on Android versions below 11
|
||||
if (Platform.OS === 'android' && Platform.Version < 30) {
|
||||
return;
|
||||
}
|
||||
|
||||
// If the extra keyboard is opened if we don't do this
|
||||
// we get a glitch in the UI that will animate the extra keyboard down
|
||||
// and immediately bring the keyboard, by doing this
|
||||
|
|
@ -81,11 +94,21 @@ export const ExtraKeyboardProvider = (({children}: {children: React.ReactElement
|
|||
}, []);
|
||||
|
||||
const registerTextInputBlur = useCallback(() => {
|
||||
// Do not use ExtraKeyboard on Android versions below 11
|
||||
if (Platform.OS === 'android' && Platform.Version < 30) {
|
||||
return;
|
||||
}
|
||||
|
||||
setIsTextInputFocused(false);
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
const keyboardHideListener = Keyboard.addListener('keyboardDidHide', () => {
|
||||
// Do not use ExtraKeyboard on Android versions below 11
|
||||
if (Platform.OS === 'android' && Platform.Version < 30) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (isTextInputFocused) {
|
||||
setExtraKeyboardVisible(false);
|
||||
}
|
||||
|
|
@ -142,7 +165,7 @@ export const useHideExtraKeyboardIfNeeded = (callback: (...args: any) => void, d
|
|||
}), [keyboardContext, ...dependencies]);
|
||||
};
|
||||
|
||||
export const ExtraKeyboard = () => {
|
||||
const ExtraKeyboardComponent = () => {
|
||||
const keyb = useAnimatedKeyboard({isStatusBarTranslucentAndroid: true});
|
||||
const defaultKeyboardHeight = Platform.select({ios: 291, default: 240});
|
||||
const context = useExtraKeyboardContext();
|
||||
|
|
@ -181,3 +204,14 @@ export const ExtraKeyboard = () => {
|
|||
</Animated.View>
|
||||
);
|
||||
};
|
||||
|
||||
// Do not use ExtraKeyboard on Android versions below 11
|
||||
export const ExtraKeyboard = () => {
|
||||
if (Platform.OS === 'android' && Platform.Version < 30) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<ExtraKeyboardComponent/>
|
||||
);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -61,10 +61,19 @@ export function useKeyboardHeightWithDuration() {
|
|||
|
||||
useEffect(() => {
|
||||
const show = Keyboard.addListener(Platform.select({ios: 'keyboardWillShow', default: 'keyboardDidShow'}), async (event) => {
|
||||
// Do not use set the height on Android versions below 11
|
||||
if (Platform.OS === 'android' && Platform.Version < 30) {
|
||||
return;
|
||||
}
|
||||
setKeyboardHeight({height: event.endCoordinates.height, duration: event.duration});
|
||||
});
|
||||
|
||||
const hide = Keyboard.addListener(Platform.select({ios: 'keyboardWillHide', default: 'keyboardDidHide'}), (event) => {
|
||||
// Do not use set the height on Android versions below 11
|
||||
if (Platform.OS === 'android' && Platform.Version < 30) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (updateTimeout.current != null) {
|
||||
clearTimeout(updateTimeout.current);
|
||||
updateTimeout.current = null;
|
||||
|
|
|
|||
|
|
@ -3,7 +3,8 @@
|
|||
|
||||
import React, {useCallback, useEffect, useMemo, useReducer, useRef, useState} from 'react';
|
||||
import {useIntl} from 'react-intl';
|
||||
import {Keyboard, ScrollView} from 'react-native';
|
||||
import {Keyboard} from 'react-native';
|
||||
import {KeyboardAwareScrollView} from 'react-native-keyboard-aware-scroll-view';
|
||||
import {type ImageResource, Navigation} from 'react-native-navigation';
|
||||
import {SafeAreaView} from 'react-native-safe-area-context';
|
||||
|
||||
|
|
@ -106,7 +107,7 @@ function InteractiveDialog({
|
|||
const serverUrl = useServerUrl();
|
||||
const intl = useIntl();
|
||||
|
||||
const scrollView = useRef<ScrollView>(null);
|
||||
const scrollView = useRef<KeyboardAwareScrollView>(null);
|
||||
|
||||
const onChange = useCallback((name: string, value: string | number | boolean) => {
|
||||
dispatchValues({name, value});
|
||||
|
|
@ -185,7 +186,7 @@ function InteractiveDialog({
|
|||
if (data.error) {
|
||||
hasErrors = true;
|
||||
setError(data.error);
|
||||
scrollView.current?.scrollTo({x: 0, y: 0});
|
||||
scrollView.current?.scrollToPosition(0, 0, true);
|
||||
} else {
|
||||
setError('');
|
||||
}
|
||||
|
|
@ -234,9 +235,19 @@ function InteractiveDialog({
|
|||
testID='interactive_dialog.screen'
|
||||
style={style.container}
|
||||
>
|
||||
<ScrollView
|
||||
<KeyboardAwareScrollView
|
||||
ref={scrollView}
|
||||
bounces={false}
|
||||
style={style.scrollView}
|
||||
enableAutomaticScroll={true}
|
||||
enableOnAndroid={true}
|
||||
noPaddingBottomOnAndroid={true}
|
||||
scrollToOverflowEnabled={true}
|
||||
enableResetScrollToCoords={true}
|
||||
extraScrollHeight={0}
|
||||
extraHeight={0}
|
||||
keyboardDismissMode='interactive'
|
||||
keyboardShouldPersistTaps='handled'
|
||||
>
|
||||
{Boolean(error) && (
|
||||
<ErrorText
|
||||
|
|
@ -246,9 +257,9 @@ function InteractiveDialog({
|
|||
/>
|
||||
)}
|
||||
{Boolean(introductionText) &&
|
||||
<DialogIntroductionText
|
||||
value={introductionText}
|
||||
/>
|
||||
<DialogIntroductionText
|
||||
value={introductionText}
|
||||
/>
|
||||
}
|
||||
{Boolean(elements) && elements.map((e) => {
|
||||
const value = secureGetFromRecord(values, e.name);
|
||||
|
|
@ -271,7 +282,7 @@ function InteractiveDialog({
|
|||
/>
|
||||
);
|
||||
})}
|
||||
</ScrollView>
|
||||
</KeyboardAwareScrollView>
|
||||
</SafeAreaView>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ package com.mattermost.rnutils
|
|||
|
||||
import android.app.Activity
|
||||
import android.net.Uri
|
||||
import android.os.Build
|
||||
import android.view.WindowManager
|
||||
import androidx.core.view.OnApplyWindowInsetsListener
|
||||
import com.facebook.react.bridge.Arguments
|
||||
|
|
@ -128,6 +129,9 @@ class RNUtilsModuleImpl(private val reactContext: ReactApplicationContext) {
|
|||
|
||||
fun setSoftKeyboardToAdjustNothing() {
|
||||
val currentActivity: Activity = reactContext.currentActivity ?: return
|
||||
if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.Q) {
|
||||
return
|
||||
}
|
||||
|
||||
currentActivity.runOnUiThread {
|
||||
currentActivity.window.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_NOTHING)
|
||||
|
|
@ -136,6 +140,9 @@ class RNUtilsModuleImpl(private val reactContext: ReactApplicationContext) {
|
|||
|
||||
fun setSoftKeyboardToAdjustResize() {
|
||||
val currentActivity: Activity = reactContext.currentActivity ?: return
|
||||
if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.Q) {
|
||||
return
|
||||
}
|
||||
|
||||
currentActivity.runOnUiThread {
|
||||
currentActivity.window.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE)
|
||||
|
|
|
|||
74
patches/react-native-keyboard-aware-scroll-view+0.9.5.patch
Normal file
74
patches/react-native-keyboard-aware-scroll-view+0.9.5.patch
Normal file
|
|
@ -0,0 +1,74 @@
|
|||
diff --git a/node_modules/react-native-keyboard-aware-scroll-view/index.d.ts b/node_modules/react-native-keyboard-aware-scroll-view/index.d.ts
|
||||
index bf03b26..e11063b 100644
|
||||
--- a/node_modules/react-native-keyboard-aware-scroll-view/index.d.ts
|
||||
+++ b/node_modules/react-native-keyboard-aware-scroll-view/index.d.ts
|
||||
@@ -69,6 +69,7 @@ interface KeyboardAwareProps {
|
||||
* @memberof KeyboardAwareProps
|
||||
*/
|
||||
enableOnAndroid?: boolean
|
||||
+ noPaddingBottomOnAndroid?: boolean
|
||||
|
||||
/**
|
||||
* Adds an extra offset when focusing the TextInputs.
|
||||
diff --git a/node_modules/react-native-keyboard-aware-scroll-view/lib/KeyboardAwareHOC.js b/node_modules/react-native-keyboard-aware-scroll-view/lib/KeyboardAwareHOC.js
|
||||
index 03f46af..f58175f 100644
|
||||
--- a/node_modules/react-native-keyboard-aware-scroll-view/lib/KeyboardAwareHOC.js
|
||||
+++ b/node_modules/react-native-keyboard-aware-scroll-view/lib/KeyboardAwareHOC.js
|
||||
@@ -57,6 +57,7 @@ export type KeyboardAwareHOCProps = {
|
||||
update?: Function,
|
||||
contentContainerStyle?: any,
|
||||
enableOnAndroid?: boolean,
|
||||
+ noPaddingBottomOnAndroid?: boolean,
|
||||
innerRef?: Function,
|
||||
...keyboardAwareHOCTypeEvents
|
||||
}
|
||||
@@ -92,6 +93,7 @@ export type ScrollIntoViewOptions = ?{
|
||||
|
||||
export type KeyboardAwareHOCOptions = ?{
|
||||
enableOnAndroid: boolean,
|
||||
+ noPaddingBottomOnAndroid: boolean,
|
||||
contentContainerStyle: ?Object,
|
||||
enableAutomaticScroll: boolean,
|
||||
extraHeight: number,
|
||||
@@ -113,6 +115,7 @@ function getDisplayName(WrappedComponent: React$Component) {
|
||||
|
||||
const ScrollIntoViewDefaultOptions: KeyboardAwareHOCOptions = {
|
||||
enableOnAndroid: false,
|
||||
+ noPaddingBottomOnAndroid: false,
|
||||
contentContainerStyle: undefined,
|
||||
enableAutomaticScroll: true,
|
||||
extraHeight: _KAM_EXTRA_HEIGHT,
|
||||
@@ -181,6 +184,7 @@ function KeyboardAwareHOC(
|
||||
update: PropTypes.func,
|
||||
contentContainerStyle: PropTypes.any,
|
||||
enableOnAndroid: PropTypes.bool,
|
||||
+ noPaddingBottomOnAndroid: PropTypes.bool,
|
||||
innerRef: PropTypes.func,
|
||||
...keyboardEventPropTypes
|
||||
}
|
||||
@@ -193,7 +197,8 @@ function KeyboardAwareHOC(
|
||||
enableResetScrollToCoords: hocOptions.enableResetScrollToCoords,
|
||||
keyboardOpeningTime: hocOptions.keyboardOpeningTime,
|
||||
viewIsInsideTabBar: hocOptions.viewIsInsideTabBar,
|
||||
- enableOnAndroid: hocOptions.enableOnAndroid
|
||||
+ enableOnAndroid: hocOptions.enableOnAndroid,
|
||||
+ noPaddingBottomOnAndroid: hocOptions.noPaddingBottomOnAndroid
|
||||
}
|
||||
|
||||
constructor(props: KeyboardAwareHOCProps) {
|
||||
@@ -523,13 +528,13 @@ function KeyboardAwareHOC(
|
||||
}
|
||||
|
||||
render() {
|
||||
- const { enableOnAndroid, contentContainerStyle, onScroll } = this.props
|
||||
+ const { enableOnAndroid, contentContainerStyle, noPaddingBottomOnAndroid, onScroll } = this.props
|
||||
let newContentContainerStyle
|
||||
if (Platform.OS === 'android' && enableOnAndroid) {
|
||||
newContentContainerStyle = [].concat(contentContainerStyle).concat({
|
||||
paddingBottom:
|
||||
((contentContainerStyle || {}).paddingBottom || 0) +
|
||||
- this.state.keyboardSpace
|
||||
+ noPaddingBottomOnAndroid ? 0 : this.state.keyboardSpace
|
||||
})
|
||||
}
|
||||
const refProps = { [hocOptions.refPropName]: this._handleRef }
|
||||
Loading…
Reference in a new issue