Skip to content

Commit

Permalink
Merge pull request Expensify#44760 from nkdengineer/fix/43546
Browse files Browse the repository at this point in the history
fix: disabled download button when downloading
  • Loading branch information
madmax330 authored Jul 25, 2024
2 parents aba404e + 01b8fce commit 2bd9f0e
Show file tree
Hide file tree
Showing 5 changed files with 61 additions and 23 deletions.
10 changes: 10 additions & 0 deletions src/components/ContextMenuItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,12 @@ type ContextMenuItemProps = {

/** Handles what to do when the item loose focus */
onBlur?: () => void;

/** Whether the menu item is disabled or not */
disabled?: boolean;

/** Whether the menu item should show loading icon */
shouldShowLoadingSpinnerIcon?: boolean;
};

type ContextMenuItemHandle = {
Expand All @@ -78,6 +84,8 @@ function ContextMenuItem(
buttonRef = {current: null},
onFocus = () => {},
onBlur = () => {},
disabled = false,
shouldShowLoadingSpinnerIcon = false,
}: ContextMenuItemProps,
ref: ForwardedRef<ContextMenuItemHandle>,
) {
Expand Down Expand Up @@ -135,6 +143,8 @@ function ContextMenuItem(
interactive={isThrottledButtonActive}
onFocus={onFocus}
onBlur={onBlur}
disabled={disabled}
shouldShowLoadingSpinnerIcon={shouldShowLoadingSpinnerIcon}
/>
);
}
Expand Down
52 changes: 31 additions & 21 deletions src/components/MenuItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import type {ImageContentFit} from 'expo-image';
import type {ReactElement, ReactNode} from 'react';
import React, {forwardRef, useContext, useMemo} from 'react';
import type {GestureResponderEvent, StyleProp, TextStyle, ViewStyle} from 'react-native';
import {View} from 'react-native';
import {ActivityIndicator, View} from 'react-native';
import type {AnimatedStyle} from 'react-native-reanimated';
import type {ValueOf} from 'type-fest';
import useResponsiveLayout from '@hooks/useResponsiveLayout';
Expand Down Expand Up @@ -304,6 +304,8 @@ type MenuItemBaseProps = {

/** Render custom content inside the tooltip. */
renderTooltipContent?: () => ReactNode;

shouldShowLoadingSpinnerIcon?: boolean;
};

type MenuItemProps = (IconProps | AvatarProps | NoIcon) & MenuItemBaseProps;
Expand Down Expand Up @@ -376,6 +378,7 @@ function MenuItem(
shouldEscapeText = undefined,
shouldGreyOutWhenDisabled = true,
shouldUseDefaultCursorWhenDisabled = false,
shouldShowLoadingSpinnerIcon = false,
isAnonymousAction = false,
shouldBlockSelection = false,
shouldParseTitle = false,
Expand Down Expand Up @@ -579,26 +582,33 @@ function MenuItem(
)}
{icon && !Array.isArray(icon) && (
<View style={[styles.popoverMenuIcon, iconStyles, StyleUtils.getAvatarWidthStyle(avatarSize)]}>
{typeof icon !== 'string' && iconType === CONST.ICON_TYPE_ICON && (
<Icon
contentFit={contentFit}
hovered={isHovered}
pressed={pressed}
src={icon}
width={iconWidth}
height={iconHeight}
fill={
displayInDefaultIconColor
? undefined
: iconFill ??
StyleUtils.getIconFillColor(
getButtonState(focused || isHovered, pressed, success, disabled, interactive),
true,
isPaneMenu,
)
}
/>
)}
{typeof icon !== 'string' &&
iconType === CONST.ICON_TYPE_ICON &&
(!shouldShowLoadingSpinnerIcon ? (
<Icon
contentFit={contentFit}
hovered={isHovered}
pressed={pressed}
src={icon}
width={iconWidth}
height={iconHeight}
fill={
displayInDefaultIconColor
? undefined
: iconFill ??
StyleUtils.getIconFillColor(
getButtonState(focused || isHovered, pressed, success, disabled, interactive),
true,
isPaneMenu,
)
}
/>
) : (
<ActivityIndicator
size="small"
color={theme.textSupporting}
/>
))}
{icon && iconType === CONST.ICON_TYPE_WORKSPACE && (
<Avatar
imageStyles={[styles.alignSelfCenter]}
Expand Down
10 changes: 10 additions & 0 deletions src/libs/ReportUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ import * as SessionUtils from './actions/Session';
import * as CurrencyUtils from './CurrencyUtils';
import DateUtils from './DateUtils';
import {hasValidDraftComment} from './DraftCommentUtils';
import getAttachmentDetails from './fileDownload/getAttachmentDetails';
import getIsSmallScreenWidth from './getIsSmallScreenWidth';
import isReportMessageAttachment from './isReportMessageAttachment';
import localeCompare from './LocaleCompare';
Expand Down Expand Up @@ -7225,6 +7226,14 @@ function findPolicyExpenseChatByPolicyID(policyID: string): OnyxEntry<Report> {
return Object.values(ReportConnection.getAllReports() ?? {}).find((report) => isPolicyExpenseChat(report) && report?.policyID === policyID);
}

function getSourceIDFromReportAction(reportAction: OnyxEntry<ReportAction>): string {
const message = Array.isArray(reportAction?.message) ? reportAction?.message?.at(-1) ?? null : reportAction?.message ?? null;
const html = message?.html ?? '';
const {sourceURL} = getAttachmentDetails(html);
const sourceID = (sourceURL?.match(CONST.REGEX.ATTACHMENT_ID) ?? [])[1];
return sourceID;
}

function getIntegrationIcon(connectionName?: ConnectionName) {
if (connectionName === CONST.POLICY.CONNECTIONS.NAME.XERO) {
return XeroSquare;
Expand Down Expand Up @@ -7537,6 +7546,7 @@ export {
isExported,
hasOnlyNonReimbursableTransactions,
getMostRecentlyVisitedReport,
getSourceIDFromReportAction,
getReport,
getReportNameValuePairs,
hasReportViolations,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import {InteractionManager, View} from 'react-native';
// eslint-disable-next-line no-restricted-imports
import type {GestureResponderEvent, Text as RNText, View as ViewType} from 'react-native';
import type {OnyxEntry} from 'react-native-onyx';
import {withOnyx} from 'react-native-onyx';
import {useOnyx, withOnyx} from 'react-native-onyx';
import type {ContextMenuItemHandle} from '@components/ContextMenuItem';
import ContextMenuItem from '@components/ContextMenuItem';
import FocusTrapForModal from '@components/FocusTrap/FocusTrapForModal';
Expand Down Expand Up @@ -135,6 +135,10 @@ function BaseReportActionContextMenu({
return reportActions[reportActionID];
}, [reportActions, reportActionID]);

const sourceID = ReportUtils.getSourceIDFromReportAction(reportAction);

const [download] = useOnyx(`${ONYXKEYS.COLLECTION.DOWNLOAD}${sourceID}`);

const originalReportID = useMemo(() => ReportUtils.getOriginalReportID(reportID, reportAction), [reportID, reportAction]);

const shouldEnableArrowNavigation = !isMini && (isVisible || shouldKeepOpen);
Expand Down Expand Up @@ -287,6 +291,8 @@ function BaseReportActionContextMenu({
shouldPreventDefaultFocusOnPress={contextAction.shouldPreventDefaultFocusOnPress}
onFocus={() => setFocusedIndex(index)}
onBlur={() => (index === filteredContextMenuActions.length - 1 || index === 1) && setFocusedIndex(-1)}
disabled={contextAction?.shouldDisable ? contextAction?.shouldDisable(download) : false}
shouldShowLoadingSpinnerIcon={contextAction?.shouldDisable ? contextAction?.shouldDisable(download) : false}
/>
);
})}
Expand Down
4 changes: 3 additions & 1 deletion src/pages/home/report/ContextMenu/ContextMenuActions.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ import CONST from '@src/CONST';
import type {TranslationPaths} from '@src/languages/types';
import ONYXKEYS from '@src/ONYXKEYS';
import ROUTES from '@src/ROUTES';
import type {Beta, OnyxInputOrEntry, ReportAction, ReportActionReactions, Transaction} from '@src/types/onyx';
import type {Beta, Download as DownloadOnyx, OnyxInputOrEntry, ReportAction, ReportActionReactions, Transaction} from '@src/types/onyx';
import type IconAsset from '@src/types/utils/IconAsset';
import type {ContextMenuAnchor} from './ReportActionContextMenu';
import {hideContextMenu, showDeleteModal} from './ReportActionContextMenu';
Expand Down Expand Up @@ -108,6 +108,7 @@ type ContextMenuAction = (ContextMenuActionWithContent | ContextMenuActionWithIc
isAnonymousAction: boolean;
shouldShow: ShouldShow;
shouldPreventDefaultFocusOnPress?: boolean;
shouldDisable?: (download: OnyxEntry<DownloadOnyx>) => boolean;
};

// A list of all the context actions in this menu.
Expand Down Expand Up @@ -533,6 +534,7 @@ const ContextMenuActions: ContextMenuAction[] = [
}
},
getDescription: () => {},
shouldDisable: (download) => download?.isDownloading ?? false,
},
{
isAnonymousAction: true,
Expand Down

0 comments on commit 2bd9f0e

Please sign in to comment.