diff --git a/src/pages/home/report/ReportActionsList.tsx b/src/pages/home/report/ReportActionsList.tsx index 707c016c130b..8b6e20029c13 100644 --- a/src/pages/home/report/ReportActionsList.tsx +++ b/src/pages/home/report/ReportActionsList.tsx @@ -189,6 +189,7 @@ function ReportActionsList({ const lastMessageTime = useRef(null); const [isVisible, setIsVisible] = useState(Visibility.isVisible); const isFocused = useIsFocused(); + const [pendingBottomScroll, setPendingBottomScroll] = useState(false); const [reportNameValuePairs] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT_NAME_VALUE_PAIRS}${report?.reportID}`); const [accountID] = useOnyx(ONYXKEYS.SESSION, {selector: (session) => session?.accountID}); @@ -443,23 +444,47 @@ function ReportActionsList({ // eslint-disable-next-line react-compiler/react-compiler, react-hooks/exhaustive-deps }, []); + const isNewMessageDisplayed = useMemo(() => { + const prevActions = Object.values(prevSortedVisibleReportActionsObjects); + const lastPrevVisibleAction = prevActions.at(0); + return lastAction?.reportActionID !== lastPrevVisibleAction?.reportActionID; + }, [prevSortedVisibleReportActionsObjects, lastAction]); + const scrollToBottomForCurrentUserAction = useCallback( (isFromCurrentUser: boolean) => { + // If a new comment is added and it's from the current user scroll to the bottom otherwise leave the user positioned where + // they are now in the list. + if (!isFromCurrentUser || scrollingVerticalOffset.current === 0 || !isReportScreenTopmostCentralPane()) { + return; + } + if (!hasNewestReportActionRef.current) { + Navigation.navigate(ROUTES.REPORT_WITH_ID.getRoute(report.reportID)); + return; + } + if (!isNewMessageDisplayed) { + setPendingBottomScroll(true); + } else { + InteractionManager.runAfterInteractions(() => { + reportScrollManager.scrollToBottom(); + }); + } + }, + [reportScrollManager, report.reportID, isNewMessageDisplayed], + ); + + useEffect(() => { + if (!pendingBottomScroll || scrollingVerticalOffset.current === 0) { + return; + } + + if (isNewMessageDisplayed) { InteractionManager.runAfterInteractions(() => { - // If a new comment is added and it's from the current user scroll to the bottom otherwise leave the user positioned where - // they are now in the list. - if (!isFromCurrentUser || !isReportScreenTopmostCentralPane()) { - return; - } - if (!hasNewestReportActionRef.current) { - Navigation.navigate(ROUTES.REPORT_WITH_ID.getRoute(report.reportID)); - return; - } reportScrollManager.scrollToBottom(); + setPendingBottomScroll(false); }); - }, - [reportScrollManager, report.reportID], - ); + } + }, [pendingBottomScroll, reportScrollManager, isNewMessageDisplayed]); + useEffect(() => { // Why are we doing this, when in the cleanup of the useEffect we are already calling the unsubscribe function? // Answer: On web, when navigating to another report screen, the previous report screen doesn't get unmounted,