Skip to content
This repository was archived by the owner on Jun 24, 2022. It is now read-only.

Commit

Permalink
refactor: transaction info is translated in the appropriate places (#…
Browse files Browse the repository at this point in the history
…2380)

* refactor: transaction info is translated in the appropriate places

fixes Uniswap/interface#1756

* getting closer

* more work

* finished, finally

* bit more refactoring

* move summary into its own file

* little more cleanup in the transaction summary file

* fix bad copy

* fix the migrate notification

* missing translation

* fix the language for vote and address other pr comments

* fix typo

* - remove old transactions with this update
- change to present tense
- show ens name where appropriate

* add a test that shows we don't clear old ones
  • Loading branch information
moodysalem authored Sep 21, 2021
1 parent 9fa3b70 commit fb07919
Show file tree
Hide file tree
Showing 30 changed files with 922 additions and 358 deletions.
19 changes: 10 additions & 9 deletions src/components/AccountDetails/Transaction.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
import styled from 'styled-components/macro'
import { CheckCircle, Triangle } from 'react-feather'
import styled from 'styled-components/macro'

import { useActiveWeb3React } from '../../hooks/web3'
import { ExternalLink } from '../../theme'
import { useAllTransactions } from '../../state/transactions/hooks'
import { ExternalLink } from '../../theme'
import { ExplorerDataType, getExplorerLink } from '../../utils/getExplorerLink'
import { RowFixed } from '../Row'
import Loader from '../Loader'

const TransactionWrapper = styled.div``
import { RowFixed } from '../Row'
import { TransactionSummary } from './TransactionSummary'

const TransactionStatusText = styled.div`
margin-right: 0.5rem;
Expand Down Expand Up @@ -40,26 +39,28 @@ export default function Transaction({ hash }: { hash: string }) {
const allTransactions = useAllTransactions()

const tx = allTransactions?.[hash]
const summary = tx?.summary
const info = tx?.info
const pending = !tx?.receipt
const success = !pending && tx && (tx.receipt?.status === 1 || typeof tx.receipt?.status === 'undefined')

if (!chainId) return null

return (
<TransactionWrapper>
<div>
<TransactionState
href={getExplorerLink(chainId, hash, ExplorerDataType.TRANSACTION)}
pending={pending}
success={success}
>
<RowFixed>
<TransactionStatusText>{summary ?? hash}</TransactionStatusText>
<TransactionStatusText>
<TransactionSummary info={info} />
</TransactionStatusText>
</RowFixed>
<IconWrapper pending={pending} success={success}>
{pending ? <Loader /> : success ? <CheckCircle size="16" /> : <Triangle size="16" />}
</IconWrapper>
</TransactionState>
</TransactionWrapper>
</div>
)
}
328 changes: 328 additions & 0 deletions src/components/AccountDetails/TransactionSummary.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,328 @@
import { Trans } from '@lingui/macro'
import { Fraction, TradeType } from '@uniswap/sdk-core'
import JSBI from 'jsbi'
import { useCurrency, useToken } from '../../hooks/Tokens'
import useENSName from '../../hooks/useENSName'
import { VoteOption } from '../../state/governance/types'
import {
AddLiquidityV2PoolTransactionInfo,
AddLiquidityV3PoolTransactionInfo,
ApproveTransactionInfo,
ClaimTransactionInfo,
CollectFeesTransactionInfo,
CreateV3PoolTransactionInfo,
DelegateTransactionInfo,
DepositLiquidityStakingTransactionInfo,
ExactInputSwapTransactionInfo,
ExactOutputSwapTransactionInfo,
MigrateV2LiquidityToV3TransactionInfo,
RemoveLiquidityV3TransactionInfo,
SubmitProposalTransactionInfo,
TransactionInfo,
TransactionType,
VoteTransactionInfo,
WithdrawLiquidityStakingTransactionInfo,
WrapTransactionInfo,
} from '../../state/transactions/actions'

function formatAmount(amountRaw: string, decimals: number, sigFigs: number): string {
return new Fraction(amountRaw, JSBI.exponentiate(JSBI.BigInt(10), JSBI.BigInt(decimals))).toSignificant(sigFigs)
}

function FormattedCurrencyAmount({
rawAmount,
symbol,
decimals,
sigFigs,
}: {
rawAmount: string
symbol: string
decimals: number
sigFigs: number
}) {
return (
<>
{formatAmount(rawAmount, decimals, sigFigs)} {symbol}
</>
)
}

function FormattedCurrencyAmountManaged({
rawAmount,
currencyId,
sigFigs = 6,
}: {
rawAmount: string
currencyId: string
sigFigs: number
}) {
const currency = useCurrency(currencyId)
return currency ? (
<FormattedCurrencyAmount
rawAmount={rawAmount}
decimals={currency.decimals}
sigFigs={sigFigs}
symbol={currency.symbol ?? '???'}
/>
) : null
}

function ClaimSummary({ info: { recipient, uniAmountRaw } }: { info: ClaimTransactionInfo }) {
const { ENSName } = useENSName()
return typeof uniAmountRaw === 'string' ? (
<Trans>
Claim <FormattedCurrencyAmount rawAmount={uniAmountRaw} symbol={'UNI'} decimals={18} sigFigs={4} /> for{' '}
{ENSName ?? recipient}
</Trans>
) : (
<Trans>Claim UNI reward for {ENSName ?? recipient}</Trans>
)
}

function SubmitProposalTransactionSummary({}: { info: SubmitProposalTransactionInfo }) {
return <Trans>Submit new proposal</Trans>
}

function ApprovalSummary({ info }: { info: ApproveTransactionInfo }) {
const token = useToken(info.tokenAddress)

return <Trans>Approve {token?.symbol}</Trans>
}

function VoteSummary({ info }: { info: VoteTransactionInfo }) {
const proposalKey = `${info.governorAddress}/${info.proposalId}`
if (info.reason && info.reason.trim().length > 0) {
switch (info.decision) {
case VoteOption.For:
return <Trans>Vote for proposal {proposalKey}</Trans>
case VoteOption.Abstain:
return <Trans>Vote to abstain on proposal {proposalKey}</Trans>
case VoteOption.Against:
return <Trans>Vote against proposal {proposalKey}</Trans>
}
} else {
switch (info.decision) {
case VoteOption.For:
return (
<Trans>
Vote for proposal {proposalKey} with reason &quot;{info.reason}&quot;
</Trans>
)
case VoteOption.Abstain:
return (
<Trans>
Vote to abstain on proposal {proposalKey} with reason &quot;{info.reason}&quot;
</Trans>
)
case VoteOption.Against:
return (
<Trans>
Vote against proposal {proposalKey} with reason &quot;{info.reason}&quot;
</Trans>
)
}
}
}

function DelegateSummary({ info: { delegatee } }: { info: DelegateTransactionInfo }) {
const { ENSName } = useENSName(delegatee)
return <Trans>Delegate voting power to {ENSName ?? delegatee}</Trans>
}

function WrapSummary({ info: { currencyAmountRaw, unwrapped } }: { info: WrapTransactionInfo }) {
if (unwrapped) {
return (
<Trans>
Unwrap <FormattedCurrencyAmount rawAmount={currencyAmountRaw} symbol={'WETH'} decimals={18} sigFigs={6} /> to
ETH
</Trans>
)
} else {
return (
<Trans>
Wrap <FormattedCurrencyAmount rawAmount={currencyAmountRaw} symbol={'ETH'} decimals={18} sigFigs={6} /> to WETH
</Trans>
)
}
}

function DepositLiquidityStakingSummary({}: { info: DepositLiquidityStakingTransactionInfo }) {
// not worth rendering the tokens since you can should no longer deposit liquidity in the staking contracts
// todo: deprecate and delete the code paths that allow this, show user more information
return <Trans>Deposit liquidity</Trans>
}

function WithdrawLiquidityStakingSummary({}: { info: WithdrawLiquidityStakingTransactionInfo }) {
return <Trans>Withdraw deposited liquidity</Trans>
}

function MigrateLiquidityToV3Summary({
info: { baseCurrencyId, quoteCurrencyId },
}: {
info: MigrateV2LiquidityToV3TransactionInfo
}) {
const baseCurrency = useCurrency(baseCurrencyId)
const quoteCurrency = useCurrency(quoteCurrencyId)

return (
<Trans>
Migrate {baseCurrency?.symbol}/{quoteCurrency?.symbol} liquidity to V3
</Trans>
)
}

function CreateV3PoolSummary({ info: { quoteCurrencyId, baseCurrencyId } }: { info: CreateV3PoolTransactionInfo }) {
const baseCurrency = useCurrency(baseCurrencyId)
const quoteCurrency = useCurrency(quoteCurrencyId)

return (
<Trans>
Create {baseCurrency?.symbol}/{quoteCurrency?.symbol} V3 pool
</Trans>
)
}

function CollectFeesSummary({ info: { currencyId0, currencyId1 } }: { info: CollectFeesTransactionInfo }) {
const currency0 = useCurrency(currencyId0)
const currency1 = useCurrency(currencyId1)

return (
<Trans>
Collect {currency0?.symbol}/{currency1?.symbol} fees
</Trans>
)
}

function RemoveLiquidityV3Summary({
info: { baseCurrencyId, quoteCurrencyId, expectedAmountBaseRaw, expectedAmountQuoteRaw },
}: {
info: RemoveLiquidityV3TransactionInfo
}) {
return (
<Trans>
Remove{' '}
<FormattedCurrencyAmountManaged rawAmount={expectedAmountBaseRaw} currencyId={baseCurrencyId} sigFigs={3} /> and{' '}
<FormattedCurrencyAmountManaged rawAmount={expectedAmountQuoteRaw} currencyId={quoteCurrencyId} sigFigs={3} />
</Trans>
)
}

function AddLiquidityV3PoolSummary({
info: { createPool, quoteCurrencyId, baseCurrencyId },
}: {
info: AddLiquidityV3PoolTransactionInfo
}) {
const baseCurrency = useCurrency(baseCurrencyId)
const quoteCurrency = useCurrency(quoteCurrencyId)

return createPool ? (
<Trans>
Create pool and add {baseCurrency?.symbol}/{quoteCurrency?.symbol} V3 liquidity
</Trans>
) : (
<Trans>
Add {baseCurrency?.symbol}/{quoteCurrency?.symbol} V3 liquidity
</Trans>
)
}

function AddLiquidityV2PoolSummary({
info: { quoteCurrencyId, expectedAmountBaseRaw, expectedAmountQuoteRaw, baseCurrencyId },
}: {
info: AddLiquidityV2PoolTransactionInfo
}) {
return (
<Trans>
Add <FormattedCurrencyAmountManaged rawAmount={expectedAmountBaseRaw} currencyId={baseCurrencyId} sigFigs={3} />{' '}
and <FormattedCurrencyAmountManaged rawAmount={expectedAmountQuoteRaw} currencyId={quoteCurrencyId} sigFigs={3} />{' '}
to Uniswap V2
</Trans>
)
}

function SwapSummary({ info }: { info: ExactInputSwapTransactionInfo | ExactOutputSwapTransactionInfo }) {
if (info.tradeType === TradeType.EXACT_INPUT) {
return (
<Trans>
Swap exactly{' '}
<FormattedCurrencyAmountManaged
rawAmount={info.inputCurrencyAmountRaw}
currencyId={info.inputCurrencyId}
sigFigs={6}
/>{' '}
for{' '}
<FormattedCurrencyAmountManaged
rawAmount={info.expectedOutputCurrencyAmountRaw}
currencyId={info.outputCurrencyId}
sigFigs={6}
/>
</Trans>
)
} else {
return (
<Trans>
Swap{' '}
<FormattedCurrencyAmountManaged
rawAmount={info.expectedInputCurrencyAmountRaw}
currencyId={info.inputCurrencyId}
sigFigs={6}
/>{' '}
for exactly{' '}
<FormattedCurrencyAmountManaged
rawAmount={info.outputCurrencyAmountRaw}
currencyId={info.outputCurrencyId}
sigFigs={6}
/>
</Trans>
)
}
}

export function TransactionSummary({ info }: { info: TransactionInfo }) {
switch (info.type) {
case TransactionType.ADD_LIQUIDITY_V3_POOL:
return <AddLiquidityV3PoolSummary info={info} />

case TransactionType.ADD_LIQUIDITY_V2_POOL:
return <AddLiquidityV2PoolSummary info={info} />

case TransactionType.CLAIM:
return <ClaimSummary info={info} />

case TransactionType.DEPOSIT_LIQUIDITY_STAKING:
return <DepositLiquidityStakingSummary info={info} />

case TransactionType.WITHDRAW_LIQUIDITY_STAKING:
return <WithdrawLiquidityStakingSummary info={info} />

case TransactionType.SWAP:
return <SwapSummary info={info} />

case TransactionType.APPROVAL:
return <ApprovalSummary info={info} />

case TransactionType.VOTE:
return <VoteSummary info={info} />

case TransactionType.DELEGATE:
return <DelegateSummary info={info} />

case TransactionType.WRAP:
return <WrapSummary info={info} />

case TransactionType.CREATE_V3_POOL:
return <CreateV3PoolSummary info={info} />

case TransactionType.MIGRATE_LIQUIDITY_V3:
return <MigrateLiquidityToV3Summary info={info} />

case TransactionType.COLLECT_FEES:
return <CollectFeesSummary info={info} />

case TransactionType.REMOVE_LIQUIDITY_V3:
return <RemoveLiquidityV3Summary info={info} />

case TransactionType.SUBMIT_PROPOSAL:
return <SubmitProposalTransactionSummary info={info} />
}
}
4 changes: 2 additions & 2 deletions src/components/Popups/PopupItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -73,9 +73,9 @@ export default function PopupItem({
let popupContent
if ('txn' in content) {
const {
txn: { hash, success, summary },
txn: { hash },
} = content
popupContent = <TransactionPopup hash={hash} success={success} summary={summary} />
popupContent = <TransactionPopup hash={hash} />
}

const faderStyle = useSpring({
Expand Down
Loading

0 comments on commit fb07919

Please sign in to comment.