Skip to content

Commit

Permalink
handle visual viewport scroll incorrect on chrome ios
Browse files Browse the repository at this point in the history
  • Loading branch information
suneox committed Jul 8, 2024
1 parent 2bf0359 commit 6364bc0
Show file tree
Hide file tree
Showing 6 changed files with 27 additions and 7 deletions.
9 changes: 8 additions & 1 deletion src/hooks/useTackInputFocus/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import {useCallback, useEffect} from 'react';
import useDebouncedState from '@hooks/useDebouncedState';
import * as Browser from '@libs/Browser';

/**
* Detects input or text area focus on browsers, to avoid scrolling on virtual viewports
Expand Down Expand Up @@ -28,7 +29,13 @@ export default function useTackInputFocus(enable = false): boolean {
);

const resetScrollPositionOnVisualViewport = useCallback(() => {
window.scrollTo({top: 0});
if (Browser.isChromeIOS() && window.visualViewport?.offsetTop) {
// On Chrome iOS, the visual viewport triggers a scroll event when the keyboard is opened, but some time the scroll position is not correct.
// So this change is specific to Chrome iOS, helping to reset the viewport position correctly.
window.scrollTo({top: -window.visualViewport.offsetTop});
} else {
window.scrollTo({top: 0});
}
}, []);

useEffect(() => {
Expand Down
2 changes: 1 addition & 1 deletion src/hooks/useWindowDimensions/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ export default function (useCachedViewportHeight = false): WindowDimensions {
unlockWindowDimensions: () => {},
};

const isCachedViewportHeight = useCachedViewportHeight && Browser.isMobileSafari();
const isCachedViewportHeight = useCachedViewportHeight && Browser.isMobileWebKit();
const cachedViewportHeightWithKeyboardRef = useRef(initalViewportHeight);
const {width: windowWidth, height: windowHeight} = useWindowDimensions();

Expand Down
6 changes: 4 additions & 2 deletions src/libs/Browser/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type {GetBrowser, IsMobile, IsMobileChrome, IsMobileSafari, IsMobileWebKit, IsSafari, OpenRouteInDesktopApp} from './types';
import type {GetBrowser, IsChromeIOS, IsMobile, IsMobileChrome, IsMobileSafari, IsMobileWebKit, IsSafari, OpenRouteInDesktopApp} from './types';

const getBrowser: GetBrowser = () => '';

Expand All @@ -10,8 +10,10 @@ const isMobileChrome: IsMobileChrome = () => false;

const isMobileWebKit: IsMobileWebKit = () => false;

const isChromeIOS: IsChromeIOS = () => false;

const isSafari: IsSafari = () => false;

const openRouteInDesktopApp: OpenRouteInDesktopApp = () => {};

export {getBrowser, isMobile, isMobileSafari, isMobileWebKit, isSafari, isMobileChrome, openRouteInDesktopApp};
export {getBrowser, isMobile, isMobileSafari, isMobileWebKit, isSafari, isMobileChrome, isChromeIOS, openRouteInDesktopApp};
12 changes: 10 additions & 2 deletions src/libs/Browser/index.website.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import CONFIG from '@src/CONFIG';
import CONST from '@src/CONST';
import ROUTES from '@src/ROUTES';
import type {GetBrowser, IsMobile, IsMobileChrome, IsMobileSafari, IsMobileWebKit, IsSafari, OpenRouteInDesktopApp} from './types';
import type {GetBrowser, IsChromeIOS, IsMobile, IsMobileChrome, IsMobileSafari, IsMobileWebKit, IsSafari, OpenRouteInDesktopApp} from './types';

/**
* Fetch browser name from UA string
Expand Down Expand Up @@ -66,6 +66,14 @@ const isMobileWebKit: IsMobileWebKit = () => {
return /iP(ad|od|hone)/i.test(userAgent) && /WebKit/i.test(userAgent);
};

/**
* Checks if the requesting user agent is a Chrome browser on an iOS mobile device.
*/
const isChromeIOS: IsChromeIOS = () => {
const userAgent = navigator.userAgent;
return /iP(ad|od|hone)/i.test(userAgent) && /CriOS/i.test(userAgent);
};

const isSafari: IsSafari = () => getBrowser() === 'safari' || isMobileSafari();

/**
Expand Down Expand Up @@ -109,4 +117,4 @@ const openRouteInDesktopApp: OpenRouteInDesktopApp = (shortLivedAuthToken = '',
}
};

export {getBrowser, isMobile, isMobileSafari, isMobileWebKit, isSafari, isMobileChrome, openRouteInDesktopApp};
export {getBrowser, isMobile, isMobileSafari, isMobileWebKit, isSafari, isMobileChrome, isChromeIOS, openRouteInDesktopApp};
4 changes: 3 additions & 1 deletion src/libs/Browser/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,10 @@ type IsMobileChrome = () => boolean;

type IsMobileWebKit = () => boolean;

type IsChromeIOS = () => boolean;

type IsSafari = () => boolean;

type OpenRouteInDesktopApp = (shortLivedAuthToken?: string, email?: string) => void;

export type {GetBrowser, IsMobile, IsMobileSafari, IsMobileChrome, IsMobileWebKit, IsSafari, OpenRouteInDesktopApp};
export type {GetBrowser, IsMobile, IsMobileSafari, IsMobileChrome, IsMobileWebKit, IsSafari, IsChromeIOS, OpenRouteInDesktopApp};
1 change: 1 addition & 0 deletions src/pages/signin/SignInPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -266,6 +266,7 @@ function SignInPage({credentials, account, activeClients = [], preferredLocale,
<ScreenWrapper
shouldShowOfflineIndicator={false}
shouldEnableMaxHeight={shouldEnableMaxHeight}
shouldUseCachedViewportHeight
style={[styles.signInPage, StyleUtils.getSafeAreaPadding({...safeAreaInsets, bottom: 0, top: isInNarrowPaneModal ? 0 : safeAreaInsets.top}, 1)]}
testID={SignInPageThemeWrapper.displayName}
>
Expand Down

0 comments on commit 6364bc0

Please sign in to comment.