Skip to content

Commit fee1ae2

Browse files
committed
1 parent 815ff90 commit fee1ae2

2 files changed

Lines changed: 16 additions & 83 deletions

File tree

src/components/ScrollOffsetContextProvider.tsx

Lines changed: 10 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import type {ParamListBase} from '@react-navigation/native';
2-
import {findFocusedRoute} from '@react-navigation/native';
32
import React, {createContext, useCallback, useEffect, useMemo, useRef} from 'react';
43
import useOnyx from '@hooks/useOnyx';
54
import usePrevious from '@hooks/usePrevious';
@@ -41,21 +40,11 @@ const defaultValue: ScrollOffsetContextValue = {
4140

4241
const ScrollOffsetContext = createContext<ScrollOffsetContextValue>(defaultValue);
4342

44-
/** This function is prepared to work with HOME and SEARCH screens. */
43+
/** This function is prepared to work with HOME screens. May need modification if we want to handle other types of screens. */
4544
function getKey(route: PlatformStackRouteProp<ParamListBase> | NavigationPartialRoute): string {
46-
// Handle routes with direct policyID parameter (HOME screens)
4745
if (route.params && 'policyID' in route.params && typeof route.params.policyID === 'string') {
4846
return `${route.name}-${route.params.policyID}`;
4947
}
50-
51-
// Handle SEARCH screens with query parameters
52-
if (route.name === SCREENS.SEARCH.ROOT && route.params && 'q' in route.params && typeof route.params.q === 'string') {
53-
// Encode the query to handle spaces and special characters
54-
const encodedQuery = encodeURIComponent(route.params.q);
55-
return `${route.name}-${encodedQuery}`;
56-
}
57-
58-
// For other routes, just use route name
5948
return `${route.name}-global`;
6049
}
6150

@@ -69,9 +58,9 @@ function ScrollOffsetContextProvider({children}: ScrollOffsetContextProviderProp
6958
return;
7059
}
7160

72-
// If the priority mode changes, we need to clear the scroll offsets for the home and search screens because it affects the size of the elements and scroll positions wouldn't be correct.
61+
// If the priority mode changes, we need to clear the scroll offsets for the home screens because it affects the size of the elements and scroll positions wouldn't be correct.
7362
for (const key of Object.keys(scrollOffsetsRef.current)) {
74-
if (key.includes(SCREENS.HOME) || key.includes(SCREENS.SEARCH.ROOT)) {
63+
if (key.includes(SCREENS.HOME)) {
7564
delete scrollOffsetsRef.current[key];
7665
}
7766
}
@@ -88,39 +77,16 @@ function ScrollOffsetContextProvider({children}: ScrollOffsetContextProviderProp
8877
return scrollOffsetsRef.current[getKey(route)];
8978
}, []);
9079

91-
const cleanScrollOffsets = useCallback((keys: string[], shouldDelete: (key: string) => boolean) => {
92-
keys.forEach((key) => {
93-
if (!shouldDelete(key)) {
94-
return;
80+
const cleanStaleScrollOffsets: ScrollOffsetContextValue['cleanStaleScrollOffsets'] = useCallback((state) => {
81+
const sidebarRoutes = state.routes.filter((route) => isSidebarScreenName(route.name));
82+
const scrollOffsetKeysOfExistingScreens = sidebarRoutes.map((route) => getKey(route));
83+
for (const key of Object.keys(scrollOffsetsRef.current)) {
84+
if (!scrollOffsetKeysOfExistingScreens.includes(key)) {
85+
delete scrollOffsetsRef.current[key];
9586
}
96-
97-
delete scrollOffsetsRef.current[key];
98-
});
87+
}
9988
}, []);
10089

101-
const cleanStaleScrollOffsets: ScrollOffsetContextValue['cleanStaleScrollOffsets'] = useCallback(
102-
(state) => {
103-
const sidebarRoutes = state.routes.filter((route) => isSidebarScreenName(route.name));
104-
const existingScreenKeys = sidebarRoutes.map(getKey);
105-
106-
const focusedRoute = findFocusedRoute(state);
107-
const routeName = focusedRoute?.name;
108-
109-
const isSearchScreen = routeName === SCREENS.SEARCH.ROOT;
110-
const isSearchMoneyRequestReport = routeName === SCREENS.SEARCH.MONEY_REQUEST_REPORT || routeName === SCREENS.SEARCH.REPORT_RHP;
111-
112-
const scrollOffsetKeys = Object.keys(scrollOffsetsRef.current);
113-
114-
if (isSearchScreen || isSearchMoneyRequestReport) {
115-
const currentKey = focusedRoute ? getKey(focusedRoute) : null;
116-
cleanScrollOffsets(scrollOffsetKeys, (key) => key.startsWith(SCREENS.SEARCH.ROOT) && key !== currentKey && !isSearchMoneyRequestReport);
117-
return;
118-
}
119-
cleanScrollOffsets(scrollOffsetKeys, (key) => !existingScreenKeys.includes(key));
120-
},
121-
[cleanScrollOffsets],
122-
);
123-
12490
const saveScrollIndex: ScrollOffsetContextValue['saveScrollIndex'] = useCallback((route, scrollIndex) => {
12591
scrollOffsetsRef.current[getKey(route)] = scrollIndex;
12692
}, []);
@@ -129,7 +95,6 @@ function ScrollOffsetContextProvider({children}: ScrollOffsetContextProviderProp
12995
if (!scrollOffsetsRef.current) {
13096
return;
13197
}
132-
13398
return scrollOffsetsRef.current[getKey(route)];
13499
}, []);
135100

src/components/Search/SearchList/index.tsx

Lines changed: 6 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import {useRoute} from '@react-navigation/native';
22
import type {FlashList, FlashListProps, ViewToken} from '@shopify/flash-list';
3-
import React, {forwardRef, useCallback, useContext, useImperativeHandle, useMemo, useRef, useState} from 'react';
3+
import React, {forwardRef, useCallback, useImperativeHandle, useMemo, useRef, useState} from 'react';
44
import type {ForwardedRef} from 'react';
55
import {View} from 'react-native';
66
import type {NativeSyntheticEvent, StyleProp, ViewStyle} from 'react-native';
@@ -11,7 +11,6 @@ import MenuItem from '@components/MenuItem';
1111
import Modal from '@components/Modal';
1212
import {usePersonalDetails} from '@components/OnyxListItemProvider';
1313
import {PressableWithFeedback} from '@components/Pressable';
14-
import {ScrollOffsetContext} from '@components/ScrollOffsetContextProvider';
1514
import {createItemHeightCalculator} from '@components/Search/itemHeightCalculator';
1615
import ITEM_HEIGHTS from '@components/Search/itemHeights';
1716
import type {SearchQueryJSON} from '@components/Search/types';
@@ -186,7 +185,6 @@ function SearchList(
186185
const [userBillingFundID] = useOnyx(ONYXKEYS.NVP_BILLING_FUND_ID, {canBeMissing: true});
187186

188187
const route = useRoute();
189-
const {saveScrollOffset, getScrollOffset} = useContext(ScrollOffsetContext);
190188

191189
const handleLongPressRow = useCallback(
192190
(item: SearchListItem) => {
@@ -347,39 +345,6 @@ function SearchList(
347345
};
348346
}, [calculatedListHeight, calculatedListWidth]);
349347

350-
const handleScroll = useCallback<NonNullable<FlashListProps<SearchListItem>['onScroll']>>(
351-
(e) => {
352-
if (onScroll && typeof onScroll === 'function') {
353-
onScroll(e);
354-
}
355-
356-
if (e.nativeEvent.layoutMeasurement.height > 0) {
357-
saveScrollOffset(route, e.nativeEvent.contentOffset.y);
358-
}
359-
},
360-
[onScroll, route, saveScrollOffset],
361-
);
362-
363-
const handleLayout = useCallback(() => {
364-
if (onLayout && typeof onLayout === 'function') {
365-
onLayout();
366-
}
367-
368-
const offset = getScrollOffset(route);
369-
if (!offset || !listRef.current) {
370-
return;
371-
}
372-
373-
// Use requestAnimationFrame to ensure proper scrolling on iOS
374-
requestAnimationFrame(() => {
375-
if (!offset || !listRef.current) {
376-
return;
377-
}
378-
379-
listRef.current.scrollToOffset({offset});
380-
});
381-
}, [onLayout, getScrollOffset, route]);
382-
383348
return (
384349
<View style={[styles.flex1, !isKeyboardShown && safeAreaPaddingBottomStyle, containerStyle]}>
385350
{tableHeaderVisible && (
@@ -418,7 +383,8 @@ function SearchList(
418383
renderItem={renderItem}
419384
onSelectRow={onSelectRow}
420385
keyExtractor={keyExtractor}
421-
onScroll={handleScroll}
386+
onScroll={onScroll}
387+
showsVerticalScrollIndicator={false}
422388
ref={listRef}
423389
scrollToIndex={scrollToIndex}
424390
isFocused={isFocused}
@@ -427,7 +393,9 @@ function SearchList(
427393
onEndReachedThreshold={onEndReachedThreshold}
428394
ListFooterComponent={ListFooterComponent}
429395
onViewableItemsChanged={onViewableItemsChanged}
430-
onLayout={handleLayout}
396+
onLayout={onLayout}
397+
removeClippedSubviews
398+
drawDistance={1000}
431399
estimatedItemSize={estimatedItemSize}
432400
overrideItemLayout={overrideItemLayout}
433401
estimatedListSize={estimatedListSize}

0 commit comments

Comments
 (0)