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": "1.0.3",
|
||||||
"@gnosis.pm/safe-apps-sdk-v1": "npm:@gnosis.pm/safe-apps-sdk@0.4.2",
|
"@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-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",
|
"@gnosis.pm/util-contracts": "2.0.6",
|
||||||
"@ledgerhq/hw-transport-node-hid-singleton": "5.49.0",
|
"@ledgerhq/hw-transport-node-hid-singleton": "5.49.0",
|
||||||
"@material-ui/core": "^4.11.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 React, { ReactElement } from 'react'
|
||||||
import styled from 'styled-components'
|
|
||||||
|
|
||||||
const Wrapper = styled.div`
|
type Props = {
|
||||||
display: flex;
|
address: string
|
||||||
align-items: center;
|
iconUrl?: string
|
||||||
`
|
iconUrlFallback?: string
|
||||||
const Icon = styled.img`
|
text?: string
|
||||||
max-width: 15px;
|
}
|
||||||
max-height: 15px;
|
|
||||||
margin-right: 9px;
|
|
||||||
`
|
|
||||||
|
|
||||||
type Props = { iconUrl: string | null | undefined; text?: string }
|
export const CustomIconText = ({ address, iconUrl, text, iconUrlFallback }: Props): ReactElement => (
|
||||||
|
<EthHashInfo
|
||||||
export const CustomIconText = ({ iconUrl, text }: Props): ReactElement => (
|
hash={address}
|
||||||
<Wrapper>
|
showHash={false}
|
||||||
{iconUrl && <Icon alt={text} src={iconUrl} />}
|
avatarSize="sm"
|
||||||
{text && <Text size="xl">{text}</Text>}
|
showAvatar
|
||||||
</Wrapper>
|
customAvatar={iconUrl || undefined}
|
||||||
|
customAvatarFallback={iconUrlFallback}
|
||||||
|
name={text}
|
||||||
|
textSize="xl"
|
||||||
|
/>
|
||||||
)
|
)
|
||||||
|
|
|
@ -136,7 +136,7 @@ type BaseCustom = {
|
||||||
toInfo?: AddressInfo
|
toInfo?: AddressInfo
|
||||||
}
|
}
|
||||||
|
|
||||||
type Custom = BaseCustom & {
|
export type Custom = BaseCustom & {
|
||||||
methodName: string | null
|
methodName: string | null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,9 +1,8 @@
|
||||||
import { EthHashInfo } from '@gnosis.pm/safe-react-components'
|
import { EthHashInfo } from '@gnosis.pm/safe-react-components'
|
||||||
import React, { ReactElement } from 'react'
|
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 = {
|
type Props = {
|
||||||
address: string
|
address: string
|
||||||
|
@ -12,7 +11,7 @@ type Props = {
|
||||||
}
|
}
|
||||||
|
|
||||||
export const AddressInfo = ({ address, name, avatarUrl }: Props): ReactElement | null => {
|
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 === '') {
|
if (address === '') {
|
||||||
return null
|
return null
|
||||||
|
@ -21,9 +20,9 @@ export const AddressInfo = ({ address, name, avatarUrl }: Props): ReactElement |
|
||||||
return (
|
return (
|
||||||
<EthHashInfo
|
<EthHashInfo
|
||||||
hash={address}
|
hash={address}
|
||||||
name={recipientName === 'UNKNOWN' ? name : recipientName}
|
name={toInfo.name}
|
||||||
showAvatar
|
showAvatar
|
||||||
customAvatar={avatarUrl}
|
customAvatar={toInfo.image}
|
||||||
showCopyBtn
|
showCopyBtn
|
||||||
explorerUrl={getExplorerInfo(address)}
|
explorerUrl={getExplorerInfo(address)}
|
||||||
/>
|
/>
|
||||||
|
|
|
@ -23,7 +23,7 @@ import { TokenTransferAmount } from './TokenTransferAmount'
|
||||||
import { TxsInfiniteScrollContext } from './TxsInfiniteScroll'
|
import { TxsInfiniteScrollContext } from './TxsInfiniteScroll'
|
||||||
import { TxLocationContext } from './TxLocationProvider'
|
import { TxLocationContext } from './TxLocationProvider'
|
||||||
import { CalculatedVotes } from './TxQueueCollapsed'
|
import { CalculatedVotes } from './TxQueueCollapsed'
|
||||||
import { isCancelTxDetails } from './utils'
|
import { getTxTo, isCancelTxDetails } from './utils'
|
||||||
|
|
||||||
const TxInfo = ({ info }: { info: AssetInfo }) => {
|
const TxInfo = ({ info }: { info: AssetInfo }) => {
|
||||||
if (isTokenTransferAsset(info)) {
|
if (isTokenTransferAsset(info)) {
|
||||||
|
@ -114,6 +114,7 @@ export const TxCollapsed = ({
|
||||||
}: TxCollapsedProps): ReactElement => {
|
}: TxCollapsedProps): ReactElement => {
|
||||||
const { txLocation } = useContext(TxLocationContext)
|
const { txLocation } = useContext(TxLocationContext)
|
||||||
const { ref, lastItemId } = useContext(TxsInfiniteScrollContext)
|
const { ref, lastItemId } = useContext(TxsInfiniteScrollContext)
|
||||||
|
const toAddress = getTxTo(transaction)
|
||||||
|
|
||||||
const willBeReplaced = transaction?.txStatus === 'WILL_BE_REPLACED' ? ' will-be-replaced' : ''
|
const willBeReplaced = transaction?.txStatus === 'WILL_BE_REPLACED' ? ' will-be-replaced' : ''
|
||||||
const onChainRejection =
|
const onChainRejection =
|
||||||
|
@ -127,7 +128,12 @@ export const TxCollapsed = ({
|
||||||
|
|
||||||
const txCollapsedType = (
|
const txCollapsedType = (
|
||||||
<div className={'tx-type' + willBeReplaced + onChainRejection}>
|
<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>
|
</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 { useEffect, useState } from 'react'
|
||||||
import { useSelector } from 'react-redux'
|
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 { safeParamAddressFromStateSelector } from 'src/logic/safe/store/selectors'
|
||||||
import CustomTxIcon from 'src/routes/safe/components/Transactions/TxList/assets/custom.svg'
|
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 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 IncomingTxIcon from 'src/routes/safe/components/Transactions/TxList/assets/incoming.svg'
|
||||||
import OutgoingTxIcon from 'src/routes/safe/components/Transactions/TxList/assets/outgoing.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 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 = {
|
export type TxTypeProps = {
|
||||||
icon: string | null
|
icon?: string
|
||||||
text: string
|
fallbackIcon?: string
|
||||||
|
text?: string
|
||||||
}
|
}
|
||||||
|
|
||||||
export const useTransactionType = (tx: Transaction): TxTypeProps => {
|
export const useTransactionType = (tx: Transaction): TxTypeProps => {
|
||||||
const [type, setType] = useState<TxTypeProps>({ icon: CustomTxIcon, text: 'Contract interaction' })
|
const [type, setType] = useState<TxTypeProps>({ icon: CustomTxIcon, text: 'Contract interaction' })
|
||||||
const safeAddress = useSelector(safeParamAddressFromStateSelector)
|
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(() => {
|
useEffect(() => {
|
||||||
switch (tx.txInfo.type) {
|
switch (tx.txInfo.type) {
|
||||||
|
@ -51,16 +60,15 @@ export const useTransactionType = (tx: Transaction): TxTypeProps => {
|
||||||
}
|
}
|
||||||
|
|
||||||
const toInfo = tx.txInfo.toInfo
|
const toInfo = tx.txInfo.toInfo
|
||||||
if (toInfo) {
|
setType({
|
||||||
setType({ icon: toInfo.logoUri, text: toInfo.name })
|
icon: knownAddress.isAddressBook ? CustomTxIcon : knownAddress.image || CustomTxIcon,
|
||||||
break
|
fallbackIcon: knownAddress.isAddressBook ? undefined : CustomTxIcon,
|
||||||
}
|
text: toInfo ? knownAddress.name : 'Contract interaction',
|
||||||
|
})
|
||||||
setType({ icon: CustomTxIcon, text: 'Contract interaction' })
|
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, [tx, safeAddress])
|
}, [tx, safeAddress, knownAddress.name, knownAddress.image, knownAddress.isAddressBook])
|
||||||
|
|
||||||
return type
|
return type
|
||||||
}
|
}
|
||||||
|
|
|
@ -96,3 +96,20 @@ export const isCancelTxDetails = (txInfo: Transaction['txInfo']): boolean =>
|
||||||
|
|
||||||
export const addressInList = (list: string[] = []) => (address: string): boolean =>
|
export const addressInList = (list: string[] = []) => (address: string): boolean =>
|
||||||
list.some((ownerAddress) => sameAddress(ownerAddress, address))
|
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"
|
solc "0.5.14"
|
||||||
truffle "^5.1.21"
|
truffle "^5.1.21"
|
||||||
|
|
||||||
"@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":
|
||||||
version "0.5.0"
|
version "0.6.0"
|
||||||
resolved "https://github.com/gnosis/safe-react-components.git#b2812381a265e9b0a17abbc11392986e6c1c74b8"
|
resolved "https://github.com/gnosis/safe-react-components.git#4864ebb57f1c0b39963c7a5a5acc4a8bf90448ea"
|
||||||
dependencies:
|
dependencies:
|
||||||
classnames "^2.2.6"
|
classnames "^2.2.6"
|
||||||
react-media "^1.10.0"
|
react-media "^1.10.0"
|
||||||
|
|
Loading…
Reference in New Issue