Address.tsx 2.39 KiB
Newer Older
Andrei Eres's avatar
Andrei Eres committed
import { useStore } from '@nanostores/react'
Andrei Eres's avatar
Andrei Eres committed
import { AccountJson } from '@polkadot/extension-base/background/types'
Andrei Eres's avatar
Andrei Eres committed
import Identicon from '@polkadot/react-identicon'
Andrei Eres's avatar
Andrei Eres committed
import { IconTheme } from '@polkadot/react-identicon/types'
Andrei Eres's avatar
Andrei Eres committed
import React, { useCallback, useEffect, useState } from 'react'
Andrei Eres's avatar
Andrei Eres committed
import { useMetadata } from '../../hooks/useMetadata'
import { editAccount } from '../../messaging/uiActions'
Andrei Eres's avatar
Andrei Eres committed
import { accountsStore } from '../../stores/accounts'
Andrei Eres's avatar
Andrei Eres committed
import { DEFAULT_TYPE, RELAY_CHAIN, UNKNOWN } from '../../utils/constants'
import { cropHash } from '../../utils/cropHash'
Andrei Eres's avatar
Andrei Eres committed
import { recodeAddress, Recoded } from '../../utils/recodeAddress'
Andrei Eres's avatar
Andrei Eres committed
import { AutosizeInput } from './AutosizeInput'
Andrei Eres's avatar
Andrei Eres committed
type Props = {
Andrei Eres's avatar
Andrei Eres committed
  address?: string
  genesisHash?: string | null
  name?: string
}

const defaultRecoded = {
  account: null,
  formatted: null,
  prefix: 42,
  type: DEFAULT_TYPE,
}

Andrei Eres's avatar
Andrei Eres committed
export const Address: React.FC<Props> = ({ address, genesisHash, name }) => {
Andrei Eres's avatar
Andrei Eres committed
  const [recoded, setRecoded] = useState<Recoded>(defaultRecoded)
Andrei Eres's avatar
Andrei Eres committed
  const accounts = useStore(accountsStore) as AccountJson[]
Andrei Eres's avatar
Andrei Eres committed
  const chain = useMetadata(genesisHash || recoded.genesisHash, true)
  const iconTheme = (chain?.icon || 'polkadot') as IconTheme
Andrei Eres's avatar
Andrei Eres committed
  const nameLabel = name || recoded.account?.name
Andrei Eres's avatar
Andrei Eres committed
  const chainLabel = ` · ${chain?.definition.chain.replace(RELAY_CHAIN, '')}`
  const hashLabel = cropHash(recoded.formatted || address || UNKNOWN)
Andrei Eres's avatar
Andrei Eres committed
  const changeName = useCallback(
    (v: string) => address && editAccount(address, v).catch(console.error),
    [address]
  )
Andrei Eres's avatar
Andrei Eres committed
  useEffect(() => {
    if (!address) return

    const recoded = recodeAddress(address, accounts, chain)
Andrei Eres's avatar
Andrei Eres committed
    recoded && setRecoded(recoded)
  }, [accounts, address, chain])
Andrei Eres's avatar
Andrei Eres committed

  return (
Andrei Eres's avatar
Andrei Eres committed
    <div className='flex relative rounded bg-_bg-300'>
      <div className='flex items-center p-2 pr-0'>
Andrei Eres's avatar
Andrei Eres committed
        <Identicon
          prefix={recoded.prefix}
          theme={iconTheme}
          value={recoded.formatted || address}
Andrei Eres's avatar
Andrei Eres committed
          size={32}
Andrei Eres's avatar
Andrei Eres committed
        />
      </div>
Andrei Eres's avatar
Andrei Eres committed
      <div className='flex flex-col justify-center py-0 px-2 leading-none space-y-1'>
        <div className=''>
Andrei Eres's avatar
Andrei Eres committed
          <AutosizeInput
            value={nameLabel}
            placeholder={UNKNOWN}
            onChange={changeName}
          />
Andrei Eres's avatar
Andrei Eres committed
          {chain && <span className='text-_crypto-400'>{chainLabel}</span>}
Andrei Eres's avatar
Andrei Eres committed
        </div>
        <div className='font-mono text-sm text-_text-400'>{hashLabel}</div>
Andrei Eres's avatar
Andrei Eres committed
      </div>
    </div>
  )
}