From f45ff6b61e2a6ac9fb52fe269200b92f9e69d91e Mon Sep 17 00:00:00 2001 From: Kristof Csillag Date: Thu, 6 Jul 2023 19:45:51 +0200 Subject: [PATCH 1/5] Display type in tokens table --- .changelog/685.feature.md | 1 + src/app/components/Tokens/TokenDetails.tsx | 4 ++++ src/app/components/Tokens/TokenList.tsx | 6 ++++++ 3 files changed, 11 insertions(+) create mode 100644 .changelog/685.feature.md diff --git a/.changelog/685.feature.md b/.changelog/685.feature.md new file mode 100644 index 000000000..1cc98d4b4 --- /dev/null +++ b/.changelog/685.feature.md @@ -0,0 +1 @@ +Display type in tokens table diff --git a/src/app/components/Tokens/TokenDetails.tsx b/src/app/components/Tokens/TokenDetails.tsx index 9fe9f72d0..c0a02fe5c 100644 --- a/src/app/components/Tokens/TokenDetails.tsx +++ b/src/app/components/Tokens/TokenDetails.tsx @@ -11,6 +11,7 @@ import { DashboardLink } from '../../pages/ParatimeDashboardPage/DashboardLink' import { DelayedContractVerificationIcon } from '../ContractVerificationIcon' import Box from '@mui/material/Box' import { COLORS } from '../../../styles/theme/colors' +import { getTokenTypeName } from '../../pages/TokenDashboardPage/TokenTypeCard' export const TokenDetails: FC<{ isLoading?: boolean @@ -40,6 +41,9 @@ export const TokenDetails: FC<{ ({token.symbol}) +
{t('common.type')}
+
{getTokenTypeName(t, token.type)}
+
{t(isMobile ? 'common.smartContract_short' : 'common.smartContract')}
diff --git a/src/app/components/Tokens/TokenList.tsx b/src/app/components/Tokens/TokenList.tsx index baa2682af..4b3f503b0 100644 --- a/src/app/components/Tokens/TokenList.tsx +++ b/src/app/components/Tokens/TokenList.tsx @@ -7,6 +7,7 @@ import { TokenLink } from './TokenLink' import { CopyToClipboard } from '../CopyToClipboard' import { DelayedContractVerificationIcon } from '../ContractVerificationIcon' import Box from '@mui/material/Box' +import { getTokenTypeName } from '../../pages/TokenDashboardPage/TokenTypeCard' type TokensProps = { tokens?: EvmToken[] @@ -21,6 +22,7 @@ export const TokenList = (props: TokensProps) => { const tableColumns: TableColProps[] = [ { key: 'index', content: '' }, { key: 'name', content: t('common.name') }, + { key: 'type', content: t('common.type') }, { key: 'contract', content: t('common.smartContract') }, { key: 'verification', content: t('contract.verification.title') }, { @@ -54,6 +56,10 @@ export const TokenList = (props: TokensProps) => { ), key: 'name', }, + { + key: 'type', + content: getTokenTypeName(t, token.type), + }, { content: ( From 6936bff79e082e8e67d29d2bef34790251a6804c Mon Sep 17 00:00:00 2001 From: Kristof Csillag Date: Fri, 7 Jul 2023 15:01:07 +0200 Subject: [PATCH 2/5] Consistently use the same token type names --- src/app/components/Tokens/TokenDetails.tsx | 2 +- src/app/components/Tokens/TokenList.tsx | 2 +- .../AccountDetailsPage/AccountTokensCard.tsx | 15 ++++-- src/app/pages/AccountDetailsPage/index.tsx | 5 +- .../TokenDashboardPage/TokenDetailsCard.tsx | 2 +- .../TokenDashboardPage/TokenTypeCard.tsx | 16 +----- src/locales/en/translation.json | 6 ++- src/types/tokens.ts | 51 +++++++++++++++++++ 8 files changed, 74 insertions(+), 25 deletions(-) create mode 100644 src/types/tokens.ts diff --git a/src/app/components/Tokens/TokenDetails.tsx b/src/app/components/Tokens/TokenDetails.tsx index c0a02fe5c..a89f44670 100644 --- a/src/app/components/Tokens/TokenDetails.tsx +++ b/src/app/components/Tokens/TokenDetails.tsx @@ -11,7 +11,7 @@ import { DashboardLink } from '../../pages/ParatimeDashboardPage/DashboardLink' import { DelayedContractVerificationIcon } from '../ContractVerificationIcon' import Box from '@mui/material/Box' import { COLORS } from '../../../styles/theme/colors' -import { getTokenTypeName } from '../../pages/TokenDashboardPage/TokenTypeCard' +import { getTokenTypeName } from '../../../types/tokens' export const TokenDetails: FC<{ isLoading?: boolean diff --git a/src/app/components/Tokens/TokenList.tsx b/src/app/components/Tokens/TokenList.tsx index 4b3f503b0..1349a664f 100644 --- a/src/app/components/Tokens/TokenList.tsx +++ b/src/app/components/Tokens/TokenList.tsx @@ -7,7 +7,7 @@ import { TokenLink } from './TokenLink' import { CopyToClipboard } from '../CopyToClipboard' import { DelayedContractVerificationIcon } from '../ContractVerificationIcon' import Box from '@mui/material/Box' -import { getTokenTypeName } from '../../pages/TokenDashboardPage/TokenTypeCard' +import { getTokenTypeName } from '../../../types/tokens' type TokensProps = { tokens?: EvmToken[] diff --git a/src/app/pages/AccountDetailsPage/AccountTokensCard.tsx b/src/app/pages/AccountDetailsPage/AccountTokensCard.tsx index 9d3735efa..e9d330e66 100644 --- a/src/app/pages/AccountDetailsPage/AccountTokensCard.tsx +++ b/src/app/pages/AccountDetailsPage/AccountTokensCard.tsx @@ -16,6 +16,11 @@ import { useRequiredScopeParam } from '../../hooks/useScopeParam' import { useAccount } from './hook' import { TokenLink } from '../../components/Tokens/TokenLink' import { AccountLink } from '../../components/Account/AccountLink' +import { + getTokenTypePluralDescription, + getTokenTypePluralName, + getTokenTypeStrictName, +} from '../../../types/tokens' type AccountTokensCardProps = { type: EvmTokenType @@ -28,8 +33,7 @@ export const AccountTokensCard: FC = ({ type }) => { const address = useLoaderData() as string const { t } = useTranslation() const locationHash = useLocation().hash.replace('#', '') - const tokenLabel = t(`account.${type}` as any) - const tokenListLabel = t('account.tokensListTitle', { token: tokenLabel }) + const tokenListLabel = getTokenTypePluralName(t, type) const tableColumns: TableColProps[] = [ { key: 'name', content: t('common.name') }, { key: 'contract', content: t('common.smartContract') }, @@ -86,7 +90,12 @@ export const AccountTokensCard: FC = ({ type }) => { {!isLoading && !account?.tokenBalances[type]?.length && ( - + )} { const { t } = useTranslation() @@ -65,12 +66,12 @@ export const AccountDetailsPage: FC = () => { { label: t('common.transactions'), to: txLink, visible: showTxs }, { label: t('tokens.transfers'), to: tokenTransfersLink, visible: showTokenTransfers }, { - label: t('account.tokensListTitle', { token: t(`account.ERC20`) }), + label: getTokenTypePluralName(t, EvmTokenType.ERC20), to: erc20Link, visible: showErc20, }, { - label: t('account.tokensListTitle', { token: t(`account.ERC721`) }), + label: getTokenTypePluralName(t, EvmTokenType.ERC721), to: erc721Link, visible: showErc721, }, diff --git a/src/app/pages/TokenDashboardPage/TokenDetailsCard.tsx b/src/app/pages/TokenDashboardPage/TokenDetailsCard.tsx index e67326b8e..b2bec5ad0 100644 --- a/src/app/pages/TokenDashboardPage/TokenDetailsCard.tsx +++ b/src/app/pages/TokenDashboardPage/TokenDetailsCard.tsx @@ -11,10 +11,10 @@ import { useTranslation } from 'react-i18next' import { AccountLink } from '../../components/Account/AccountLink' import { CopyToClipboard } from '../../components/CopyToClipboard' import { DelayedContractVerificationIcon } from '../../components/ContractVerificationIcon' -import { getTokenTypeName } from './TokenTypeCard' import { getNameForTicker, Ticker } from '../../../types/ticker' import { DelayedContractCreatorInfo } from '../../components/Account/ContractCreatorInfo' import CardContent from '@mui/material/CardContent' +import { getTokenTypeName } from '../../../types/tokens' export const TokenDetailsCard: FC = () => { const { t } = useTranslation() diff --git a/src/app/pages/TokenDashboardPage/TokenTypeCard.tsx b/src/app/pages/TokenDashboardPage/TokenTypeCard.tsx index e6f8fc2c0..fd5a97470 100644 --- a/src/app/pages/TokenDashboardPage/TokenTypeCard.tsx +++ b/src/app/pages/TokenDashboardPage/TokenTypeCard.tsx @@ -7,21 +7,7 @@ import { COLORS } from '../../../styles/theme/colors' import { useRequiredScopeParam } from '../../hooks/useScopeParam' import { useTokenInfo } from './hook' import { useLoaderData } from 'react-router-dom' -import { EvmTokenType } from '../../../oasis-nexus/api' -import { TFunction } from 'i18next' -import { exhaustedTypeWarning } from '../../../types/errors' - -export const getTokenTypeName = (t: TFunction, type: EvmTokenType): string => { - switch (type) { - case 'ERC20': - return t('account.ERC20') - case 'ERC721': - return t('account.ERC721') - default: - exhaustedTypeWarning('Unknown token type', type) - return type - } -} +import { getTokenTypeName } from '../../../types/tokens' export const TokenTypeCard: FC = () => { const { t } = useTranslation() diff --git a/src/locales/en/translation.json b/src/locales/en/translation.json index 628185992..c9f380526 100644 --- a/src/locales/en/translation.json +++ b/src/locales/en/translation.json @@ -2,7 +2,7 @@ "appName": "Oasis Explorer", "account": { "cantLoadDetails": "Unfortunately we couldn't load the account details at this time. Please try again later.", - "emptyTokenList": "This account holds no {{token}} tokens.", + "emptyTokenList": "This account holds no {{spec}} {{description}}.", "emptyTransactionList": "There are no transactions on record for this account.", "emptyTokenTransferList": "There are no token transfers on record for this account.", "ERC20": "ERC-20", @@ -10,7 +10,6 @@ "noTokens": "This account holds no tokens", "showMore": "+ {{counter}} more", "title": "Account", - "tokensListTitle": "{{token}} Tokens", "transactionsListTitle": "Account Transactions", "totalReceived": "Total Received", "totalSent": "Total Sent" @@ -65,6 +64,8 @@ "lessThanAmount": "< {{value}} {{ticker}}", "missing": "n/a", "name": "Name", + "nft": "NFT", + "nfts": "NFTs", "oasis": "Oasis", "paratime": "Paratime", "percentage": "Percentage", @@ -203,6 +204,7 @@ "request": "Request test tokens" }, "tokens": { + "typeDescription": "{{description}} ({{spec}})", "emptyTokenHolderList": "There are no token holders on record for this token.", "holders": "Token Holders", "holdersValue": "{{ value, number }}", diff --git a/src/types/tokens.ts b/src/types/tokens.ts new file mode 100644 index 000000000..a91cff509 --- /dev/null +++ b/src/types/tokens.ts @@ -0,0 +1,51 @@ +import { EvmTokenType } from '../oasis-nexus/api' +import { TFunction } from 'i18next' +import { exhaustedTypeWarning } from './errors' + +const getTokenTypeDescription = (t: TFunction, tokenType: EvmTokenType): string => { + switch (tokenType) { + case 'ERC20': + return t('common.token') + case 'ERC721': + return t('common.nft') + default: + exhaustedTypeWarning('Unknown token type', tokenType) + return '???' + } +} + +export const getTokenTypePluralDescription = (t: TFunction, tokenType: EvmTokenType): string => { + switch (tokenType) { + case 'ERC20': + return t('common.tokens') + case 'ERC721': + return t('common.nfts') + default: + exhaustedTypeWarning('Unknown token type', tokenType) + return '???' + } +} + +export const getTokenTypeStrictName = (t: TFunction, tokenType: EvmTokenType): string => { + switch (tokenType) { + case 'ERC20': + return t('account.ERC20') + case 'ERC721': + return t('account.ERC721') + default: + exhaustedTypeWarning('Unknown token type', tokenType) + return tokenType + } +} + +export const getTokenTypeName = (t: TFunction, tokenType: EvmTokenType): string => + t('tokens.typeDescription', { + spec: getTokenTypeStrictName(t, tokenType), + description: getTokenTypeDescription(t, tokenType), + }) + +export const getTokenTypePluralName = (t: TFunction, tokenType: EvmTokenType): string => + t('tokens.typeDescription', { + spec: getTokenTypeStrictName(t, tokenType), + description: getTokenTypePluralDescription(t, tokenType), + }) From 91cf1ca1cda77edae5337010424156813e3e8253 Mon Sep 17 00:00:00 2001 From: Kristof Csillag Date: Fri, 7 Jul 2023 15:01:59 +0200 Subject: [PATCH 3/5] Don't repeat "token" on token type card --- src/app/pages/TokenDashboardPage/TokenTypeCard.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/app/pages/TokenDashboardPage/TokenTypeCard.tsx b/src/app/pages/TokenDashboardPage/TokenTypeCard.tsx index fd5a97470..ef363d8a6 100644 --- a/src/app/pages/TokenDashboardPage/TokenTypeCard.tsx +++ b/src/app/pages/TokenDashboardPage/TokenTypeCard.tsx @@ -18,7 +18,7 @@ export const TokenTypeCard: FC = () => { const { token, isFetched } = useTokenInfo(scope, address) return ( - + {isFetched && ( <> From e63e9435288738aec9d93bc0ce0e20f6473836ac Mon Sep 17 00:00:00 2001 From: Kristof Csillag Date: Fri, 7 Jul 2023 15:27:12 +0200 Subject: [PATCH 4/5] Add new colors designed for token type tags --- src/styles/theme/colors.ts | 3 +++ src/types/tokens.ts | 13 ++++++++++++- 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/src/styles/theme/colors.ts b/src/styles/theme/colors.ts index 9cc323a80..92c0060e6 100644 --- a/src/styles/theme/colors.ts +++ b/src/styles/theme/colors.ts @@ -10,6 +10,7 @@ export const COLORS = { brandExtraLight: '#e5e5ef', brandLight: '#6665d8', brandMedium: '#0092f6', + brandMedium15: '#d9effe', brightGray2: '#ececec', brightGray: '#e6edf3', ceil: '#8f8cdf', @@ -51,4 +52,6 @@ export const COLORS = { graphLabel: '#191932', graphLine: '#01F1E3', paraTimeStatus: '#8081ac', + pink: '#ed32fa', + pink15: '#fce0fe', } satisfies { [colorName: string]: string } diff --git a/src/types/tokens.ts b/src/types/tokens.ts index a91cff509..f09a59f07 100644 --- a/src/types/tokens.ts +++ b/src/types/tokens.ts @@ -1,8 +1,9 @@ import { EvmTokenType } from '../oasis-nexus/api' import { TFunction } from 'i18next' import { exhaustedTypeWarning } from './errors' +import { COLORS } from '../styles/theme/colors' -const getTokenTypeDescription = (t: TFunction, tokenType: EvmTokenType): string => { +export const getTokenTypeDescription = (t: TFunction, tokenType: EvmTokenType): string => { switch (tokenType) { case 'ERC20': return t('common.token') @@ -14,6 +15,16 @@ const getTokenTypeDescription = (t: TFunction, tokenType: EvmTokenType): string } } +export const tokenBackgroundColor: Record = { + ERC20: COLORS.brandMedium15, + ERC721: COLORS.pink15, +} + +export const tokenBorderColor: Record = { + ERC20: COLORS.brandMedium, + ERC721: COLORS.pink, +} + export const getTokenTypePluralDescription = (t: TFunction, tokenType: EvmTokenType): string => { switch (tokenType) { case 'ERC20': From 3985b5b8cd17edabb2c006e507df37947653c759 Mon Sep 17 00:00:00 2001 From: Kristof Csillag Date: Fri, 7 Jul 2023 15:27:42 +0200 Subject: [PATCH 5/5] Implement token type tabs --- src/app/components/Tokens/TokenDetails.tsx | 6 ++- src/app/components/Tokens/TokenList.tsx | 44 +++++++++++++++++-- .../TokenDashboardPage/TokenDetailsCard.tsx | 6 ++- src/locales/en/translation.json | 1 + 4 files changed, 49 insertions(+), 8 deletions(-) diff --git a/src/app/components/Tokens/TokenDetails.tsx b/src/app/components/Tokens/TokenDetails.tsx index a89f44670..f351a9564 100644 --- a/src/app/components/Tokens/TokenDetails.tsx +++ b/src/app/components/Tokens/TokenDetails.tsx @@ -11,7 +11,7 @@ import { DashboardLink } from '../../pages/ParatimeDashboardPage/DashboardLink' import { DelayedContractVerificationIcon } from '../ContractVerificationIcon' import Box from '@mui/material/Box' import { COLORS } from '../../../styles/theme/colors' -import { getTokenTypeName } from '../../../types/tokens' +import { TokenTypeTag } from './TokenList' export const TokenDetails: FC<{ isLoading?: boolean @@ -42,7 +42,9 @@ export const TokenDetails: FC<{
{t('common.type')}
-
{getTokenTypeName(t, token.type)}
+
+ +
{t(isMobile ? 'common.smartContract_short' : 'common.smartContract')}
diff --git a/src/app/components/Tokens/TokenList.tsx b/src/app/components/Tokens/TokenList.tsx index 1349a664f..9c964b57b 100644 --- a/src/app/components/Tokens/TokenList.tsx +++ b/src/app/components/Tokens/TokenList.tsx @@ -1,13 +1,22 @@ import { useTranslation } from 'react-i18next' -import { EvmToken } from '../../../oasis-nexus/api' +import { EvmToken, EvmTokenType } from '../../../oasis-nexus/api' import { Table, TableCellAlign, TableColProps } from '../../components/Table' import { TablePaginationProps } from '../Table/TablePagination' import { AccountLink } from '../Account/AccountLink' import { TokenLink } from './TokenLink' import { CopyToClipboard } from '../CopyToClipboard' -import { DelayedContractVerificationIcon } from '../ContractVerificationIcon' +import { DelayedContractVerificationIcon, verificationIconBoxHeight } from '../ContractVerificationIcon' import Box from '@mui/material/Box' -import { getTokenTypeName } from '../../../types/tokens' +import { + getTokenTypeDescription, + getTokenTypeStrictName, + tokenBackgroundColor, + tokenBorderColor, +} from '../../../types/tokens' +import { FC } from 'react' +import Typography from '@mui/material/Typography' +import { COLORS } from '../../../styles/theme/colors' +import { SxProps } from '@mui/material/styles' type TokensProps = { tokens?: EvmToken[] @@ -16,6 +25,33 @@ type TokensProps = { pagination: false | TablePaginationProps } +export const TokenTypeTag: FC<{ tokenType: EvmTokenType; sx?: SxProps }> = ({ tokenType, sx = {} }) => { + const { t } = useTranslation() + return ( + + {getTokenTypeDescription(t, tokenType)} +   + + {t('common.parentheses', { subject: getTokenTypeStrictName(t, tokenType) })} + + + ) +} + export const TokenList = (props: TokensProps) => { const { isLoading, tokens, pagination, limit } = props const { t } = useTranslation() @@ -58,7 +94,7 @@ export const TokenList = (props: TokensProps) => { }, { key: 'type', - content: getTokenTypeName(t, token.type), + content: , }, { content: ( diff --git a/src/app/pages/TokenDashboardPage/TokenDetailsCard.tsx b/src/app/pages/TokenDashboardPage/TokenDetailsCard.tsx index b2bec5ad0..5a0b07778 100644 --- a/src/app/pages/TokenDashboardPage/TokenDetailsCard.tsx +++ b/src/app/pages/TokenDashboardPage/TokenDetailsCard.tsx @@ -14,7 +14,7 @@ import { DelayedContractVerificationIcon } from '../../components/ContractVerifi import { getNameForTicker, Ticker } from '../../../types/ticker' import { DelayedContractCreatorInfo } from '../../components/Account/ContractCreatorInfo' import CardContent from '@mui/material/CardContent' -import { getTokenTypeName } from '../../../types/tokens' +import { TokenTypeTag } from '../../components/Tokens/TokenList' export const TokenDetailsCard: FC = () => { const { t } = useTranslation() @@ -57,7 +57,9 @@ export const TokenDetailsCard: FC = () => {
{t('common.type')}
-
{getTokenTypeName(t, token.type)}
+
+ +
{t('contract.creator')}
diff --git a/src/locales/en/translation.json b/src/locales/en/translation.json index c9f380526..da847e3fc 100644 --- a/src/locales/en/translation.json +++ b/src/locales/en/translation.json @@ -68,6 +68,7 @@ "nfts": "NFTs", "oasis": "Oasis", "paratime": "Paratime", + "parentheses":"({{subject}})", "percentage": "Percentage", "rank": "Rank", "select": "Select",