-
Notifications
You must be signed in to change notification settings - Fork 43
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #1841 from lubej/ionic-bluetooth-ui
Ionic Bluetooth UI
- Loading branch information
Showing
25 changed files
with
518 additions
and
254 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
Ionic Bluetooth UI |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
20 changes: 20 additions & 0 deletions
20
src/app/pages/OpenWalletPage/Features/FromBleLedger/__tests__/index.test.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
import { render, screen } from '@testing-library/react' | ||
import { FromBleLedger } from '..' | ||
|
||
jest.mock('react-redux', () => ({ | ||
useSelector: jest.fn(), | ||
useDispatch: jest.fn(), | ||
})) | ||
|
||
describe('<FromBleLedger />', () => { | ||
it('should render component', () => { | ||
render(<FromBleLedger />) | ||
|
||
expect(screen.queryByText('ledger.instructionSteps.connectBluetoothLedger')).toBeInTheDocument() | ||
expect(screen.queryByText('ledger.instructionSteps.deviceIsPaired')).toBeInTheDocument() | ||
expect(screen.queryByText('ledger.instructionSteps.closeLedgerLive')).toBeInTheDocument() | ||
expect(screen.queryByText('ledger.instructionSteps.openOasisApp')).toBeInTheDocument() | ||
|
||
expect(screen.getByRole('button', { name: 'openWallet.importAccounts.selectDevice' })).toBeInTheDocument() | ||
}) | ||
}) |
78 changes: 78 additions & 0 deletions
78
src/app/pages/OpenWalletPage/Features/FromBleLedger/index.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
import { importAccountsActions } from 'app/state/importaccounts' | ||
import { Box } from 'grommet/es6/components/Box' | ||
import { Button } from 'grommet/es6/components/Button' | ||
import { Heading } from 'grommet/es6/components/Heading' | ||
import { useTranslation } from 'react-i18next' | ||
import { useDispatch, useSelector } from 'react-redux' | ||
import { | ||
selectShowAccountsSelectionModal, | ||
selectShowBleLedgerDevicesModal, | ||
} from 'app/state/importaccounts/selectors' | ||
import { Header } from 'app/components/Header' | ||
import { ListBleLedgerDevicesModal } from '../ListBleLedgerDevicesModal' | ||
import { ImportAccountsSelectionModal } from '../ImportAccountsSelectionModal' | ||
import { WalletType } from '../../../../state/wallet/types' | ||
|
||
export function FromBleLedger() { | ||
const { t } = useTranslation() | ||
const dispatch = useDispatch() | ||
const showAccountsSelectionModal = useSelector(selectShowAccountsSelectionModal) | ||
const showBleLedgerDevicesModal = useSelector(selectShowBleLedgerDevicesModal) | ||
|
||
return ( | ||
<Box | ||
background="background-front" | ||
margin="small" | ||
pad="medium" | ||
round="5px" | ||
border={{ color: 'background-front-border', size: '1px' }} | ||
> | ||
<Header>{t('openWallet.ledger.header', 'Open from Ledger device')}</Header> | ||
|
||
<Heading level="3" margin="0"> | ||
{t('ledger.instructionSteps.header', 'Steps:')} | ||
</Heading> | ||
<ol> | ||
<li> | ||
{t( | ||
'ledger.instructionSteps.connectBluetoothLedger', | ||
'Connect your Ledger to this device via Bluetooth', | ||
)} | ||
</li> | ||
<li> | ||
{t('ledger.instructionSteps.deviceIsPaired', 'Make sure your Ledger is paired with this device')} | ||
</li> | ||
<li>{t('ledger.instructionSteps.closeLedgerLive', 'Close Ledger Live app on the device')}</li> | ||
<li>{t('ledger.instructionSteps.openOasisApp', 'Open the Oasis app on your Ledger')}</li> | ||
</ol> | ||
<Box direction="row" margin={{ top: 'medium' }}> | ||
<Button | ||
type="submit" | ||
label={t('openWallet.importAccounts.selectDevice', 'Select device')} | ||
onClick={() => { | ||
dispatch(importAccountsActions.enumerateDevicesFromBleLedger()) | ||
}} | ||
primary | ||
/> | ||
</Box> | ||
{showBleLedgerDevicesModal && ( | ||
<ListBleLedgerDevicesModal | ||
abort={() => { | ||
dispatch(importAccountsActions.clear()) | ||
}} | ||
next={() => { | ||
dispatch(importAccountsActions.enumerateAccountsFromLedger(WalletType.BleLedger)) | ||
}} | ||
/> | ||
)} | ||
{showAccountsSelectionModal && ( | ||
<ImportAccountsSelectionModal | ||
abort={() => { | ||
dispatch(importAccountsActions.clear()) | ||
}} | ||
type={WalletType.BleLedger} | ||
/> | ||
)} | ||
</Box> | ||
) | ||
} |
37 changes: 32 additions & 5 deletions
37
src/app/pages/OpenWalletPage/Features/FromLedger/__tests__/index.test.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,16 +1,43 @@ | ||
import * as React from 'react' | ||
import { render } from '@testing-library/react' | ||
import { render, screen, waitFor } from '@testing-library/react' | ||
import { FromLedger } from '..' | ||
import { MemoryRouter } from 'react-router-dom' | ||
|
||
jest.mock('react-redux', () => ({ | ||
useSelector: jest.fn(), | ||
useDispatch: jest.fn(), | ||
})) | ||
|
||
jest.mock('../../../../../lib/ledger', () => ({ | ||
...jest.requireActual('../../../../../lib/ledger'), | ||
// Throws BLE not supported | ||
canAccessBle: jest.fn().mockResolvedValue(false), | ||
})) | ||
|
||
const renderComponent = () => | ||
render( | ||
<MemoryRouter> | ||
<FromLedger /> | ||
</MemoryRouter>, | ||
) | ||
|
||
describe('<FromLedger />', () => { | ||
it('should render component', () => { | ||
const { container } = render(<FromLedger />) | ||
it('should render component in disabled state', async () => { | ||
renderComponent() | ||
|
||
await waitFor(() => { | ||
expect(screen.queryByText('openWallet.importAccounts.usbLedger')).toBeInTheDocument() | ||
expect(screen.queryByText('openWallet.importAccounts.bluetoothLedger')).toBeInTheDocument() | ||
|
||
expect(screen.getByText('errors.usbTransportNotSupported')).toBeInTheDocument() | ||
expect(screen.getByText('errors.bluetoothTransportNotSupported')).toBeInTheDocument() | ||
|
||
const usbLedgerBtn = screen.getByRole('button', { name: 'openWallet.importAccounts.usbLedger' }) | ||
const bluetoothLedgerBtn = screen.getByRole('button', { | ||
name: 'openWallet.importAccounts.bluetoothLedger', | ||
}) | ||
|
||
expect(container).toMatchSnapshot() | ||
expect(usbLedgerBtn).toHaveProperty('disabled', true) | ||
expect(bluetoothLedgerBtn).toHaveProperty('disabled', true) | ||
}) | ||
}) | ||
}) |
122 changes: 82 additions & 40 deletions
122
src/app/pages/OpenWalletPage/Features/FromLedger/index.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,56 +1,98 @@ | ||
import { importAccountsActions } from 'app/state/importaccounts' | ||
import { Box } from 'grommet/es6/components/Box' | ||
import React, { useEffect } from 'react' | ||
import { Header } from 'app/components/Header' | ||
import { ButtonLink } from '../../../../components/ButtonLink' | ||
import { Button } from 'grommet/es6/components/Button' | ||
import { Heading } from 'grommet/es6/components/Heading' | ||
import React from 'react' | ||
import { Text } from 'grommet/es6/components/Text' | ||
import { canAccessBle, canAccessNavigatorUsb } from '../../../../lib/ledger' | ||
import { useTranslation } from 'react-i18next' | ||
import { useDispatch, useSelector } from 'react-redux' | ||
import { ImportAccountsSelectionModal } from 'app/pages/OpenWalletPage/Features/ImportAccountsSelectionModal' | ||
import { selectShowAccountsSelectionModal } from 'app/state/importaccounts/selectors' | ||
import { Header } from 'app/components/Header' | ||
import { WalletType } from 'app/state/wallet/types' | ||
import { Capacitor } from '@capacitor/core' | ||
|
||
type SelectOpenMethodProps = { | ||
webExtensionUSBLedgerAccess?: () => void | ||
} | ||
|
||
export function FromLedger() { | ||
export function FromLedger({ webExtensionUSBLedgerAccess }: SelectOpenMethodProps) { | ||
const { t } = useTranslation() | ||
const dispatch = useDispatch() | ||
const showAccountsSelectionModal = useSelector(selectShowAccountsSelectionModal) | ||
const [supportsUsbLedger, setSupportsUsbLedger] = React.useState<boolean | undefined>(true) | ||
const [supportsBleLedger, setSupportsBleLedger] = React.useState<boolean | undefined>(true) | ||
|
||
useEffect(() => { | ||
async function getLedgerSupport() { | ||
const usbLedgerSupported = await canAccessNavigatorUsb() | ||
|
||
const isNativePlatform = Capacitor.isNativePlatform() | ||
const bleLedgerSupported = isNativePlatform && (await canAccessBle()) | ||
|
||
setSupportsUsbLedger(usbLedgerSupported) | ||
setSupportsBleLedger(bleLedgerSupported) | ||
} | ||
|
||
getLedgerSupport() | ||
}, []) | ||
|
||
return ( | ||
<Box | ||
round="5px" | ||
border={{ color: 'background-front-border', size: '1px' }} | ||
background="background-front" | ||
margin="small" | ||
pad="medium" | ||
round="5px" | ||
border={{ color: 'background-front-border', size: '1px' }} | ||
> | ||
<Header>{t('openWallet.ledger.header', 'Open from Ledger device')}</Header> | ||
|
||
<Heading level="3" margin="0"> | ||
{t('ledger.instructionSteps.header', 'Steps:')} | ||
</Heading> | ||
<ol> | ||
<li>{t('ledger.instructionSteps.connectLedger', 'Connect your Ledger device to the computer')}</li> | ||
<li>{t('ledger.instructionSteps.closeLedgerLive', 'Close Ledger Live app on the computer')}</li> | ||
<li>{t('ledger.instructionSteps.openOasisApp', 'Open the Oasis App on your Ledger device')}</li> | ||
</ol> | ||
<Box direction="row" margin={{ top: 'medium' }}> | ||
<Button | ||
type="submit" | ||
label={t('openWallet.importAccounts.selectWallets', 'Select accounts to open')} | ||
onClick={() => { | ||
dispatch(importAccountsActions.enumerateAccountsFromLedger(WalletType.UsbLedger)) | ||
}} | ||
primary | ||
/> | ||
<Header> | ||
{t('openWallet.importAccounts.connectDeviceHeader', 'How do you want to connect your Ledger device?')} | ||
</Header> | ||
|
||
<Box direction="row-responsive" justify="start" margin={{ top: 'medium' }} gap="medium"> | ||
<div> | ||
<div> | ||
{webExtensionUSBLedgerAccess ? ( | ||
<Button | ||
disabled={!supportsUsbLedger} | ||
style={{ width: 'fit-content' }} | ||
onClick={webExtensionUSBLedgerAccess} | ||
label={t('ledger.extension.grantAccess', 'Grant access to your USB Ledger')} | ||
primary | ||
/> | ||
) : ( | ||
<span> | ||
<ButtonLink | ||
disabled={!supportsUsbLedger} | ||
to="usb" | ||
label={t('openWallet.importAccounts.usbLedger', 'USB Ledger')} | ||
primary | ||
/> | ||
</span> | ||
)} | ||
</div> | ||
{!supportsUsbLedger && ( | ||
<Text size="small" textAlign="center"> | ||
{t( | ||
'errors.usbTransportNotSupported', | ||
'Current platform does not support WebUSB capability. Try on different platform or browser(preferably Chrome).', | ||
)} | ||
</Text> | ||
)} | ||
</div> | ||
<div> | ||
<div> | ||
<ButtonLink | ||
disabled={!supportsBleLedger} | ||
to="ble" | ||
label={t('openWallet.importAccounts.bluetoothLedger', 'Bluetooth Ledger')} | ||
primary | ||
/> | ||
</div> | ||
{!supportsBleLedger && ( | ||
<Text size="small" textAlign="center"> | ||
{t( | ||
'errors.bluetoothTransportNotSupported', | ||
'Bluetooth may be turned off or your current platform does not support Bluetooth capability.', | ||
)} | ||
</Text> | ||
)} | ||
</div> | ||
</Box> | ||
{showAccountsSelectionModal && ( | ||
<ImportAccountsSelectionModal | ||
abort={() => { | ||
dispatch(importAccountsActions.clear()) | ||
}} | ||
type={WalletType.UsbLedger} | ||
/> | ||
)} | ||
</Box> | ||
) | ||
} |
Oops, something went wrong.