|
1 | 1 | /* eslint-disable react-hooks/refs -- Refs in this hook are used inside callbacks that capture stable references; the lint rule flags false positives for these patterns */ |
2 | 2 | import {isTrackIntentUserSelector} from '@selectors/Onboarding'; |
3 | 3 | import {useCallback, useEffect, useMemo, useRef, useState} from 'react'; |
| 4 | +// eslint-disable-next-line no-restricted-imports -- InteractionManager is only exposed on the react-native root module; there is no internal re-export to import from |
| 5 | +import {InteractionManager} from 'react-native'; |
4 | 6 | import type {OnyxCollection, OnyxEntry} from 'react-native-onyx'; |
5 | 7 | import type {ValueOf} from 'type-fest'; |
6 | 8 | import type {DropdownOption} from '@components/ButtonWithDropdownMenu/types'; |
@@ -911,19 +913,24 @@ function useSearchBulkActions({queryJSON}: UseSearchBulkActionsParams) { |
911 | 913 | return; |
912 | 914 | } |
913 | 915 |
|
914 | | - TransitionTracker.runAfterTransitions({ |
915 | | - callback: async () => { |
916 | | - const result = await showConfirmModal({ |
917 | | - title: deleteModalTitle, |
918 | | - prompt: deleteModalPrompt, |
919 | | - confirmText: translate('common.delete'), |
920 | | - cancelText: translate('common.cancel'), |
921 | | - danger: true, |
922 | | - }); |
923 | | - if (result.action !== ModalActions.CONFIRM) { |
924 | | - return; |
925 | | - } |
926 | | - const validTransactions = Object.fromEntries(Object.entries(allTransactions ?? {}).filter((entry): entry is [string, Transaction] => entry[1] !== undefined)); |
| 916 | + // InteractionManager is deprecated but still required here to defer showing the confirm modal until pending interactions settle, matching the production behavior this PR restores (see https://github.com/Expensify/App/issues/95114). |
| 917 | + // eslint-disable-next-line @typescript-eslint/no-deprecated |
| 918 | + InteractionManager.runAfterInteractions(async () => { |
| 919 | + const result = await showConfirmModal({ |
| 920 | + title: deleteModalTitle, |
| 921 | + prompt: deleteModalPrompt, |
| 922 | + confirmText: translate('common.delete'), |
| 923 | + cancelText: translate('common.cancel'), |
| 924 | + danger: true, |
| 925 | + }); |
| 926 | + if (result.action !== ModalActions.CONFIRM) { |
| 927 | + return; |
| 928 | + } |
| 929 | + const validTransactions = Object.fromEntries(Object.entries(allTransactions ?? {}).filter((entry): entry is [string, Transaction] => entry[1] !== undefined)); |
| 930 | + // Defer the actual deletion until after the confirm modal's dismiss interaction completes. |
| 931 | + // Dispatching it synchronously as the modal closes caused the delete to be dropped (see https://github.com/Expensify/App/issues/95114). |
| 932 | + // eslint-disable-next-line @typescript-eslint/no-deprecated |
| 933 | + InteractionManager.runAfterInteractions(() => { |
927 | 934 | if (isExpenseReportType) { |
928 | 935 | for (const reportID of selectedReportIDs) { |
929 | 936 | const report = allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${reportID}`]; |
@@ -992,7 +999,7 @@ function useSearchBulkActions({queryJSON}: UseSearchBulkActionsParams) { |
992 | 999 | } |
993 | 1000 | } |
994 | 1001 | clearSelectedTransactions(); |
995 | | - }, |
| 1002 | + }); |
996 | 1003 | }); |
997 | 1004 | }, [ |
998 | 1005 | hash, |
|
0 commit comments