diff --git a/src/components/MoneyReportHeader.tsx b/src/components/MoneyReportHeader.tsx index 94a86003c6c1..65b12f0227ae 100644 --- a/src/components/MoneyReportHeader.tsx +++ b/src/components/MoneyReportHeader.tsx @@ -1173,7 +1173,7 @@ function MoneyReportHeader({ }; }, []); - if (isMobileSelectionModeEnabled) { + if (isMobileSelectionModeEnabled && shouldUseNarrowLayout) { // If mobile selection mode is enabled but only one or no transactions remain, turn it off const visibleTransactions = transactions.filter((t) => t.pendingAction !== CONST.RED_BRICK_ROAD_PENDING_ACTION.DELETE || isOffline); if (visibleTransactions.length <= 1) { diff --git a/src/components/Search/SearchContext.tsx b/src/components/Search/SearchContext.tsx index 782d0531e931..34063b5ed663 100644 --- a/src/components/Search/SearchContext.tsx +++ b/src/components/Search/SearchContext.tsx @@ -1,4 +1,5 @@ import React, {useCallback, useContext, useMemo, useRef, useState} from 'react'; +import useHandleSelectionMode from '@hooks/useHandleSelectionMode'; import {isMoneyRequestReport} from '@libs/ReportUtils'; import {isTransactionListItemType, isTransactionReportGroupListItemType} from '@libs/SearchUIUtils'; import type {SearchKey} from '@libs/SearchUIUtils'; @@ -195,6 +196,12 @@ function SearchContextProvider({children}: ChildrenProps) { })); }, []); + const selectedItems = useMemo(() => { + return [...searchContextData.selectedTransactionIDs, ...searchContextData.selectedReports.map((item) => item.reportID)]; + }, [searchContextData.selectedReports, searchContextData.selectedTransactionIDs]); + + useHandleSelectionMode(selectedItems); + const searchContext = useMemo( () => ({ ...searchContextData, diff --git a/src/components/SelectionListWithModal/index.tsx b/src/components/SelectionListWithModal/index.tsx index d75e31444980..f84f28a5663a 100644 --- a/src/components/SelectionListWithModal/index.tsx +++ b/src/components/SelectionListWithModal/index.tsx @@ -1,21 +1,21 @@ import {useIsFocused} from '@react-navigation/native'; import type {ForwardedRef} from 'react'; -import React, {forwardRef, useEffect, useRef, useState} from 'react'; +import React, {forwardRef, useMemo, useState} from 'react'; import {CheckSquare} from '@components/Icon/Expensicons'; import MenuItem from '@components/MenuItem'; import Modal from '@components/Modal'; import SelectionList from '@components/SelectionListWithSections'; import type {ListItem, SelectionListHandle, SelectionListProps} from '@components/SelectionListWithSections/types'; +import useHandleSelectionMode from '@hooks/useHandleSelectionMode'; import useLocalize from '@hooks/useLocalize'; import useMobileSelectionMode from '@hooks/useMobileSelectionMode'; import useResponsiveLayout from '@hooks/useResponsiveLayout'; -import {turnOffMobileSelectionMode, turnOnMobileSelectionMode} from '@libs/actions/MobileSelectionMode'; +import {turnOnMobileSelectionMode} from '@libs/actions/MobileSelectionMode'; import CONST from '@src/CONST'; type SelectionListWithModalProps = SelectionListProps & { turnOnSelectionModeOnLongPress?: boolean; onTurnOnSelectionMode?: (item: TItem | null) => void; - isSelected?: (item: TItem) => boolean; isScreenFocused?: boolean; }; @@ -42,53 +42,21 @@ function SelectionListWithModal( const isFocused = useIsFocused(); const isMobileSelectionModeEnabled = useMobileSelectionMode(); - // Check if selection should be on when the modal is opened - const wasSelectionOnRef = useRef(false); - // Keep track of the number of selected items to determine if we should turn off selection mode - const selectionRef = useRef(0); - useEffect(() => { - // We can access 0 index safely as we are not displaying multiple sections in table view - const selectedItems = + const selectedItems = useMemo( + () => selectedItemsProp ?? sections[0].data.filter((item) => { if (isSelected) { return isSelected(item); } return !!item.isSelected; - }); - selectionRef.current = selectedItems.length; - - if (!isSmallScreenWidth) { - if (selectedItems.length === 0 && isMobileSelectionModeEnabled) { - turnOffMobileSelectionMode(); - } - return; - } - if (!isFocused) { - return; - } - if (!wasSelectionOnRef.current && selectedItems.length > 0) { - wasSelectionOnRef.current = true; - } - if (selectedItems.length > 0 && !isMobileSelectionModeEnabled) { - turnOnMobileSelectionMode(); - } else if (selectedItems.length === 0 && isMobileSelectionModeEnabled && !wasSelectionOnRef.current) { - turnOffMobileSelectionMode(); - } - // eslint-disable-next-line react-compiler/react-compiler, react-hooks/exhaustive-deps - }, [sections, selectedItemsProp, isMobileSelectionModeEnabled, isSmallScreenWidth, isSelected, isFocused]); - - useEffect( - () => () => { - if (selectionRef.current !== 0) { - return; - } - turnOffMobileSelectionMode(); - }, - [], + }), + [isSelected, sections, selectedItemsProp], ); + useHandleSelectionMode(selectedItems); + const handleLongPressRow = (item: TItem) => { // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing if (!turnOnSelectionModeOnLongPress || !isSmallScreenWidth || item?.isDisabled || item?.isDisabledCheckbox || (!isFocused && !isScreenFocused)) { diff --git a/src/hooks/useHandleSelectionMode.ts b/src/hooks/useHandleSelectionMode.ts new file mode 100644 index 000000000000..77efb9a3fa38 --- /dev/null +++ b/src/hooks/useHandleSelectionMode.ts @@ -0,0 +1,52 @@ +import {useIsFocused} from '@react-navigation/native'; +import {useEffect, useRef} from 'react'; +import type {ListItem} from '@components/SelectionListWithSections/types'; +import {turnOffMobileSelectionMode, turnOnMobileSelectionMode} from '@libs/actions/MobileSelectionMode'; +import useMobileSelectionMode from './useMobileSelectionMode'; +import useResponsiveLayout from './useResponsiveLayout'; + +function useHandleSelectionMode(selectedItems: string[] | TItem[]) { + // eslint-disable-next-line rulesdir/prefer-shouldUseNarrowLayout-instead-of-isSmallScreenWidth + const {isSmallScreenWidth} = useResponsiveLayout(); + const isFocused = useIsFocused(); + + const isMobileSelectionModeEnabled = useMobileSelectionMode(); + // Check if selection should be on when the modal is opened + const wasSelectionOnRef = useRef(false); + // Keep track of the number of selected items to determine if we should turn off selection mode + const selectionRef = useRef(0); + + useEffect(() => { + selectionRef.current = selectedItems.length; + + if (!isSmallScreenWidth) { + if (selectedItems.length === 0 && isMobileSelectionModeEnabled) { + turnOffMobileSelectionMode(); + } + return; + } + if (!isFocused) { + return; + } + if (!wasSelectionOnRef.current && selectedItems.length > 0) { + wasSelectionOnRef.current = true; + } + if (selectedItems.length > 0 && !isMobileSelectionModeEnabled) { + turnOnMobileSelectionMode(); + } else if (selectedItems.length === 0 && isMobileSelectionModeEnabled && !wasSelectionOnRef.current) { + turnOffMobileSelectionMode(); + } + }, [isMobileSelectionModeEnabled, isSmallScreenWidth, isFocused, selectedItems.length]); + + useEffect( + () => () => { + if (selectionRef.current !== 0) { + return; + } + turnOffMobileSelectionMode(); + }, + [], + ); +} + +export default useHandleSelectionMode;