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

chore: show Nfd addresses #276

Draft
wants to merge 18 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from 6 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
21 changes: 20 additions & 1 deletion src/features/accounts/components/account-info.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { Card, CardContent } from '@/features/common/components/card'
import { DescriptionList } from '@/features/common/components/description-list'
import { cn } from '@/features/common/utils'
import { DisplayAlgo } from '@/features/common/components/display-algo'
import { AccountLink } from './account-link'
import { AccountLink, transformError } from './account-link'
import {
accountAddressLabel,
accountApplicationsCreatedLabel,
Expand All @@ -15,16 +15,20 @@ import {
accountBalanceLabel,
accountInformationLabel,
accountMinBalanceLabel,
accountNfdLabel,
accountRekeyedToLabel,
} from './labels'
import { OpenJsonViewDialogButton } from '@/features/common/components/json-view-dialog-button'
import { CopyButton } from '@/features/common/components/copy-button'
import { useLoadableNfd } from '@/features/nfd/data/nfd'
import { RenderLoadable } from '@/features/common/components/render-loadable'

type Props = {
account: Account
}

export function AccountInfo({ account }: Props) {
const [loadableNfd] = useLoadableNfd(account.address)
const accountInfoItems = useMemo(() => {
const items = [
{
Expand All @@ -36,6 +40,20 @@ export function AccountInfo({ account }: Props) {
</div>
),
},
...(loadableNfd.state === 'hasData' && loadableNfd.data !== null
? [
{
dt: accountNfdLabel,
dd: (
<div className="flex items-center">
<RenderLoadable loadable={loadableNfd} transformError={transformError} fallback={<></>}>
{(nfd) => <span className="truncate">{nfd?.name}</span>}
</RenderLoadable>
</div>
),
},
]
: []),
{
dt: accountBalanceLabel,
dd: <DisplayAlgo amount={account.balance} />,
Expand Down Expand Up @@ -84,6 +102,7 @@ export function AccountInfo({ account }: Props) {
account.totalApplicationsCreated,
account.totalApplicationsOptedIn,
account.rekeyedTo,
loadableNfd,
])
return (
<Card aria-label={accountInformationLabel}>
Expand Down
51 changes: 51 additions & 0 deletions src/features/accounts/components/account-link-inner.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import { CopyButton } from '@/features/common/components/copy-button'
import { cn } from '@/features/common/utils'
import { useSelectedNetwork } from '@/features/network/data'
import { TemplatedNavLink } from '@/features/routing/components/templated-nav-link/templated-nav-link'
import { Urls } from '@/routes/urls'
import { ellipseAddress } from '@/utils/ellipse-address'
import { fixedForwardRef } from '@/utils/fixed-forward-ref'
import { AccountLinkProps } from './account-link'

type Props = AccountLinkProps & {
nfd?: string
}

export const AccountLinkInner = fixedForwardRef(
negar-abbasi marked this conversation as resolved.
Show resolved Hide resolved
({ address, nfd, short, className, children, showCopyButton, ...rest }: Props, ref?: React.LegacyRef<HTMLAnchorElement>) => {
const [selectedNetwork] = useSelectedNetwork()

const link = (
<TemplatedNavLink
className={cn(!children && 'text-primary underline', !children && !short && 'truncate', className)}
urlTemplate={Urls.Explore.Account.ByAddress}
urlParams={{ address, networkId: selectedNetwork }}
ref={ref}
{...rest}
>
{children ? (
children
) : nfd ? (
<abbr className="tracking-wide" title={address}>
{nfd}
</abbr>
) : short ? (
<abbr className="tracking-wide" title={address}>
{ellipseAddress(address)}
</abbr>
) : (
address
)}
</TemplatedNavLink>
)

return children ? (
link
) : (
<div className="flex items-center">
{link}
{showCopyButton && <CopyButton value={address} />}
</div>
)
}
)
68 changes: 27 additions & 41 deletions src/features/accounts/components/account-link.tsx
Original file line number Diff line number Diff line change
@@ -1,50 +1,36 @@
import { CopyButton } from '@/features/common/components/copy-button'
import { cn } from '@/features/common/utils'
import { TemplatedNavLink } from '@/features/routing/components/templated-nav-link/templated-nav-link'
import { Urls } from '@/routes/urls'
import { ellipseAddress } from '@/utils/ellipse-address'
import { fixedForwardRef } from '@/utils/fixed-forward-ref'
import { PropsWithChildren } from 'react'
import { useSelectedNetwork } from '@/features/network/data'
import { useLoadableNfd } from '@/features/nfd/data/nfd'
import { RenderLoadable } from '@/features/common/components/render-loadable'
import { is404 } from '@/utils/error'
import { AccountLinkInner } from './account-link-inner'

type Props = PropsWithChildren<{
const nfdInvalidAddressMessage = 'Invalid nfd address'
const nfdFailedToLoadMessage = 'Nfd failed to load'

export const transformError = (e: Error) => {
if (is404(e)) {
negar-abbasi marked this conversation as resolved.
Show resolved Hide resolved
return new Error(nfdInvalidAddressMessage)
}
// eslint-disable-next-line no-console
console.error(e)
return new Error(nfdFailedToLoadMessage)
}

export type AccountLinkProps = PropsWithChildren<{
address: string
short?: boolean
className?: string
showCopyButton?: boolean
}>

export const AccountLink = fixedForwardRef(
({ address, short, className, children, showCopyButton, ...rest }: Props, ref?: React.LegacyRef<HTMLAnchorElement>) => {
const [selectedNetwork] = useSelectedNetwork()
export const AccountLink = ({ address, ...rest }: AccountLinkProps) => {
const [loadablenfd] = useLoadableNfd(address)

negar-abbasi marked this conversation as resolved.
Show resolved Hide resolved
const link = (
<TemplatedNavLink
className={cn(!children && 'text-primary underline', !children && !short && 'truncate', className)}
urlTemplate={Urls.Explore.Account.ByAddress}
urlParams={{ address, networkId: selectedNetwork }}
ref={ref}
{...rest}
>
{children ? (
children
) : short ? (
<abbr className="tracking-wide" title={address}>
{ellipseAddress(address)}
</abbr>
) : (
address
)}
</TemplatedNavLink>
)

return children ? (
link
) : (
<div className="flex items-center">
{link}
{showCopyButton && <CopyButton value={address} />}
</div>
)
}
)
return (
<>
<RenderLoadable loadable={loadablenfd} transformError={transformError} fallback={<AccountLinkInner address={address} {...rest} />}>
{(nfd) => <AccountLinkInner address={address} nfd={nfd?.name ?? undefined} {...rest} />}
</RenderLoadable>
</>
)
}
1 change: 1 addition & 0 deletions src/features/accounts/components/labels.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ export const accountOptedApplicationsTabId = 'opted-applications'

export const accountInformationLabel = 'Account Information'
export const accountAddressLabel = 'Address'
export const accountNfdLabel = 'Nfd'
negar-abbasi marked this conversation as resolved.
Show resolved Hide resolved
export const accountBalanceLabel = 'Balance'
export const accountMinBalanceLabel = 'Min Balance'
export const accountAssetsHeldLabel = 'Held assets'
Expand Down
28 changes: 28 additions & 0 deletions src/features/nfd/data/nfd.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { Address } from '@/features/accounts/data/types'
import { atom, useAtomValue } from 'jotai'
import { getNfdResultAtom } from './nfd-result'
import { loadable } from 'jotai/utils'
import { useMemo } from 'react'

const createNfdAtoms = (address: Address) => {
negar-abbasi marked this conversation as resolved.
Show resolved Hide resolved
return [
atom(async (get) => {
const nfdResult = await get(getNfdResultAtom({ address: address }))
if (!nfdResult) {
return null
}
return nfdResult
}),
] as const
}

export const useNfdAtoms = (address: Address) => {
negar-abbasi marked this conversation as resolved.
Show resolved Hide resolved
negar-abbasi marked this conversation as resolved.
Show resolved Hide resolved
return useMemo(() => {
return createNfdAtoms(address)
}, [address])
}

export const useLoadableNfd = (address: Address) => {
negar-abbasi marked this conversation as resolved.
Show resolved Hide resolved
const [nfdAtom] = useNfdAtoms(address)
return [useAtomValue(loadable(nfdAtom))] as const
}
Loading