From ac2987d9997dc1ae7648c0df874305ef3bfe20f9 Mon Sep 17 00:00:00 2001 From: nicolas Date: Wed, 12 May 2021 07:53:02 -0300 Subject: [PATCH] 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 --- package.json | 2 +- src/components/CustomIconText/index.tsx | 36 +++++++++---------- .../safe/store/models/types/gateway.d.ts | 2 +- .../Transactions/TxList/AddressInfo.tsx | 11 +++--- .../Transactions/TxList/TxCollapsed.tsx | 10 ++++-- .../TxList/hooks/useKnownAddress.ts | 21 +++++++++++ .../TxList/hooks/useTransactionType.ts | 28 +++++++++------ .../components/Transactions/TxList/utils.ts | 17 +++++++++ yarn.lock | 6 ++-- 9 files changed, 92 insertions(+), 41 deletions(-) create mode 100644 src/routes/safe/components/Transactions/TxList/hooks/useKnownAddress.ts diff --git a/package.json b/package.json index 8e7ef51d..fde07599 100644 --- a/package.json +++ b/package.json @@ -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", diff --git a/src/components/CustomIconText/index.tsx b/src/components/CustomIconText/index.tsx index 5cbb94ab..5e3740b3 100644 --- a/src/components/CustomIconText/index.tsx +++ b/src/components/CustomIconText/index.tsx @@ -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 => ( - - {iconUrl && } - {text && {text}} - +export const CustomIconText = ({ address, iconUrl, text, iconUrlFallback }: Props): ReactElement => ( + ) diff --git a/src/logic/safe/store/models/types/gateway.d.ts b/src/logic/safe/store/models/types/gateway.d.ts index f77a82f9..ded94e31 100644 --- a/src/logic/safe/store/models/types/gateway.d.ts +++ b/src/logic/safe/store/models/types/gateway.d.ts @@ -136,7 +136,7 @@ type BaseCustom = { toInfo?: AddressInfo } -type Custom = BaseCustom & { +export type Custom = BaseCustom & { methodName: string | null } diff --git a/src/routes/safe/components/Transactions/TxList/AddressInfo.tsx b/src/routes/safe/components/Transactions/TxList/AddressInfo.tsx index 45f4b654..d9082f50 100644 --- a/src/routes/safe/components/Transactions/TxList/AddressInfo.tsx +++ b/src/routes/safe/components/Transactions/TxList/AddressInfo.tsx @@ -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 ( diff --git a/src/routes/safe/components/Transactions/TxList/TxCollapsed.tsx b/src/routes/safe/components/Transactions/TxList/TxCollapsed.tsx index 724393c9..664d8c91 100644 --- a/src/routes/safe/components/Transactions/TxList/TxCollapsed.tsx +++ b/src/routes/safe/components/Transactions/TxList/TxCollapsed.tsx @@ -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 = (
- +
) diff --git a/src/routes/safe/components/Transactions/TxList/hooks/useKnownAddress.ts b/src/routes/safe/components/Transactions/TxList/hooks/useKnownAddress.ts new file mode 100644 index 00000000..1542d1eb --- /dev/null +++ b/src/routes/safe/components/Transactions/TxList/hooks/useKnownAddress.ts @@ -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 } +} diff --git a/src/routes/safe/components/Transactions/TxList/hooks/useTransactionType.ts b/src/routes/safe/components/Transactions/TxList/hooks/useTransactionType.ts index 8766fa38..8ab2ecad 100644 --- a/src/routes/safe/components/Transactions/TxList/hooks/useTransactionType.ts +++ b/src/routes/safe/components/Transactions/TxList/hooks/useTransactionType.ts @@ -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({ 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 } diff --git a/src/routes/safe/components/Transactions/TxList/utils.ts b/src/routes/safe/components/Transactions/TxList/utils.ts index 13b15057..488cfd65 100644 --- a/src/routes/safe/components/Transactions/TxList/utils.ts +++ b/src/routes/safe/components/Transactions/TxList/utils.ts @@ -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 + } + } +} diff --git a/yarn.lock b/yarn.lock index 295bf2b8..65459414 100644 --- a/yarn.lock +++ b/yarn.lock @@ -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"