Skip to content

Commit

Permalink
feat(wallet): Add Loading State for Domain Lookup
Browse files Browse the repository at this point in the history
  • Loading branch information
Douglashdaniel committed Nov 29, 2022
1 parent 9a13fb5 commit 105487f
Show file tree
Hide file tree
Showing 8 changed files with 109 additions and 86 deletions.
1 change: 1 addition & 0 deletions components/brave_wallet/browser/brave_wallet_constants.h
Original file line number Diff line number Diff line change
Expand Up @@ -942,6 +942,7 @@ constexpr webui::LocalizedString kLocalizedStrings[] = {
{"braveWalletHelpCenter", IDS_BRAVE_WALLET_HELP_CENTER},
{"braveWalletBuyTapBuyNotSupportedMessage",
IDS_BRAVE_WALLET_BUY_TAB_BUY_NOT_SUPPORTED_MESSAGE},
{"braveWalletSearchingForDomain", IDS_BRAVE_WALLET_SEARCHING_FOR_DOMAIN},
{"braveWalletPortfolioTokenDetailsMenuLabel",
IDS_BRAVE_WALLET_PORTFOLIO_TOKEN_DETAILS_MENU_LABEL},
{"braveWalletPortfolioViewOnExplorerMenuLabel",
Expand Down
113 changes: 49 additions & 64 deletions components/brave_wallet_ui/common/hooks/send.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,8 @@ export default function useSend (isSendTab?: boolean) {
toAddress,
toAddressOrUrl,
showEnsOffchainLookupOptions,
ensOffchainLookupOptions
ensOffchainLookupOptions,
searchingForDomain
} = useSelector((state: { sendCrypto: PendingCryptoSendState }) => state.sendCrypto)

// custom hooks
Expand Down Expand Up @@ -88,6 +89,9 @@ export default function useSend (isSendTab?: boolean) {
const setToAddressOrUrl = (payload?: string | undefined) => {
dispatch(SendCryptoActions.setToAddressOrUrl(payload))
}
const setSearchingForDomain = (payload: boolean) => {
dispatch(SendCryptoActions.setSearchingForDomain(payload))
}

const selectSendAsset = (asset: BraveWallet.BlockchainToken | undefined) => {
if (asset?.isErc721 || asset?.isNft) {
Expand All @@ -102,44 +106,50 @@ export default function useSend (isSendTab?: boolean) {
setAddressError(getLocale('braveWalletNotDomain').replace('$1', url))
}

const handleDomainLookupResponse = React.useCallback((address: string, error: BraveWallet.ProviderError, requireOffchainConsent: boolean) => {
if (address && error === BraveWallet.ProviderError.kSuccess) {
setAddressError('')
setAddressWarning('')
setToAddress(address)
setShowEnsOffchainLookupOptions(requireOffchainConsent)
// If found UD address is the same as the selectedAccounts Wallet Address
if (address.toLowerCase() === selectedAccount?.address?.toLowerCase()) {
setAddressError(getLocale('braveWalletSameAddressError'))
}
setSearchingForDomain(false)
return
}
setShowEnsOffchainLookupOptions(false)
setNotRegisteredError(toAddressOrUrl)
setSearchingForDomain(false)
}, [selectedAccount?.address, toAddressOrUrl])

const handleUDAddressLookUp = React.useCallback(() => {
setSearchingForDomain(true)
setToAddress('')
findUnstoppableDomainAddress(toAddressOrUrl, selectedSendAsset ?? null).then((value: GetUnstoppableDomainsWalletAddrReturnInfo) => {
handleDomainLookupResponse(value.address, value.error, false)
}).catch(e => console.log(e))
}, [findUnstoppableDomainAddress, handleDomainLookupResponse, findSNSAddress, findENSAddress, toAddressOrUrl, selectedSendAsset, selectedAccount?.coin])

const processEthereumAddress = React.useCallback((toAddressOrUrl: string) => {
const valueToLowerCase = toAddressOrUrl.toLowerCase()

// If value ends with a supported ENS extension, will call findENSAddress.
// If success true, will set toAddress else will return error message.
if (endsWithAny(supportedENSExtensions, valueToLowerCase)) {
setSearchingForDomain(true)
setToAddress('')
findENSAddress(toAddressOrUrl, ensOffchainLookupOptions).then((value: GetEthAddrReturnInfo) => {
if (value.error === BraveWallet.ProviderError.kSuccess) {
setAddressError('')
setAddressWarning('')
setToAddress(value.address)
setShowEnsOffchainLookupOptions(value.requireOffchainConsent)
// If found ENS address is the same as the selectedAccounts Wallet Address
if (value.address.toLowerCase() === selectedAccount?.address?.toLowerCase()) {
setAddressError(getLocale('braveWalletSameAddressError'))
}
return
}
setShowEnsOffchainLookupOptions(false)
setNotRegisteredError(valueToLowerCase)
handleDomainLookupResponse(value.address, value.error, value.requireOffchainConsent)
}).catch(e => console.log(e))
return
}

// If value ends with a supported UD extension, will call findUnstoppableDomainAddress.
// If success true, will set toAddress else will return error message.
if (endsWithAny(supportedUDExtensions, valueToLowerCase)) {
findUnstoppableDomainAddress(toAddressOrUrl, selectedSendAsset ?? null).then((value: GetUnstoppableDomainsWalletAddrReturnInfo) => {
if (value.address && value.error === BraveWallet.ProviderError.kSuccess) {
setAddressError('')
setAddressWarning('')
setToAddress(value.address)
// If found UD address is the same as the selectedAccounts Wallet Address
if (value.address.toLowerCase() === selectedAccount?.address?.toLowerCase()) {
setAddressError(getLocale('braveWalletSameAddressError'))
}
return
}
setNotRegisteredError(valueToLowerCase)
}).catch(e => console.log(e))
handleUDAddressLookUp()
return
}

Expand Down Expand Up @@ -198,23 +208,15 @@ export default function useSend (isSendTab?: boolean) {
// Fallback error state
setAddressWarning('')
setAddressError(getLocale('braveWalletNotValidAddress'))
}, [selectedAccount?.address, selectedSendAsset, ensOffchainLookupOptions])
}, [selectedAccount?.address, ensOffchainLookupOptions, handleUDAddressLookUp, handleDomainLookupResponse])

const processFilecoinAddress = React.useCallback((toAddressOrUrl: string) => {
const valueToLowerCase = toAddressOrUrl.toLowerCase()

// If value ends with a supported UD extension, will call findUnstoppableDomainAddress.
// If success true, will set toAddress else will return error message.
if (endsWithAny(supportedUDExtensions, valueToLowerCase)) {
findUnstoppableDomainAddress(toAddressOrUrl, selectedSendAsset ?? null).then((value: GetUnstoppableDomainsWalletAddrReturnInfo) => {
if (value.address && value.error === BraveWallet.ProviderError.kSuccess) {
setAddressError('')
setAddressWarning('')
setToAddress(value.address)
return
}
setNotRegisteredError(valueToLowerCase)
}).catch(e => console.log(e))
handleUDAddressLookUp()
return
}

Expand Down Expand Up @@ -243,43 +245,25 @@ export default function useSend (isSendTab?: boolean) {
// Reset error and warning state back to normal
setAddressWarning('')
setAddressError('')
}, [selectedSendAsset, selectedAccount?.address])
}, [selectedAccount?.address, handleUDAddressLookUp])

const processSolanaAddress = React.useCallback((toAddressOrUrl: string) => {
const valueToLowerCase = toAddressOrUrl.toLowerCase()

// If value ends with a supported UD extension, will call findUnstoppableDomainAddress.
// If success true, will set toAddress else will return error message.
if (endsWithAny(supportedUDExtensions, valueToLowerCase)) {
findUnstoppableDomainAddress(toAddressOrUrl, selectedSendAsset ?? null).then((value: GetUnstoppableDomainsWalletAddrReturnInfo) => {
if (value.address && value.error === BraveWallet.ProviderError.kSuccess) {
setAddressError('')
setAddressWarning('')
setToAddress(value.address)
// If found UD address is the same as the selectedAccounts Wallet Address
if (value.address.toLowerCase() === selectedAccount?.address?.toLowerCase()) {
setAddressError(getLocale('braveWalletSameAddressError'))
}
return
}
setNotRegisteredError(valueToLowerCase)
}).catch(e => console.log(e))
handleUDAddressLookUp()
return
}

// If value ends with a supported SNS extension, will call findENSAddress.
// If success true, will set toAddress else will return error message.
if (endsWithAny(supportedSNSExtensions, valueToLowerCase)) {
setSearchingForDomain(true)
setToAddress('')
findSNSAddress(toAddressOrUrl).then((value: GetSolAddrReturnInfo) => {
if (value.error === BraveWallet.ProviderError.kSuccess) {
setAddressError('')
setAddressWarning('')
setToAddress(value.address)
// If found SNS address is the same as the selectedAccounts Wallet Address
if (value.address.toLowerCase() === selectedAccount?.address?.toLowerCase()) {
setAddressError(getLocale('braveWalletSameAddressError'))
}
return
}
setNotRegisteredError(valueToLowerCase)
handleDomainLookupResponse(value.address, value.error, false)
}).catch(e => console.log(e))
return
}
Expand Down Expand Up @@ -325,7 +309,7 @@ export default function useSend (isSendTab?: boolean) {
setAddressWarning('')
setAddressError('')
})
}, [selectedAccount?.address, selectedSendAsset, fullTokenList])
}, [selectedAccount?.address, fullTokenList, handleUDAddressLookUp, handleDomainLookupResponse])

const resetSendFields = React.useCallback((reselectSendAsset?: boolean) => {
if (isSendTab) {
Expand Down Expand Up @@ -490,6 +474,7 @@ export default function useSend (isSendTab?: boolean) {
sendAmountValidationError,
showEnsOffchainLookupOptions,
ensOffchainLookupOptions,
setEnsOffchainLookupOptions
setEnsOffchainLookupOptions,
searchingForDomain
}
}
17 changes: 15 additions & 2 deletions components/brave_wallet_ui/common/reducers/send_crypto_reducer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ export interface PendingCryptoSendState {
sendAmount: string
showEnsOffchainLookupOptions: boolean
ensOffchainLookupOptions?: BraveWallet.EnsOffchainLookupOptions
searchingForDomain: boolean
}

const defaultState: PendingCryptoSendState = {
Expand All @@ -25,7 +26,8 @@ const defaultState: PendingCryptoSendState = {
selectedSendAsset: undefined,
toAddressOrUrl: '',
showEnsOffchainLookupOptions: false,
ensOffchainLookupOptions: undefined
ensOffchainLookupOptions: undefined,
searchingForDomain: false
}

export const SendCryptoActions = {
Expand All @@ -36,7 +38,8 @@ export const SendCryptoActions = {
setShowEnsOffchainLookupOptions: createAction<boolean>('setShowEnsOffchainLookupOptions'),
setEnsOffchainLookupOptions: createAction<BraveWallet.EnsOffchainLookupOptions | undefined>('setEnsOffchainLookupOptions'),
setAddressWarning: createAction<string | undefined>('setAddressWarning'),
selectSendAsset: createAction<BraveWallet.BlockchainToken | undefined>('selectSendAsset')
selectSendAsset: createAction<BraveWallet.BlockchainToken | undefined>('selectSendAsset'),
setSearchingForDomain: createAction<boolean>('setSearchingForDomain')
}

export const createSendCryptoReducer = (initialState: PendingCryptoSendState) => {
Expand Down Expand Up @@ -122,6 +125,16 @@ export const createSendCryptoReducer = (initialState: PendingCryptoSendState) =>
}
})

reducer.on(SendCryptoActions.setSearchingForDomain, (
state: PendingCryptoSendState,
payload: boolean
): PendingCryptoSendState => {
return {
...state,
searchingForDomain: payload
}
})

return reducer
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@

import styled from 'styled-components'

// Assets
import { LoaderIcon } from 'brave-ui/components/icons'

// Shared Styles
import { StyledButton, Icon } from '../../shared.styles'

Expand Down Expand Up @@ -78,3 +81,11 @@ export const ErrorIcon = styled(Icon)`
background-color: ${(p) => p.theme.color.errorBorder};
margin-right: 12px;
`

export const LoadIcon = styled(LoaderIcon)`
color: ${p => p.theme.color.white};
height: 25px;
width: 25px;
opacity: .4;
margin-right: 10px;
`
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,11 @@ import * as React from 'react'
import InfoIcon from '../../../../../assets/svg-icons/info-icon.svg'

// Styled Components
import { Button, ErrorIcon, StandardButtonStyleProps } from './standard-button.style'
import { Button, ErrorIcon, StandardButtonStyleProps, LoadIcon } from './standard-button.style'

interface Props extends StandardButtonStyleProps {
buttonText: string
isLoading: boolean
onClick: () => void
}

Expand All @@ -24,6 +25,7 @@ export const StandardButton = (props: Props) => {
disabled,
marginRight,
hasError,
isLoading,
onClick
} = props

Expand All @@ -39,6 +41,9 @@ export const StandardButton = (props: Props) => {
{hasError &&
<ErrorIcon icon={InfoIcon} size={22} />
}
{isLoading &&
<LoadIcon />
}
{buttonText}
</Button>
)
Expand Down
44 changes: 25 additions & 19 deletions components/brave_wallet_ui/page/screens/send/send/send.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,8 @@ export const Send = (props: Props) => {
setSendAmount,
setToAddressOrUrl,
submitSend,
selectSendAsset
selectSendAsset,
searchingForDomain
} = useSend(true)

// Hooks
Expand Down Expand Up @@ -176,25 +177,28 @@ export const Send = (props: Props) => {
}, [spotPrices, selectedSendAsset, sendAmount, defaultCurrencies.fiat, sendAssetBalance, selectedSendOption])

const reviewButtonText = React.useMemo(() => {
return sendAmountValidationError
? getLocale('braveWalletDecimalPlacesError')
: insufficientFundsError
? getLocale('braveWalletNotEnoughFunds')
: (addressError !== undefined && addressError !== '')
? addressError
: (addressWarning !== undefined && addressWarning !== '')
? addressWarning
: getLocale('braveWalletReviewOrder')
}, [insufficientFundsError, addressError, addressWarning, sendAmountValidationError])
return searchingForDomain
? getLocale('braveWalletSearchingForDomain')
: sendAmountValidationError
? getLocale('braveWalletDecimalPlacesError')
: insufficientFundsError
? getLocale('braveWalletNotEnoughFunds')
: (addressError !== undefined && addressError !== '')
? addressError
: (addressWarning !== undefined && addressWarning !== '')
? addressWarning
: getLocale('braveWalletReviewOrder')
}, [insufficientFundsError, addressError, addressWarning, sendAmountValidationError, searchingForDomain])

const isReviewButtonDisabled = React.useMemo(() => {
return toAddressOrUrl === '' ||
return searchingForDomain ||
toAddressOrUrl === '' ||
parseFloat(sendAmount) === 0 ||
sendAmount === '' ||
insufficientFundsError ||
(addressError !== undefined && addressError !== '') ||
sendAmountValidationError !== undefined
}, [toAddressOrUrl, sendAmount, insufficientFundsError, addressError, sendAmountValidationError])
}, [toAddressOrUrl, sendAmount, insufficientFundsError, addressError, sendAmountValidationError, searchingForDomain])

const selectedTokensNetwork = React.useMemo(() => {
if (selectedSendAsset) {
Expand Down Expand Up @@ -347,8 +351,9 @@ export const Send = (props: Props) => {
<DIVForWidth id={INPUT_WIDTH_ID}>{toAddressOrUrl}</DIVForWidth>
<AddressInput
placeholder={getLocale('braveWalletEnterRecipientAddress')}
hasError={
(addressError !== undefined && addressError !== '') ||
hasError={searchingForDomain
? false
: (addressError !== undefined && addressError !== '') ||
(addressWarning !== undefined && addressWarning !== '')
}
value={toAddressOrUrl}
Expand All @@ -362,11 +367,12 @@ export const Send = (props: Props) => {
onClick={submitSend}
buttonType='primary'
buttonWidth='full'
isLoading={searchingForDomain}
disabled={isReviewButtonDisabled}
hasError={
insufficientFundsError ||
(addressError !== undefined && addressError !== '')
}
hasError={searchingForDomain
? false
: insufficientFundsError ||
(addressError !== undefined && addressError !== '')}
/>
</SendContainer>
<Background
Expand Down
1 change: 1 addition & 0 deletions components/brave_wallet_ui/stories/locale.ts
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ provideStrings({
braveWalletSwapFeesNotice: 'Quote includes a $1 Brave fee.',
braveWalletDecimalPlacesError: 'Too many decimal places',
braveWalletBuyTapBuyNotSupportedMessage: 'Buy not supported for selected network',
braveWalletSearchingForDomain: 'Searching for Domain...',

// Send Tab
braveWalletSendToken: 'Send token',
Expand Down
1 change: 1 addition & 0 deletions components/resources/wallet_strings.grdp
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@
<message name="IDS_BRAVE_WALLET_SEARCH_NFTS" desc="Send tab search for nfts.">Search NFT by name, id</message>
<message name="IDS_BRAVE_WALLET_BUY_NOT_SUPPORTED_TOOLTIP" desc="Tooltip text when buy action is not supported">Buy support is not available for <ph name="NETWORK"><ex>Binance Smart Chain</ex>$1</ph></message>
<message name="IDS_BRAVE_WALLET_BUY_TAB_BUY_NOT_SUPPORTED_MESSAGE" desc="Message shown when the selected network is not supported for buy transactions">Buy not supported for selected network</message>
<message name="IDS_BRAVE_WALLET_SEARCHING_FOR_DOMAIN" desc="Message shown when searching for a UD or ENS domain">Searching for Domain...</message>
<message name="IDS_BRAVE_WALLET_SWAP_NOT_SUPPORTED_TOOLTIP" desc="Tooltip text when swap action is not supported">Swap support is not available for <ph name="NETWORK"><ex>Binance Smart Chain</ex>$1</ph></message>
<message name="IDS_BRAVE_WALLET_SLIPPAGE_TOLERANCE_WARNING" desc="Warning if slippage tolerance is to high">Transaction may be frontrun</message>
<message name="IDS_BRAVE_WALLET_SLIPPAGE_TOLERANCE_TITLE" desc="BuySendSwapo slippage tolerance title">Slippage tolerance</message>
Expand Down

0 comments on commit 105487f

Please sign in to comment.