Browse Source

Move signTransaction to top level to unsubscribe correctly

master
meriadec 7 years ago
parent
commit
9de76638b1
No known key found for this signature in database GPG Key ID: 1D2FC2305E2CB399
  1. 47
      src/components/modals/Send/index.js
  2. 52
      src/components/modals/Send/steps/03-step-verification.js

47
src/components/modals/Send/index.js

@ -1,12 +1,14 @@
// @flow
import React, { PureComponent } from 'react'
import invariant from 'invariant'
import { compose } from 'redux'
import { connect } from 'react-redux'
import { translate } from 'react-i18next'
import { createStructuredSelector } from 'reselect'
import type { Account, Operation } from '@ledgerhq/live-common/lib/types'
import { createCustomErrorClass } from 'helpers/errors'
import Track from 'analytics/Track'
import { updateAccountWithUpdater } from 'actions/accounts'
import { MODAL_SEND } from 'config/constants'
@ -29,6 +31,8 @@ import StepConnectDevice, { StepConnectDeviceFooter } from './steps/02-step-conn
import StepVerification from './steps/03-step-verification'
import StepConfirmation, { StepConfirmationFooter } from './steps/04-step-confirmation'
const UserRefusedOnDevice = createCustomErrorClass('UserRefusedOnDevice')
type Props = {
t: T,
device: ?Device,
@ -65,6 +69,7 @@ export type StepProps<Transaction> = DefaultStepProps & {
onTransactionError: Error => void,
onOperationBroadcasted: Operation => void,
onRetry: void => void,
signTransaction: ({ transitionTo: string => void }) => void,
}
const createSteps = ({ t }: { t: T }) => [
@ -125,6 +130,14 @@ const INITIAL_STATE = {
class SendModal extends PureComponent<Props, State<*>> {
state = INITIAL_STATE
STEPS = createSteps({ t: this.props.t })
_signTransactionSub = null
_isUnmounted = false
componentWillUnmount() {
if (this._signTransactionSub) {
this._signTransactionSub.unsubscribe()
}
}
handleReset = () => this.setState({ ...INITIAL_STATE })
@ -173,6 +186,37 @@ class SendModal extends PureComponent<Props, State<*>> {
this.setState({ optimisticOperation, error: null })
}
handleSignTransaction = async ({ transitionTo }: { transitionTo: string => void }) => {
const { device } = this.props
const { account, transaction, bridge } = this.state
invariant(device && account && transaction && bridge, 'signTransaction invalid conditions')
this._signTransactionSub = bridge
.signAndBroadcast(account, transaction, device.path)
.subscribe({
next: e => {
switch (e.type) {
case 'signed': {
if (this._isUnmounted) return
transitionTo('confirmation')
break
}
case 'broadcasted': {
this.handleOperationBroadcasted(e.operation)
break
}
default:
}
},
error: err => {
const error = err.statusCode === 0x6985 ? new UserRefusedOnDevice() : err
this.handleTransactionError(error)
transitionTo('confirmation')
},
})
}
render() {
const { t, device } = this.props
const {
@ -199,9 +243,8 @@ class SendModal extends PureComponent<Props, State<*>> {
onChangeAccount: this.handleChangeAccount,
onChangeAppOpened: this.handleChangeAppOpened,
onChangeTransaction: this.handleChangeTransaction,
onTransactionError: this.handleTransactionError,
onRetry: this.handleRetry,
onOperationBroadcasted: this.handleOperationBroadcasted,
signTransaction: this.handleSignTransaction,
}
const isModalLocked = stepId === 'verification'

52
src/components/modals/Send/steps/03-step-verification.js

@ -1,11 +1,9 @@
// @flow
import invariant from 'invariant'
import React, { PureComponent } from 'react'
import styled from 'styled-components'
import { multiline } from 'styles/helpers'
import { createCustomErrorClass } from 'helpers/errors'
import TrackPage from 'analytics/TrackPage'
import Box from 'components/base/Box'
@ -14,8 +12,6 @@ import DeviceConfirm from 'components/DeviceConfirm'
import type { StepProps } from '../index'
export const UserRefusedOnDevice = createCustomErrorClass('UserRefusedOnDevice')
const Container = styled(Box).attrs({ alignItems: 'center', fontSize: 4, pb: 4 })``
const Info = styled(Box).attrs({ ff: 'Open Sans|SemiBold', color: 'dark', mt: 6, mb: 4, px: 5 })`
text-align: center;
@ -26,51 +22,13 @@ export default class StepVerification extends PureComponent<StepProps<*>> {
this.signTransaction()
}
componentWillUnmount() {
this._isUnmounted = true
if (this._signTransactionSub) {
this._signTransactionSub.unsubscribe()
}
}
_isUnmounted = false
_signTransactionSub = null
signTransaction = async () => {
const {
device,
account,
transaction,
bridge,
onTransactionError,
transitionTo,
onOperationBroadcasted,
} = this.props
invariant(device && account && transaction && bridge, 'signTransaction invalid conditions')
this._signTransactionSub = bridge
.signAndBroadcast(account, transaction, device.path)
.subscribe({
next: e => {
switch (e.type) {
case 'signed': {
if (this._isUnmounted) return
transitionTo('confirmation')
break
}
case 'broadcasted': {
onOperationBroadcasted(e.operation)
break
}
default:
}
},
error: err => {
const error = err.statusCode === 0x6985 ? new UserRefusedOnDevice() : err
onTransactionError(error)
transitionTo('confirmation')
},
})
const { transitionTo } = this.props
// TODO: not very good pattern to pass transitionTo... Stepper needs to be
// controlled
this.props.signTransaction({ transitionTo })
}
render() {
const { t } = this.props
return (

Loading…
Cancel
Save