Skip to content

Commit

Permalink
Uplift of #26850 (squashed) to beta
Browse files Browse the repository at this point in the history
  • Loading branch information
brave-builds committed Dec 9, 2024
1 parent 7228742 commit 9d598dc
Show file tree
Hide file tree
Showing 8 changed files with 316 additions and 3 deletions.
5 changes: 5 additions & 0 deletions components/brave_wallet/browser/brave_wallet_constants.h
Original file line number Diff line number Diff line change
Expand Up @@ -1086,6 +1086,11 @@ inline constexpr webui::LocalizedString kLocalizedStrings[] = {
{"braveWalletNoResultsFound", IDS_BRAVE_WALLET_NO_RESULTS_FOUND},
{"braveWalletTryDifferentKeywords",
IDS_BRAVE_WALLET_TRY_DIFFERENT_KEYWORDS},
{"braveWalletCreateAccountToBuyTitle",
IDS_BRAVE_WALLET_CREATE_ACCOUNT_TO_BUY_TITLE},
{"braveWalletCreateAccountToBuyDescription",
IDS_BRAVE_WALLET_CREATE_ACCOUNT_TO_BUY_DESCRIPTION},
{"braveWalletAccountName", IDS_BRAVE_WALLET_ACCOUNT_NAME},
{"braveWalletBuyWithSardine", IDS_BRAVE_WALLET_BUY_WITH_SARDINE},
{"braveWalletBuyWithTransak", IDS_BRAVE_WALLET_BUY_WITH_TRANSAK},
{"braveWalletBuyWithStripe", IDS_BRAVE_WALLET_BUY_WITH_STRIPE},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ export const IconWrapper = styled.div<{
`

export type IconSize =
| 'massive'
| 'huge'
| 'big'
| 'medium'
Expand All @@ -49,6 +50,8 @@ interface IconProps extends AssetIconProps {

function getNetworkIconWidthFromSize(size?: IconSize): string {
switch (size) {
case 'massive':
return '64px'
case 'huge':
return '32px'
case 'big':
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
// Copyright (c) 2024 The Brave Authors. All rights reserved.
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this file,
// You can obtain one at https://mozilla.org/MPL/2.0/.

import styled from 'styled-components'
import LeoInput from '@brave/leo/react/input'
import LeoDialog from '@brave/leo/react/dialog'
import {
layoutPanelWidth //
} from '../../../../../components/desktop/wallet-page-wrapper/wallet-page-wrapper.style'

export const Dialog = styled(LeoDialog).attrs({
size: window.innerWidth <= layoutPanelWidth ? 'mobile' : 'normal'
})`
--leo-dialog-padding: 32px;
--leo-dialog-width: 600px;
--leo-dialog-backdrop-filter: blur(8px);
`

export const Input = styled(LeoInput)`
width: 100%;
max-width: 400px;
`
Original file line number Diff line number Diff line change
@@ -0,0 +1,230 @@
// Copyright (c) 2024 The Brave Authors. All rights reserved.
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this file,
// You can obtain one at https://mozilla.org/MPL/2.0/.

import * as React from 'react'
import { skipToken } from '@reduxjs/toolkit/query'
import { DialogProps } from '@brave/leo/react/dialog'
import { InputEventDetail } from '@brave/leo/react/input'
import Button from '@brave/leo/react/button'

// Queries
import { useAccountsQuery } from '../../../../../common/slices/api.slice.extra'
import {
useAddAccountMutation,
useGetNetworkQuery
} from '../../../../../common/slices/api.slice'

// Selectors
import {
useSafeUISelector //
} from '../../../../../common/hooks/use-safe-selector'
import { UISelectors } from '../../../../../common/selectors'

// Types
import { MeldCryptoCurrency, BraveWallet } from '../../../../../constants/types'

// Utils
import { getLocale } from '../../../../../../common/locale'
import { suggestNewAccountName } from '../../../../../utils/address-utils'
import { keyringIdForNewAccount } from '../../../../../utils/account-utils'
import { getMeldTokensCoinType } from '../../../../../utils/meld_utils'

// Components
import {
BottomSheet //
} from '../../../../../components/shared/bottom_sheet/bottom_sheet'
import {
CreateNetworkIcon //
} from '../../../../../components/shared/create-network-icon'

// Styled Components
import { Input, Dialog } from './create_account.style'
import { DialogTitle } from '../shared/style'
import { Column, Row, Text } from '../../../../../components/shared/style'

interface Props extends DialogProps {
isOpen: boolean
token?: MeldCryptoCurrency
onSelectToken: (asset: MeldCryptoCurrency) => void
onClose: () => void
}

export const CreateAccount = (props: Props) => {
const { token, onSelectToken, onClose, isOpen, ...rest } = props

// Selectors
const isPanel = useSafeUISelector(UISelectors.isPanel)

// State
const [accountName, setAccountName] = React.useState<string>('')

// Queries
const { accounts } = useAccountsQuery()
const { data: network } = useGetNetworkQuery(
token?.chainId
? {
chainId: token.chainId,
coin: getMeldTokensCoinType(token)
}
: skipToken
)

// Computed
const suggestedAccountName = network
? suggestNewAccountName(accounts, network)
: ''

// Mutations
const [addAccount] = useAddAccountMutation()

// Methods
const onClickCreateAccount = React.useCallback(async () => {
if (!network || !token) {
return
}
try {
const account = await addAccount({
coin: network.coin,
keyringId: keyringIdForNewAccount(network.coin, network.chainId),
accountName: suggestedAccountName
}).unwrap()

if (account) {
onSelectToken(token)
}
} catch (error) {
console.log(error)
}
}, [addAccount, network, suggestedAccountName, onSelectToken, token])

const handleAccountNameChanged = (detail: InputEventDetail) => {
setAccountName(detail.value)
}

const handleKeyDown = React.useCallback(
(detail: InputEventDetail) => {
if ((detail.innerEvent as unknown as KeyboardEvent).key === 'Enter') {
onClickCreateAccount()
}
},
[onClickCreateAccount]
)

// Effects
React.useEffect(() => {
setAccountName(suggestedAccountName)
}, [suggestedAccountName])

// Memos
const createAccountContent = React.useMemo(() => {
return (
<>
<DialogTitle slot='title'>
{getLocale('braveWalletCreateAccountButton')}
</DialogTitle>
<Column
gap='16px'
margin='0px 0px 46px 0px'
>
<CreateNetworkIcon
network={network}
size='massive'
/>
<Text
textSize='22px'
textColor='primary'
isBold={true}
>
{token
? getLocale('braveWalletCreateAccountToBuyTitle').replace(
'$1',
token.name ?? ''
)
: ''}
</Text>
<Text
textSize='14px'
textColor='tertiary'
isBold={false}
>
{token
? getLocale('braveWalletCreateAccountToBuyDescription')
.replace('$1', token.currencyCode ?? '')
.replace('$2', token.name ?? '')
: ''}
</Text>
</Column>
<Row margin='0px 0px 46px 0px'>
<Input
value={accountName}
placeholder={getLocale('braveWalletAddAccountPlaceholder')}
onInput={handleAccountNameChanged}
onKeyDown={handleKeyDown}
maxlength={BraveWallet.ACCOUNT_NAME_MAX_CHARACTER_LENGTH}
>
<Text
textSize='12px'
textColor='primary'
isBold={true}
>
{getLocale('braveWalletAccountName')}
</Text>
</Input>
</Row>
<Row gap='16px'>
<Button
kind='outline'
onClick={onClose}
>
{getLocale('braveWalletButtonCancel')}
</Button>
<Button
kind='filled'
onClick={onClickCreateAccount}
isDisabled={accountName === ''}
>
{getLocale('braveWalletCreateAccountButton')}
</Button>
</Row>
</>
)
}, [
network,
token,
accountName,
onClose,
onClickCreateAccount,
handleKeyDown
])

if (isPanel) {
return (
<BottomSheet
onClose={onClose}
isOpen={isOpen}
>
<Column
fullWidth={true}
padding='0px 16px'
height='90vh'
>
{createAccountContent}
</Column>
</BottomSheet>
)
}

return (
<Dialog
isOpen={isOpen}
onClose={onClose}
showClose
backdropClickCloses={false}
{...rest}
>
{createAccountContent}
</Dialog>
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ import { SelectCurrency } from './components/select_currency/select_currency'
import { SelectAccount } from './components/select_account/select_account'
import { SelectAsset } from './components/select_asset/select_asset'
import { BuyQuote } from './components/buy_quote/buy_quote'
import { CreateAccount } from './components/create_account/create_account'

// Styled Components
import {
Expand Down Expand Up @@ -106,7 +107,10 @@ export const FundWalletScreen = ({ isAndroid }: Props) => {
onBuy,
searchTerm,
onSearch,
hasQuoteError
hasQuoteError,
showCreateAccount,
onCloseCreateAccount,
pendingSelectedToken
} = useBuy()

// Redux
Expand Down Expand Up @@ -389,6 +393,13 @@ export const FundWalletScreen = ({ isAndroid }: Props) => {
selectedAsset={selectedAsset}
onClose={() => setIsAccountDialogOpen(false)}
/>

<CreateAccount
isOpen={showCreateAccount}
token={pendingSelectedToken || selectedAsset}
onClose={onCloseCreateAccount}
onSelectToken={onSelectToken}
/>
</>
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@ import {
MeldCryptoQuote,
MeldPaymentMethod,
CryptoBuySessionData,
CryptoWidgetCustomerData
CryptoWidgetCustomerData,
WalletRoutes
} from '../../../../constants/types'

// Hooks
Expand Down Expand Up @@ -136,6 +137,10 @@ export const useBuy = () => {
string | undefined
>(undefined)
const [searchTerm, setSearchTerm] = useState<string>('')
const [showCreateAccount, setShowCreateAccount] = useState<boolean>(false)
const [pendingSelectedToken, setPendingSelectedToken] = useState<
MeldCryptoCurrency | undefined
>(undefined)

// Mutations
const [generateQuotes] = useGenerateMeldCryptoQuotesMutation()
Expand Down Expand Up @@ -396,6 +401,13 @@ export const useBuy = () => {
selectedAccount.accountId.coin !== incomingAssetsCoinType
? getFirstAccountByCoinType(incomingAssetsCoinType, accounts)
: selectedAccount
if (!accountToUse) {
setPendingSelectedToken(asset)
setShowCreateAccount(true)
return
}
setShowCreateAccount(false)
setPendingSelectedToken(undefined)
history.replace(makeFundWalletRoute(asset, accountToUse))
setQuotes([])

Expand Down Expand Up @@ -464,6 +476,13 @@ export const useBuy = () => {
]
)

const onCloseCreateAccount = useCallback(() => {
if (!pendingSelectedToken) {
history.push(WalletRoutes.FundWalletPageStart)
}
setShowCreateAccount(false)
}, [pendingSelectedToken, history])

// Effects
useEffect(() => {
if (fiatCurrencies && fiatCurrencies.length > 0 && !selectedCurrency) {
Expand Down Expand Up @@ -509,6 +528,17 @@ export const useBuy = () => {
}
}, [selectedAsset, currencyCode, chainId, quotes, hasQuoteError])

useEffect(() => {
if (
selectedAsset.currencyCode !== DEFAULT_ASSET.currencyCode &&
currencyCode !== undefined &&
chainId !== undefined &&
selectedAccount === undefined
) {
setShowCreateAccount(true)
}
}, [selectedAsset, currencyCode, chainId, selectedAccount])

return {
selectedAsset,
selectedCurrency,
Expand Down Expand Up @@ -545,6 +575,9 @@ export const useBuy = () => {
cryptoEstimate,
hasQuoteError,
isLoadingServiceProvider,
reset
reset,
showCreateAccount,
onCloseCreateAccount,
pendingSelectedToken
}
}
Loading

0 comments on commit 9d598dc

Please sign in to comment.