Consistently render known address with Address Book priority (#2195)
* update SRC * fix known address to take priority from adress book * rename useGetTxTo to getTxTo * Liliya feedback * Liliya feedback * fix eslint warning * Fix customIcon for TX-collapsed if address is in AB Co-authored-by: katspaugh <katspaugh@users.noreply.github.com>
This commit is contained in:
parent
28e1bd3e77
commit
ac2987d999
|
@ -161,7 +161,7 @@
|
|||
"@gnosis.pm/safe-apps-sdk": "1.0.3",
|
||||
"@gnosis.pm/safe-apps-sdk-v1": "npm:@gnosis.pm/safe-apps-sdk@0.4.2",
|
||||
"@gnosis.pm/safe-contracts": "1.1.1-dev.2",
|
||||
"@gnosis.pm/safe-react-components": "https://github.com/gnosis/safe-react-components.git#b281238",
|
||||
"@gnosis.pm/safe-react-components": "https://github.com/gnosis/safe-react-components.git#4864ebb",
|
||||
"@gnosis.pm/util-contracts": "2.0.6",
|
||||
"@ledgerhq/hw-transport-node-hid-singleton": "5.49.0",
|
||||
"@material-ui/core": "^4.11.0",
|
||||
|
|
|
@ -1,22 +1,22 @@
|
|||
import { Text } from '@gnosis.pm/safe-react-components'
|
||||
import { EthHashInfo } from '@gnosis.pm/safe-react-components'
|
||||
import React, { ReactElement } from 'react'
|
||||
import styled from 'styled-components'
|
||||
|
||||
const Wrapper = styled.div`
|
||||
display: flex;
|
||||
align-items: center;
|
||||
`
|
||||
const Icon = styled.img`
|
||||
max-width: 15px;
|
||||
max-height: 15px;
|
||||
margin-right: 9px;
|
||||
`
|
||||
type Props = {
|
||||
address: string
|
||||
iconUrl?: string
|
||||
iconUrlFallback?: string
|
||||
text?: string
|
||||
}
|
||||
|
||||
type Props = { iconUrl: string | null | undefined; text?: string }
|
||||
|
||||
export const CustomIconText = ({ iconUrl, text }: Props): ReactElement => (
|
||||
<Wrapper>
|
||||
{iconUrl && <Icon alt={text} src={iconUrl} />}
|
||||
{text && <Text size="xl">{text}</Text>}
|
||||
</Wrapper>
|
||||
export const CustomIconText = ({ address, iconUrl, text, iconUrlFallback }: Props): ReactElement => (
|
||||
<EthHashInfo
|
||||
hash={address}
|
||||
showHash={false}
|
||||
avatarSize="sm"
|
||||
showAvatar
|
||||
customAvatar={iconUrl || undefined}
|
||||
customAvatarFallback={iconUrlFallback}
|
||||
name={text}
|
||||
textSize="xl"
|
||||
/>
|
||||
)
|
||||
|
|
|
@ -136,7 +136,7 @@ type BaseCustom = {
|
|||
toInfo?: AddressInfo
|
||||
}
|
||||
|
||||
type Custom = BaseCustom & {
|
||||
export type Custom = BaseCustom & {
|
||||
methodName: string | null
|
||||
}
|
||||
|
||||
|
|
|
@ -1,9 +1,8 @@
|
|||
import { EthHashInfo } from '@gnosis.pm/safe-react-components'
|
||||
import React, { ReactElement } from 'react'
|
||||
import { useSelector } from 'react-redux'
|
||||
import { getExplorerInfo } from 'src/config'
|
||||
|
||||
import { getNameFromAddressBookSelector } from 'src/logic/addressBook/store/selectors'
|
||||
import { getExplorerInfo } from 'src/config'
|
||||
import { useKnownAddress } from './hooks/useKnownAddress'
|
||||
|
||||
type Props = {
|
||||
address: string
|
||||
|
@ -12,7 +11,7 @@ type Props = {
|
|||
}
|
||||
|
||||
export const AddressInfo = ({ address, name, avatarUrl }: Props): ReactElement | null => {
|
||||
const recipientName = useSelector((state) => getNameFromAddressBookSelector(state, address))
|
||||
const toInfo = useKnownAddress(address, { name, image: avatarUrl })
|
||||
|
||||
if (address === '') {
|
||||
return null
|
||||
|
@ -21,9 +20,9 @@ export const AddressInfo = ({ address, name, avatarUrl }: Props): ReactElement |
|
|||
return (
|
||||
<EthHashInfo
|
||||
hash={address}
|
||||
name={recipientName === 'UNKNOWN' ? name : recipientName}
|
||||
name={toInfo.name}
|
||||
showAvatar
|
||||
customAvatar={avatarUrl}
|
||||
customAvatar={toInfo.image}
|
||||
showCopyBtn
|
||||
explorerUrl={getExplorerInfo(address)}
|
||||
/>
|
||||
|
|
|
@ -23,7 +23,7 @@ import { TokenTransferAmount } from './TokenTransferAmount'
|
|||
import { TxsInfiniteScrollContext } from './TxsInfiniteScroll'
|
||||
import { TxLocationContext } from './TxLocationProvider'
|
||||
import { CalculatedVotes } from './TxQueueCollapsed'
|
||||
import { isCancelTxDetails } from './utils'
|
||||
import { getTxTo, isCancelTxDetails } from './utils'
|
||||
|
||||
const TxInfo = ({ info }: { info: AssetInfo }) => {
|
||||
if (isTokenTransferAsset(info)) {
|
||||
|
@ -114,6 +114,7 @@ export const TxCollapsed = ({
|
|||
}: TxCollapsedProps): ReactElement => {
|
||||
const { txLocation } = useContext(TxLocationContext)
|
||||
const { ref, lastItemId } = useContext(TxsInfiniteScrollContext)
|
||||
const toAddress = getTxTo(transaction)
|
||||
|
||||
const willBeReplaced = transaction?.txStatus === 'WILL_BE_REPLACED' ? ' will-be-replaced' : ''
|
||||
const onChainRejection =
|
||||
|
@ -127,7 +128,12 @@ export const TxCollapsed = ({
|
|||
|
||||
const txCollapsedType = (
|
||||
<div className={'tx-type' + willBeReplaced + onChainRejection}>
|
||||
<CustomIconText iconUrl={type.icon} text={type.text} />
|
||||
<CustomIconText
|
||||
address={toAddress || '0x'}
|
||||
iconUrl={type.icon}
|
||||
iconUrlFallback={type.fallbackIcon}
|
||||
text={type.text}
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
import { useSelector } from 'react-redux'
|
||||
|
||||
import { getNameFromAddressBookSelector } from 'src/logic/addressBook/store/selectors'
|
||||
|
||||
type AddressInfo = { name: string | undefined; image: string | undefined }
|
||||
|
||||
type UseKnownAddressResponse = AddressInfo & { isAddressBook: boolean }
|
||||
|
||||
export const useKnownAddress = (address: string, addressInfo: AddressInfo): UseKnownAddressResponse => {
|
||||
const recipientName = useSelector((state) => getNameFromAddressBookSelector(state, address))
|
||||
|
||||
const isInAddressBook = recipientName !== 'UNKNOWN'
|
||||
|
||||
return isInAddressBook
|
||||
? {
|
||||
name: recipientName,
|
||||
image: undefined,
|
||||
isAddressBook: true,
|
||||
}
|
||||
: { ...addressInfo, isAddressBook: false }
|
||||
}
|
|
@ -1,22 +1,31 @@
|
|||
import { useEffect, useState } from 'react'
|
||||
import { useSelector } from 'react-redux'
|
||||
|
||||
import { Transaction } from 'src/logic/safe/store/models/types/gateway.d'
|
||||
import { Transaction, Custom } from 'src/logic/safe/store/models/types/gateway.d'
|
||||
import { safeParamAddressFromStateSelector } from 'src/logic/safe/store/selectors'
|
||||
import CustomTxIcon from 'src/routes/safe/components/Transactions/TxList/assets/custom.svg'
|
||||
import CircleCrossRed from 'src/routes/safe/components/Transactions/TxList/assets/circle-cross-red.svg'
|
||||
import IncomingTxIcon from 'src/routes/safe/components/Transactions/TxList/assets/incoming.svg'
|
||||
import OutgoingTxIcon from 'src/routes/safe/components/Transactions/TxList/assets/outgoing.svg'
|
||||
import SettingsTxIcon from 'src/routes/safe/components/Transactions/TxList/assets/settings.svg'
|
||||
import { getTxTo } from 'src/routes/safe/components/Transactions/TxList/utils'
|
||||
import { useKnownAddress } from './useKnownAddress'
|
||||
|
||||
export type TxTypeProps = {
|
||||
icon: string | null
|
||||
text: string
|
||||
icon?: string
|
||||
fallbackIcon?: string
|
||||
text?: string
|
||||
}
|
||||
|
||||
export const useTransactionType = (tx: Transaction): TxTypeProps => {
|
||||
const [type, setType] = useState<TxTypeProps>({ icon: CustomTxIcon, text: 'Contract interaction' })
|
||||
const safeAddress = useSelector(safeParamAddressFromStateSelector)
|
||||
const toAddress = getTxTo(tx)
|
||||
// Fixed casting because known address only works for Custom tx
|
||||
const knownAddress = useKnownAddress(toAddress || '0x', {
|
||||
name: (tx.txInfo as Custom)?.toInfo?.name,
|
||||
image: (tx.txInfo as Custom)?.toInfo?.logoUri || undefined,
|
||||
})
|
||||
|
||||
useEffect(() => {
|
||||
switch (tx.txInfo.type) {
|
||||
|
@ -51,16 +60,15 @@ export const useTransactionType = (tx: Transaction): TxTypeProps => {
|
|||
}
|
||||
|
||||
const toInfo = tx.txInfo.toInfo
|
||||
if (toInfo) {
|
||||
setType({ icon: toInfo.logoUri, text: toInfo.name })
|
||||
break
|
||||
}
|
||||
|
||||
setType({ icon: CustomTxIcon, text: 'Contract interaction' })
|
||||
setType({
|
||||
icon: knownAddress.isAddressBook ? CustomTxIcon : knownAddress.image || CustomTxIcon,
|
||||
fallbackIcon: knownAddress.isAddressBook ? undefined : CustomTxIcon,
|
||||
text: toInfo ? knownAddress.name : 'Contract interaction',
|
||||
})
|
||||
break
|
||||
}
|
||||
}
|
||||
}, [tx, safeAddress])
|
||||
}, [tx, safeAddress, knownAddress.name, knownAddress.image, knownAddress.isAddressBook])
|
||||
|
||||
return type
|
||||
}
|
||||
|
|
|
@ -96,3 +96,20 @@ export const isCancelTxDetails = (txInfo: Transaction['txInfo']): boolean =>
|
|||
|
||||
export const addressInList = (list: string[] = []) => (address: string): boolean =>
|
||||
list.some((ownerAddress) => sameAddress(ownerAddress, address))
|
||||
|
||||
export const getTxTo = (tx: Transaction): string | undefined => {
|
||||
switch (tx.txInfo.type) {
|
||||
case 'Transfer': {
|
||||
return tx.txInfo.recipient
|
||||
}
|
||||
case 'SettingsChange': {
|
||||
return undefined
|
||||
}
|
||||
case 'Custom': {
|
||||
return tx.txInfo.to
|
||||
}
|
||||
case 'Creation': {
|
||||
return tx.txInfo.factory || undefined
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1637,9 +1637,9 @@
|
|||
solc "0.5.14"
|
||||
truffle "^5.1.21"
|
||||
|
||||
"@gnosis.pm/safe-react-components@https://github.com/gnosis/safe-react-components.git#b281238":
|
||||
version "0.5.0"
|
||||
resolved "https://github.com/gnosis/safe-react-components.git#b2812381a265e9b0a17abbc11392986e6c1c74b8"
|
||||
"@gnosis.pm/safe-react-components@https://github.com/gnosis/safe-react-components.git#4864ebb":
|
||||
version "0.6.0"
|
||||
resolved "https://github.com/gnosis/safe-react-components.git#4864ebb57f1c0b39963c7a5a5acc4a8bf90448ea"
|
||||
dependencies:
|
||||
classnames "^2.2.6"
|
||||
react-media "^1.10.0"
|
||||
|
|
Loading…
Reference in New Issue