Skip to content

Commit

Permalink
Merge pull request #51626 from bernhardoj/fix/50828-auto-download-wal…
Browse files Browse the repository at this point in the history
…let-statement

Auto download wallet statement after finish genereating
  • Loading branch information
carlosmiceli authored Nov 1, 2024
2 parents e7267ea + 658d138 commit 648aee5
Show file tree
Hide file tree
Showing 5 changed files with 62 additions and 48 deletions.
56 changes: 32 additions & 24 deletions src/components/HeaderWithBackButton/index.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React, {useMemo} from 'react';
import {Keyboard, StyleSheet, View} from 'react-native';
import {ActivityIndicator, Keyboard, StyleSheet, View} from 'react-native';
import Avatar from '@components/Avatar';
import AvatarWithDisplayName from '@components/AvatarWithDisplayName';
import Header from '@components/Header';
Expand Down Expand Up @@ -39,6 +39,7 @@ function HeaderWithBackButton({
shouldShowBorderBottom = false,
shouldShowCloseButton = false,
shouldShowDownloadButton = false,
isDownloading = false,
shouldShowGetAssistanceButton = false,
shouldDisableGetAssistanceButton = false,
shouldShowPinButton = false,
Expand Down Expand Up @@ -193,32 +194,39 @@ function HeaderWithBackButton({
{middleContent}
<View style={[styles.reportOptions, styles.flexRow, styles.pr5, styles.alignItemsCenter]}>
{children}
{shouldShowDownloadButton && (
<Tooltip text={translate('common.download')}>
<PressableWithoutFeedback
onPress={(event) => {
// Blur the pressable in case this button triggers a Growl notification
// We do not want to overlap Growl with the Tooltip (#15271)
(event?.currentTarget as HTMLElement)?.blur();
{shouldShowDownloadButton &&
(!isDownloading ? (
<Tooltip text={translate('common.download')}>
<PressableWithoutFeedback
onPress={(event) => {
// Blur the pressable in case this button triggers a Growl notification
// We do not want to overlap Growl with the Tooltip (#15271)
(event?.currentTarget as HTMLElement)?.blur();

if (!isDownloadButtonActive) {
return;
}
if (!isDownloadButtonActive) {
return;
}

onDownloadButtonPress();
temporarilyDisableDownloadButton();
}}
onDownloadButtonPress();
temporarilyDisableDownloadButton();
}}
style={[styles.touchableButtonImage]}
role="button"
accessibilityLabel={translate('common.download')}
>
<Icon
src={Expensicons.Download}
fill={iconFill ?? StyleUtils.getIconFillColor(getButtonState(false, false, !isDownloadButtonActive))}
/>
</PressableWithoutFeedback>
</Tooltip>
) : (
<ActivityIndicator
style={[styles.touchableButtonImage]}
role="button"
accessibilityLabel={translate('common.download')}
>
<Icon
src={Expensicons.Download}
fill={iconFill ?? StyleUtils.getIconFillColor(getButtonState(false, false, !isDownloadButtonActive))}
/>
</PressableWithoutFeedback>
</Tooltip>
)}
size="small"
color={theme.spinner}
/>
))}
{shouldShowGetAssistanceButton && (
<Tooltip text={translate('getAssistancePage.questionMarkButtonTooltip')}>
<PressableWithoutFeedback
Expand Down
3 changes: 3 additions & 0 deletions src/components/HeaderWithBackButton/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,9 @@ type HeaderWithBackButtonProps = Partial<ChildrenProps> & {
/** Whether we should show a download button */
shouldShowDownloadButton?: boolean;

/** Whether we should show a loading indicator replacing the download button */
isDownloading?: boolean;

/** Whether we should show a get assistance (question mark) button */
shouldShowGetAssistanceButton?: boolean;

Expand Down
1 change: 0 additions & 1 deletion src/languages/en.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4291,7 +4291,6 @@ const translations = {
},
statementPage: {
title: ({year, monthName}: StatementTitleParams) => `${monthName} ${year} statement`,
generatingPDF: "We're generating your PDF right now. Please check back soon!",
},
keyboardShortcutsPage: {
title: 'Keyboard shortcuts',
Expand Down
1 change: 0 additions & 1 deletion src/languages/es.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4338,7 +4338,6 @@ const translations = {
},
statementPage: {
title: ({year, monthName}: StatementTitleParams) => `Estado de cuenta de ${monthName} ${year}`,
generatingPDF: 'Estamos generando tu PDF ahora mismo. ¡Por favor, vuelve más tarde!',
},
keyboardShortcutsPage: {
title: 'Atajos de teclado',
Expand Down
49 changes: 27 additions & 22 deletions src/pages/wallet/WalletStatementPage.tsx
Original file line number Diff line number Diff line change
@@ -1,39 +1,35 @@
import type {StackScreenProps} from '@react-navigation/stack';
import {format, getMonth, getYear} from 'date-fns';
import {Str} from 'expensify-common';
import React, {useEffect} from 'react';
import {withOnyx} from 'react-native-onyx';
import type {OnyxEntry} from 'react-native-onyx';
import React, {useCallback, useEffect, useState} from 'react';
import {useOnyx} from 'react-native-onyx';
import FullPageOfflineBlockingView from '@components/BlockingViews/FullPageOfflineBlockingView';
import HeaderWithBackButton from '@components/HeaderWithBackButton';
import ScreenWrapper from '@components/ScreenWrapper';
import WalletStatementModal from '@components/WalletStatementModal';
import useLocalize from '@hooks/useLocalize';
import useNetwork from '@hooks/useNetwork';
import usePrevious from '@hooks/usePrevious';
import useThemePreference from '@hooks/useThemePreference';
import DateUtils from '@libs/DateUtils';
import fileDownload from '@libs/fileDownload';
import Growl from '@libs/Growl';
import Navigation from '@libs/Navigation/Navigation';
import type {WalletStatementNavigatorParamList} from '@navigation/types';
import * as User from '@userActions/User';
import CONFIG from '@src/CONFIG';
import CONST from '@src/CONST';
import ONYXKEYS from '@src/ONYXKEYS';
import type SCREENS from '@src/SCREENS';
import type {WalletStatement} from '@src/types/onyx';

type WalletStatementOnyxProps = {
walletStatement: OnyxEntry<WalletStatement>;
};
type WalletStatementPageProps = StackScreenProps<WalletStatementNavigatorParamList, typeof SCREENS.WALLET_STATEMENT_ROOT>;

type WalletStatementPageProps = WalletStatementOnyxProps & StackScreenProps<WalletStatementNavigatorParamList, typeof SCREENS.WALLET_STATEMENT_ROOT>;

function WalletStatementPage({walletStatement, route}: WalletStatementPageProps) {
function WalletStatementPage({route}: WalletStatementPageProps) {
const [walletStatement] = useOnyx(ONYXKEYS.WALLET_STATEMENT);
const themePreference = useThemePreference();
const yearMonth = route.params.yearMonth ?? null;
const isWalletStatementGenerating = walletStatement?.isGenerating ?? false;

const prevIsWalletStatementGenerating = usePrevious(isWalletStatementGenerating);
const [isDownloading, setIsDownloading] = useState(isWalletStatementGenerating);
const {translate, preferredLocale} = useLocalize();
const {isOffline} = useNetwork();

Expand All @@ -49,23 +45,35 @@ function WalletStatementPage({walletStatement, route}: WalletStatementPageProps)
DateUtils.setLocale(preferredLocale);
}, [preferredLocale]);

const processDownload = () => {
const processDownload = useCallback(() => {
if (isWalletStatementGenerating) {
return;
}

setIsDownloading(true);
if (walletStatement?.[yearMonth]) {
// We already have a file URL for this statement, so we can download it immediately
const downloadFileName = `Expensify_Statement_${yearMonth}.pdf`;
const fileName = walletStatement[yearMonth];
const pdfURL = `${CONFIG.EXPENSIFY.EXPENSIFY_URL}secure?secureType=pdfreport&filename=${fileName}&downloadName=${downloadFileName}`;
fileDownload(pdfURL, downloadFileName);
fileDownload(pdfURL, downloadFileName).finally(() => setIsDownloading(false));
return;
}

Growl.show(translate('statementPage.generatingPDF'), CONST.GROWL.SUCCESS, 3000);
User.generateStatementPDF(yearMonth);
};
}, [isWalletStatementGenerating, walletStatement, yearMonth]);

// eslint-disable-next-line rulesdir/prefer-early-return
useEffect(() => {
// If the statement generate is complete, download it automatically.
if (prevIsWalletStatementGenerating && !isWalletStatementGenerating) {
if (walletStatement?.[yearMonth]) {
processDownload();
} else {
setIsDownloading(false);
}
}
}, [prevIsWalletStatementGenerating, isWalletStatementGenerating, processDownload, walletStatement, yearMonth]);

const year = yearMonth?.substring(0, 4) || getYear(new Date());
const month = yearMonth?.substring(4) || getMonth(new Date());
Expand All @@ -81,7 +89,8 @@ function WalletStatementPage({walletStatement, route}: WalletStatementPageProps)
>
<HeaderWithBackButton
title={Str.recapitalize(title)}
shouldShowDownloadButton={!isOffline || isWalletStatementGenerating}
shouldShowDownloadButton={!isOffline || isDownloading}
isDownloading={isDownloading}
onDownloadButtonPress={processDownload}
/>
<FullPageOfflineBlockingView>
Expand All @@ -93,8 +102,4 @@ function WalletStatementPage({walletStatement, route}: WalletStatementPageProps)

WalletStatementPage.displayName = 'WalletStatementPage';

export default withOnyx<WalletStatementPageProps, WalletStatementOnyxProps>({
walletStatement: {
key: ONYXKEYS.WALLET_STATEMENT,
},
})(WalletStatementPage);
export default WalletStatementPage;

0 comments on commit 648aee5

Please sign in to comment.