Skip to content

Commit

Permalink
Merge pull request #45987 from bernhardoj/fix/23959-mini-context-menu…
Browse files Browse the repository at this point in the history
…-doesnt-close

Fix mini context menu doesn't close when using shortcut to other pages
  • Loading branch information
puneetlath authored Jul 29, 2024
2 parents 6be6082 + c4d0b95 commit beb1c95
Show file tree
Hide file tree
Showing 9 changed files with 52 additions and 20 deletions.
8 changes: 7 additions & 1 deletion src/components/ButtonWithDropdownMenu/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ function ButtonWithDropdownMenu<IValueType>({
onPress,
options,
onOptionSelected,
onOptionsMenuShow,
onOptionsMenuHide,
enterKeyEventListenerPriority = 0,
wrapperStyle,
}: ButtonWithDropdownMenuProps<IValueType>) {
Expand Down Expand Up @@ -136,7 +138,11 @@ function ButtonWithDropdownMenu<IValueType>({
{(shouldAlwaysShowDropdownMenu || options.length > 1) && popoverAnchorPosition && (
<PopoverMenu
isVisible={isMenuVisible}
onClose={() => setIsMenuVisible(false)}
onClose={() => {
setIsMenuVisible(false);
onOptionsMenuHide?.();
}}
onModalShow={onOptionsMenuShow}
onItemSelected={() => setIsMenuVisible(false)}
anchorPosition={popoverAnchorPosition}
anchorRef={caretButton}
Expand Down
6 changes: 6 additions & 0 deletions src/components/ButtonWithDropdownMenu/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,12 @@ type ButtonWithDropdownMenuProps<TValueType> = {
/** Callback to execute when a dropdown option is selected */
onOptionSelected?: (option: DropdownOption<TValueType>) => void;

/** Callback when the options popover is shown */
onOptionsMenuShow?: () => void;

/** Callback when the options popover is shown */
onOptionsMenuHide?: () => void;

/** Call the onPress function on main button when Enter key is pressed */
pressOnEnter?: boolean;

Expand Down
7 changes: 2 additions & 5 deletions src/components/EmojiPicker/EmojiPicker.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ function EmojiPicker({viewportOffsetTop}: EmojiPickerProps, ref: ForwardedRef<Em
width: 0,
height: 0,
});
const onModalHide = useRef(() => {});
const onModalHide = useRef<OnModalHideValue>(() => {});
const onEmojiSelected = useRef<OnEmojiSelected>(() => {});
const activeEmoji = useRef<string | undefined>();
const emojiSearchInput = useRef<BaseTextInputRef | null>();
Expand Down Expand Up @@ -112,13 +112,10 @@ function EmojiPicker({viewportOffsetTop}: EmojiPickerProps, ref: ForwardedRef<Em
* Hide the emoji picker menu.
*/
const hideEmojiPicker = (isNavigating?: boolean) => {
if (isNavigating) {
onModalHide.current = () => {};
}
const currOnModalHide = onModalHide.current;
onModalHide.current = () => {
if (currOnModalHide) {
currOnModalHide();
currOnModalHide(!!isNavigating);
}
// eslint-disable-next-line react-compiler/react-compiler
emojiPopoverAnchorRef.current = null;
Expand Down
5 changes: 5 additions & 0 deletions src/components/PopoverMenu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,9 @@ type PopoverMenuProps = Partial<PopoverModalProps> & {
/** Callback method fired when the user requests to close the modal */
onClose: () => void;

/** Callback method fired when the modal is shown */
onModalShow?: () => void;

/** State that determines whether to display the modal or not */
isVisible: boolean;

Expand Down Expand Up @@ -89,6 +92,7 @@ function PopoverMenu({
anchorPosition,
anchorRef,
onClose,
onModalShow,
headerText,
fromSidebarMediumScreen,
anchorAlignment = {
Expand Down Expand Up @@ -211,6 +215,7 @@ function PopoverMenu({
}}
isVisible={isVisible}
onModalHide={onModalHide}
onModalShow={onModalShow}
animationIn={animationIn}
animationOut={animationOut}
animationInTiming={animationInTiming}
Expand Down
10 changes: 10 additions & 0 deletions src/components/ReportActionItem/ReportPreview.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,12 @@ type ReportPreviewProps = ReportPreviewOnyxProps & {
/** Callback for updating context menu active state, used for showing context menu */
checkIfContextMenuActive?: () => void;

/** Callback when the payment options popover is shown */
onPaymentOptionsShow?: () => void;

/** Callback when the payment options popover is closed */
onPaymentOptionsHide?: () => void;

/** Whether a message is a whisper */
isWhisper?: boolean;

Expand All @@ -106,6 +112,8 @@ function ReportPreview({
isHovered = false,
isWhisper = false,
checkIfContextMenuActive = () => {},
onPaymentOptionsShow,
onPaymentOptionsHide,
userWallet,
}: ReportPreviewProps) {
const theme = useTheme();
Expand Down Expand Up @@ -433,6 +441,8 @@ function ReportPreview({
chatReportID={chatReportID}
iouReport={iouReport}
onPress={confirmPayment}
onPaymentOptionsShow={onPaymentOptionsShow}
onPaymentOptionsHide={onPaymentOptionsHide}
confirmApproval={confirmApproval}
enablePaymentsRoute={ROUTES.ENABLE_PAYMENTS}
addBankAccountRoute={bankAccountRoute}
Expand Down
10 changes: 10 additions & 0 deletions src/components/SettlementButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,12 @@ type SettlementButtonProps = SettlementButtonOnyxProps & {
/** Callback to execute when this button is pressed. Receives a single payment type argument. */
onPress: (paymentType?: PaymentMethodType) => void;

/** Callback when the payment options popover is shown */
onPaymentOptionsShow?: () => void;

/** Callback when the payment options popover is closed */
onPaymentOptionsHide?: () => void;

/** The route to redirect if user does not have a payment method setup */
enablePaymentsRoute: EnablePaymentsRoute;

Expand Down Expand Up @@ -140,6 +146,8 @@ function SettlementButton({
enterKeyEventListenerPriority = 0,
confirmApproval,
policy,
onPaymentOptionsShow,
onPaymentOptionsHide,
}: SettlementButtonProps) {
const {translate} = useLocalize();
const {isOffline} = useNetwork();
Expand Down Expand Up @@ -273,6 +281,8 @@ function SettlementButton({
{(triggerKYCFlow, buttonRef) => (
<ButtonWithDropdownMenu<PaymentType>
success
onOptionsMenuShow={onPaymentOptionsShow}
onOptionsMenuHide={onPaymentOptionsHide}
buttonRef={buttonRef}
shouldAlwaysShowDropdownMenu={isInvoiceReport}
customText={isInvoiceReport ? translate('iou.settlePayment', {formattedAmount}) : undefined}
Expand Down
2 changes: 1 addition & 1 deletion src/libs/actions/EmojiPickerAction.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ type EmojiPopoverAnchor = MutableRefObject<View | HTMLDivElement | TextInput | n

type OnWillShowPicker = (callback?: CloseContextMenuCallback) => void;

type OnModalHideValue = () => void;
type OnModalHideValue = (isNavigating?: boolean) => void;

type EmojiPickerRef = {
showEmojiPicker: (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -482,7 +482,12 @@ function ReportActionCompose({
{DeviceCapabilities.canUseTouchScreen() && isMediumScreenWidth ? null : (
<EmojiPickerButton
isDisabled={isBlockedFromConcierge || disabled}
onModalHide={focus}
onModalHide={(isNavigating) => {
if (isNavigating) {
return;
}
focus();
}}
onEmojiSelected={(...args) => composerRef.current?.replaceSelectionWithText(...args)}
emojiPickerID={report?.reportID}
shiftVertical={emojiShiftVertical}
Expand Down
17 changes: 5 additions & 12 deletions src/pages/home/report/ReportActionItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -90,9 +90,6 @@ const getDraftMessage = (drafts: OnyxCollection<OnyxTypes.ReportActionsDrafts>,
};

type ReportActionItemOnyxProps = {
/** Get modal status */
modal: OnyxEntry<OnyxTypes.Modal>;

/** IOU report for this action, if any */
iouReport: OnyxEntry<OnyxTypes.Report>;

Expand Down Expand Up @@ -161,7 +158,6 @@ type ReportActionItemProps = {
} & ReportActionItemOnyxProps;

function ReportActionItem({
modal,
action,
report,
transactionThreadReport,
Expand Down Expand Up @@ -195,6 +191,7 @@ function ReportActionItem({
const personalDetails = usePersonalDetails() || CONST.EMPTY_OBJECT;
const [isContextMenuActive, setIsContextMenuActive] = useState(() => ReportActionContextMenu.isActiveReportAction(action.reportActionID));
const [isEmojiPickerActive, setIsEmojiPickerActive] = useState<boolean | undefined>();
const [isPaymentMethodPopoverActive, setIsPaymentMethodPopoverActive] = useState<boolean | undefined>();

const [isHidden, setIsHidden] = useState(false);
const [moderationDecision, setModerationDecision] = useState<OnyxTypes.DecisionName>(CONST.MODERATION.MODERATOR_DECISION_APPROVED);
Expand Down Expand Up @@ -566,6 +563,8 @@ function ReportActionItem({
isHovered={hovered}
contextMenuAnchor={popoverAnchorRef.current}
checkIfContextMenuActive={toggleContextMenuFromActiveReportAction}
onPaymentOptionsShow={() => setIsPaymentMethodPopoverActive(true)}
onPaymentOptionsHide={() => setIsPaymentMethodPopoverActive(false)}
isWhisper={isWhisper}
/>
);
Expand Down Expand Up @@ -901,7 +900,6 @@ function ReportActionItem({
accessible
>
<Hoverable
shouldFreezeCapture={modal?.willAlertModalBecomeVisible}
shouldHandleScroll
isDisabled={draftMessage !== undefined}
>
Expand All @@ -926,7 +924,7 @@ function ReportActionItem({
)}
<View
style={StyleUtils.getReportActionItemStyle(
hovered || isWhisper || isContextMenuActive || !!isEmojiPickerActive || draftMessage !== undefined,
hovered || isWhisper || isContextMenuActive || !!isEmojiPickerActive || draftMessage !== undefined || isPaymentMethodPopoverActive,
draftMessage === undefined && !!onPress,
)}
>
Expand Down Expand Up @@ -998,15 +996,11 @@ export default withOnyx<ReportActionItemProps, ReportActionItemOnyxProps>({
`${ONYXKEYS.COLLECTION.TRANSACTION}${ReportActionsUtils.isMoneyRequestAction(action) ? ReportActionsUtils.getOriginalMessage(action)?.IOUTransactionID ?? -1 : -1}`,
selector: (transaction: OnyxEntry<OnyxTypes.Transaction>) => transaction?.errorFields?.route ?? null,
},
modal: {
key: ONYXKEYS.MODAL,
},
})(
memo(ReportActionItem, (prevProps, nextProps) => {
const prevParentReportAction = prevProps.parentReportAction;
const nextParentReportAction = nextProps.parentReportAction;
return (
prevProps.modal?.willAlertModalBecomeVisible === nextProps.modal?.willAlertModalBecomeVisible &&
prevProps.displayAsGroup === nextProps.displayAsGroup &&
prevProps.isMostRecentIOUReportAction === nextProps.isMostRecentIOUReportAction &&
prevProps.shouldDisplayNewMarker === nextProps.shouldDisplayNewMarker &&
Expand Down Expand Up @@ -1035,8 +1029,7 @@ export default withOnyx<ReportActionItemProps, ReportActionItemOnyxProps>({
lodashIsEqual(prevProps.transactionThreadReport, nextProps.transactionThreadReport) &&
lodashIsEqual(prevProps.reportActions, nextProps.reportActions) &&
lodashIsEqual(prevProps.linkedTransactionRouteError, nextProps.linkedTransactionRouteError) &&
lodashIsEqual(prevParentReportAction, nextParentReportAction) &&
prevProps.modal?.willAlertModalBecomeVisible === nextProps.modal?.willAlertModalBecomeVisible
lodashIsEqual(prevParentReportAction, nextParentReportAction)
);
}),
);

0 comments on commit beb1c95

Please sign in to comment.