Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
135 changes: 71 additions & 64 deletions src/pages/home/report/ContextMenu/PopoverReportActionContextMenu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,10 @@ import type {EmitterSubscription, GestureResponderEvent, NativeTouchEvent, View}
import {DeviceEventEmitter, Dimensions, InteractionManager} from 'react-native';
import type {OnyxEntry} from 'react-native-onyx';
import {Actions, ActionSheetAwareScrollViewContext} from '@components/ActionSheetAwareScrollView';
import {ModalActions} from '@components/Modal/Global/ModalContext';
import ConfirmModal from '@components/ConfirmModal';
import PopoverWithMeasuredContent from '@components/PopoverWithMeasuredContent';
import {useSearchContext} from '@components/Search/SearchContext';
import useAncestors from '@hooks/useAncestors';
import useConfirmModal from '@hooks/useConfirmModal';
import useCurrentUserPersonalDetails from '@hooks/useCurrentUserPersonalDetails';
import useDeleteTransactions from '@hooks/useDeleteTransactions';
import useDuplicateTransactionsAndViolations from '@hooks/useDuplicateTransactionsAndViolations';
Expand Down Expand Up @@ -50,7 +49,6 @@ type PopoverReportActionContextMenuProps = {

function PopoverReportActionContextMenu({ref}: PopoverReportActionContextMenuProps) {
const {translate} = useLocalize();
const {showConfirmModal} = useConfirmModal();
const reportIDRef = useRef<string | undefined>(undefined);
const typeRef = useRef<ContextMenuType | undefined>(undefined);
const reportActionRef = useRef<NonNullable<OnyxEntry<ReportAction>> | null>(null);
Expand All @@ -77,6 +75,8 @@ function PopoverReportActionContextMenu({ref}: PopoverReportActionContextMenuPro
const {email} = useCurrentUserPersonalDetails();

const [isPopoverVisible, setIsPopoverVisible] = useState(false);
const [isDeleteCommentConfirmModalVisible, setIsDeleteCommentConfirmModalVisible] = useState(false);
const [shouldSetModalVisibilityForDeleteConfirmation, setShouldSetModalVisibilityForDeleteConfirmation] = useState(true);

const [isRoomArchived, setIsRoomArchived] = useState(false);
const [isChronosReportEnabled, setIsChronosReportEnabled] = useState(false);
Expand Down Expand Up @@ -104,6 +104,7 @@ function PopoverReportActionContextMenu({ref}: PopoverReportActionContextMenuPro
const onPopoverHide = useRef(() => {});
const onEmojiPickerToggle = useRef<undefined | ((state: boolean) => void)>(undefined);
const onCancelDeleteModal = useRef(() => {});
const onConfirmDeleteModal = useRef(() => {});

const onPopoverHideActionCallback = useRef(() => {});
const callbackWhenDeleteModalHide = useRef(() => {});
Expand Down Expand Up @@ -342,7 +343,8 @@ function PopoverReportActionContextMenu({ref}: PopoverReportActionContextMenuPro
}
ancestorsRef.current = ancestors;
}, [originalReport, ancestors]);
const performDelete = useCallback(() => {
const confirmDeleteAndHideModal = useCallback(() => {
callbackWhenDeleteModalHide.current = runAndResetCallback(onConfirmDeleteModal.current);
const reportAction = reportActionRef.current;
if (isMoneyRequestAction(reportAction)) {
const originalMessage = getOriginalMessage(reportAction);
Expand Down Expand Up @@ -373,6 +375,7 @@ function PopoverReportActionContextMenu({ref}: PopoverReportActionContextMenuPro
}

DeviceEventEmitter.emit(`deletedReportAction_${reportIDRef.current}`, reportAction?.reportActionID);
setIsDeleteCommentConfirmModalVisible(false);
}, [
report,
iouReport,
Expand All @@ -383,48 +386,33 @@ function PopoverReportActionContextMenu({ref}: PopoverReportActionContextMenuPro
isChatIOUReportArchived,
deleteTransactions,
currentSearchHash,
isOriginalReportArchived,
email,
reportTransactions,
violations,
isOriginalReportArchived,
]);

const hideDeleteModal = useCallback(() => {
const hideDeleteModal = () => {
callbackWhenDeleteModalHide.current = () => (onCancelDeleteModal.current = runAndResetCallback(onCancelDeleteModal.current));
setIsDeleteCommentConfirmModalVisible(false);
setShouldSetModalVisibilityForDeleteConfirmation(true);
setIsRoomArchived(false);
setIsChronosReportEnabled(false);
setIsChatPinned(false);
setHasUnreadMessages(false);
}, []);
};

/** Opens the Confirm delete action modal */
const showDeleteModal: ReportActionContextMenu['showDeleteModal'] = useCallback(
async (reportID, reportAction, shouldSetModalVisibility = true, onConfirm = () => {}, onCancel = () => {}) => {
reportIDRef.current = reportID;
reportActionRef.current = reportAction ?? null;

const result = await showConfirmModal({
title: translate('reportActionContextMenu.deleteAction', {action: reportAction}),
prompt: translate('reportActionContextMenu.deleteConfirmation', {action: reportAction}),
confirmText: translate('common.delete'),
cancelText: translate('common.cancel'),
danger: true,
shouldSetModalVisibility,
});
const showDeleteModal: ReportActionContextMenu['showDeleteModal'] = (reportID, reportAction, shouldSetModalVisibility = true, onConfirm = () => {}, onCancel = () => {}) => {
onCancelDeleteModal.current = onCancel;

if (result.action === ModalActions.CONFIRM) {
onConfirm();
performDelete();
} else {
onCancel();
}
onConfirmDeleteModal.current = onConfirm;
reportIDRef.current = reportID;
reportActionRef.current = reportAction ?? null;

// Clear refs and run callbacks AFTER the action is performed
clearActiveReportAction();
callbackWhenDeleteModalHide.current();
},
[showConfirmModal, translate, performDelete],
);
setShouldSetModalVisibilityForDeleteConfirmation(shouldSetModalVisibility);
setIsDeleteCommentConfirmModalVisible(true);
};

useImperativeHandle(ref, () => ({
showContextMenu,
Expand All @@ -440,41 +428,60 @@ function PopoverReportActionContextMenu({ref}: PopoverReportActionContextMenuPro
composerToRefocusOnCloseEmojiPicker: composerToRefocusOnClose,
}));

const reportAction = reportActionRef.current;

return (
<PopoverWithMeasuredContent
isVisible={isPopoverVisible}
onClose={() => hideContextMenu()}
onModalShow={runAndResetOnPopoverShow}
onModalHide={runAndResetOnPopoverHide}
anchorPosition={popoverAnchorPosition.current}
animationIn="fadeIn"
disableAnimation={false}
shouldSetModalVisibility={false}
fullscreen
withoutOverlay={isWithoutOverlay}
anchorDimensions={contextMenuDimensions.current}
anchorRef={anchorRef}
shouldSwitchPositionIfOverflow={shouldSwitchPositionIfOverflow}
>
<BaseReportActionContextMenu
<>
<PopoverWithMeasuredContent
isVisible={isPopoverVisible}
type={typeRef.current}
reportID={reportIDRef.current}
reportActionID={reportActionIDRef.current}
draftMessage={reportActionDraftMessageRef.current}
selection={selectionRef.current}
isArchivedRoom={isRoomArchived}
isChronosReport={isChronosReportEnabled}
isPinnedChat={isChatPinned}
isUnreadChat={hasUnreadMessages}
isThreadReportParentAction={isThreadReportParentAction}
anchor={contextMenuTargetNode}
contentRef={contentRef}
originalReportID={originalReportIDRef.current}
disabledActions={disabledActions}
setIsEmojiPickerActive={onEmojiPickerToggle.current}
onClose={() => hideContextMenu()}
onModalShow={runAndResetOnPopoverShow}
onModalHide={runAndResetOnPopoverHide}
anchorPosition={popoverAnchorPosition.current}
animationIn="fadeIn"
disableAnimation={false}
shouldSetModalVisibility={false}
fullscreen
withoutOverlay={isWithoutOverlay}
anchorDimensions={contextMenuDimensions.current}
anchorRef={anchorRef}
shouldSwitchPositionIfOverflow={shouldSwitchPositionIfOverflow}
>
<BaseReportActionContextMenu
isVisible={isPopoverVisible}
type={typeRef.current}
reportID={reportIDRef.current}
reportActionID={reportActionIDRef.current}
draftMessage={reportActionDraftMessageRef.current}
selection={selectionRef.current}
isArchivedRoom={isRoomArchived}
isChronosReport={isChronosReportEnabled}
isPinnedChat={isChatPinned}
isUnreadChat={hasUnreadMessages}
isThreadReportParentAction={isThreadReportParentAction}
anchor={contextMenuTargetNode}
contentRef={contentRef}
originalReportID={originalReportIDRef.current}
disabledActions={disabledActions}
setIsEmojiPickerActive={onEmojiPickerToggle.current}
/>
</PopoverWithMeasuredContent>
<ConfirmModal
title={translate('reportActionContextMenu.deleteAction', {action: reportAction})}
isVisible={isDeleteCommentConfirmModalVisible}
shouldSetModalVisibility={shouldSetModalVisibilityForDeleteConfirmation}
onConfirm={confirmDeleteAndHideModal}
onCancel={hideDeleteModal}
onModalHide={() => {
clearActiveReportAction();
callbackWhenDeleteModalHide.current();
}}
prompt={translate('reportActionContextMenu.deleteConfirmation', {action: reportAction})}
confirmText={translate('common.delete')}
cancelText={translate('common.cancel')}
danger
/>
</PopoverWithMeasuredContent>
</>
);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ type HideContextMenu = (params?: HideContextMenuParams) => void;
type ReportActionContextMenu = {
showContextMenu: ShowContextMenu;
hideContextMenu: HideContextMenu;
showDeleteModal: (reportID: string, reportAction: OnyxEntry<ReportAction>, shouldSetModalVisibility?: boolean, onConfirm?: OnConfirm, onCancel?: OnCancel) => Promise<void>;
showDeleteModal: (reportID: string, reportAction: OnyxEntry<ReportAction>, shouldSetModalVisibility?: boolean, onConfirm?: OnConfirm, onCancel?: OnCancel) => void;
hideDeleteModal: () => void;
isActiveReportAction: (accountID: string | number) => boolean;
instanceIDRef: RefObject<string>;
Expand Down
Loading