Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 0 additions & 3 deletions src/CONST.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2879,9 +2879,6 @@ const CONST = {
*/
ADDITIONAL_ALLOWED_CHARACTERS: 20,

/** <input /> 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',
Expand Down
30 changes: 10 additions & 20 deletions src/components/SwipeableView/index.native.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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 <View {...panResponder.panHandlers}>{children}</View>;
return (
// eslint-disable-next-line react/jsx-props-no-spreading
<View {...panResponder.panHandlers}>{children}</View>
);
}

SwipeableView.displayName = 'SwipeableView';
Expand Down
77 changes: 2 additions & 75 deletions src/components/SwipeableView/index.tsx
Original file line number Diff line number Diff line change
@@ -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<View | null>(null);
const scrollableChildRef = useRef<HTMLElement | null>(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 (
<View
ref={ref}
style={style}
>
{children}
</View>
);
}

SwipeableView.displayName = 'SwipeableView';

export default SwipeableView;
// Swipeable View is available just on Android/iOS for now.
export default ({children}: SwipeableViewProps) => children;
9 changes: 1 addition & 8 deletions src/components/SwipeableView/types.ts
Original file line number Diff line number Diff line change
@@ -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<ViewStyle>;
onSwipeDown: () => void;
};

export default SwipeableViewProps;
15 changes: 0 additions & 15 deletions src/hooks/useBlockViewportScroll/index.native.ts

This file was deleted.

43 changes: 0 additions & 43 deletions src/hooks/useBlockViewportScroll/index.ts

This file was deleted.

16 changes: 0 additions & 16 deletions src/libs/DomUtils/index.native.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -27,6 +12,5 @@ const requestAnimationFrame = (callback: () => void) => {

export default {
getActiveElement,
isActiveTextSelection,
requestAnimationFrame,
};
23 changes: 0 additions & 23 deletions src/libs/DomUtils/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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),
};
3 changes: 0 additions & 3 deletions src/libs/NativeWebKeyboard/index.native.ts

This file was deleted.

Loading