diff --git a/src/components/MoneyReportHeader.tsx b/src/components/MoneyReportHeader.tsx index 4cd55943dc1f9..84f3cea629e97 100644 --- a/src/components/MoneyReportHeader.tsx +++ b/src/components/MoneyReportHeader.tsx @@ -1154,7 +1154,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/MoneyRequestReportView/MoneyRequestReportTransactionList.tsx b/src/components/MoneyRequestReportView/MoneyRequestReportTransactionList.tsx index c801dbdf40b35..27fc0c593e9e4 100644 --- a/src/components/MoneyRequestReportView/MoneyRequestReportTransactionList.tsx +++ b/src/components/MoneyRequestReportView/MoneyRequestReportTransactionList.tsx @@ -17,6 +17,7 @@ import Text from '@components/Text'; import {WideRHPContext} from '@components/WideRHPContextProvider'; import useCopySelectionHelper from '@hooks/useCopySelectionHelper'; import useCurrentUserPersonalDetails from '@hooks/useCurrentUserPersonalDetails'; +import useHandleSelectionMode from '@hooks/useHandleSelectionMode'; import useLocalize from '@hooks/useLocalize'; import useMobileSelectionMode from '@hooks/useMobileSelectionMode'; import useReportIsArchived from '@hooks/useReportIsArchived'; @@ -163,6 +164,7 @@ function MoneyRequestReportTransactionList({ }, [hasPendingDeletionTransaction, transactions]); const {selectedTransactionIDs, setSelectedTransactions, clearSelectedTransactions} = useSearchContext(); + useHandleSelectionMode(selectedTransactionIDs); const isMobileSelectionModeEnabled = useMobileSelectionMode(); const personalDetailsList = usePersonalDetails(); diff --git a/src/components/SelectionListWithModal/index.tsx b/src/components/SelectionListWithModal/index.tsx index d75e314449805..a6f006728b673 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,23 @@ 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 sectionData = sections[0]?.data; + const selectedItems = useMemo( + () => selectedItemsProp ?? - sections[0].data.filter((item) => { + sectionData?.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, sectionData, 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 0000000000000..77efb9a3fa389 --- /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;