Skip to content

Commit

Permalink
Disable button when web usb navigator api is not supported
Browse files Browse the repository at this point in the history
  • Loading branch information
buberdds committed Nov 8, 2022
1 parent 2a4bad6 commit e07f288
Show file tree
Hide file tree
Showing 4 changed files with 164 additions and 28 deletions.
6 changes: 5 additions & 1 deletion src/app/lib/ledger.ts
Expand Up @@ -12,7 +12,11 @@ interface LedgerAccount {
path: number[]
}

export async function requestDevice() {
export async function canAccessNavigatorUsb(): Promise<boolean> {
return await isSupported()
}

export async function requestDevice(): Promise<USBDevice | undefined> {
if (await isSupported()) {
return await requestLedgerDevice()
}
Expand Down
Expand Up @@ -50,6 +50,12 @@ exports[`<SelectOpenMethod /> should render component 1`] = `
width: 24px;
}
.c6 {
font-size: 14px;
line-height: 20px;
text-align: center;
}
.c3 {
display: inline-block;
box-sizing: border-box;
Expand Down Expand Up @@ -119,6 +125,73 @@ exports[`<SelectOpenMethod /> should render component 1`] = `
border: 0;
}
.c5 {
display: inline-block;
box-sizing: border-box;
cursor: pointer;
font: inherit;
-webkit-text-decoration: none;
text-decoration: none;
margin: 0;
background: transparent;
overflow: visible;
text-transform: none;
border: 2px solid #7D4CDB;
border-radius: 18px;
color: #444444;
padding: 4px 22px;
font-size: 18px;
line-height: 24px;
background-color: #7D4CDB;
color: #f8f8f8;
border-radius: 18px;
opacity: 0.3;
cursor: default;
-webkit-transition-property: color,background-color,border-color,box-shadow;
transition-property: color,background-color,border-color,box-shadow;
-webkit-transition-duration: 0.1s;
transition-duration: 0.1s;
-webkit-transition-timing-function: ease-in-out;
transition-timing-function: ease-in-out;
}
.c5:focus {
outline: none;
box-shadow: 0 0 2px 2px #6FFFB0;
}
.c5:focus > circle,
.c5:focus > ellipse,
.c5:focus > line,
.c5:focus > path,
.c5:focus > polygon,
.c5:focus > polyline,
.c5:focus > rect {
outline: none;
box-shadow: 0 0 2px 2px #6FFFB0;
}
.c5:focus::-moz-focus-inner {
border: 0;
}
.c5:focus:not(:focus-visible) {
outline: none;
box-shadow: none;
}
.c5:focus:not(:focus-visible) > circle,.c5:focus:not(:focus-visible) > ellipse,
.c5:focus:not(:focus-visible) > line,.c5:focus:not(:focus-visible) > path,
.c5:focus:not(:focus-visible) > polygon,.c5:focus:not(:focus-visible) > polyline,
.c5:focus:not(:focus-visible) > rect {
outline: none;
box-shadow: none;
}
.c5:focus:not(:focus-visible)::-moz-focus-inner {
border: 0;
}
.c1 {
margin-top: 0px;
font-size: 34px;
Expand Down Expand Up @@ -238,20 +311,30 @@ exports[`<SelectOpenMethod /> should render component 1`] = `
<div
class="c4"
/>
<span>
<a
aria-label="openWallet.method.ledger"
href="/ledger"
<div>
<div>
<span>
<a
aria-label="openWallet.method.ledger"
href="/ledger"
>
<button
class="c5"
disabled=""
tabindex="-1"
type="button"
>
openWallet.method.ledger
</button>
</a>
</span>
</div>
<span
class="c6"
>
<button
class="c3"
tabindex="-1"
type="button"
>
openWallet.method.ledger
</button>
</a>
</span>
errors.usbTransportNotSupported
</span>
</div>
</div>
<div
class="c2"
Expand Down
23 changes: 22 additions & 1 deletion src/app/pages/OpenWalletPage/__tests__/index.test.tsx
@@ -1,14 +1,16 @@
import React from 'react'
import { render, screen } from '@testing-library/react'
import { render, screen, waitForElementToBeRemoved } from '@testing-library/react'
import { MemoryRouter } from 'react-router-dom'
import { useSelector } from 'react-redux'
import { when } from 'jest-when'
import { selectShowAccountsSelectionModal } from 'app/state/importaccounts/selectors'
import { canAccessNavigatorUsb } from 'app/lib/ledger'
import { SelectOpenMethod } from '..'

jest.mock('react-redux', () => ({
useSelector: jest.fn(),
}))
jest.mock('app/lib/ledger')

const mockNavigate = jest.fn()
jest.mock('react-router-dom', () => ({
Expand All @@ -24,10 +26,15 @@ const renderComponent = (webExtensionLedgerAccess?: () => void) =>
)

describe('<SelectOpenMethod />', () => {
beforeEach(() => {
jest.mocked(canAccessNavigatorUsb).mockResolvedValue(false)
})

it('should render component', () => {
const { container } = renderComponent()

expect(container).toMatchSnapshot()
expect(screen.getByText('errors.usbTransportNotSupported')).toBeInTheDocument()
})

it('should render component with an access button', () => {
Expand All @@ -46,4 +53,18 @@ describe('<SelectOpenMethod />', () => {

expect(mockNavigate).toHaveBeenCalledWith('/open-wallet/ledger')
})

it('should render variant with web usb support', async () => {
jest.mocked(canAccessNavigatorUsb).mockResolvedValue(true)

const { rerender } = renderComponent()
rerender(
<MemoryRouter>
<SelectOpenMethod />
</MemoryRouter>,
)

await waitForElementToBeRemoved(() => screen.queryByText('errors.usbTransportNotSupported'))
expect(screen.getByRole('button', { name: 'openWallet.method.ledger' })).not.toBeDisabled()
})
})
54 changes: 41 additions & 13 deletions src/app/pages/OpenWalletPage/index.tsx
Expand Up @@ -3,21 +3,23 @@
* OpenWalletPage
*
*/
import { Anchor, Box, Button } from 'grommet'
import { Anchor, Box, Button, Text } from 'grommet'
import React, { useEffect } from 'react'
import { useSelector } from 'react-redux'
import { useNavigate } from 'react-router-dom'
import { Trans, useTranslation } from 'react-i18next'
import { ButtonLink } from 'app/components/ButtonLink'
import { Header } from 'app/components/Header'
import { selectShowAccountsSelectionModal } from 'app/state/importaccounts/selectors'
import { canAccessNavigatorUsb } from 'app/lib/ledger'

type SelectOpenMethodProps = {
webExtensionLedgerAccess?: () => void
}

export function SelectOpenMethod({ webExtensionLedgerAccess }: SelectOpenMethodProps) {
const { t } = useTranslation()
const [supportsWebUsb, setSupportsWebUsb] = React.useState<boolean | undefined>(false)
const navigate = useNavigate()
const showAccountsSelectionModal = useSelector(selectShowAccountsSelectionModal)

Expand All @@ -27,6 +29,14 @@ export function SelectOpenMethod({ webExtensionLedgerAccess }: SelectOpenMethodP
}
}, [navigate, showAccountsSelectionModal, webExtensionLedgerAccess])

useEffect(() => {
async function getWebUsb() {
setSupportsWebUsb(await canAccessNavigatorUsb())
}

getWebUsb()
}, [])

return (
<Box
round="5px"
Expand All @@ -44,18 +54,36 @@ export function SelectOpenMethod({ webExtensionLedgerAccess }: SelectOpenMethodP
<span>
<ButtonLink to="private-key" label={t('openWallet.method.privateKey', 'Private key')} primary />
</span>
{webExtensionLedgerAccess ? (
<Button
style={{ width: 'fit-content' }}
onClick={webExtensionLedgerAccess}
label={t('ledger.extension.grantAccess', 'Grant access to your Ledger')}
primary
/>
) : (
<span>
<ButtonLink to="ledger" label={t('openWallet.method.ledger', 'Ledger')} primary />
</span>
)}
<div>
<div>
{webExtensionLedgerAccess ? (
<Button
disabled={!supportsWebUsb}
style={{ width: 'fit-content' }}
onClick={webExtensionLedgerAccess}
label={t('ledger.extension.grantAccess', 'Grant access to your Ledger')}
primary
/>
) : (
<span>
<ButtonLink
disabled={!supportsWebUsb}
to="ledger"
label={t('openWallet.method.ledger', 'Ledger')}
primary
/>
</span>
)}
</div>
{!supportsWebUsb && (
<Text size="small" textAlign="center">
{t(
'errors.usbTransportNotSupported',
'Your browser does not support WebUSB (e.g. Firefox). Try using Chrome.',
)}
</Text>
)}
</div>
</Box>

<Box
Expand Down

0 comments on commit e07f288

Please sign in to comment.