From 60499ea8437568566d4c2972b7ea388b3d4db169 Mon Sep 17 00:00:00 2001 From: NagaraniKaleeswaran Date: Sat, 27 Sep 2025 19:22:33 +0530 Subject: [PATCH] Fix: scroll to bottom when error appears after content size change --- src/components/BookTravelButton.tsx | 20 +++++++++++--------- src/pages/Travel/ManageTrips.tsx | 15 +++++---------- 2 files changed, 16 insertions(+), 19 deletions(-) diff --git a/src/components/BookTravelButton.tsx b/src/components/BookTravelButton.tsx index aec67792600a..8d7b57f300cf 100644 --- a/src/components/BookTravelButton.tsx +++ b/src/components/BookTravelButton.tsx @@ -1,7 +1,7 @@ import {emailSelector} from '@selectors/Session'; import {Str} from 'expensify-common'; import type {ReactElement} from 'react'; -import React, {useCallback, useEffect, useState} from 'react'; +import React, {useCallback, useState} from 'react'; import useCurrentUserPersonalDetails from '@hooks/useCurrentUserPersonalDetails'; import useEnvironment from '@hooks/useEnvironment'; import useLocalize from '@hooks/useLocalize'; @@ -74,12 +74,13 @@ function BookTravelButton({text, shouldRenderErrorMessageBelowButton = false, se const hidePreventionModal = () => setPreventionModalVisibility(false); const hideVerificationModal = () => setVerificationModalVisibility(false); - useEffect(() => { - if (!errorMessage) { - return; - } - setShouldScrollToBottom?.(true); - }, [errorMessage, setShouldScrollToBottom]); + const showError = useCallback( + (msg: string | ReactElement) => { + setErrorMessage(msg); + setShouldScrollToBottom?.(true); + }, + [setShouldScrollToBottom], + ); const bookATrip = useCallback(() => { setErrorMessage(''); @@ -91,7 +92,7 @@ function BookTravelButton({text, shouldRenderErrorMessageBelowButton = false, se // The primary login of the user is where Spotnana sends the emails with booking confirmations, itinerary etc. It can't be a phone number. if (!primaryContactMethod || Str.isSMSLogin(primaryContactMethod)) { - setErrorMessage(); + showError(); return; } @@ -107,7 +108,7 @@ function BookTravelButton({text, shouldRenderErrorMessageBelowButton = false, se } if (!isPaidGroupPolicy(policy)) { - setErrorMessage(translate('travel.termsAndConditions.defaultWorkspaceError')); + showError(translate('travel.termsAndConditions.defaultWorkspaceError')); return; } @@ -147,6 +148,7 @@ function BookTravelButton({text, shouldRenderErrorMessageBelowButton = false, se translate, isUserValidated, phoneErrorMethodsRoute, + showError, ]); return ( diff --git a/src/pages/Travel/ManageTrips.tsx b/src/pages/Travel/ManageTrips.tsx index 024d5ae37f72..629f1bb4af5a 100644 --- a/src/pages/Travel/ManageTrips.tsx +++ b/src/pages/Travel/ManageTrips.tsx @@ -1,7 +1,7 @@ -import React, {useEffect, useRef, useState} from 'react'; +import React, {useCallback, useRef, useState} from 'react'; // eslint-disable-next-line no-restricted-imports import type {ScrollView as RNScrollView} from 'react-native'; -import {InteractionManager, Linking, View} from 'react-native'; +import {Linking, View} from 'react-native'; import BookTravelButton from '@components/BookTravelButton'; import Button from '@components/Button'; import type {FeatureListItem} from '@components/FeatureList'; @@ -38,17 +38,11 @@ function ManageTrips() { const scrollViewRef = useRef(null); - const scrollToBottom = () => { - InteractionManager.runAfterInteractions(() => { - scrollViewRef.current?.scrollToEnd({animated: true}); - }); - }; - - useEffect(() => { + const handleOnContentSizeChange = useCallback(() => { if (!shouldScrollToBottom) { return; } - scrollToBottom(); + scrollViewRef.current?.scrollToEnd({animated: true}); setShouldScrollToBottom(false); }, [shouldScrollToBottom]); @@ -56,6 +50,7 @@ function ManageTrips() {