From 0b214f7f1c59b244b4e530377bb4707140377f02 Mon Sep 17 00:00:00 2001 From: Janic Duplessis Date: Sat, 27 Jul 2024 16:56:51 -0400 Subject: [PATCH 1/4] Fix mvcp on Android --- ...act-native+0.73.4+024+fixMVCPAndroid.patch | 334 ++++++++++++++++++ src/pages/home/report/ReportActionsView.tsx | 1 + 2 files changed, 335 insertions(+) create mode 100644 patches/react-native+0.73.4+024+fixMVCPAndroid.patch diff --git a/patches/react-native+0.73.4+024+fixMVCPAndroid.patch b/patches/react-native+0.73.4+024+fixMVCPAndroid.patch new file mode 100644 index 000000000000..fe37e38c3040 --- /dev/null +++ b/patches/react-native+0.73.4+024+fixMVCPAndroid.patch @@ -0,0 +1,334 @@ +diff --git a/node_modules/react-native/ReactAndroid/src/main/java/com/facebook/react/views/scroll/MaintainVisibleScrollPositionHelper.java b/node_modules/react-native/ReactAndroid/src/main/java/com/facebook/react/views/scroll/MaintainVisibleScrollPositionHelper.java +index fff761f..2cebd6b 100644 +--- a/node_modules/react-native/ReactAndroid/src/main/java/com/facebook/react/views/scroll/MaintainVisibleScrollPositionHelper.java ++++ b/node_modules/react-native/ReactAndroid/src/main/java/com/facebook/react/views/scroll/MaintainVisibleScrollPositionHelper.java +@@ -82,6 +82,7 @@ public class MaintainVisibleScrollPositionHelper currentScroll || i == contentView.getChildCount() - 1) { +- mFirstVisibleView = new WeakReference<>(child); +- Rect frame = new Rect(); +- child.getHitRect(frame); +- mPrevFirstVisibleFrame = frame; +- break; ++ if ((position > currentScroll && position < firstVisibleViewPosition) || ++ (firstVisibleView == null && i == contentView.getChildCount() - 1)) { ++ firstVisibleView = child; ++ firstVisibleViewPosition = position; ++ } ++ } ++ mFirstVisibleView = new WeakReference<>(firstVisibleView); ++ } ++ ++ private View getFirstVisibleView() { ++ return mFirstVisibleView != null ? mFirstVisibleView.get() : null; ++ } ++ ++ private void willMountItemsInternal() { ++ View firstVisibleView = getFirstVisibleView(); ++ ++ // If we don't have a first visible view because no scroll happened call onScroll ++ // to update it. ++ if (firstVisibleView == null) { ++ onScroll(); ++ firstVisibleView = getFirstVisibleView(); ++ ++ // There are cases where it is possible for this to still be null so just bail out. ++ if (firstVisibleView == null) { ++ return; + } + } ++ Rect frame = new Rect(); ++ firstVisibleView.getHitRect(frame); ++ mPrevFirstVisibleFrame = frame; + } + + // UIManagerListener +@@ -177,19 +205,19 @@ public class MaintainVisibleScrollPositionHelper Date: Thu, 25 Jul 2024 14:33:46 -0400 Subject: [PATCH 2/4] Fix newer messages not loading after comment linking --- src/pages/home/report/ReportActionsView.tsx | 15 +-------------- 1 file changed, 1 insertion(+), 14 deletions(-) diff --git a/src/pages/home/report/ReportActionsView.tsx b/src/pages/home/report/ReportActionsView.tsx index c608a3105675..f59539d97ad3 100755 --- a/src/pages/home/report/ReportActionsView.tsx +++ b/src/pages/home/report/ReportActionsView.tsx @@ -10,7 +10,6 @@ import useInitialValue from '@hooks/useInitialValue'; import useNetwork from '@hooks/useNetwork'; import usePrevious from '@hooks/usePrevious'; import useResponsiveLayout from '@hooks/useResponsiveLayout'; -import useWindowDimensions from '@hooks/useWindowDimensions'; import DateUtils from '@libs/DateUtils'; import getIsReportFullyVisible from '@libs/getIsReportFullyVisible'; import type {AuthScreensParamList} from '@libs/Navigation/types'; @@ -79,9 +78,6 @@ type ReportActionsViewProps = ReportActionsViewOnyxProps & { transactionThreadReportID?: string | null; }; -const DIFF_BETWEEN_SCREEN_HEIGHT_AND_LIST = 120; -const SPACER = 16; - let listOldID = Math.round(Math.random() * 100); function ReportActionsView({ @@ -114,7 +110,6 @@ function ReportActionsView({ const isFirstLinkedActionRender = useRef(true); const network = useNetwork(); - const {windowHeight} = useWindowDimensions(); const {shouldUseNarrowLayout} = useResponsiveLayout(); const contentListHeight = useRef(0); const isFocused = useIsFocused(); @@ -342,8 +337,6 @@ function ReportActionsView({ contentListHeight.current = h; }, []); - const checkIfContentSmallerThanList = useCallback(() => windowHeight - DIFF_BETWEEN_SCREEN_HEIGHT_AND_LIST - SPACER > contentListHeight.current, [windowHeight]); - /** * Retrieves the next set of report actions for the chat once we are nearing the end of what we are currently * displaying. @@ -397,10 +390,6 @@ function ReportActionsView({ const loadNewerChats = useCallback( (force = false) => { - // Determines if loading older reports is necessary when the content is smaller than the list - // and there are fewer than 23 items, indicating we've reached the oldest message. - const isLoadingOlderReportsFirstNeeded = checkIfContentSmallerThanList() && reportActions.length > 23; - if ( !force && (!reportActionID || @@ -417,18 +406,16 @@ function ReportActionsView({ didLoadNewerChats.current = true; - if ((reportActionID && indexOfLinkedAction > -1 && !isLoadingOlderReportsFirstNeeded) || (!reportActionID && !isLoadingOlderReportsFirstNeeded)) { + if ((reportActionID && indexOfLinkedAction > -1) || !reportActionID) { handleReportActionPagination({firstReportActionID: newestReportAction?.reportActionID}); } }, [ isLoadingInitialReportActions, isLoadingNewerReportActions, - checkIfContentSmallerThanList, reportActionID, indexOfLinkedAction, handleReportActionPagination, - reportActions.length, newestReportAction, isFocused, hasLoadingNewerReportActionsError, From c804881c26cf6275539c2f521c86da8cd2ceda95 Mon Sep 17 00:00:00 2001 From: Janic Duplessis Date: Thu, 25 Jul 2024 15:37:32 -0400 Subject: [PATCH 3/4] Fix not found view flicker when comment linking --- src/pages/home/ReportScreen.tsx | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/src/pages/home/ReportScreen.tsx b/src/pages/home/ReportScreen.tsx index 94089f880c92..533d9831292f 100644 --- a/src/pages/home/ReportScreen.tsx +++ b/src/pages/home/ReportScreen.tsx @@ -259,13 +259,6 @@ function ReportScreen({route, currentReportID = '', navigation}: ReportScreenPro const [currentUserAccountID = -1] = useOnyx(ONYXKEYS.SESSION, {selector: (value) => value?.accountID}); const {reportActions, linkedAction, sortedAllReportActions} = usePaginatedReportActions(report.reportID, reportActionIDFromRoute); - // Define here because reportActions are recalculated before mount, allowing data to display faster than useEffect can trigger. - // If we have cached reportActions, they will be shown immediately. - // We aim to display a loader first, then fetch relevant reportActions, and finally show them. - useLayoutEffect(() => { - setIsLinkingToMessage(!!reportActionIDFromRoute); - }, [route, reportActionIDFromRoute]); - const [isBannerVisible, setIsBannerVisible] = useState(true); const [scrollPosition, setScrollPosition] = useState({}); @@ -728,6 +721,16 @@ function ReportScreen({route, currentReportID = '', navigation}: ReportScreenPro Report.readNewestAction(report.reportID); }, [report]); + const lastRoute = usePrevious(route); + const lastReportActionIDFromRoute = usePrevious(reportActionIDFromRoute); + // Define here because reportActions are recalculated before mount, allowing data to display faster than useEffect can trigger. + // If we have cached reportActions, they will be shown immediately. + // We aim to display a loader first, then fetch relevant reportActions, and finally show them. + if ((lastRoute !== route || lastReportActionIDFromRoute !== reportActionIDFromRoute) && isLinkingToMessage !== !!reportActionIDFromRoute) { + setIsLinkingToMessage(!!reportActionIDFromRoute); + return null; + } + return ( From 13c9acb1a37667c7a2952c4a4080071992f21674 Mon Sep 17 00:00:00 2001 From: Janic Duplessis Date: Thu, 1 Aug 2024 14:48:53 -0400 Subject: [PATCH 4/4] Fix scrollTo called when not needed --- src/components/FlatList/index.android.tsx | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/src/components/FlatList/index.android.tsx b/src/components/FlatList/index.android.tsx index c8ce7ee10d6b..261d10488098 100644 --- a/src/components/FlatList/index.android.tsx +++ b/src/components/FlatList/index.android.tsx @@ -1,29 +1,30 @@ import {useFocusEffect} from '@react-navigation/native'; import type {ForwardedRef} from 'react'; -import React, {forwardRef, useCallback, useContext} from 'react'; +import React, {forwardRef, useCallback, useRef} from 'react'; import type {FlatListProps, NativeScrollEvent, NativeSyntheticEvent} from 'react-native'; import {FlatList} from 'react-native'; -import {ActionListContext} from '@pages/home/ReportScreenContext'; // FlatList wrapped with the freeze component will lose its scroll state when frozen (only for Android). // CustomFlatList saves the offset and use it for scrollToOffset() when unfrozen. function CustomFlatList(props: FlatListProps, ref: ForwardedRef) { - const {scrollPosition, setScrollPosition} = useContext(ActionListContext); + const lastScrollOffsetRef = useRef(0); const onScreenFocus = useCallback(() => { if (typeof ref === 'function') { return; } - if (!ref?.current || !scrollPosition?.offset) { + if (!ref?.current || !lastScrollOffsetRef.current) { return; } - if (ref.current && scrollPosition.offset) { - ref.current.scrollToOffset({offset: scrollPosition.offset, animated: false}); + if (ref.current && lastScrollOffsetRef.current) { + ref.current.scrollToOffset({offset: lastScrollOffsetRef.current, animated: false}); } - }, [scrollPosition?.offset, ref]); + }, [ref]); // eslint-disable-next-line react-compiler/react-compiler, react-hooks/exhaustive-deps - const onMomentumScrollEnd = useCallback((event: NativeSyntheticEvent) => setScrollPosition({offset: event.nativeEvent.contentOffset.y}), []); + const onMomentumScrollEnd = useCallback((event: NativeSyntheticEvent) => { + lastScrollOffsetRef.current = event.nativeEvent.contentOffset.y; + }, []); useFocusEffect( useCallback(() => {