Skip to content

Commit 6556e9a

Browse files
Merge pull request #49510 from daledah/fix/49084
fix: search header flickering on selection mode
2 parents 3a6676e + 9e80633 commit 6556e9a

File tree

2 files changed

+40
-6
lines changed

2 files changed

+40
-6
lines changed

src/components/Search/index.tsx

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,8 +91,8 @@ function Search({queryJSON, onSearchListScroll, contentContainerStyle}: SearchPr
9191
const {isSmallScreenWidth, isLargeScreenWidth} = useResponsiveLayout();
9292
const navigation = useNavigation<StackNavigationProp<AuthScreensParamList>>();
9393
const lastSearchResultsRef = useRef<OnyxEntry<SearchResults>>();
94+
const {selectionMode} = useMobileSelectionMode(false);
9495
const {setCurrentSearchHash, setSelectedTransactions, selectedTransactions, clearSelectedTransactions, setShouldShowStatusBarLoading} = useSearchContext();
95-
const {selectionMode} = useMobileSelectionMode();
9696
const [offset, setOffset] = useState(0);
9797

9898
const {type, status, sortBy, sortOrder, hash} = queryJSON;
@@ -379,6 +379,11 @@ function Search({queryJSON, onSearchListScroll, contentContainerStyle}: SearchPr
379379
onTurnOnSelectionMode={(item) => item && toggleTransaction(item)}
380380
onCheckboxPress={toggleTransaction}
381381
onSelectAll={toggleAllTransactions}
382+
isSelected={(item) =>
383+
status !== CONST.SEARCH.STATUS.EXPENSE.ALL && SearchUtils.isReportListItemType(item)
384+
? item.transactions.some((transaction) => selectedTransactions[transaction.keyForList]?.isSelected)
385+
: !!item.isSelected
386+
}
382387
customListHeader={
383388
!isLargeScreenWidth ? null : (
384389
<SearchTableHeader
@@ -392,6 +397,7 @@ function Search({queryJSON, onSearchListScroll, contentContainerStyle}: SearchPr
392397
/>
393398
)
394399
}
400+
shouldAutoTurnOff={false}
395401
onScroll={onSearchListScroll}
396402
canSelectMultiple={type !== CONST.SEARCH.DATA_TYPES.CHAT && canSelectMultiple}
397403
customListHeaderHeight={searchHeaderHeight}

src/components/SelectionListWithModal/index.tsx

Lines changed: 33 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import type {ForwardedRef} from 'react';
2-
import React, {forwardRef, useEffect, useState} from 'react';
2+
import React, {forwardRef, useEffect, useRef, useState} from 'react';
33
import * as Expensicons from '@components/Icon/Expensicons';
44
import MenuItem from '@components/MenuItem';
55
import Modal from '@components/Modal';
@@ -14,10 +14,12 @@ import CONST from '@src/CONST';
1414
type SelectionListWithModalProps<TItem extends ListItem> = BaseSelectionListProps<TItem> & {
1515
turnOnSelectionModeOnLongPress?: boolean;
1616
onTurnOnSelectionMode?: (item: TItem | null) => void;
17+
shouldAutoTurnOff?: boolean;
18+
isSelected?: (item: TItem) => boolean;
1719
};
1820

1921
function SelectionListWithModal<TItem extends ListItem>(
20-
{turnOnSelectionModeOnLongPress, onTurnOnSelectionMode, onLongPressRow, sections, ...rest}: SelectionListWithModalProps<TItem>,
22+
{turnOnSelectionModeOnLongPress, onTurnOnSelectionMode, onLongPressRow, sections, shouldAutoTurnOff, isSelected, ...rest}: SelectionListWithModalProps<TItem>,
2123
ref: ForwardedRef<SelectionListHandle>,
2224
) {
2325
const [isModalVisible, setIsModalVisible] = useState(false);
@@ -26,21 +28,47 @@ function SelectionListWithModal<TItem extends ListItem>(
2628
// We need to use isSmallScreenWidth instead of shouldUseNarrowLayout here because there is a race condition that causes shouldUseNarrowLayout to change indefinitely in this component
2729
// See https://github.com/Expensify/App/issues/48675 for more details
2830
const {isSmallScreenWidth} = useResponsiveLayout();
29-
const {selectionMode} = useMobileSelectionMode(true);
31+
const {selectionMode} = useMobileSelectionMode(shouldAutoTurnOff);
32+
// Check if selection should be on when the modal is opened
33+
const wasSelectionOnRef = useRef(false);
34+
// Keep track of the number of selected items to determine if we should turn off selection mode
35+
const selectionRef = useRef(0);
3036

3137
useEffect(() => {
3238
// We can access 0 index safely as we are not displaying multiple sections in table view
33-
const selectedItems = sections[0].data.filter((item) => item.isSelected);
39+
const selectedItems = sections[0].data.filter((item) => {
40+
if (isSelected) {
41+
return isSelected(item);
42+
}
43+
return !!item.isSelected;
44+
});
45+
selectionRef.current = selectedItems.length;
46+
3447
if (!isSmallScreenWidth) {
3548
if (selectedItems.length === 0) {
3649
turnOffMobileSelectionMode();
3750
}
3851
return;
3952
}
53+
if (!wasSelectionOnRef.current && selectedItems.length > 0) {
54+
wasSelectionOnRef.current = true;
55+
}
4056
if (selectedItems.length > 0 && !selectionMode?.isEnabled) {
4157
turnOnMobileSelectionMode();
58+
} else if (selectedItems.length === 0 && selectionMode?.isEnabled && !wasSelectionOnRef.current) {
59+
turnOffMobileSelectionMode();
4260
}
43-
}, [sections, selectionMode, isSmallScreenWidth]);
61+
}, [sections, selectionMode, isSmallScreenWidth, isSelected]);
62+
63+
useEffect(
64+
() => () => {
65+
if (selectionRef.current !== 0) {
66+
return;
67+
}
68+
turnOffMobileSelectionMode();
69+
},
70+
[],
71+
);
4472

4573
const handleLongPressRow = (item: TItem) => {
4674
// eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing

0 commit comments

Comments
 (0)