Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Transactions - Update Generic Receipts to use ReceiptBackground #34843

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
80 commits
Select commit Hold shift + click to select a range
d99d92d
implemented receipt image component
FitseTLT Jan 19, 2024
a1f5f69
pass receipt name for non modal display
FitseTLT Jan 19, 2024
7dfd885
minor fix
FitseTLT Jan 19, 2024
e9c7666
changed implementation
FitseTLT Jan 20, 2024
e88e1ce
fix styling
FitseTLT Jan 20, 2024
26fa66b
fix borderRadius
FitseTLT Jan 20, 2024
d4abf53
type fix
FitseTLT Jan 20, 2024
63b41f6
minor fix
FitseTLT Jan 20, 2024
404fd8c
passed transaction prop
FitseTLT Jan 20, 2024
d6c274e
resolved conflict
FitseTLT Jan 23, 2024
9d38d93
updated attachement modal to consider thumnail display
FitseTLT Jan 23, 2024
796c340
minor fix
FitseTLT Jan 23, 2024
e9e2161
minor revert
FitseTLT Jan 23, 2024
dc760ca
small fix
FitseTLT Jan 23, 2024
7e1fd22
fix on thumbnail display logic
FitseTLT Jan 24, 2024
9a94024
minor type fix
FitseTLT Jan 24, 2024
0cfb3cb
Added file type label support for eThumbnail
FitseTLT Jan 25, 2024
c059ed1
pass transactionID for confirmation
FitseTLT Jan 25, 2024
7008a5d
minor fix
FitseTLT Jan 29, 2024
6a05c03
fix unnecessary condition
FitseTLT Jan 29, 2024
3f019a5
update to static icon layout
FitseTLT Jan 29, 2024
7b55b72
resolved conflicts
FitseTLT Jan 31, 2024
6d7481c
changed to isStaticIconLayout
FitseTLT Jan 31, 2024
e61a6c7
typescript fix
FitseTLT Jan 31, 2024
afbb639
set label text black
FitseTLT Jan 31, 2024
7310663
removed inline styles
FitseTLT Feb 1, 2024
21b5f5e
fix on comment
FitseTLT Feb 1, 2024
73f6495
fixed pending waypoints thumbnail display
FitseTLT Feb 1, 2024
10ff3ee
simplified condition
FitseTLT Feb 1, 2024
1f1b3dc
changed to isReceiptThumbnail prop
FitseTLT Feb 1, 2024
1fb6284
separated Ereceipt and thumbnail logic
FitseTLT Feb 5, 2024
45238a6
Merge branch 'main' into fix-update-to-use-of-ReceiptBackground
FitseTLT Feb 5, 2024
bb10a48
resolve conflicts
FitseTLT Feb 5, 2024
75ca883
minor lint fix
FitseTLT Feb 5, 2024
ee4d711
fix minor typescript issue
FitseTLT Feb 5, 2024
63c88ec
Merge branch 'main' into fix-update-to-use-of-ReceiptBackground
FitseTLT Feb 6, 2024
5f07c39
fix type
FitseTLT Feb 6, 2024
8f85721
fix based on comments
FitseTLT Feb 6, 2024
7b14b86
fix type
FitseTLT Feb 7, 2024
2a1ddf3
fix typescript
FitseTLT Feb 7, 2024
660ac05
Merge branch 'main' into fix-update-to-use-of-ReceiptBackground
FitseTLT Feb 8, 2024
4b058fd
Merge branch 'main' into fix-update-to-use-of-ReceiptBackground
FitseTLT Feb 12, 2024
6dfc00b
minor change
FitseTLT Feb 12, 2024
4a08601
pass iconSize prop
FitseTLT Feb 12, 2024
60c0773
Merge branch 'main' into fix-update-to-use-of-ReceiptBackground
FitseTLT Feb 13, 2024
8a97cad
Merge branch 'main' into fix-update-to-use-of-ReceiptBackground
FitseTLT Feb 13, 2024
f721557
use fetching waypoint function
FitseTLT Feb 13, 2024
c31c4b4
Merge branch 'main' into fix-update-to-use-of-ReceiptBackground
FitseTLT Feb 20, 2024
0f157fc
fix type
FitseTLT Feb 20, 2024
6db9480
Merge branch 'main' into fix-update-to-use-of-ReceiptBackground
FitseTLT Feb 21, 2024
c44b430
add fallbackIcon
FitseTLT Feb 21, 2024
7025bfa
applied dynamic thumbnail icon size
FitseTLT Feb 21, 2024
2b1c802
Merge branch 'main' into fix-update-to-use-of-ReceiptBackground
FitseTLT Feb 21, 2024
94174ba
Merge branch 'main' into fix-update-to-use-of-ReceiptBackground
FitseTLT Feb 22, 2024
9927c84
Merge branch 'main' into fix-update-to-use-of-ReceiptBackground
FitseTLT Feb 26, 2024
9eb1edd
use primary color for label text color
FitseTLT Feb 26, 2024
04a5193
Merge branch 'main' into fix-update-to-use-of-ReceiptBackground
FitseTLT Mar 6, 2024
c90ce7e
add Pdf thumbnail
FitseTLT Mar 6, 2024
9f38e25
updated to fixed color code depending on file extensions
FitseTLT Mar 6, 2024
63dc6f6
Merge branch 'main' into fix-update-to-use-of-ReceiptBackground
FitseTLT Mar 8, 2024
e05df18
remove unnecessary condition
FitseTLT Mar 8, 2024
b6fd6f4
final refactor changes
FitseTLT Mar 8, 2024
4d18121
minor fix
FitseTLT Mar 8, 2024
aa290ff
minor fix
FitseTLT Mar 8, 2024
b6a111a
minor
FitseTLT Mar 8, 2024
8d38141
Merge branch 'main' into fix-update-to-use-of-ReceiptBackground
FitseTLT Mar 8, 2024
79a95ff
Merge branch 'main' into fix-update-to-use-of-ReceiptBackground
FitseTLT Mar 11, 2024
7c1cf62
fix typescript
FitseTLT Mar 11, 2024
3fdef47
Merge branch 'main' into fix-update-to-use-of-ReceiptBackground
FitseTLT Mar 14, 2024
3a4760d
fix type
FitseTLT Mar 14, 2024
02e8025
suppress eslint warning
FitseTLT Mar 14, 2024
d492e62
Merge branch 'main' into fix-update-to-use-of-ReceiptBackground
FitseTLT Mar 18, 2024
edd747f
Merge branch 'main' into fix-update-to-use-of-ReceiptBackground
FitseTLT Mar 19, 2024
c32c8fb
updated label font size and line heights
FitseTLT Mar 19, 2024
edf7677
type update
FitseTLT Mar 21, 2024
e3236a3
Merge branch 'main' into fix-update-to-use-of-ReceiptBackground
FitseTLT Mar 21, 2024
8a02896
Merge branch 'main' into fix-update-to-use-of-ReceiptBackground
FitseTLT Mar 25, 2024
1bd9230
made label unselectable
FitseTLT Mar 25, 2024
3f2e1d3
fix lint
FitseTLT Mar 25, 2024
ab837e1
Merge branch 'main' into fix-update-to-use-of-ReceiptBackground
FitseTLT Mar 25, 2024
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
12 changes: 5 additions & 7 deletions src/components/DistanceEReceipt.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,9 @@ import Icon from './Icon';
import * as Expensicons from './Icon/Expensicons';
import ImageSVG from './ImageSVG';
import PendingMapView from './MapView/PendingMapView';
import ReceiptImage from './ReceiptImage';
import ScrollView from './ScrollView';
import Text from './Text';
import ThumbnailImage from './ThumbnailImage';

type DistanceEReceiptProps = {
/** The transaction for the distance request */
Expand All @@ -30,7 +30,7 @@ function DistanceEReceipt({transaction}: DistanceEReceiptProps) {
const thumbnail = TransactionUtils.hasReceipt(transaction) ? ReceiptUtils.getThumbnailAndImageURIs(transaction).thumbnail : null;
const {amount: transactionAmount, currency: transactionCurrency, merchant: transactionMerchant, created: transactionDate} = ReportUtils.getTransactionDetails(transaction) ?? {};
const formattedTransactionAmount = CurrencyUtils.convertToDisplayString(transactionAmount, transactionCurrency);
const thumbnailSource = tryResolveUrlFromApiRoot((thumbnail as string) || '');
const thumbnailSource = tryResolveUrlFromApiRoot(thumbnail ?? '');
const waypoints = useMemo(() => transaction?.comment?.waypoints ?? {}, [transaction?.comment?.waypoints]);
const sortedWaypoints = useMemo<WaypointCollection>(
() =>
Expand Down Expand Up @@ -58,11 +58,9 @@ function DistanceEReceipt({transaction}: DistanceEReceiptProps) {
{TransactionUtils.isFetchingWaypointsFromServer(transaction) || !thumbnailSource ? (
<PendingMapView />
) : (
<ThumbnailImage
previewSourceURL={thumbnailSource}
style={[styles.w100, styles.h100]}
isAuthTokenRequired
shouldDynamicallyResize={false}
<ReceiptImage
source={thumbnailSource}
shouldUseThumbnailImage
/>
)}
</View>
Expand Down
43 changes: 37 additions & 6 deletions src/components/EReceiptThumbnail.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import {withOnyx} from 'react-native-onyx';
import useStyleUtils from '@hooks/useStyleUtils';
import useThemeStyles from '@hooks/useThemeStyles';
import * as ReportUtils from '@libs/ReportUtils';
import colors from '@styles/theme/colors';
import variables from '@styles/variables';
import CONST from '@src/CONST';
import ONYXKEYS from '@src/ONYXKEYS';
Expand All @@ -14,6 +15,7 @@ import * as eReceiptBGs from './Icon/EReceiptBGs';
import * as Expensicons from './Icon/Expensicons';
import * as MCCIcons from './Icon/MCCIcons';
import Image from './Image';
import Text from './Text';

type EReceiptThumbnailOnyxProps = {
transaction: OnyxEntry<Transaction>;
Expand All @@ -26,6 +28,15 @@ type EReceiptThumbnailProps = EReceiptThumbnailOnyxProps & {
// eslint-disable-next-line react/no-unused-prop-types
transactionID: string;

/** Border radius to be applied on the parent view. */
borderRadius?: number;
FitseTLT marked this conversation as resolved.
Show resolved Hide resolved

/** The file extension of the receipt that the preview thumbnail is being displayed for. */
fileExtension?: string;

/** Whether it is a receipt thumbnail we are displaying. */
isReceiptThumbnail?: boolean;

/** Center the eReceipt Icon vertically */
centerIconV?: boolean;

Expand All @@ -42,13 +53,14 @@ const backgroundImages = {
[CONST.ERECEIPT_COLORS.PINK]: eReceiptBGs.EReceiptBG_Pink,
};

function EReceiptThumbnail({transaction, centerIconV = true, iconSize = 'large'}: EReceiptThumbnailProps) {
function EReceiptThumbnail({transaction, borderRadius, fileExtension, isReceiptThumbnail = false, centerIconV = true, iconSize = 'large'}: EReceiptThumbnailProps) {
const styles = useThemeStyles();
const StyleUtils = useStyleUtils();
const colorCode = isReceiptThumbnail ? StyleUtils.getFileExtensionColorCode(fileExtension) : StyleUtils.getEReceiptColorCode(transaction);

const backgroundImage = useMemo(() => backgroundImages[StyleUtils.getEReceiptColorCode(transaction)], [StyleUtils, transaction]);
const backgroundImage = useMemo(() => backgroundImages[colorCode], [colorCode]);

const colorStyles = StyleUtils.getEReceiptColorStyles(StyleUtils.getEReceiptColorCode(transaction));
const colorStyles = StyleUtils.getEReceiptColorStyles(colorCode);
const primaryColor = colorStyles?.backgroundColor;
const secondaryColor = colorStyles?.color;
const transactionDetails = ReportUtils.getTransactionDetails(transaction);
Expand All @@ -58,15 +70,21 @@ function EReceiptThumbnail({transaction, centerIconV = true, iconSize = 'large'}
let receiptIconWidth: number = variables.eReceiptIconWidth;
let receiptIconHeight: number = variables.eReceiptIconHeight;
let receiptMCCSize: number = variables.eReceiptMCCHeightWidth;
let labelFontSize: number = variables.fontSizeNormal;
let labelLineHeight: number = variables.lineHeightLarge;

if (iconSize === 'small') {
receiptIconWidth = variables.eReceiptIconWidthSmall;
receiptIconHeight = variables.eReceiptIconHeightSmall;
receiptMCCSize = variables.eReceiptMCCHeightWidthSmall;
labelFontSize = variables.fontSizeExtraSmall;
labelLineHeight = variables.lineHeightXSmall;
} else if (iconSize === 'medium') {
receiptIconWidth = variables.eReceiptIconWidthMedium;
receiptIconHeight = variables.eReceiptIconHeightMedium;
receiptMCCSize = variables.eReceiptMCCHeightWidthMedium;
labelFontSize = variables.fontSizeLabel;
labelLineHeight = variables.lineHeightNormal;
}

return (
Expand All @@ -77,6 +95,7 @@ function EReceiptThumbnail({transaction, centerIconV = true, iconSize = 'large'}
styles.overflowHidden,
styles.alignItemsCenter,
centerIconV ? styles.justifyContentCenter : {},
borderRadius ? {borderRadius} : {},
FitseTLT marked this conversation as resolved.
Show resolved Hide resolved
]}
>
<Image
Expand All @@ -93,7 +112,20 @@ function EReceiptThumbnail({transaction, centerIconV = true, iconSize = 'large'}
fill={secondaryColor}
additionalStyles={[styles.fullScreen]}
/>
{MCCIcon ? (
{isReceiptThumbnail && fileExtension && (
<Text
selectable={false}
style={[
styles.labelStrong,
StyleUtils.getFontSizeStyle(labelFontSize),
StyleUtils.getLineHeightStyle(labelLineHeight),
StyleUtils.getTextColorStyle(primaryColor ?? colors.black),
]}
>
{fileExtension.toUpperCase()}
</Text>
)}
{MCCIcon && !isReceiptThumbnail ? (
FitseTLT marked this conversation as resolved.
Show resolved Hide resolved
<Icon
src={MCCIcon}
height={receiptMCCSize}
Expand All @@ -108,10 +140,9 @@ function EReceiptThumbnail({transaction, centerIconV = true, iconSize = 'large'}
}

EReceiptThumbnail.displayName = 'EReceiptThumbnail';

export default withOnyx<EReceiptThumbnailProps, EReceiptThumbnailOnyxProps>({
transaction: {
key: ({transactionID}) => `${ONYXKEYS.COLLECTION.TRANSACTION}${transactionID}`,
},
})(EReceiptThumbnail);
export type {EReceiptThumbnailProps, EReceiptThumbnailOnyxProps};
export type {IconSize, EReceiptThumbnailProps, EReceiptThumbnailOnyxProps};
19 changes: 12 additions & 7 deletions src/components/MoneyRequestConfirmationList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,10 @@ import ButtonWithDropdownMenu from './ButtonWithDropdownMenu';
import type {DropdownOption} from './ButtonWithDropdownMenu/types';
import ConfirmedRoute from './ConfirmedRoute';
import FormHelpMessage from './FormHelpMessage';
import Image from './Image';
import MenuItemWithTopDescription from './MenuItemWithTopDescription';
import OptionsSelector from './OptionsSelector';
import ReceiptEmptyState from './ReceiptEmptyState';
import ReceiptImage from './ReceiptImage';
import SettlementButton from './SettlementButton';
import ShowMoreButton from './ShowMoreButton';
import Switch from './Switch';
Expand Down Expand Up @@ -577,8 +577,12 @@ function MoneyRequestConfirmationList({
);
}, [isReadOnly, iouType, bankAccountRoute, iouCurrencyCode, policyID, selectedParticipants.length, confirm, splitOrRequestOptions, formError, styles.ph1, styles.mb2]);

const {image: receiptImage, thumbnail: receiptThumbnail} =
receiptPath && receiptFilename ? ReceiptUtils.getThumbnailAndImageURIs(transaction, receiptPath, receiptFilename) : ({} as ReceiptUtils.ThumbnailAndImageURI);
const {
image: receiptImage,
thumbnail: receiptThumbnail,
isThumbnail,
fileExtension,
} = receiptPath && receiptFilename ? ReceiptUtils.getThumbnailAndImageURIs(transaction, receiptPath, receiptFilename) : ({} as ReceiptUtils.ThumbnailAndImageURI);
return (
// @ts-expect-error This component is deprecated and will not be migrated to TypeScript (context: https://expensify.slack.com/archives/C01GTK53T8Q/p1709232289899589?thread_ts=1709156803.359359&cid=C01GTK53T8Q)
<OptionsSelector
Expand All @@ -604,16 +608,17 @@ function MoneyRequestConfirmationList({
<ConfirmedRoute transaction={transaction} />
</View>
)}

{/* eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing */}
{receiptImage || receiptThumbnail ? (
<Image
<ReceiptImage
style={styles.moneyRequestImage}
// eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing
source={{uri: String(receiptThumbnail || receiptImage)}}
isThumbnail={isThumbnail}
source={String(receiptThumbnail ?? receiptImage)}
// AuthToken is required when retrieving the image from the server
// but we don't need it to load the blob:// or file:// image when starting a money request / split bill
// So if we have a thumbnail, it means we're retrieving the image from the server
isAuthTokenRequired={!!receiptThumbnail}
fileExtension={fileExtension}
/>
) : (
// The empty receipt component should only show for IOU Requests of a paid policy ("Team" or "Corporate")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,12 +37,12 @@ import ConfirmedRoute from './ConfirmedRoute';
import ConfirmModal from './ConfirmModal';
import FormHelpMessage from './FormHelpMessage';
import * as Expensicons from './Icon/Expensicons';
import Image from './Image';
import MenuItemWithTopDescription from './MenuItemWithTopDescription';
import optionPropTypes from './optionPropTypes';
import OptionsSelector from './OptionsSelector';
import PDFThumbnail from './PDFThumbnail';
import ReceiptEmptyState from './ReceiptEmptyState';
import ReceiptImage from './ReceiptImage';
import SettlementButton from './SettlementButton';
import Switch from './Switch';
import tagPropTypes from './tagPropTypes';
Expand Down Expand Up @@ -897,6 +897,8 @@ function MoneyTemporaryForRefactorRequestConfirmationList({
const {
image: receiptImage,
thumbnail: receiptThumbnail,
isThumbnail,
fileExtension,
isLocalFile,
} = receiptPath && receiptFilename ? ReceiptUtils.getThumbnailAndImageURIs(transaction, receiptPath, receiptFilename) : {};

Expand All @@ -911,16 +913,18 @@ function MoneyTemporaryForRefactorRequestConfirmationList({
onPassword={() => setIsAttachmentInvalid(true)}
/>
) : (
<Image
<ReceiptImage
style={styles.moneyRequestImage}
source={{uri: receiptThumbnail || receiptImage}}
isThumbnail={isThumbnail}
source={receiptThumbnail || receiptImage}
// AuthToken is required when retrieving the image from the server
// but we don't need it to load the blob:// or file:// image when starting a money request / split bill
// So if we have a thumbnail, it means we're retrieving the image from the server
isAuthTokenRequired={!_.isEmpty(receiptThumbnail)}
fileExtension={fileExtension}
/>
),
[receiptFilename, receiptImage, styles, receiptThumbnail, isLocalFile, isAttachmentInvalid],
[isLocalFile, receiptFilename, receiptImage, styles.moneyRequestImage, isAttachmentInvalid, isThumbnail, receiptThumbnail, fileExtension],
);

return (
Expand Down
136 changes: 136 additions & 0 deletions src/components/ReceiptImage.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
import React from 'react';
import {View} from 'react-native';
import useThemeStyles from '@hooks/useThemeStyles';
import type IconAsset from '@src/types/utils/IconAsset';
import EReceiptThumbnail from './EReceiptThumbnail';
import type {IconSize} from './EReceiptThumbnail';
import Image from './Image';
import PDFThumbnail from './PDFThumbnail';
import ThumbnailImage from './ThumbnailImage';

type Style = {height: number; borderRadius: number; margin: number};

type ReceiptImageProps = (
| {
/** Transaction ID of the transaction the receipt belongs to */
transactionID: string;

/** Whether it is EReceipt */
isEReceipt: boolean;

/** Whether it is receipt preview thumbnail we are displaying */
isThumbnail?: boolean;

/** Url of the receipt image */
source?: string;

/** Whether it is a pdf thumbnail we are displaying */
isPDFThumbnail?: boolean;
}
| {
transactionID?: string;
isEReceipt?: boolean;
isThumbnail: boolean;
source?: string;
isPDFThumbnail?: boolean;
}
| {
transactionID?: string;
isEReceipt?: boolean;
isThumbnail?: boolean;
source: string;
isPDFThumbnail?: boolean;
}
| {
transactionID?: string;
isEReceipt?: boolean;
isThumbnail?: boolean;
source: string;
isPDFThumbnail: string;
}
) & {
/** Whether we should display the receipt with ThumbnailImage component */
shouldUseThumbnailImage?: boolean;

/** Whether the receipt image requires an authToken */
isAuthTokenRequired?: boolean;

/** Any additional styles to apply */
style?: Style;

/** The file extension of the receipt file */
fileExtension?: string;

/** number of images displayed in the same parent container */
iconSize?: IconSize;

/** If the image fails to load – show the provided fallback icon */
fallbackIcon?: IconAsset;

/** The size of the fallback icon */
fallbackIconSize?: number;
};

function ReceiptImage({
transactionID,
isPDFThumbnail = false,
isThumbnail = false,
shouldUseThumbnailImage = false,
isEReceipt = false,
source,
isAuthTokenRequired,
style,
fileExtension,
iconSize,
fallbackIcon,
fallbackIconSize,
}: ReceiptImageProps) {
const styles = useThemeStyles();

if (isPDFThumbnail) {
return (
<PDFThumbnail
previewSourceURL={source ?? ''}
style={[styles.w100, styles.h100]}
/>
);
}

if (isEReceipt || isThumbnail) {
const props = isThumbnail && {borderRadius: style?.borderRadius, fileExtension, isReceiptThumbnail: true};
return (
<View style={style ?? [styles.w100, styles.h100]}>
<EReceiptThumbnail
transactionID={transactionID ?? ''}
iconSize={iconSize}
// eslint-disable-next-line react/jsx-props-no-spreading
{...props}
/>
</View>
);
}

if (shouldUseThumbnailImage) {
return (
<ThumbnailImage
previewSourceURL={source ?? ''}
style={[styles.w100, styles.h100]}
isAuthTokenRequired
shouldDynamicallyResize={false}
fallbackIcon={fallbackIcon}
fallbackIconSize={fallbackIconSize}
/>
);
}

return (
<Image
source={{uri: source}}
style={style ?? [styles.w100, styles.h100]}
isAuthTokenRequired={isAuthTokenRequired}
/>
);
}

export type {ReceiptImageProps};
export default ReceiptImage;
2 changes: 2 additions & 0 deletions src/components/ReportActionItem/MoneyRequestView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -259,6 +259,8 @@ function MoneyRequestView({
) : (
<ReportActionItemImage
thumbnail={receiptURIs?.thumbnail}
fileExtension={receiptURIs?.fileExtension}
isThumbnail={receiptURIs?.isThumbnail}
image={receiptURIs?.image}
isLocalFile={receiptURIs?.isLocalFile}
filename={receiptURIs?.filename}
Expand Down
Loading
Loading