Skip to content

Commit

Permalink
feat(suite-native): better txn names according to desktop logic
Browse files Browse the repository at this point in the history
  • Loading branch information
vytick committed Nov 7, 2024
1 parent cb8cded commit 60fc5dc
Show file tree
Hide file tree
Showing 5 changed files with 109 additions and 43 deletions.
16 changes: 16 additions & 0 deletions suite-native/intl/src/en.ts
Original file line number Diff line number Diff line change
Expand Up @@ -789,6 +789,22 @@ export const en = {
toggleTokens: 'Include tokens',
title: 'Note, your {networkName} balance doesn’t include tokens.',
},
name: {
received: 'Received',
receiving: 'Receiving',
sent: 'Sent',
sending: 'Sending',
pending: 'Pending',
contract: 'Contract',
self: 'Self',
joint: 'Joined',
failed: 'Failed',
unknown: 'Unknown',
withdrawal: 'Rewards withdrawal',
stake_delegation: 'Stake delegation',
stake_registration: 'Registration of a stake address',
stake_deregistration: 'Deregistration of a stake address',
},
},
device: {
title: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,13 +55,15 @@ export const TransactionDetailHeader = ({
const isPendingTx = isPending(transaction);
const isFailedTx = transaction.type === 'failed';
const signValue = getTransactionValueSign(tokenTransfer?.type ?? transaction.type);
const isTokenOnlyTransaction = transaction.amount === '0' && transaction.tokens.length !== 0;
const txType = isTokenOnlyTransaction ? transaction.tokens[0].type : type;

return (
<DiscreetTextTrigger>
<Box alignItems="center">
<VStack spacing="sp16" alignItems="center" justifyContent="center">
<TransactionIcon
transactionType={type}
transactionType={txType}
isAnimated={isPendingTx}
containerSize={ICON_SIZE}
iconSize="extraLarge"
Expand Down
64 changes: 64 additions & 0 deletions suite-native/transactions/src/components/TransactionName.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
import { WalletAccountTransaction } from '@suite-common/wallet-types';
import { Translation, TxKeyPath } from '@suite-native/intl';

type TransactionNameProps = {
transaction: WalletAccountTransaction;
isPending: boolean;
};

interface GetSelfTransactionMessageByTypeProps {
type?: Required<WalletAccountTransaction>['cardanoSpecific']['subtype'];
}

const getSelfTransactionMessageByType = ({
type,
}: GetSelfTransactionMessageByTypeProps): TxKeyPath => {
switch (type) {
case 'withdrawal':
return 'transactions.name.withdrawal';
case 'stake_delegation':
return 'transactions.name.stake_delegation';
case 'stake_registration':
return 'transactions.name.stake_registration';
case 'stake_deregistration':
return 'transactions.name.stake_deregistration';
default:
return 'transactions.name.self';
}
};

export const getTransactionName = (
transaction: WalletAccountTransaction,
isPending: boolean,
): TxKeyPath => {
switch (transaction.type) {
case 'sent':
return isPending ? 'transactions.name.sending' : 'transactions.name.sent';
case 'recv':
return isPending ? 'transactions.name.receiving' : 'transactions.name.received';
case 'failed':
return 'transactions.name.failed';
case 'joint':
return 'transactions.name.joint';
case 'contract':
return 'transactions.name.contract';
case 'self':
return getSelfTransactionMessageByType({
type: transaction.cardanoSpecific?.subtype,
});
case 'unknown':
default:
return isPending ? 'transactions.name.pending' : 'transactions.name.unknown';
}
};

export const TransactionName = ({ transaction, isPending }: TransactionNameProps) => {
const ethName = transaction.ethereumSpecific?.parsedData?.name;

// use name of eth txns, but for Transfer
if (ethName && !(ethName === 'Transfer' && ['recv', 'sent'].includes(transaction.type))) {
return ethName;
}

return <Translation id={getTransactionName(transaction, isPending)} />;
};
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { useSelector } from 'react-redux';

import { useNavigation } from '@react-navigation/native';

import { AccountKey, TransactionType } from '@suite-common/wallet-types';
import { AccountKey, TransactionType, WalletAccountTransaction } from '@suite-common/wallet-types';
import { prepareNativeStyle, useNativeStyles } from '@trezor/styles';
import {
RootStackParamList,
Expand All @@ -17,6 +17,7 @@ import {
selectIsPhishingTransaction,
selectIsTransactionPending,
selectTransactionBlockTimeById,
selectTransactionByTxidAndAccountKey,
TransactionsRootState,
} from '@suite-common/wallet-core';
import { NetworkSymbol } from '@suite-common/wallet-config';
Expand All @@ -26,6 +27,7 @@ import { Translation } from '@suite-native/intl';
import { TokenDefinitionsRootState } from '@suite-common/token-definitions';

import { TransactionIcon } from './TransactionIcon';
import { TransactionName } from '../TransactionName';

type TransactionListItemContainerProps = {
children: ReactNode;
Expand All @@ -44,16 +46,6 @@ type TransactionListItemStyleProps = {
isLast: boolean;
};

const transactionTitleMap = {
recv: 'Received',
sent: 'Sent',
self: 'Self',
joint: 'Joined',
contract: 'Contract',
failed: 'Transaction failed',
unknown: 'Unknown',
} as const satisfies Record<TransactionType, string>;

export const transactionListItemContainerStyle = prepareNativeStyle<TransactionListItemStyleProps>(
(utils, { isFirst, isLast }) => ({
flexDirection: 'row',
Expand Down Expand Up @@ -104,23 +96,6 @@ export const valuesContainerStyle = prepareNativeStyle(utils => ({
maxWidth: '40%',
}));

const getTransactionTitle = (transactionType: TransactionType, isPending: boolean) => {
if (isPending) {
switch (transactionType) {
case 'recv':
return 'Receiving';

case 'sent':
return 'Sending';

default:
return 'Pending';
}
}

return transactionTitleMap[transactionType];
};

export const TransactionListItemContainer = ({
children,
txid,
Expand Down Expand Up @@ -148,6 +123,9 @@ export const TransactionListItemContainer = ({
const includedCoinsLabel = `+${includedCoinsCount} coin${includedCoinsCount > 1 ? 's' : ''}`;

const { DateTimeFormatter } = useFormatters();
const transaction = useSelector((state: TransactionsRootState) =>
selectTransactionByTxidAndAccountKey(state, txid, accountKey),
) as WalletAccountTransaction;
const transactionBlockTime = useSelector((state: TransactionsRootState) =>
selectTransactionBlockTimeById(state, txid, accountKey),
);
Expand All @@ -164,7 +142,6 @@ export const TransactionListItemContainer = ({
const iconColor: Color = isTransactionPending ? 'backgroundAlertYellowBold' : 'iconSubdued';
const coinSymbol = isPhishingTransaction ? undefined : networkSymbol;
const contractAddress = isPhishingTransaction ? undefined : tokenTransfer?.contract;
const transactionTitle = getTransactionTitle(transactionType, isTransactionPending);

const DateTextComponent = isPhishingTransaction ? DiscreetText : Text;

Expand All @@ -184,7 +161,14 @@ export const TransactionListItemContainer = ({
<Box marginLeft="sp16" flex={1}>
<HStack flexDirection="row" alignItems="center" spacing="sp4">
<Box style={applyStyle(titleStyle)}>
<Text variant="body">{transactionTitle}</Text>
<Text variant="body">
{

Check warning on line 165 in suite-native/transactions/src/components/TransactionsList/TransactionListItemContainer.tsx

View workflow job for this annotation

GitHub Actions / Linting and formatting

Curly braces are unnecessary here
<TransactionName
transaction={transaction}
isPending={isTransactionPending}
/>
}
</Text>
{isPhishingTransaction && (
<Badge
label={<Translation id="transactions.phishing.badge" />}
Expand Down
24 changes: 12 additions & 12 deletions suite-native/transactions/src/screens/TransactionDetailScreen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { useSelector } from 'react-redux';
import {
BlockchainRootState,
selectBlockchainExplorerBySymbol,
selectIsTransactionPending,
selectTransactionByTxidAndAccountKey,
TransactionsRootState,
} from '@suite-common/wallet-core';
Expand All @@ -19,21 +20,12 @@ import {
} from '@suite-native/navigation';
import { useNativeStyles } from '@trezor/styles';
import { TypedTokenTransfer, WalletAccountTransaction } from '@suite-native/tokens';
import { TokenAddress, TokenSymbol, TransactionType } from '@suite-common/wallet-types';
import { TokenAddress, TokenSymbol } from '@suite-common/wallet-types';
import { Translation } from '@suite-native/intl';

import { TransactionDetailData } from '../components/TransactionDetail/TransactionDetailData';
import { TransactionDetailHeader } from '../components/TransactionDetail/TransactionDetailHeader';

const typeHeaderMap = {
recv: 'Received',
sent: 'Sent',
contract: 'Contract',
self: 'Self',
joint: 'Joint',
failed: 'Failed',
unknown: 'Unknown',
} as const satisfies Record<TransactionType, string>;
import { TransactionName } from '../components/TransactionName';

export const TransactionDetailScreen = ({
route,
Expand All @@ -47,6 +39,9 @@ export const TransactionDetailScreen = ({
const blockchainExplorer = useSelector((state: BlockchainRootState) =>
selectBlockchainExplorerBySymbol(state, transaction?.symbol),
);
const isPending = useSelector((state: TransactionsRootState) =>
selectIsTransactionPending(state, txid, accountKey),
);

const tokenTransfer = transaction?.tokens.find(token => token.contract === tokenContract);

Expand Down Expand Up @@ -82,7 +77,12 @@ export const TransactionDetailScreen = ({
<Translation
id="transactions.detail.header"
values={{
transactionType: _ => typeHeaderMap[transaction.type],
transactionType: _ => (
<TransactionName
transaction={transaction}
isPending={isPending}
/>
),
}}
/>
</Text>
Expand Down

0 comments on commit 60fc5dc

Please sign in to comment.