diff --git a/app/context/extra_keyboard/index.tsx b/app/context/extra_keyboard/index.tsx index cb14db6cc..69282bf08 100644 --- a/app/context/extra_keyboard/index.tsx +++ b/app/context/extra_keyboard/index.tsx @@ -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 = () => { ); }; + +// Do not use ExtraKeyboard on Android versions below 11 +export const ExtraKeyboard = () => { + if (Platform.OS === 'android' && Platform.Version < 30) { + return null; + } + + return ( + + ); +}; diff --git a/app/hooks/device.ts b/app/hooks/device.ts index bf0313159..abca58490 100644 --- a/app/hooks/device.ts +++ b/app/hooks/device.ts @@ -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; diff --git a/app/screens/interactive_dialog/index.tsx b/app/screens/interactive_dialog/index.tsx index eaa2042e2..97daff23f 100644 --- a/app/screens/interactive_dialog/index.tsx +++ b/app/screens/interactive_dialog/index.tsx @@ -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(null); + const scrollView = useRef(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} > - {Boolean(error) && ( )} {Boolean(introductionText) && - + } {Boolean(elements) && elements.map((e) => { const value = secureGetFromRecord(values, e.name); @@ -271,7 +282,7 @@ function InteractiveDialog({ /> ); })} - + ); } diff --git a/libraries/@mattermost/rnutils/android/src/main/java/com/mattermost/rnutils/RNUtilsModuleImpl.kt b/libraries/@mattermost/rnutils/android/src/main/java/com/mattermost/rnutils/RNUtilsModuleImpl.kt index 60c2921e7..250ec3c45 100644 --- a/libraries/@mattermost/rnutils/android/src/main/java/com/mattermost/rnutils/RNUtilsModuleImpl.kt +++ b/libraries/@mattermost/rnutils/android/src/main/java/com/mattermost/rnutils/RNUtilsModuleImpl.kt @@ -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) diff --git a/patches/react-native-keyboard-aware-scroll-view+0.9.5.patch b/patches/react-native-keyboard-aware-scroll-view+0.9.5.patch new file mode 100644 index 000000000..791a3260a --- /dev/null +++ b/patches/react-native-keyboard-aware-scroll-view+0.9.5.patch @@ -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 }