diff --git a/src/CONST.ts b/src/CONST.ts
index c29a7c51e6ef..4024158d0805 100755
--- a/src/CONST.ts
+++ b/src/CONST.ts
@@ -2879,9 +2879,6 @@ const CONST = {
*/
ADDITIONAL_ALLOWED_CHARACTERS: 20,
- /** types that will show a virtual keyboard in a mobile browser */
- INPUT_TYPES_WITH_KEYBOARD: ['text', 'search', 'tel', 'url', 'email', 'password'],
-
REFERRAL_PROGRAM: {
CONTENT_TYPES: {
MONEY_REQUEST: 'request',
diff --git a/src/components/SwipeableView/index.native.tsx b/src/components/SwipeableView/index.native.tsx
index 07f1d785d0a6..91d851101d4e 100644
--- a/src/components/SwipeableView/index.native.tsx
+++ b/src/components/SwipeableView/index.native.tsx
@@ -3,40 +3,30 @@ import {PanResponder, View} from 'react-native';
import CONST from '@src/CONST';
import SwipeableViewProps from './types';
-function SwipeableView({children, onSwipeDown, onSwipeUp}: SwipeableViewProps) {
+function SwipeableView({children, onSwipeDown}: SwipeableViewProps) {
const minimumPixelDistance = CONST.COMPOSER_MAX_HEIGHT;
const oldYRef = useRef(0);
- const directionRef = useRef<'UP' | 'DOWN' | null>(null);
-
const panResponder = useRef(
PanResponder.create({
- onMoveShouldSetPanResponderCapture: (event, gestureState) => {
+ // The PanResponder gets focus only when the y-axis movement is over minimumPixelDistance & swipe direction is downwards
+ // eslint-disable-next-line @typescript-eslint/naming-convention
+ onMoveShouldSetPanResponderCapture: (_event, gestureState) => {
if (gestureState.dy - oldYRef.current > 0 && gestureState.dy > minimumPixelDistance) {
- directionRef.current = 'DOWN';
- return true;
- }
-
- if (gestureState.dy - oldYRef.current < 0 && Math.abs(gestureState.dy) > minimumPixelDistance) {
- directionRef.current = 'UP';
return true;
}
oldYRef.current = gestureState.dy;
return false;
},
- onPanResponderRelease: () => {
- if (directionRef.current === 'DOWN' && onSwipeDown) {
- onSwipeDown();
- } else if (directionRef.current === 'UP' && onSwipeUp) {
- onSwipeUp();
- }
- directionRef.current = null; // Reset the direction after the gesture completes
- },
+ // Calls the callback when the swipe down is released; after the completion of the gesture
+ onPanResponderRelease: onSwipeDown,
}),
).current;
- // eslint-disable-next-line react/jsx-props-no-spreading
- return {children};
+ return (
+ // eslint-disable-next-line react/jsx-props-no-spreading
+ {children}
+ );
}
SwipeableView.displayName = 'SwipeableView';
diff --git a/src/components/SwipeableView/index.tsx b/src/components/SwipeableView/index.tsx
index 478935173841..335c3e7dcf03 100644
--- a/src/components/SwipeableView/index.tsx
+++ b/src/components/SwipeableView/index.tsx
@@ -1,77 +1,4 @@
-import React, {useEffect, useRef} from 'react';
-import {View} from 'react-native';
-import DomUtils from '@libs/DomUtils';
import SwipeableViewProps from './types';
-// Min delta y in px to trigger swipe
-const MIN_DELTA_Y = 25;
-
-function SwipeableView({onSwipeUp, onSwipeDown, style, children}: SwipeableViewProps) {
- const ref = useRef(null);
- const scrollableChildRef = useRef(null);
- const startY = useRef(0);
- const isScrolling = useRef(false);
-
- useEffect(() => {
- if (!ref.current) {
- return;
- }
-
- const element = ref.current as unknown as HTMLElement;
-
- const handleTouchStart = (event: TouchEvent) => {
- startY.current = event.touches[0].clientY;
- };
-
- const handleTouchEnd = (event: TouchEvent) => {
- const deltaY = event.changedTouches[0].clientY - startY.current;
- const isSelecting = DomUtils.isActiveTextSelection();
- let canSwipeDown = true;
- let canSwipeUp = true;
- if (scrollableChildRef.current) {
- canSwipeUp = scrollableChildRef.current.scrollHeight - scrollableChildRef.current.scrollTop === scrollableChildRef.current.clientHeight;
- canSwipeDown = scrollableChildRef.current.scrollTop === 0;
- }
-
- if (deltaY > MIN_DELTA_Y && onSwipeDown && !isSelecting && canSwipeDown && !isScrolling.current) {
- onSwipeDown();
- }
-
- if (deltaY < -MIN_DELTA_Y && onSwipeUp && !isSelecting && canSwipeUp && !isScrolling.current) {
- onSwipeUp();
- }
- isScrolling.current = false;
- };
-
- const handleScroll = (event: Event) => {
- isScrolling.current = true;
- if (!event.target || scrollableChildRef.current) {
- return;
- }
- scrollableChildRef.current = event.target as HTMLElement;
- };
-
- element.addEventListener('touchstart', handleTouchStart);
- element.addEventListener('touchend', handleTouchEnd);
- element.addEventListener('scroll', handleScroll, true);
-
- return () => {
- element.removeEventListener('touchstart', handleTouchStart);
- element.removeEventListener('touchend', handleTouchEnd);
- element.removeEventListener('scroll', handleScroll);
- };
- }, [onSwipeDown, onSwipeUp]);
-
- return (
-
- {children}
-
- );
-}
-
-SwipeableView.displayName = 'SwipeableView';
-
-export default SwipeableView;
+// Swipeable View is available just on Android/iOS for now.
+export default ({children}: SwipeableViewProps) => children;
diff --git a/src/components/SwipeableView/types.ts b/src/components/SwipeableView/types.ts
index 1f2fbcdc752c..560df7ef5a45 100644
--- a/src/components/SwipeableView/types.ts
+++ b/src/components/SwipeableView/types.ts
@@ -1,18 +1,11 @@
import {ReactNode} from 'react';
-import {StyleProp, ViewStyle} from 'react-native';
type SwipeableViewProps = {
/** The content to be rendered within the SwipeableView */
children: ReactNode;
/** Callback to fire when the user swipes down on the child content */
- onSwipeDown?: () => void;
-
- /** Callback to fire when the user swipes up on the child content */
- onSwipeUp?: () => void;
-
- /** Style for the wrapper View, applied only for the web version. Not used by the native version, as it brakes the layout. */
- style?: StyleProp;
+ onSwipeDown: () => void;
};
export default SwipeableViewProps;
diff --git a/src/hooks/useBlockViewportScroll/index.native.ts b/src/hooks/useBlockViewportScroll/index.native.ts
deleted file mode 100644
index 59ee34b1c9f6..000000000000
--- a/src/hooks/useBlockViewportScroll/index.native.ts
+++ /dev/null
@@ -1,15 +0,0 @@
-/**
- * A hook that blocks viewport scroll when the keyboard is visible.
- * It does this by capturing the current scrollY position when the keyboard is shown, then scrolls back to this position smoothly on 'touchend' event.
- * This scroll blocking is removed when the keyboard hides.
- * This hook is doing nothing on native platforms.
- *
- * @example
- * useBlockViewportScroll();
- */
-function useBlockViewportScroll() {
- // This hook is doing nothing on native platforms.
- // Check index.ts for web implementation.
-}
-
-export default useBlockViewportScroll;
diff --git a/src/hooks/useBlockViewportScroll/index.ts b/src/hooks/useBlockViewportScroll/index.ts
deleted file mode 100644
index 5766d59f2bdd..000000000000
--- a/src/hooks/useBlockViewportScroll/index.ts
+++ /dev/null
@@ -1,43 +0,0 @@
-import {useEffect, useRef} from 'react';
-import Keyboard from '@libs/NativeWebKeyboard';
-
-/**
- * A hook that blocks viewport scroll when the keyboard is visible.
- * It does this by capturing the current scrollY position when the keyboard is shown, then scrolls back to this position smoothly on 'touchend' event.
- * This scroll blocking is removed when the keyboard hides.
- * This hook is doing nothing on native platforms.
- *
- * @example
- * useBlockViewportScroll();
- */
-function useBlockViewportScroll() {
- const optimalScrollY = useRef(0);
- const keyboardShowListenerRef = useRef(() => {});
- const keyboardHideListenerRef = useRef(() => {});
-
- useEffect(() => {
- const handleTouchEnd = () => {
- window.scrollTo({top: optimalScrollY.current, behavior: 'smooth'});
- };
-
- const handleKeybShow = () => {
- optimalScrollY.current = window.scrollY;
- window.addEventListener('touchend', handleTouchEnd);
- };
-
- const handleKeybHide = () => {
- window.removeEventListener('touchend', handleTouchEnd);
- };
-
- keyboardShowListenerRef.current = Keyboard.addListener('keyboardDidShow', handleKeybShow);
- keyboardHideListenerRef.current = Keyboard.addListener('keyboardDidHide', handleKeybHide);
-
- return () => {
- keyboardShowListenerRef.current();
- keyboardHideListenerRef.current();
- window.removeEventListener('touchend', handleTouchEnd);
- };
- }, []);
-}
-
-export default useBlockViewportScroll;
diff --git a/src/libs/DomUtils/index.native.ts b/src/libs/DomUtils/index.native.ts
index 8af83968e8d1..0864f1a16ac0 100644
--- a/src/libs/DomUtils/index.native.ts
+++ b/src/libs/DomUtils/index.native.ts
@@ -2,21 +2,6 @@ import GetActiveElement from './types';
const getActiveElement: GetActiveElement = () => null;
-/**
- * Checks if there is a text selection within the currently focused input or textarea element.
- *
- * This function determines whether the currently focused element is an input or textarea,
- * and if so, it checks whether there is a text selection (i.e., whether the start and end
- * of the selection are at different positions). It assumes that only inputs and textareas
- * can have text selections.
- * Works only on web. Throws an error on native.
- *
- * @returns True if there is a text selection within the focused element, false otherwise.
- */
-const isActiveTextSelection = () => {
- throw new Error('Not implemented in React Native. Use only for web.');
-};
-
const requestAnimationFrame = (callback: () => void) => {
if (!callback) {
return;
@@ -27,6 +12,5 @@ const requestAnimationFrame = (callback: () => void) => {
export default {
getActiveElement,
- isActiveTextSelection,
requestAnimationFrame,
};
diff --git a/src/libs/DomUtils/index.ts b/src/libs/DomUtils/index.ts
index 78c2cb37ccc8..6a2eed57fbe6 100644
--- a/src/libs/DomUtils/index.ts
+++ b/src/libs/DomUtils/index.ts
@@ -2,30 +2,7 @@ import GetActiveElement from './types';
const getActiveElement: GetActiveElement = () => document.activeElement;
-/**
- * Checks if there is a text selection within the currently focused input or textarea element.
- *
- * This function determines whether the currently focused element is an input or textarea,
- * and if so, it checks whether there is a text selection (i.e., whether the start and end
- * of the selection are at different positions). It assumes that only inputs and textareas
- * can have text selections.
- * Works only on web. Throws an error on native.
- *
- * @returns True if there is a text selection within the focused element, false otherwise.
- */
-const isActiveTextSelection = (): boolean => {
- const focused = document.activeElement as HTMLInputElement | HTMLTextAreaElement | null;
- if (!focused) {
- return false;
- }
- if (typeof focused.selectionStart === 'number' && typeof focused.selectionEnd === 'number') {
- return focused.selectionStart !== focused.selectionEnd;
- }
- return false;
-};
-
export default {
getActiveElement,
- isActiveTextSelection,
requestAnimationFrame: window.requestAnimationFrame.bind(window),
};
diff --git a/src/libs/NativeWebKeyboard/index.native.ts b/src/libs/NativeWebKeyboard/index.native.ts
deleted file mode 100644
index 404bd58075d4..000000000000
--- a/src/libs/NativeWebKeyboard/index.native.ts
+++ /dev/null
@@ -1,3 +0,0 @@
-import {Keyboard} from 'react-native';
-
-export default Keyboard;
diff --git a/src/libs/NativeWebKeyboard/index.ts b/src/libs/NativeWebKeyboard/index.ts
deleted file mode 100644
index 45223d4d5b42..000000000000
--- a/src/libs/NativeWebKeyboard/index.ts
+++ /dev/null
@@ -1,136 +0,0 @@
-import {Keyboard} from 'react-native';
-import CONST from '@src/CONST';
-
-type InputType = (typeof CONST.INPUT_TYPES_WITH_KEYBOARD)[number];
-type TCallbackFn = () => void;
-
-const isInputKeyboardType = (element: Element | null): boolean => {
- if (element && ((element.tagName === 'INPUT' && CONST.INPUT_TYPES_WITH_KEYBOARD.includes((element as HTMLInputElement).type as InputType)) || element.tagName === 'TEXTAREA')) {
- return true;
- }
- return false;
-};
-
-const isVisible = (): boolean => {
- const focused = document.activeElement;
- return isInputKeyboardType(focused);
-};
-
-const nullFn: () => null = () => null;
-
-let isKeyboardListenerRunning = false;
-let currentVisibleElement: Element | null = null;
-const showListeners: TCallbackFn[] = [];
-const hideListeners: TCallbackFn[] = [];
-const visualViewport = window.visualViewport ?? {
- height: window.innerHeight,
- width: window.innerWidth,
- addEventListener: window.addEventListener.bind(window),
- removeEventListener: window.removeEventListener.bind(window),
-};
-let previousVPHeight = visualViewport.height;
-
-const handleViewportResize = (): void => {
- if (visualViewport.height < previousVPHeight) {
- if (isInputKeyboardType(document.activeElement) && document.activeElement !== currentVisibleElement) {
- showListeners.forEach((fn) => fn());
- }
- }
-
- if (visualViewport.height > previousVPHeight) {
- if (!isVisible()) {
- hideListeners.forEach((fn) => fn());
- }
- }
-
- previousVPHeight = visualViewport.height;
- currentVisibleElement = document.activeElement;
-};
-
-const startKeboardListeningService = (): void => {
- isKeyboardListenerRunning = true;
- visualViewport.addEventListener('resize', handleViewportResize);
-};
-
-const addListener = (eventName: 'keyboardDidShow' | 'keyboardDidHide', callbackFn: TCallbackFn): (() => void) => {
- if ((eventName !== 'keyboardDidShow' && eventName !== 'keyboardDidHide') || !callbackFn) {
- throw new Error('Invalid eventName passed to addListener()');
- }
-
- if (eventName === 'keyboardDidShow') {
- showListeners.push(callbackFn);
- }
-
- if (eventName === 'keyboardDidHide') {
- hideListeners.push(callbackFn);
- }
-
- if (!isKeyboardListenerRunning) {
- startKeboardListeningService();
- }
-
- return () => {
- if (eventName === 'keyboardDidShow') {
- showListeners.filter((fn) => fn !== callbackFn);
- }
-
- if (eventName === 'keyboardDidHide') {
- hideListeners.filter((fn) => fn !== callbackFn);
- }
-
- if (isKeyboardListenerRunning && !showListeners.length && !hideListeners.length) {
- visualViewport.removeEventListener('resize', handleViewportResize);
- isKeyboardListenerRunning = false;
- }
- };
-};
-
-export default {
- /**
- * Whether the keyboard is last known to be visible.
- */
- isVisible,
- /**
- * Dismisses the active keyboard and removes focus.
- */
- dismiss: Keyboard.dismiss,
- /**
- * The `addListener` function connects a JavaScript function to an identified native
- * keyboard notification event.
- *
- * This function then returns the reference to the listener.
- *
- * {string} eventName The `nativeEvent` is the string that identifies the event you're listening for. This
- * can be any of the following:
- *
- * - `keyboardWillShow`
- * - `keyboardDidShow`
- * - `keyboardWillHide`
- * - `keyboardDidHide`
- * - `keyboardWillChangeFrame`
- * - `keyboardDidChangeFrame`
- *
- * Note that if you set `android:windowSoftInputMode` to `adjustResize` or `adjustNothing`,
- * only `keyboardDidShow` and `keyboardDidHide` events will be available on Android.
- * `keyboardWillShow` as well as `keyboardWillHide` are generally not available on Android
- * since there is no native corresponding event.
- *
- * On Web only two events are available:
- *
- * - `keyboardDidShow`
- * - `keyboardDidHide`
- *
- * {function} callback function to be called when the event fires.
- */
- addListener,
- /**
- * Useful for syncing TextInput (or other keyboard accessory view) size of
- * position changes with keyboard movements.
- * Not working on web.
- */
- scheduleLayoutAnimation: nullFn,
- /**
- * Return the metrics of the soft-keyboard if visible. Currently not working on web.
- */
- metrics: nullFn,
-};
diff --git a/src/pages/home/ReportScreen.js b/src/pages/home/ReportScreen.js
index 09d147b05f69..649bcee6da18 100644
--- a/src/pages/home/ReportScreen.js
+++ b/src/pages/home/ReportScreen.js
@@ -15,7 +15,6 @@ import ScreenWrapper from '@components/ScreenWrapper';
import TaskHeaderActionButton from '@components/TaskHeaderActionButton';
import withCurrentReportID, {withCurrentReportIDDefaultProps, withCurrentReportIDPropTypes} from '@components/withCurrentReportID';
import withViewportOffsetTop from '@components/withViewportOffsetTop';
-import useBlockViewportScroll from '@hooks/useBlockViewportScroll';
import useLocalize from '@hooks/useLocalize';
import usePrevious from '@hooks/usePrevious';
import useWindowDimensions from '@hooks/useWindowDimensions';
@@ -151,7 +150,6 @@ function ReportScreen({
const styles = useThemeStyles();
const {translate} = useLocalize();
const {isSmallScreenWidth} = useWindowDimensions();
- useBlockViewportScroll();
const firstRenderRef = useRef(true);
const flatListRef = useRef();
diff --git a/src/pages/home/report/ReportFooter.js b/src/pages/home/report/ReportFooter.js
index 9f973674d6a7..e5dd5da19ad5 100644
--- a/src/pages/home/report/ReportFooter.js
+++ b/src/pages/home/report/ReportFooter.js
@@ -92,10 +92,7 @@ function ReportFooter(props) {
)}
{!hideComposer && (props.shouldShowComposeInput || !props.isSmallScreenWidth) && (
-
+