Skip to content

Commit

Permalink
Merge 8724d39 into dbff8d8
Browse files Browse the repository at this point in the history
  • Loading branch information
fernandomg committed Oct 9, 2018
2 parents dbff8d8 + 8724d39 commit 1dc5eda
Show file tree
Hide file tree
Showing 11 changed files with 529 additions and 397 deletions.
2 changes: 1 addition & 1 deletion src/assets/stylesheets/application.css

Large diffs are not rendered by default.

14 changes: 14 additions & 0 deletions src/assets/stylesheets/application/flex-table.scss
Expand Up @@ -76,6 +76,20 @@
&:nth-child(even) {
background-color: #e8e8e8;
}

&.active {
background-color: #6b0392;
color: #e8e8e8;
transition: 0.8s;
}
}
.tx-status {
border: 1px solid #e8e8e8;
padding: 0.15em 0.5em;
-webkit-border-radius: 5px;
-moz-border-radius: 5px;
border-radius: 5px;
margin-left: 5px;
}
}

Expand Down
65 changes: 49 additions & 16 deletions src/components/Common/TxProgressStatus.js
@@ -1,17 +1,14 @@
import React, { Component } from 'react'
import { observer, inject } from 'mobx-react'
import { inject, observer } from 'mobx-react'
import '../../assets/stylesheets/application.css'
import { TX_STEP_DESCRIPTION } from '../stepFour/constants'
import classNames from 'classnames'

@inject('tierStore', 'deploymentStore')
@observer
export class TxProgressStatus extends Component {
constructor(props) {
super(props)

this.state = {
showModal: true
}
state = {
showModal: true
}

txStatuses = () => {
Expand All @@ -25,6 +22,24 @@ export class TxProgressStatus extends Component {
return table
}

isConstructing = ({ active, confirmationPending }) => active && !confirmationPending
isConfirmationPending = ({ confirmationPending, miningPending }) => confirmationPending && !miningPending
isMiningPending = ({ miningPending, mined }) => miningPending && !mined

txActivity = (status, index) => {
let statusMessage = ''

if (this.isConstructing(status)) statusMessage = 'constructing tx...'
if (this.isConfirmationPending(status)) statusMessage = 'please confirm tx...'
if (this.isMiningPending(status)) statusMessage = 'tx pending of being mined...'

return statusMessage === '' ? null : (
<span className="tx-status" key={index.toString()}>
{statusMessage}
</span>
)
}

render() {
const { tierStore } = this.props
const whitelisted = tierStore.tiers.map((tier, index) => (index === 0 ? true : tier.whitelistEnabled === 'yes'))
Expand All @@ -36,8 +51,8 @@ export class TxProgressStatus extends Component {
<div className="table-row flex-table-header">
<div className="text">Tx Name</div>
{whitelisted.map(
(value, index) =>
value || index === 0 ? (
(tierWhitelisted, index) =>
tierWhitelisted || index === 0 ? (
<div className="sm-text" key={index.toString()}>
Tier {index + 1}
</div>
Expand All @@ -48,16 +63,29 @@ export class TxProgressStatus extends Component {
{tableContent.map(
tx =>
tx.status.length ? (
<div className="table-row datagrid" key={tx.name}>
<div className="text">{TX_STEP_DESCRIPTION[tx.name]}</div>
<div
className={classNames('table-row', 'datagrid', {
active: tx.status.some(
status =>
status
? this.isMiningPending(status) ||
this.isConfirmationPending(status) ||
this.isConstructing(status)
: false
)
})}
key={tx.name}
>
<div className="text">
{TX_STEP_DESCRIPTION[tx.name]}{' '}
{tx.status.map((status, index) => (status ? this.txActivity(status, index) : null))}
</div>
{whitelisted.map(
(tierWhitelisted, index) =>
tierWhitelisted ? (
tierWhitelisted || index === 0 ? (
<div className="sm-text" key={index.toString()}>
{tx.status[index] === true ? (
<i className="material-icons">check</i>
) : tx.status[index] === false ? (
<i className="material-icons">access_time</i>
{tx.status[index] ? (
<i className="material-icons">{tx.status[index].mined ? 'check' : 'access_time'}</i>
) : (
''
)}
Expand All @@ -70,6 +98,11 @@ export class TxProgressStatus extends Component {
</div>
</div>
<div className="steps">
{this.props.onRetry ? (
<a onClick={this.props.onRetry} className="no_image button button_fill" style={{ marginRight: '15px' }}>
Retry transaction
</a>
) : null}
{this.props.onSkip ? (
<a onClick={this.props.onSkip} className="no_image button button_fill">
Skip transaction
Expand Down
130 changes: 104 additions & 26 deletions src/components/stepFour/index.js
Expand Up @@ -4,23 +4,31 @@ import {
buildDeploymentSteps,
download,
getDownloadName,
getOptimizationFlagByStore,
getVersionFlagByStore,
handleConstantForFile,
handleContractsForFile,
handlerForFile,
scrollToBottom,
summaryFileContents,
getOptimizationFlagByStore,
getVersionFlagByStore
updateCrowdsaleContractInfo,
updateProxyContractInfo
} from './utils'
import { noContractDataAlert, successfulDeployment, skippingTransaction, deployHasEnded } from '../../utils/alerts'
import {
deployHasEnded,
noContractDataAlert,
skippingTransaction,
successfulDeployment,
transactionLost
} from '../../utils/alerts'
import {
CROWDSALE_STRATEGIES,
CROWDSALE_STRATEGIES_DISPLAYNAMES,
DESCRIPTION,
NAVIGATION_STEPS,
TOAST,
CROWDSALE_STRATEGIES_DISPLAYNAMES,
TEXT_FIELDS,
PUBLISH_DESCRIPTION,
CROWDSALE_STRATEGIES
TEXT_FIELDS,
TOAST
} from '../../utils/constants'
import { DOWNLOAD_TYPE } from './constants'
import { getNetworkID, toast, convertDateToUTCTimezoneToDisplay } from '../../utils/utils'
Expand All @@ -37,7 +45,7 @@ import { PreventRefresh } from '../Common/PreventRefresh'
import cancelDeploy from '../../utils/cancelDeploy'
import PropTypes from 'prop-types'
import logdown from 'logdown'
import { checkNetWorkByID } from '../../utils/blockchainHelpers'
import { checkNetWorkByID, sendTXResponse } from '../../utils/blockchainHelpers'
import { CrowdsaleConfig } from '../Common/config'
import { ButtonContinue } from '../Common/ButtonContinue'
import classNames from 'classnames'
Expand Down Expand Up @@ -89,7 +97,8 @@ export class stepFour extends Component {
contractDownloaded: false,
modal: false,
preventRefresh: true,
transactionFailed: false
transactionFailed: false,
allowRetry: false
}

constructor(props, context) {
Expand Down Expand Up @@ -146,34 +155,101 @@ export class stepFour extends Component {
}
}

deployCrowdsale = () => {
this.resumeContractDeployment()
async deployCrowdsale() {
const { deploymentStore } = this.props
let startAt = deploymentStore.deploymentStep ? deploymentStore.deploymentStep : 0

if (deploymentStore.txLost) {
// temporarily hide modal to display error message
this.hideModal()
await transactionLost()
this.showModal()
this.retryTransaction()
} else {
if (deploymentStore.txRecoverable) {
const receipt = await this.context.web3.eth.getTransactionReceipt(deploymentStore.txRecoverable.txHash)

if (receipt && receipt.blockNumber) {
try {
// analyze receipt
await sendTXResponse(receipt)
const executionOrder = deploymentStore.getStepExecutionOrder(deploymentStore.txRecoverable)

// if is one of the contract deployment steps, call the proper method to update the information
if (deploymentStore.txRecoverable.name === 'deployProxy') updateProxyContractInfo(receipt)
if (deploymentStore.txRecoverable.name === 'crowdsaleCreate') updateCrowdsaleContractInfo(receipt)

deploymentStore.setDeploymentStep(executionOrder)
deploymentStore.setDeploymentStepStatus({ executionOrder, status: 'mined' })

// after the step was finished we continue with the deployment process
setTimeout(() => this.deployCrowdsale(), 100)
} catch (e) {
this.handleError([e, deploymentStore.deploymentStep])
}
} else {
// block wasn't mined yet, wait 5s and retry
setTimeout(() => this.deployCrowdsale(), 5000)
}
} else {
// if it's a tx not lost or not recoverable we assume everything is fine and continue with the deployment process
const nextStep = deploymentStore.activeSteps[startAt]

if (!nextStep) {
this.finalizeCrowdsaleDeployment()
} else {
if (nextStep.active && nextStep.mined) {
startAt++
deploymentStore.setDeploymentStep(startAt)
}
this.resumeContractDeployment(startAt)
}
}
}
}

resumeContractDeployment = () => {
/**
* cleanup tx lost and restarts deployCrowdsale
*/
retryTransaction = () => {
const { deploymentStore } = this.props
const { web3 } = this.context
const startAt = deploymentStore.deploymentStep ? deploymentStore.deploymentStep : 0
const deploymentSteps = buildDeploymentSteps(web3, deploymentStore)

executeSequentially(deploymentSteps, startAt, index => {
deploymentStore.setDeploymentStep(index)
})
.then(() => {
this.hideModal()
deploymentStore.resetTx(deploymentStore.txLost)
this.setState({ allowRetry: false, transactionFailed: false })
setTimeout(() => this.deployCrowdsale(), 100)
}

deploymentStore.setHasEnded(true)
resumeContractDeployment(startAt) {
const { deploymentStore } = this.props
const deploymentSteps = buildDeploymentSteps(deploymentStore)

return successfulDeployment()
})
executeSequentially(
deploymentSteps,
startAt,
executionOrder => {
deploymentStore.setDeploymentStepStatus({ executionOrder, status: 'active' })
},
executionOrder => {
deploymentStore.setDeploymentStep(executionOrder)
deploymentStore.setDeploymentStepStatus({ executionOrder, status: 'mined' })
}
)
.then(this.finalizeCrowdsaleDeployment)
.catch(this.handleError)
}

finalizeCrowdsaleDeployment = () => {
const { deploymentStore } = this.props
this.hideModal()
deploymentStore.setHasEnded(true)
return successfulDeployment()
}

handleError = ([err, failedAt]) => {
const { deploymentStore } = this.props

this.setState({
transactionFailed: true
transactionFailed: true,
allowRetry: err.message && err.message.includes('User denied transaction signature')
})

if (!deploymentStore.deploymentHasFinished) {
Expand All @@ -198,8 +274,9 @@ export class stepFour extends Component {
transactionFailed: false
})

deploymentStore.resetTx(deploymentStore.activeSteps[deploymentStore.deploymentStep])
deploymentStore.setDeploymentStep(deploymentStore.deploymentStep + 1)
this.resumeContractDeployment()
this.deployCrowdsale()
}
})
.then(
Expand Down Expand Up @@ -573,6 +650,7 @@ export class stepFour extends Component {
txMap={deploymentStore.txMap}
deployCrowdsale={this.deployCrowdsale}
onSkip={this.state.transactionFailed ? this.skipTransaction : null}
onRetry={this.state.allowRetry ? this.retryTransaction : null}
/>
)

Expand Down

0 comments on commit 1dc5eda

Please sign in to comment.