Browse Source

Move import step state to import modal state

master
meriadec 7 years ago
parent
commit
2542498dc0
No known key found for this signature in database GPG Key ID: 1D2FC2305E2CB399
  1. 4
      src/bridge/index.js
  2. 6
      src/components/base/Input/index.js
  3. 1
      src/components/base/Modal/index.js
  4. 3
      src/components/modals/ImportAccounts/AccountRow.js
  5. 55
      src/components/modals/ImportAccounts/index.js
  6. 112
      src/components/modals/ImportAccounts/steps/03-step-import.js

4
src/bridge/index.js

@ -1,8 +1,5 @@
// @flow
import type { Currency } from '@ledgerhq/live-common/lib/types'
import makeMockBridge from 'bridge/makeMockBridge'
import { WalletBridge } from './types'
import LibcoreBridge from './LibcoreBridge'
import EthereumJSBridge from './EthereumJSBridge'
@ -15,6 +12,5 @@ export const getBridgeForCurrency = (currency: Currency): WalletBridge<any> => {
if (currency.id === 'ripple') {
return RippleJSBridge // polyfill js
}
return makeMockBridge({})
return LibcoreBridge // libcore for the rest
}

6
src/components/base/Input/index.js

@ -69,6 +69,7 @@ type Props = {
onBlur: Function,
onChange?: Function,
onEnter?: Function,
onEsc?: Function,
onFocus: Function,
renderLeft?: any,
renderRight?: any,
@ -108,6 +109,11 @@ class Input extends PureComponent<Props, State> {
if (onEnter) {
onEnter(e)
}
} else if (e.which === 27) {
const { onEsc } = this.props
if (onEsc) {
onEsc(e)
}
}
}

1
src/components/base/Modal/index.js

@ -164,6 +164,7 @@ export class Modal extends Component<Props> {
isOpened={isOpened}
onClose={onClose}
onHide={onHide}
closeOnEsc={!preventBackdropClick}
motionStyle={(spring, isVisible) => ({
opacity: spring(isVisible ? 1 : 0, springConfig),
scale: spring(isVisible ? 1 : 0.95, springConfig),

3
src/components/modals/ImportAccounts/AccountRow.js

@ -64,6 +64,8 @@ export default class AccountRow extends PureComponent<Props, State> {
handleChangeName = accountNameCopy => this.setState({ accountNameCopy })
handleReset = () => this.setState({ isEditing: false, accountNameCopy: '' })
_input = null
render() {
@ -81,6 +83,7 @@ export default class AccountRow extends PureComponent<Props, State> {
onChange={this.handleChangeName}
onClick={this.handlePreventSubmit}
onEnter={this.handleSubmitName}
onEsc={this.handleReset}
renderRight={
<InputRight onClick={this.handleSubmitName}>
<IconCheck size={16} />

55
src/components/modals/ImportAccounts/index.js

@ -5,11 +5,12 @@ import { compose } from 'redux'
import { connect } from 'react-redux'
import { translate } from 'react-i18next'
import type { Currency } from '@ledgerhq/live-common/lib/types'
import type { Currency, Account } from '@ledgerhq/live-common/lib/types'
import type { T, Device } from 'types/common'
import { getCurrentDevice } from 'reducers/devices'
import { getAccounts } from 'reducers/accounts'
import Modal, { ModalContent, ModalTitle, ModalFooter, ModalBody } from 'components/base/Modal'
import Box from 'components/base/Box'
@ -20,8 +21,6 @@ import StepConnectDevice, { StepConnectDeviceFooter } from './steps/02-step-conn
import StepImport, { StepImportFooter } from './steps/03-step-import'
import StepFinish from './steps/04-step-finish'
const { getCryptoCurrencyById } = require('@ledgerhq/live-common/lib/helpers/currencies')
const createSteps = ({ t }: { t: T }) => [
{
id: 'chooseCurrency',
@ -60,10 +59,25 @@ const createSteps = ({ t }: { t: T }) => [
type Props = {
t: T,
currentDevice: ?Device,
existingAccounts: Account[],
}
type StepId = 'chooseCurrency' | 'connectDevice' | 'import' | 'finish'
type ScanStatus = 'idle' | 'scanning' | 'error' | 'finished'
type State = {
stepId: StepId,
isAppOpened: boolean,
currency: ?Currency,
// scan process
scannedAccounts: Account[],
checkedAccountsIds: string[],
scanStatus: ScanStatus,
err: ?Error,
}
export type StepProps = {
t: T,
currency: ?Currency,
@ -71,22 +85,26 @@ export type StepProps = {
isAppOpened: boolean,
transitionTo: StepId => void,
setState: any => void,
}
type State = {
stepId: StepId,
isAppOpened: boolean,
currency: ?Currency,
// scan process
scannedAccounts: Account[],
existingAccounts: Account[],
checkedAccountsIds: string[],
scanStatus: ScanStatus,
err: ?Error,
}
const mapStateToProps = state => ({
currentDevice: getCurrentDevice(state),
existingAccounts: getAccounts(state),
})
const INITIAL_STATE = {
stepId: 'import',
stepId: 'chooseCurrency',
isAppOpened: false,
currency: getCryptoCurrencyById('bitcoin'),
currency: null,
scannedAccounts: [],
checkedAccountsIds: [],
}
class ImportAccounts extends PureComponent<Props, State> {
@ -104,8 +122,16 @@ class ImportAccounts extends PureComponent<Props, State> {
}
render() {
const { t, currentDevice } = this.props
const { stepId, currency, isAppOpened } = this.state
const { t, currentDevice, existingAccounts } = this.props
const {
stepId,
currency,
isAppOpened,
scannedAccounts,
checkedAccountsIds,
scanStatus,
err,
} = this.state
const stepIndex = this.STEPS.findIndex(s => s.id === stepId)
const step = this.STEPS[stepIndex]
@ -120,6 +146,11 @@ class ImportAccounts extends PureComponent<Props, State> {
t,
currency,
currentDevice,
existingAccounts,
scannedAccounts,
checkedAccountsIds,
scanStatus,
err,
isAppOpened,
transitionTo: this.transitionTo,
setState: (...args) => this.setState(...args),

112
src/components/modals/ImportAccounts/steps/03-step-import.js

@ -1,9 +1,6 @@
// @flow
import React, { PureComponent } from 'react'
import keyBy from 'lodash/keyBy'
import type { Account } from '@ledgerhq/live-common/lib/types'
import { getBridgeForCurrency } from 'bridge'
@ -16,25 +13,7 @@ import AccountRow from '../AccountRow'
import type { StepProps } from '../index'
type Status = 'scanning' | 'error' | 'finished'
type State = {
status: Status,
err: ?Error,
scannedAccounts: Account[],
checkedAccountsIds: string[],
}
const INITIAL_STATE = {
status: 'scanning',
err: null,
scannedAccounts: [],
checkedAccountsIds: [],
}
class StepImport extends PureComponent<StepProps, State> {
state = INITIAL_STATE
class StepImport extends PureComponent<StepProps> {
componentDidMount() {
console.log(`starting import...`)
this.startScanAccountsDevice()
@ -48,30 +27,37 @@ class StepImport extends PureComponent<StepProps, State> {
}
startScanAccountsDevice() {
const { currency } = this.props
if (!currency) {
throw new Error('No currency to scan')
const { currency, currentDevice, setState } = this.props
try {
if (!currency) {
throw new Error('No currency to scan')
}
if (!currentDevice) {
throw new Error('No device')
}
const bridge = getBridgeForCurrency(currency)
// TODO: use the real device
const devicePath = currentDevice.path
setState({ scanStatus: 'scanning' })
this.scanSubscription = bridge.scanAccountsOnDevice(currency, devicePath, {
next: account => {
const { scannedAccounts } = this.props
const hasAlreadyBeenScanned = !!scannedAccounts.find(a => account.id === a.id)
if (!hasAlreadyBeenScanned) {
setState({ scannedAccounts: [...scannedAccounts, account] })
}
},
complete: () => setState({ scanStatus: 'finished' }),
error: err => setState({ scanStatus: 'error', err }),
})
} catch (err) {
setState({ scanStatus: 'error', err })
}
const bridge = getBridgeForCurrency(currency)
// TODO: use the real device
const devicePath = ''
this.scanSubscription = bridge.scanAccountsOnDevice(currency, devicePath, {
next: account => {
const { scannedAccounts } = this.state
const hasAlreadyBeenScanned = !!scannedAccounts.find(a => account.id === a.id)
if (!hasAlreadyBeenScanned) {
this.setState({ scannedAccounts: [...scannedAccounts, account] })
}
},
complete: () => {
this.setState({ status: 'finished' })
},
error: err => this.setState({ status: 'error', err }),
})
}
handleRetry = () => {
@ -79,23 +65,33 @@ class StepImport extends PureComponent<StepProps, State> {
this.scanSubscription.unsubscribe()
this.scanSubscription = null
}
this.setState(INITIAL_STATE)
this.handleResetState()
this.startScanAccountsDevice()
}
handleResetState = () => {
const { setState } = this.props
setState({
scanStatus: 'idle',
err: null,
scannedAccounts: [],
checkedAccountsIds: [],
})
}
handleToggleAccount = account => {
const { checkedAccountsIds } = this.state
const { checkedAccountsIds, setState } = this.props
const isChecked = checkedAccountsIds.find(id => id === account.id) !== undefined
if (isChecked) {
this.setState({ checkedAccountsIds: checkedAccountsIds.filter(id => id !== account.id) })
setState({ checkedAccountsIds: checkedAccountsIds.filter(id => id !== account.id) })
} else {
this.setState({ checkedAccountsIds: [...checkedAccountsIds, account.id] })
setState({ checkedAccountsIds: [...checkedAccountsIds, account.id] })
}
}
handleAccountUpdate = updatedAccount => {
const { scannedAccounts } = this.state
this.setState({
const { scannedAccounts, setState } = this.props
setState({
scannedAccounts: scannedAccounts.map(account => {
if (account.id !== updatedAccount.id) {
return account
@ -106,11 +102,11 @@ class StepImport extends PureComponent<StepProps, State> {
}
render() {
const { status, err, scannedAccounts, checkedAccountsIds } = this.state
const { scanStatus, err, scannedAccounts, checkedAccountsIds } = this.props
return (
<Box>
{err && <Box shrink>{err.toString()}</Box>}
{err && <Box shrink>{err.message}</Box>}
<Box flow={2}>
{scannedAccounts.map(account => {
@ -125,7 +121,7 @@ class StepImport extends PureComponent<StepProps, State> {
/>
)
})}
{status === 'scanning' && (
{scanStatus === 'scanning' && (
<Box
horizontal
bg="lightGrey"
@ -141,7 +137,7 @@ class StepImport extends PureComponent<StepProps, State> {
</Box>
<Box horizontal mt={2}>
{['error', 'finished'].includes(status) && (
{['error', 'finished'].includes(scanStatus) && (
<Button small outline onClick={this.handleRetry}>
<Box horizontal flow={2} align="center">
<IconExchange size={13} />
@ -157,8 +153,4 @@ class StepImport extends PureComponent<StepProps, State> {
export default StepImport
export const StepImportFooter = (props: StepProps) => {
return (
<div>noetuhnoethunot</div>
)
}
export const StepImportFooter = (props: StepProps) => <div>noetuhnoethunot</div>

Loading…
Cancel
Save