Skip to content

Commit

Permalink
Merge pull request #34254 from suneox/33546-visual-viewport-deplay
Browse files Browse the repository at this point in the history
33546 visual viewport deplay
  • Loading branch information
techievivek authored Feb 8, 2024
2 parents afa88d4 + e6511f1 commit 02f0613
Show file tree
Hide file tree
Showing 2 changed files with 63 additions and 3 deletions.
2 changes: 1 addition & 1 deletion src/components/ScreenWrapper.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ function ScreenWrapper(
*/
const navigationFallback = useNavigation<StackNavigationProp<RootStackParamList>>();
const navigation = navigationProp ?? navigationFallback;
const {windowHeight, isSmallScreenWidth} = useWindowDimensions();
const {windowHeight, isSmallScreenWidth} = useWindowDimensions(shouldEnableMaxHeight);
const {initialHeight} = useInitialDimensions();
const styles = useThemeStyles();
const keyboardState = useKeyboardState();
Expand Down
64 changes: 62 additions & 2 deletions src/hooks/useWindowDimensions/index.ts
Original file line number Diff line number Diff line change
@@ -1,23 +1,83 @@
import {useEffect, useRef, useState} from 'react';
// eslint-disable-next-line no-restricted-imports
import {Dimensions, useWindowDimensions} from 'react-native';
import * as Browser from '@libs/Browser';
import variables from '@styles/variables';
import type WindowDimensions from './types';

const initalViewportHeight = window.visualViewport?.height ?? window.innerHeight;
const tagNamesOpenKeyboard = ['INPUT', 'TEXTAREA'];

/**
* A convenience wrapper around React Native's useWindowDimensions hook that also provides booleans for our breakpoints.
*/
export default function (): WindowDimensions {
export default function (useCachedViewportHeight = false): WindowDimensions {
const isCachedViewportHeight = useCachedViewportHeight && Browser.isMobileSafari();
const cachedViewportHeightWithKeyboardRef = useRef(initalViewportHeight);
const {width: windowWidth, height: windowHeight} = useWindowDimensions();

// When the soft keyboard opens on mWeb, the window height changes. Use static screen height instead to get real screenHeight.
const screenHeight = Dimensions.get('screen').height;
const isExtraSmallScreenHeight = screenHeight <= variables.extraSmallMobileResponsiveHeightBreakpoint;
const isSmallScreenWidth = windowWidth <= variables.mobileResponsiveWidthBreakpoint;
const isMediumScreenWidth = windowWidth > variables.mobileResponsiveWidthBreakpoint && windowWidth <= variables.tabletResponsiveWidthBreakpoint;
const isLargeScreenWidth = windowWidth > variables.tabletResponsiveWidthBreakpoint;

const [cachedViewportHeight, setCachedViewportHeight] = useState(windowHeight);

const handleFocusIn = useRef((event: FocusEvent) => {
const targetElement = event.target as HTMLElement;
if (tagNamesOpenKeyboard.includes(targetElement.tagName)) {
setCachedViewportHeight(cachedViewportHeightWithKeyboardRef.current);
}
});

useEffect(() => {
if (!isCachedViewportHeight) {
return;
}
window.addEventListener('focusin', handleFocusIn.current);
return () => {
// eslint-disable-next-line react-hooks/exhaustive-deps
window.removeEventListener('focusin', handleFocusIn.current);
};
}, [isCachedViewportHeight]);

const handleFocusOut = useRef((event: FocusEvent) => {
const targetElement = event.target as HTMLElement;
if (tagNamesOpenKeyboard.includes(targetElement.tagName)) {
setCachedViewportHeight(initalViewportHeight);
}
});

useEffect(() => {
if (!isCachedViewportHeight) {
return;
}
window.addEventListener('focusout', handleFocusOut.current);
return () => {
// eslint-disable-next-line react-hooks/exhaustive-deps
window.removeEventListener('focusout', handleFocusOut.current);
};
}, [isCachedViewportHeight]);

useEffect(() => {
if (!isCachedViewportHeight && windowHeight >= cachedViewportHeightWithKeyboardRef.current) {
return;
}
setCachedViewportHeight(windowHeight);
}, [windowHeight, isCachedViewportHeight]);

useEffect(() => {
if (!isCachedViewportHeight || !window.matchMedia('(orientation: portrait)').matches || windowHeight >= initalViewportHeight) {
return;
}
cachedViewportHeightWithKeyboardRef.current = windowHeight;
}, [isCachedViewportHeight, windowHeight]);

return {
windowWidth,
windowHeight,
windowHeight: isCachedViewportHeight ? cachedViewportHeight : windowHeight,
isExtraSmallScreenHeight,
isSmallScreenWidth,
isMediumScreenWidth,
Expand Down

0 comments on commit 02f0613

Please sign in to comment.