Skip to content

Commit

Permalink
Revamp AccountLink and implement searching for account names
Browse files Browse the repository at this point in the history
  • Loading branch information
csillag committed Feb 23, 2024
1 parent f2cc351 commit cebc8f3
Show file tree
Hide file tree
Showing 29 changed files with 413 additions and 121 deletions.
186 changes: 127 additions & 59 deletions src/app/components/Account/AccountLink.tsx
Original file line number Diff line number Diff line change
@@ -1,88 +1,156 @@
import { FC } from 'react'
import { FC, ReactNode } from 'react'
import { Link as RouterLink } from 'react-router-dom'
import { useScreenSize } from '../../hooks/useScreensize'
import Link from '@mui/material/Link'
import { RouteUtils } from '../../utils/route-utils'
import InfoIcon from '@mui/icons-material/Info'
import Typography from '@mui/material/Typography'
import { COLORS } from '../../../styles/theme/colors'
import { SearchScope } from '../../../types/searchScope'
import { useAccountName } from '../../hooks/useAccountName'
import { trimLongString } from '../../utils/trimLongString'
import Tooltip from '@mui/material/Tooltip'
import { tooltipDelay } from '../../../styles/theme'
import Box from '@mui/material/Box'
import { HighlightedText } from '../HighlightedText'
import { AdaptiveHighlightedText } from '../HighlightedText/AdaptiveHighlightedText'
import { WithTooltip } from '../AdaptiveTrimmer/WithToolTip'
import { AdaptiveTrimmer } from '../AdaptiveTrimmer/AdaptiveTrimmer'

const WithLink: FC<{
content: ReactNode
to: string
plain?: boolean
}> = ({ content, to, plain }) => {
return (
<Typography
variant="mono"
component="span"
sx={{
maxWidth: '100%',
overflowX: 'hidden',
...(plain
? { color: COLORS.grayExtraDark, fontWeight: 400 }
: { color: COLORS.brandDark, fontWeight: 700 }),
}}
>
{plain ? (
content
) : (
<Link component={RouterLink} to={to}>
{content}
</Link>
)}
</Typography>
)
}

export const AccountLink: FC<{
scope: SearchScope
address: string

/**
* Should we always trim the text to a short line?
*/
alwaysTrim?: boolean

/**
* Plain mode? (No link required)
*/
plain?: boolean
}> = ({ scope, address, alwaysTrim, plain }) => {

/**
* What part of the name should be highlighted (if any)
*/
highlightedPartOfName?: string | undefined

/**
* Any extra tooltips to display
*
* (Besides the content necessary because of potential shortening)
*/
extraTooltip?: ReactNode
}> = ({ scope, address, alwaysTrim, plain, highlightedPartOfName, extraTooltip }) => {
const { isTablet } = useScreenSize()
const { name: accountName } = useAccountName(scope, address)
const to = RouteUtils.getAccountRoute(scope, address)

const shortMode = alwaysTrim || isTablet // Do we want shortened lines?

const nameDisplay = accountName ? (
<Box sx={{ fontWeight: 'bold' }}>
{shortMode ? (
<Tooltip
arrow
placement="top"
title={accountName}
enterDelay={tooltipDelay}
enterNextDelay={tooltipDelay}
>
<span>{trimLongString(accountName, 12, 0)}</span>
</Tooltip>
) : (
accountName
)}
</Box>
const tooltipPostfix = extraTooltip ? (
<>
<InfoIcon />
{extraTooltip}
</>
) : undefined

const addressDisplay = shortMode ? (
<Tooltip arrow placement="top" title={address} enterDelay={tooltipDelay} enterNextDelay={tooltipDelay}>
<span>{trimLongString(address, 6, 6)}</span>
</Tooltip>
) : (
address
)
// Are we in a table?
if (alwaysTrim) {
// In a table, we only ever want one short line

const label = shortMode ? ( // Working with limited horizontal space
accountName ? ( // Do we want two lines ?
<>
{nameDisplay}({addressDisplay})
</>
) : (
// No, only a single short line, either name or address
nameDisplay ?? addressDisplay
return (
<WithLink
content={
<WithTooltip
title={
accountName ? (
<div>
<Box sx={{ fontWeight: 'bold' }}>{accountName}</Box>
<Box sx={{ fontWeight: 'normal' }}>{address}</Box>
{tooltipPostfix}
</div>
) : (
address
)
}
content={accountName ? trimLongString(accountName, 12, 0) : trimLongString(address, 6, 6)}
/>
}
to={to}
plain={plain}
/>
)
) : // We can have a long line
accountName ? (
`${accountName} (${address})`
) : (
address
)
}

if (!isTablet) {
// Details in desktop mode.
// We want one long line, with name and address.

return (
<WithLink
content={
<WithTooltip
title={tooltipPostfix}
content={
accountName ? (
<span>
<HighlightedText text={accountName} pattern={highlightedPartOfName} /> {address}
</span>
) : (
address
)
}
/>
}
to={to}
plain={plain}
/>
)
}

// We need to show the data in details mode on mobile.
// We want two lines, one for name (if available), one for address
// Both line adaptively shortened to fill available space
return (
<Typography
variant="mono"
component="span"
sx={
plain
? { color: COLORS.grayExtraDark, fontWeight: 400 }
: { color: COLORS.brandDark, fontWeight: 700 }
<WithLink
content={
<>
<AdaptiveHighlightedText
text={accountName}
pattern={highlightedPartOfName}
extraTooltip={extraTooltip}
/>
<AdaptiveTrimmer text={address} strategy="middle" extraTooltip={extraTooltip} />
</>
}
>
{plain ? (
label
) : (
<Link component={RouterLink} to={to}>
{label}
</Link>
)}
</Typography>
to={to}
plain={plain}
/>
)
}
25 changes: 18 additions & 7 deletions src/app/components/Account/ContractCreatorInfo.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,11 @@ import Box from '@mui/material/Box'
import Skeleton from '@mui/material/Skeleton'
import { useScreenSize } from '../../hooks/useScreensize'

const TxSender: FC<{ scope: SearchScope; txHash: string }> = ({ scope, txHash }) => {
const TxSender: FC<{ scope: SearchScope; txHash: string; alwaysTrim?: boolean }> = ({
scope,
txHash,
alwaysTrim,
}) => {
const { t } = useTranslation()
if (scope.layer === Layer.consensus) {
throw AppErrors.UnsupportedLayer
Expand All @@ -31,7 +35,7 @@ const TxSender: FC<{ scope: SearchScope; txHash: string }> = ({ scope, txHash })
}}
/>
) : senderAddress ? (
<AccountLink scope={scope} address={senderAddress} alwaysTrim />
<AccountLink scope={scope} address={senderAddress} alwaysTrim={alwaysTrim} />
) : (
t('common.missing')
)
Expand All @@ -41,7 +45,8 @@ export const ContractCreatorInfo: FC<{
scope: SearchScope
isLoading?: boolean
creationTxHash: string | undefined
}> = ({ scope, isLoading, creationTxHash }) => {
alwaysTrim?: boolean
}> = ({ scope, isLoading, creationTxHash, alwaysTrim }) => {
const { t } = useTranslation()
const { isMobile } = useScreenSize()

Expand All @@ -59,17 +64,18 @@ export const ContractCreatorInfo: FC<{
minWidth: '25%',
}}
>
<TxSender scope={scope} txHash={creationTxHash} />
<TxSender scope={scope} txHash={creationTxHash} alwaysTrim={alwaysTrim} />
<Box>{t('contract.createdAt')}</Box>
<TransactionLink scope={scope} hash={creationTxHash} alwaysTrim />
<TransactionLink scope={scope} hash={creationTxHash} alwaysTrim={alwaysTrim} />
</Box>
)
}

export const DelayedContractCreatorInfo: FC<{
scope: SearchScope
contractOasisAddress: string | undefined
}> = ({ scope, contractOasisAddress }) => {
alwaysTrim?: boolean
}> = ({ scope, contractOasisAddress, alwaysTrim }) => {
const accountQuery = useGetRuntimeAccountsAddress(
scope.network,
scope.layer as Runtime,
Expand All @@ -82,6 +88,11 @@ export const DelayedContractCreatorInfo: FC<{
const creationTxHash = contract?.eth_creation_tx || contract?.creation_tx

return (
<ContractCreatorInfo scope={scope} isLoading={accountQuery.isLoading} creationTxHash={creationTxHash} />
<ContractCreatorInfo
scope={scope}
isLoading={accountQuery.isLoading}
creationTxHash={creationTxHash}
alwaysTrim={alwaysTrim}
/>
)
}
12 changes: 10 additions & 2 deletions src/app/components/Account/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,17 @@ type AccountProps = {
isLoading: boolean
tokenPrices: AllTokenPrices
showLayer?: boolean
highlightedPartOfName: string | undefined
}

export const Account: FC<AccountProps> = ({ account, token, isLoading, tokenPrices, showLayer }) => {
export const Account: FC<AccountProps> = ({
account,
token,
isLoading,
tokenPrices,
showLayer,
highlightedPartOfName,
}) => {
const { t } = useTranslation()
const { isMobile } = useScreenSize()
const address = account ? account.address_eth ?? account.address : undefined
Expand Down Expand Up @@ -67,7 +75,7 @@ export const Account: FC<AccountProps> = ({ account, token, isLoading, tokenPric
<AccountAvatar address={account.address} />
</StyledListTitleWithAvatar>
<dd>
<AccountLink scope={account} address={address!} />
<AccountLink scope={account} address={address!} highlightedPartOfName={highlightedPartOfName} />
<CopyToClipboard value={address!} />
</dd>

Expand Down
2 changes: 1 addition & 1 deletion src/app/components/AccountList/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ export const AccountList: FC<AccountListProps> = ({ isLoading, limit, pagination
key: 'size',
},
{
content: <AccountLink scope={account} address={account.address} />,
content: <AccountLink scope={account} address={account.address} alwaysTrim />,
key: 'address',
},
...(verbose
Expand Down
5 changes: 5 additions & 0 deletions src/app/components/Search/search-utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,11 @@ export const validateAndNormalize = {
return searchTerm.toLowerCase()
}
},
accountNameFragment: (searchTerm: string) => {
if (searchTerm?.length >= textSearchMininumLength) {
return searchTerm.toLowerCase()
}
},
} satisfies { [name: string]: (searchTerm: string) => string | undefined }

export function isSearchValid(searchTerm: string) {
Expand Down
2 changes: 2 additions & 0 deletions src/app/components/StyledDescriptionList/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,8 @@ export const StyledDescriptionList = styled(InlineDescriptionList, {
color: COLORS.brandExtraDark,
overflowWrap: 'anywhere',
alignItems: 'center',
maxWidth: '100%',
overflowX: 'hidden',
},
...(standalone && {
'&&': {
Expand Down
6 changes: 5 additions & 1 deletion src/app/components/Tokens/TokenHolders.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,11 @@ export const TokenHolders: FC<TokenHoldersProps> = ({
{
key: 'address',
content: (
<AccountLink scope={holder} address={holder.eth_holder_address || holder.holder_address} />
<AccountLink
scope={holder}
address={holder.eth_holder_address || holder.holder_address}
alwaysTrim
/>
),
},
{
Expand Down
6 changes: 5 additions & 1 deletion src/app/components/Tokens/TokenList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,11 @@ export const TokenList = (props: TokensProps) => {
{
content: (
<span>
<AccountLink scope={token} address={token.eth_contract_addr ?? token.contract_addr} />
<AccountLink
scope={token}
address={token.eth_contract_addr ?? token.contract_addr}
alwaysTrim
/>
<CopyToClipboard value={token.eth_contract_addr ?? token.contract_addr} />
</span>
),
Expand Down
4 changes: 2 additions & 2 deletions src/app/components/Tokens/TokenTransfers.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,7 @@ export const TokenTransfers: FC<TokenTransfersProps> = ({
{trimLongString(fromAddress)}
</Typography>
) : (
<AccountLink scope={transfer} address={fromAddress} alwaysTrim={true} />
<AccountLink scope={transfer} address={fromAddress} alwaysTrim />
)}

<StyledCircle>
Expand All @@ -210,7 +210,7 @@ export const TokenTransfers: FC<TokenTransfersProps> = ({
{trimLongString(toAddress)}
</Typography>
) : (
<AccountLink scope={transfer} address={toAddress} alwaysTrim={true} />
<AccountLink scope={transfer} address={toAddress} alwaysTrim />
),
},
...(differentTokens
Expand Down
Loading

0 comments on commit cebc8f3

Please sign in to comment.