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

Add named accounts #1398

Merged
merged 4 commits into from
May 22, 2024
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
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
1 change: 1 addition & 0 deletions .changelog/1398.feature.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Initial support for named accounts
71 changes: 60 additions & 11 deletions src/app/components/Account/AccountLink.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,12 @@ import { RouteUtils } from '../../utils/route-utils'
import InfoIcon from '@mui/icons-material/Info'
import Typography from '@mui/material/Typography'
import { SearchScope } from '../../../types/searchScope'
import { useAccountMetadata } from '../../hooks/useAccountMetadata'
import { trimLongString } from '../../utils/trimLongString'
import { MaybeWithTooltip } from '../AdaptiveTrimmer/MaybeWithTooltip'
import Box from '@mui/material/Box'
import { HighlightedText } from '../HighlightedText'
import { AdaptiveHighlightedText } from '../HighlightedText/AdaptiveHighlightedText'
import { AdaptiveTrimmer } from '../AdaptiveTrimmer/AdaptiveTrimmer'

const WithTypographyAndLink: FC<{
Expand All @@ -24,7 +28,7 @@ const WithTypographyAndLink: FC<{
...(mobile
? {
maxWidth: '100%',
overflowX: 'hidden',
overflow: 'hidden',
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is unexpected

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(I don't think this behaves different from overflow-x)

}
: {}),
}}
Expand Down Expand Up @@ -52,7 +56,12 @@ interface Props {
/**
* Should we always trim the text to a short line when on mobile or Tablet?
*/
alwaysTrimOnTable?: boolean
alwaysTrimOnTablet?: boolean

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

/**
* Any extra tooltips to display
Expand All @@ -73,47 +82,87 @@ export const AccountLink: FC<Props> = ({
scope,
address,
alwaysTrim,
alwaysTrimOnTable,
alwaysTrimOnTablet,
highlightedPartOfName,
extraTooltip,
labelOnly,
}) => {
const { isTablet } = useScreenSize()
const {
metadata: accountMetadata,
// isError, // Use this to indicate that we have failed to load the name for this account
} = useAccountMetadata(scope, address)
const accountName = accountMetadata?.name // TODO: we should also use the description

const to = RouteUtils.getAccountRoute(scope, address)

const extraTooltipWithIcon = extraTooltip ? (
<>
<Box
sx={{
display: 'inline-flex',
alignItems: 'center',
verticalAlign: 'middle',
gap: 2,
}}
>
<InfoIcon />
{extraTooltip}
</>
</Box>
) : undefined

// Are we in a situation when we should always trim?
if (alwaysTrim || (alwaysTrimOnTable && isTablet)) {
if (alwaysTrim || (alwaysTrimOnTablet && isTablet)) {
// In a table, we only ever want a short line

return (
<WithTypographyAndLink to={to} labelOnly={labelOnly}>
<MaybeWithTooltip title={address}>{trimLongString(address, 6, 6)}</MaybeWithTooltip>
<MaybeWithTooltip
title={
<div>
{accountName && <Box sx={{ fontWeight: 'bold' }}>{accountName}</Box>}
<Box sx={{ fontWeight: 'normal' }}>{address}</Box>
{extraTooltipWithIcon}
</div>
}
>
{accountName ? trimLongString(accountName, 12, 0) : trimLongString(address, 6, 6)}
</MaybeWithTooltip>
</WithTypographyAndLink>
)
}

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

return (
<WithTypographyAndLink to={to} labelOnly={labelOnly}>
<MaybeWithTooltip title={extraTooltipWithIcon}>{address} </MaybeWithTooltip>
<MaybeWithTooltip title={extraTooltipWithIcon}>
{accountName ? (
<span>
<HighlightedText text={accountName} pattern={highlightedPartOfName} /> ({address})
</span>
) : (
address
)}
</MaybeWithTooltip>
</WithTypographyAndLink>
)
}

// We need to show the data in details mode on mobile.
// Line adaptively shortened to fill available space
// We want two lines, one for name (if available), one for address
// Both lines adaptively shortened to fill available space
return (
<WithTypographyAndLink to={to} mobile labelOnly={labelOnly}>
<AdaptiveTrimmer text={address} strategy="middle" extraTooltip={extraTooltip} />
<>
<AdaptiveHighlightedText
text={accountName}
pattern={highlightedPartOfName}
extraTooltip={extraTooltip}
/>
<AdaptiveTrimmer text={address} strategy="middle" extraTooltip={extraTooltip} />
</>
</WithTypographyAndLink>
)
}
12 changes: 10 additions & 2 deletions src/app/components/Account/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ type RuntimeAccountDataProps = {
isLoading: boolean
tokenPrices: AllTokenPrices
showLayer?: boolean
highlightedPartOfName: string | undefined
}

export const RuntimeAccountData: FC<RuntimeAccountDataProps> = ({
Expand All @@ -41,6 +42,7 @@ export const RuntimeAccountData: FC<RuntimeAccountDataProps> = ({
isLoading,
tokenPrices,
showLayer,
highlightedPartOfName,
}) => {
const { t } = useTranslation()
const { isMobile } = useScreenSize()
Expand Down Expand Up @@ -76,7 +78,7 @@ export const RuntimeAccountData: FC<RuntimeAccountDataProps> = ({
<AccountAvatar account={account} />
</StyledListTitleWithAvatar>
<dd>
<AccountLink scope={account} address={address!} />
<AccountLink scope={account} address={address!} highlightedPartOfName={highlightedPartOfName} />
<CopyToClipboard value={address!} />
</dd>

Expand Down Expand Up @@ -175,13 +177,15 @@ export type ConsensusAccountDataProps = {
isLoading?: boolean
showLayer?: boolean
standalone?: boolean
highlightedPartOfName?: string | undefined
}

export const ConsensusAccountData: FC<ConsensusAccountDataProps> = ({
account,
isLoading,
showLayer,
standalone,
highlightedPartOfName,
}) => {
const { t } = useTranslation()
const { isMobile } = useScreenSize()
Expand All @@ -205,7 +209,11 @@ export const ConsensusAccountData: FC<ConsensusAccountDataProps> = ({
</Box>
</StyledListTitleWithAvatar>
<dd>
<AccountLink scope={account} address={account.address} />
<AccountLink
scope={account}
address={account.address}
highlightedPartOfName={highlightedPartOfName}
/>
<CopyToClipboard value={account.address} />
</dd>
<dt>
Expand Down
2 changes: 1 addition & 1 deletion src/app/components/RuntimeEvents/RuntimeEventDetails.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ const EvmEventParamData: FC<{
// TODO: handle more EVM types
case 'address':
return address ? (
<AccountLink address={address} scope={scope} alwaysTrimOnTable={alwaysTrimOnTable} />
<AccountLink address={address} scope={scope} alwaysTrimOnTablet={alwaysTrimOnTable} />
) : null
case 'uint256':
// TODO: format with BigNumber
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 @@ -119,6 +119,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
51 changes: 51 additions & 0 deletions src/app/data/named-accounts.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import { Network } from '../../types/network'
import { Account, Layer, Runtime, RuntimeAccount } from '../../oasis-nexus/api'

export type AccountMetadata = {
address: string
name?: string
description?: string
}

export type AccountMetadataInfo = {
metadata?: AccountMetadata
isLoading: boolean
isError: boolean
}

export type AccountMap = Map<string, AccountMetadata>

export type AccountData = {
map: AccountMap
list: AccountMetadata[]
}

export type AccountNameSearchMatch = {
network: Network
layer: Layer
address: string
}

export type AccountNameSearchRuntimeMatch = {
network: Network
layer: Runtime
address: string
}

export type AccountNameSearchConsensusMatch = {
network: Network
layer: typeof Layer.consensus
address: string
}

export type AccountNameSearchResults = {
results: (Account | RuntimeAccount)[] | undefined
isLoading: boolean
isError: boolean
}

export type AccountNameSearchRuntimeResults = {
results: RuntimeAccount[] | undefined
isLoading: boolean
isError: boolean
}
Loading
Loading