diff --git a/src/hooks/useViewportOffsetTop/index.ts b/src/hooks/useViewportOffsetTop/index.ts index 56fb19187c4fe..da2325a7e13f5 100644 --- a/src/hooks/useViewportOffsetTop/index.ts +++ b/src/hooks/useViewportOffsetTop/index.ts @@ -1,4 +1,5 @@ -import {useEffect, useRef, useState} from 'react'; +import {useCallback, useEffect, useRef, useState} from 'react'; +import * as Browser from '@libs/Browser'; import addViewportResizeListener from '@libs/VisualViewport'; /** @@ -6,17 +7,18 @@ import addViewportResizeListener from '@libs/VisualViewport'; */ export default function useViewportOffsetTop(shouldAdjustScrollView = false): number { const [viewportOffsetTop, setViewportOffsetTop] = useState(0); - const initialHeight = useRef(window.visualViewport?.height ?? window.innerHeight).current; const cachedDefaultOffsetTop = useRef(0); - useEffect(() => { - const updateOffsetTop = (event?: Event) => { + + const updateOffsetTop = useCallback( + (event?: Event) => { let targetOffsetTop = window.visualViewport?.offsetTop ?? 0; if (event?.target instanceof VisualViewport) { targetOffsetTop = event.target.offsetTop; } - if (shouldAdjustScrollView && window.visualViewport) { - const adjustScrollY = Math.round(initialHeight - window.visualViewport.height); + if (Browser.isMobileSafari() && shouldAdjustScrollView && window.visualViewport) { + const clientHeight = document.body.clientHeight; + const adjustScrollY = Math.round(clientHeight - window.visualViewport.height); if (cachedDefaultOffsetTop.current === 0) { cachedDefaultOffsetTop.current = targetOffsetTop; } @@ -31,16 +33,17 @@ export default function useViewportOffsetTop(shouldAdjustScrollView = false): nu } else { setViewportOffsetTop(targetOffsetTop); } - }; - updateOffsetTop(); - return addViewportResizeListener(updateOffsetTop); - }, [initialHeight, shouldAdjustScrollView]); + }, + [shouldAdjustScrollView], + ); + + useEffect(() => addViewportResizeListener(updateOffsetTop), [updateOffsetTop]); useEffect(() => { if (!shouldAdjustScrollView) { return; } - window.scrollTo({top: viewportOffsetTop}); + window.scrollTo({top: viewportOffsetTop, behavior: 'instant'}); }, [shouldAdjustScrollView, viewportOffsetTop]); return viewportOffsetTop; diff --git a/src/pages/home/ReportScreen.tsx b/src/pages/home/ReportScreen.tsx index 940cba181db73..798c526c93cc8 100644 --- a/src/pages/home/ReportScreen.tsx +++ b/src/pages/home/ReportScreen.tsx @@ -27,7 +27,6 @@ import useThemeStyles from '@hooks/useThemeStyles'; import useViewportOffsetTop from '@hooks/useViewportOffsetTop'; import useWindowDimensions from '@hooks/useWindowDimensions'; import Timing from '@libs/actions/Timing'; -import * as Browser from '@libs/Browser'; import Navigation from '@libs/Navigation/Navigation'; import clearReportNotifications from '@libs/Notification/clearReportNotifications'; import Performance from '@libs/Performance'; @@ -275,7 +274,8 @@ function ReportScreen({ Performance.markStart(CONST.TIMING.CHAT_RENDER); } const [isComposerFocus, setIsComposerFocus] = useState(false); - const viewportOffsetTop = useViewportOffsetTop(Browser.isMobileSafari() && isComposerFocus && !modal?.willAlertModalBecomeVisible); + const shouldAdjustScrollView = useMemo(() => isComposerFocus && !modal?.willAlertModalBecomeVisible, [isComposerFocus, modal]); + const viewportOffsetTop = useViewportOffsetTop(shouldAdjustScrollView); const {reportPendingAction, reportErrors} = ReportUtils.getReportOfflinePendingActionAndErrors(report); const screenWrapperStyle: ViewStyle[] = [styles.appContent, styles.flex1, {marginTop: viewportOffsetTop}];