mirror of
https://github.com/kremalicious/metamask-extension.git
synced 2024-12-23 09:52:26 +01:00
Refactor onboarding flow
This commit is contained in:
parent
2fa554a641
commit
6277a4c46a
@ -1,14 +1,15 @@
|
||||
import React, { Component } from 'react'
|
||||
import PropTypes from 'prop-types'
|
||||
import { connect } from 'react-redux'
|
||||
import { withRouter } from 'react-router-dom'
|
||||
import classnames from 'classnames'
|
||||
import shuffle from 'lodash.shuffle'
|
||||
import { compose, onlyUpdateForPropTypes } from 'recompose'
|
||||
import { compose } from 'recompose'
|
||||
import Identicon from '../../../../ui/app/components/identicon'
|
||||
import { confirmSeedWords } from '../../../../ui/app/actions'
|
||||
import Breadcrumbs from './breadcrumbs'
|
||||
import LoadingScreen from './loading-screen'
|
||||
import { DEFAULT_ROUTE } from '../../../../ui/app/routes'
|
||||
import { INITIALIZE_ROUTE, DEFAULT_ROUTE } from '../../../../ui/app/routes'
|
||||
|
||||
class ConfirmSeedScreen extends Component {
|
||||
static propTypes = {
|
||||
@ -35,10 +36,18 @@ class ConfirmSeedScreen extends Component {
|
||||
componentWillMount () {
|
||||
const { seedWords, history } = this.props
|
||||
if (!seedWords) {
|
||||
history.push(DEFAULT_ROUTE)
|
||||
history.push(INITIALIZE_ROUTE)
|
||||
}
|
||||
}
|
||||
|
||||
handleClick () {
|
||||
this.props.confirmSeedWords()
|
||||
.then(() => {
|
||||
console.log('FINISHED')
|
||||
this.props.history.push(DEFAULT_ROUTE)
|
||||
})
|
||||
}
|
||||
|
||||
render () {
|
||||
const { seedWords, confirmSeedWords, history } = this.props
|
||||
const { selectedSeeds, shuffledSeeds } = this.state
|
||||
@ -50,66 +59,70 @@ class ConfirmSeedScreen extends Component {
|
||||
this.props.isLoading
|
||||
? <LoadingScreen loadingMessage="Creating your new account" />
|
||||
: (
|
||||
<div className="backup-phrase">
|
||||
<Identicon address={this.props.address} diameter={70} />
|
||||
<div className="backup-phrase__content-wrapper">
|
||||
<div>
|
||||
<div className="backup-phrase__title">
|
||||
Confirm your Secret Backup Phrase
|
||||
</div>
|
||||
<div className="backup-phrase__body-text">
|
||||
Please select each phrase in order to make sure it is correct.
|
||||
</div>
|
||||
<div className="backup-phrase__confirm-secret">
|
||||
{selectedSeeds.map(([_, word], i) => (
|
||||
<button
|
||||
key={i}
|
||||
className="backup-phrase__confirm-seed-option"
|
||||
>
|
||||
{word}
|
||||
</button>
|
||||
))}
|
||||
</div>
|
||||
<div className="backup-phrase__confirm-seed-options">
|
||||
{shuffledSeeds.map((word, i) => {
|
||||
const isSelected = selectedSeeds
|
||||
.filter(([index, seed]) => seed === word && index === i)
|
||||
.length
|
||||
<div className="first-view-main-wrapper">
|
||||
<div className="first-view-main">
|
||||
<div className="backup-phrase">
|
||||
<Identicon address={this.props.address} diameter={70} />
|
||||
<div className="backup-phrase__content-wrapper">
|
||||
<div>
|
||||
<div className="backup-phrase__title">
|
||||
Confirm your Secret Backup Phrase
|
||||
</div>
|
||||
<div className="backup-phrase__body-text">
|
||||
Please select each phrase in order to make sure it is correct.
|
||||
</div>
|
||||
<div className="backup-phrase__confirm-secret">
|
||||
{selectedSeeds.map(([_, word], i) => (
|
||||
<button
|
||||
key={i}
|
||||
className="backup-phrase__confirm-seed-option"
|
||||
>
|
||||
{word}
|
||||
</button>
|
||||
))}
|
||||
</div>
|
||||
<div className="backup-phrase__confirm-seed-options">
|
||||
{shuffledSeeds.map((word, i) => {
|
||||
const isSelected = selectedSeeds
|
||||
.filter(([index, seed]) => seed === word && index === i)
|
||||
.length
|
||||
|
||||
return (
|
||||
<button
|
||||
key={i}
|
||||
className={classnames('backup-phrase__confirm-seed-option', {
|
||||
'backup-phrase__confirm-seed-option--selected': isSelected,
|
||||
})}
|
||||
onClick={() => {
|
||||
if (!isSelected) {
|
||||
this.setState({
|
||||
selectedSeeds: [...selectedSeeds, [i, word]],
|
||||
})
|
||||
} else {
|
||||
this.setState({
|
||||
selectedSeeds: selectedSeeds
|
||||
.filter(([index, seed]) => !(seed === word && index === i)),
|
||||
})
|
||||
}
|
||||
}}
|
||||
>
|
||||
{word}
|
||||
</button>
|
||||
)
|
||||
})}
|
||||
return (
|
||||
<button
|
||||
key={i}
|
||||
className={classnames('backup-phrase__confirm-seed-option', {
|
||||
'backup-phrase__confirm-seed-option--selected': isSelected,
|
||||
})}
|
||||
onClick={() => {
|
||||
if (!isSelected) {
|
||||
this.setState({
|
||||
selectedSeeds: [...selectedSeeds, [i, word]],
|
||||
})
|
||||
} else {
|
||||
this.setState({
|
||||
selectedSeeds: selectedSeeds
|
||||
.filter(([index, seed]) => !(seed === word && index === i)),
|
||||
})
|
||||
}
|
||||
}}
|
||||
>
|
||||
{word}
|
||||
</button>
|
||||
)
|
||||
})}
|
||||
</div>
|
||||
<button
|
||||
className="first-time-flow__button"
|
||||
onClick={() => isValid && this.handleClick()}
|
||||
disabled={!isValid}
|
||||
>
|
||||
Confirm
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<button
|
||||
className="first-time-flow__button"
|
||||
onClick={() => isValid && confirmSeedWords().then(() => history.push(DEFAULT_ROUTE))}
|
||||
disabled={!isValid}
|
||||
>
|
||||
Confirm
|
||||
</button>
|
||||
<Breadcrumbs total={3} currentIndex={1} />
|
||||
</div>
|
||||
</div>
|
||||
<Breadcrumbs total={3} currentIndex={1} />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
@ -119,7 +132,7 @@ class ConfirmSeedScreen extends Component {
|
||||
}
|
||||
|
||||
export default compose(
|
||||
onlyUpdateForPropTypes,
|
||||
withRouter,
|
||||
connect(
|
||||
({ metamask: { selectedAddress, seedWords }, appState: { isLoading } }) => ({
|
||||
seedWords,
|
||||
|
@ -1,7 +1,7 @@
|
||||
import React, { Component } from 'react'
|
||||
import PropTypes from 'prop-types'
|
||||
import {connect} from 'react-redux'
|
||||
import { withRouter } from 'react-router-dom'
|
||||
import { withRouter, Redirect } from 'react-router-dom'
|
||||
import { compose } from 'recompose'
|
||||
import { createNewVaultAndKeychain } from '../../../../ui/app/actions'
|
||||
import LoadingScreen from './loading-screen'
|
||||
@ -11,8 +11,10 @@ import Mascot from '../../../../ui/app/components/mascot'
|
||||
import classnames from 'classnames'
|
||||
import {
|
||||
DEFAULT_ROUTE,
|
||||
INITIALIZE_UNIQUE_IMAGE_ROUTE,
|
||||
INITIALIZE_IMPORT_WITH_SEED_PHRASE_ROUTE,
|
||||
INITIALIZE_IMPORT_ACCOUNT_ROUTE,
|
||||
// INITIALIZE_IMPORT_ACCOUNT_ROUTE,
|
||||
INITIALIZE_NOTICE_ROUTE,
|
||||
} from '../../../../ui/app/routes'
|
||||
|
||||
class CreatePasswordScreen extends Component {
|
||||
@ -28,6 +30,7 @@ class CreatePasswordScreen extends Component {
|
||||
state = {
|
||||
password: '',
|
||||
confirmPassword: '',
|
||||
isLoading: false,
|
||||
}
|
||||
|
||||
constructor () {
|
||||
@ -36,9 +39,11 @@ class CreatePasswordScreen extends Component {
|
||||
}
|
||||
|
||||
componentWillMount () {
|
||||
const { isInitialized, isUnlocked, history } = this.props
|
||||
if (isInitialized || isUnlocked) {
|
||||
history.push(DEFAULT_ROUTE)
|
||||
const { isInitialized, isUnlocked, history, noActiveNotices } = this.props
|
||||
|
||||
if (isInitialized) {
|
||||
console.log('%c IM already initialized', 'background: #222; color: #bada55')
|
||||
history.push(INITIALIZE_NOTICE_ROUTE)
|
||||
}
|
||||
}
|
||||
|
||||
@ -64,95 +69,188 @@ class CreatePasswordScreen extends Component {
|
||||
const { password } = this.state
|
||||
const { createAccount, history } = this.props
|
||||
|
||||
this.setState({ isLoading: true })
|
||||
createAccount(password)
|
||||
.then(() => history.push(DEFAULT_ROUTE))
|
||||
.then(() => {
|
||||
// this.setState({ isLoading: false })
|
||||
history.push(INITIALIZE_UNIQUE_IMAGE_ROUTE)
|
||||
})
|
||||
.catch(() => this.setState({ isLoading: false}))
|
||||
}
|
||||
|
||||
renderFields () {
|
||||
const { isMascara, history } = this.props
|
||||
const { isLoading } = this.state
|
||||
|
||||
return (
|
||||
<div className={classnames({ 'first-view-main-wrapper': !isMascara })}>
|
||||
<div className={classnames({
|
||||
'first-view-main': !isMascara,
|
||||
'first-view-main__mascara': isMascara,
|
||||
})}>
|
||||
{isMascara && <div className="mascara-info first-view-phone-invisible">
|
||||
<Mascot
|
||||
animationEventEmitter={this.animationEventEmitter}
|
||||
width="225"
|
||||
height="225"
|
||||
/>
|
||||
<div className="info">
|
||||
MetaMask is a secure identity vault for Ethereum.
|
||||
</div>
|
||||
<div className="info">
|
||||
It allows you to hold ether & tokens, and interact with decentralized applications.
|
||||
</div>
|
||||
</div>}
|
||||
<div className="create-password">
|
||||
<div className="create-password__title">
|
||||
Create Password
|
||||
</div>
|
||||
<input
|
||||
className="first-time-flow__input"
|
||||
type="password"
|
||||
placeholder="New Password (min 8 characters)"
|
||||
onChange={e => this.setState({password: e.target.value})}
|
||||
/>
|
||||
<input
|
||||
className="first-time-flow__input create-password__confirm-input"
|
||||
type="password"
|
||||
placeholder="Confirm Password"
|
||||
onChange={e => this.setState({confirmPassword: e.target.value})}
|
||||
/>
|
||||
<button
|
||||
className="first-time-flow__button"
|
||||
disabled={!this.isValid()}
|
||||
onClick={this.createAccount}
|
||||
>
|
||||
Create
|
||||
</button>
|
||||
<a
|
||||
href=""
|
||||
className="first-time-flow__link create-password__import-link"
|
||||
onClick={e => {
|
||||
e.preventDefault()
|
||||
history.push(INITIALIZE_IMPORT_WITH_SEED_PHRASE_ROUTE)
|
||||
}}
|
||||
>
|
||||
Import with seed phrase
|
||||
</a>
|
||||
{ /* }
|
||||
<a
|
||||
href=""
|
||||
className="first-time-flow__link create-password__import-link"
|
||||
onClick={e => {
|
||||
e.preventDefault()
|
||||
history.push(INITIALIZE_IMPORT_ACCOUNT_ROUTE)
|
||||
}}
|
||||
>
|
||||
Import an account
|
||||
</a>
|
||||
{ */ }
|
||||
<Breadcrumbs total={3} currentIndex={0} />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
render () {
|
||||
const { isLoading, isMascara, history } = this.props
|
||||
const { isInitialized, isUnlocked, history, noActiveNotices, isMascara } = this.props
|
||||
|
||||
return isLoading
|
||||
? <LoadingScreen loadingMessage="Creating your new account" />
|
||||
: (
|
||||
<div className={classnames({ 'first-view-main-wrapper': !isMascara })}>
|
||||
<div className={classnames({
|
||||
'first-view-main': !isMascara,
|
||||
'first-view-main__mascara': isMascara,
|
||||
})}>
|
||||
{isMascara && <div className="mascara-info first-view-phone-invisible">
|
||||
<Mascot
|
||||
animationEventEmitter={this.animationEventEmitter}
|
||||
width="225"
|
||||
height="225"
|
||||
/>
|
||||
<div className="info">
|
||||
MetaMask is a secure identity vault for Ethereum.
|
||||
</div>
|
||||
<div className="info">
|
||||
It allows you to hold ether & tokens, and interact with decentralized applications.
|
||||
</div>
|
||||
</div>}
|
||||
<div className="create-password">
|
||||
<div className="create-password__title">
|
||||
Create Password
|
||||
</div>
|
||||
<input
|
||||
className="first-time-flow__input"
|
||||
type="password"
|
||||
placeholder="New Password (min 8 characters)"
|
||||
onChange={e => this.setState({password: e.target.value})}
|
||||
/>
|
||||
<input
|
||||
className="first-time-flow__input create-password__confirm-input"
|
||||
type="password"
|
||||
placeholder="Confirm Password"
|
||||
onChange={e => this.setState({confirmPassword: e.target.value})}
|
||||
/>
|
||||
<button
|
||||
className="first-time-flow__button"
|
||||
disabled={!this.isValid()}
|
||||
onClick={this.createAccount}
|
||||
>
|
||||
Create
|
||||
</button>
|
||||
<a
|
||||
href=""
|
||||
className="first-time-flow__link create-password__import-link"
|
||||
onClick={e => {
|
||||
e.preventDefault()
|
||||
history.push(INITIALIZE_IMPORT_WITH_SEED_PHRASE_ROUTE)
|
||||
}}
|
||||
>
|
||||
Import with seed phrase
|
||||
</a>
|
||||
{ /* }
|
||||
<a
|
||||
href=""
|
||||
className="first-time-flow__link create-password__import-link"
|
||||
onClick={e => {
|
||||
e.preventDefault()
|
||||
history.push(INITIALIZE_IMPORT_ACCOUNT_ROUTE)
|
||||
}}
|
||||
>
|
||||
Import an account
|
||||
</a>
|
||||
{ */ }
|
||||
<Breadcrumbs total={3} currentIndex={0} />
|
||||
// if (isInitialized) {
|
||||
// console.log('%c IM already initialized', 'background: #222; color: #bada55')
|
||||
// if (!noActiveNotices) {
|
||||
// console.log('%c GOING TO NOTICES', 'background: #222; color: #bada55')
|
||||
// // history.replace(INITIALIZE_NOTICE_ROUTE)
|
||||
// return <Redirect to={INITIALIZE_NOTICE_ROUTE} />
|
||||
// } else {
|
||||
// console.log('%c GOING TO DEFAULT', 'background: #222; color: #bada55')
|
||||
// // history.replace(DEFAULT_ROUTE)
|
||||
// return <Redirect to={DEFAULT_ROUTE} />
|
||||
// }
|
||||
// }
|
||||
|
||||
return (
|
||||
<div className={classnames({ 'first-view-main-wrapper': !isMascara })}>
|
||||
<div className={classnames({
|
||||
'first-view-main': !isMascara,
|
||||
'first-view-main__mascara': isMascara,
|
||||
})}>
|
||||
{isMascara && <div className="mascara-info first-view-phone-invisible">
|
||||
<Mascot
|
||||
animationEventEmitter={this.animationEventEmitter}
|
||||
width="225"
|
||||
height="225"
|
||||
/>
|
||||
<div className="info">
|
||||
MetaMask is a secure identity vault for Ethereum.
|
||||
</div>
|
||||
<div className="info">
|
||||
It allows you to hold ether & tokens, and interact with decentralized applications.
|
||||
</div>
|
||||
</div>}
|
||||
<div className="create-password">
|
||||
<div className="create-password__title">
|
||||
Create Password
|
||||
</div>
|
||||
<input
|
||||
className="first-time-flow__input"
|
||||
type="password"
|
||||
placeholder="New Password (min 8 characters)"
|
||||
onChange={e => this.setState({password: e.target.value})}
|
||||
/>
|
||||
<input
|
||||
className="first-time-flow__input create-password__confirm-input"
|
||||
type="password"
|
||||
placeholder="Confirm Password"
|
||||
onChange={e => this.setState({confirmPassword: e.target.value})}
|
||||
/>
|
||||
<button
|
||||
className="first-time-flow__button"
|
||||
disabled={!this.isValid()}
|
||||
onClick={this.createAccount}
|
||||
>
|
||||
Create
|
||||
</button>
|
||||
<a
|
||||
href=""
|
||||
className="first-time-flow__link create-password__import-link"
|
||||
onClick={e => {
|
||||
e.preventDefault()
|
||||
history.push(INITIALIZE_IMPORT_WITH_SEED_PHRASE_ROUTE)
|
||||
}}
|
||||
>
|
||||
Import with seed phrase
|
||||
</a>
|
||||
{ /* }
|
||||
<a
|
||||
href=""
|
||||
className="first-time-flow__link create-password__import-link"
|
||||
onClick={e => {
|
||||
e.preventDefault()
|
||||
history.push(INITIALIZE_IMPORT_ACCOUNT_ROUTE)
|
||||
}}
|
||||
>
|
||||
Import an account
|
||||
</a>
|
||||
{ */ }
|
||||
<Breadcrumbs total={3} currentIndex={0} />
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
const mapStateToProps = state => {
|
||||
const { metamask: { isInitialized, isUnlocked, isMascara }, appState: { isLoading } } = state
|
||||
const mapStateToProps = ({ metamask, appState }) => {
|
||||
const { isInitialized, isUnlocked, isMascara, noActiveNotices } = metamask
|
||||
const { isLoading } = appState
|
||||
|
||||
return {
|
||||
isLoading,
|
||||
isInitialized,
|
||||
isUnlocked,
|
||||
isMascara,
|
||||
noActiveNotices,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -8,7 +8,7 @@ import {
|
||||
displayWarning,
|
||||
unMarkPasswordForgotten,
|
||||
} from '../../../../ui/app/actions'
|
||||
import { DEFAULT_ROUTE } from '../../../../ui/app/routes'
|
||||
import { DEFAULT_ROUTE, INITIALIZE_NOTICE_ROUTE } from '../../../../ui/app/routes'
|
||||
|
||||
class ImportSeedPhraseScreen extends Component {
|
||||
static propTypes = {
|
||||
@ -71,7 +71,7 @@ class ImportSeedPhraseScreen extends Component {
|
||||
|
||||
leaveImportSeedScreenState()
|
||||
createNewVaultAndRestore(password, this.parseSeedPhrase(seedPhrase))
|
||||
.then(() => history.push(DEFAULT_ROUTE))
|
||||
.then(() => history.push(INITIALIZE_NOTICE_ROUTE))
|
||||
}
|
||||
|
||||
render () {
|
||||
|
@ -9,6 +9,7 @@ import NoticeScreen from './notice-screen'
|
||||
import BackupPhraseScreen from './seed-screen'
|
||||
import ImportAccountScreen from './import-account-screen'
|
||||
import ImportSeedPhraseScreen from './import-seed-phrase-screen'
|
||||
import ConfirmSeed from './confirm-seed-screen'
|
||||
import {
|
||||
onboardingBuyEthView,
|
||||
unMarkPasswordForgotten,
|
||||
@ -19,8 +20,14 @@ import {
|
||||
WELCOME_ROUTE,
|
||||
INITIALIZE_ROUTE,
|
||||
INITIALIZE_IMPORT_ACCOUNT_ROUTE,
|
||||
INITIALIZE_UNIQUE_IMAGE_ROUTE,
|
||||
INITIALIZE_IMPORT_WITH_SEED_PHRASE_ROUTE,
|
||||
INITIALIZE_NOTICE_ROUTE,
|
||||
INITIALIZE_BACKUP_PHRASE_ROUTE,
|
||||
INITIALIZE_CONFIRM_SEED_ROUTE,
|
||||
INITIALIZE_CREATE_PASSWORD_ROUTE,
|
||||
} from '../../../../ui/app/routes'
|
||||
import WelcomeScreen from '../../../../ui/app/welcome-screen'
|
||||
|
||||
class FirstTimeFlow extends Component {
|
||||
|
||||
@ -60,11 +67,17 @@ class FirstTimeFlow extends Component {
|
||||
}
|
||||
|
||||
componentDidMount () {
|
||||
const { isInitialized, isUnlocked, history } = this.props
|
||||
const { isInitialized, isUnlocked, history, noActiveNotices } = this.props
|
||||
|
||||
// if (isInitialized || isUnlocked) {
|
||||
// history.push(DEFAULT_ROUTE)
|
||||
// }
|
||||
|
||||
// if (!noActiveNotices) {
|
||||
// console.log('INITIALIZE ACTIVE NOTICES')
|
||||
// history.push(INITIALIZE_NOTICE_ROUTE)
|
||||
// }
|
||||
|
||||
if (isInitialized || isUnlocked) {
|
||||
history.push(DEFAULT_ROUTE)
|
||||
}
|
||||
}
|
||||
|
||||
setScreenType (screenType) {
|
||||
@ -161,21 +174,24 @@ class FirstTimeFlow extends Component {
|
||||
}
|
||||
|
||||
render () {
|
||||
return this.props.welcomeScreenSeen
|
||||
? (
|
||||
<div className="first-time-flow">
|
||||
<Switch>
|
||||
<Route exact path={INITIALIZE_IMPORT_ACCOUNT_ROUTE} component={ImportAccountScreen} />
|
||||
<Route
|
||||
exact
|
||||
path={INITIALIZE_IMPORT_WITH_SEED_PHRASE_ROUTE}
|
||||
component={ImportSeedPhraseScreen}
|
||||
/>
|
||||
<Route exact path={INITIALIZE_ROUTE} component={CreatePasswordScreen} />
|
||||
</Switch>
|
||||
</div>
|
||||
)
|
||||
: <Redirect to={WELCOME_ROUTE } />
|
||||
return (
|
||||
<div className="first-time-flow">
|
||||
<Switch>
|
||||
<Route exact path={INITIALIZE_IMPORT_ACCOUNT_ROUTE} component={ImportAccountScreen} />
|
||||
<Route
|
||||
exact
|
||||
path={INITIALIZE_IMPORT_WITH_SEED_PHRASE_ROUTE}
|
||||
component={ImportSeedPhraseScreen}
|
||||
/>
|
||||
<Route exact path={INITIALIZE_UNIQUE_IMAGE_ROUTE} component={UniqueImageScreen} />
|
||||
<Route exact path={INITIALIZE_NOTICE_ROUTE} component={NoticeScreen} />
|
||||
<Route exact path={INITIALIZE_BACKUP_PHRASE_ROUTE} component={BackupPhraseScreen} />
|
||||
<Route exact path={INITIALIZE_CONFIRM_SEED_ROUTE} component={ConfirmSeed} />
|
||||
<Route exact path={INITIALIZE_CREATE_PASSWORD_ROUTE} component={CreatePasswordScreen} />
|
||||
<Route exact path={INITIALIZE_ROUTE} component={WelcomeScreen} />
|
||||
</Switch>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2,11 +2,17 @@ import React, { Component } from 'react'
|
||||
import PropTypes from 'prop-types'
|
||||
import Markdown from 'react-markdown'
|
||||
import { connect } from 'react-redux'
|
||||
import { withRouter } from 'react-router-dom'
|
||||
import { compose } from 'recompose'
|
||||
import debounce from 'lodash.debounce'
|
||||
import { markNoticeRead } from '../../../../ui/app/actions'
|
||||
import Identicon from '../../../../ui/app/components/identicon'
|
||||
import Breadcrumbs from './breadcrumbs'
|
||||
import { DEFAULT_ROUTE } from '../../../../ui/app/routes'
|
||||
import {
|
||||
INITIALIZE_ROUTE,
|
||||
DEFAULT_ROUTE,
|
||||
INITIALIZE_BACKUP_PHRASE_ROUTE,
|
||||
} from '../../../../ui/app/routes'
|
||||
import LoadingScreen from './loading-screen'
|
||||
|
||||
class NoticeScreen extends Component {
|
||||
@ -25,6 +31,7 @@ class NoticeScreen extends Component {
|
||||
markNoticeRead: PropTypes.func,
|
||||
history: PropTypes.object,
|
||||
isLoading: PropTypes.bool,
|
||||
noActiveNotices: PropTypes.bool,
|
||||
};
|
||||
|
||||
static defaultProps = {
|
||||
@ -35,14 +42,27 @@ class NoticeScreen extends Component {
|
||||
atBottom: false,
|
||||
}
|
||||
|
||||
componentDidMount () {
|
||||
componentWillMount () {
|
||||
if (this.props.noActiveNotices) {
|
||||
console.log('%c NOTICESCREEN NOACTIVENOTICES', 'background: #222; color: #bada55')
|
||||
this.props.history.push(INITIALIZE_BACKUP_PHRASE_ROUTE)
|
||||
}
|
||||
|
||||
this.onScroll()
|
||||
}
|
||||
|
||||
acceptTerms = () => {
|
||||
const { markNoticeRead, lastUnreadNotice, history } = this.props
|
||||
markNoticeRead(lastUnreadNotice)
|
||||
.then(() => history.push(DEFAULT_ROUTE))
|
||||
.then(hasActiveNotices => {
|
||||
console.log('ACCEPT TERMS, NO ACTIVE NOTICES', hasActiveNotices, 'background: #222; color: #bada55')
|
||||
if (!hasActiveNotices) {
|
||||
history.push(INITIALIZE_BACKUP_PHRASE_ROUTE)
|
||||
} else {
|
||||
this.setState({ atBottom: false })
|
||||
this.onScroll()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
onScroll = debounce(() => {
|
||||
@ -98,12 +118,24 @@ class NoticeScreen extends Component {
|
||||
}
|
||||
}
|
||||
|
||||
export default connect(
|
||||
({ metamask: { selectedAddress, lastUnreadNotice }, appState: { isLoading } }) => ({
|
||||
lastUnreadNotice,
|
||||
const mapStateToProps = ({ metamask, appState }) => {
|
||||
const { selectedAddress, lastUnreadNotice, noActiveNotices } = metamask
|
||||
const { isLoading } = appState
|
||||
|
||||
return {
|
||||
address: selectedAddress,
|
||||
}),
|
||||
dispatch => ({
|
||||
markNoticeRead: notice => dispatch(markNoticeRead(notice)),
|
||||
})
|
||||
lastUnreadNotice,
|
||||
noActiveNotices,
|
||||
isLoading,
|
||||
}
|
||||
}
|
||||
|
||||
export default compose(
|
||||
withRouter,
|
||||
connect(
|
||||
mapStateToProps,
|
||||
dispatch => ({
|
||||
markNoticeRead: notice => dispatch(markNoticeRead(notice)),
|
||||
})
|
||||
)
|
||||
)(NoticeScreen)
|
||||
|
@ -2,11 +2,12 @@ import React, { Component } from 'react'
|
||||
import PropTypes from 'prop-types'
|
||||
import { connect } from 'react-redux'
|
||||
import classnames from 'classnames'
|
||||
import { compose, onlyUpdateForPropTypes } from 'recompose'
|
||||
import { withRouter } from 'react-router-dom'
|
||||
import { compose } from 'recompose'
|
||||
import Identicon from '../../../../ui/app/components/identicon'
|
||||
import Breadcrumbs from './breadcrumbs'
|
||||
import LoadingScreen from './loading-screen'
|
||||
import { DEFAULT_ROUTE, CONFIRM_SEED_ROUTE } from '../../../../ui/app/routes'
|
||||
import { DEFAULT_ROUTE, INITIALIZE_CONFIRM_SEED_ROUTE } from '../../../../ui/app/routes'
|
||||
|
||||
const LockIcon = props => (
|
||||
<svg
|
||||
@ -105,14 +106,6 @@ class BackupPhraseScreen extends Component {
|
||||
WARNING: Never disclose your backup phrase. Anyone with this phrase can take your Ether forever.
|
||||
</div>
|
||||
{this.renderSecretWordsContainer()}
|
||||
<button
|
||||
className="first-time-flow__button"
|
||||
onClick={() => isShowingSecret && history.push(CONFIRM_SEED_ROUTE)}
|
||||
disabled={!isShowingSecret}
|
||||
>
|
||||
Next
|
||||
</button>
|
||||
<Breadcrumbs total={3} currentIndex={1} />
|
||||
</div>
|
||||
<div className="backup-phrase__tips">
|
||||
<div className="backup-phrase__tips-text">Tips:</div>
|
||||
@ -129,10 +122,7 @@ class BackupPhraseScreen extends Component {
|
||||
<div className="backup-phrase__next-button">
|
||||
<button
|
||||
className="first-time-flow__button"
|
||||
onClick={() => isShowingSecret && this.setState({
|
||||
isShowingSecret: false,
|
||||
page: BackupPhraseScreen.PAGE.CONFIRM,
|
||||
})}
|
||||
onClick={() => isShowingSecret && history.push(INITIALIZE_CONFIRM_SEED_ROUTE)}
|
||||
disabled={!isShowingSecret}
|
||||
>
|
||||
Next
|
||||
@ -160,7 +150,7 @@ class BackupPhraseScreen extends Component {
|
||||
}
|
||||
|
||||
export default compose(
|
||||
onlyUpdateForPropTypes,
|
||||
withRouter,
|
||||
connect(
|
||||
({ metamask: { selectedAddress, seedWords }, appState: { isLoading } }) => ({
|
||||
seedWords,
|
||||
|
@ -1,13 +1,16 @@
|
||||
import React, { Component } from 'react'
|
||||
import PropTypes from 'prop-types'
|
||||
import { withRouter } from 'react-router-dom'
|
||||
import { compose } from 'recompose'
|
||||
import {connect} from 'react-redux'
|
||||
import Identicon from '../../../../ui/app/components/identicon'
|
||||
import Breadcrumbs from './breadcrumbs'
|
||||
import { INITIALIZE_NOTICE_ROUTE } from '../../../../ui/app/routes'
|
||||
|
||||
class UniqueImageScreen extends Component {
|
||||
static propTypes = {
|
||||
address: PropTypes.string,
|
||||
next: PropTypes.func.isRequired,
|
||||
history: PropTypes.object,
|
||||
}
|
||||
|
||||
render () {
|
||||
@ -25,7 +28,7 @@ class UniqueImageScreen extends Component {
|
||||
</div>
|
||||
<button
|
||||
className="first-time-flow__button"
|
||||
onClick={this.props.next}
|
||||
onClick={() => this.props.history.push(INITIALIZE_NOTICE_ROUTE)}
|
||||
>
|
||||
Next
|
||||
</button>
|
||||
@ -37,8 +40,11 @@ class UniqueImageScreen extends Component {
|
||||
}
|
||||
}
|
||||
|
||||
export default connect(
|
||||
({ metamask: { selectedAddress } }) => ({
|
||||
address: selectedAddress,
|
||||
})
|
||||
export default compose(
|
||||
withRouter,
|
||||
connect(
|
||||
({ metamask: { selectedAddress } }) => ({
|
||||
address: selectedAddress,
|
||||
})
|
||||
)
|
||||
)(UniqueImageScreen)
|
||||
|
@ -1322,12 +1322,13 @@ function markNoticeRead (notice) {
|
||||
dispatch(actions.displayWarning(err))
|
||||
return reject(err)
|
||||
}
|
||||
|
||||
if (notice) {
|
||||
dispatch(actions.showNotice(notice))
|
||||
resolve()
|
||||
resolve(true)
|
||||
} else {
|
||||
dispatch(actions.clearNotices())
|
||||
resolve()
|
||||
resolve(false)
|
||||
}
|
||||
})
|
||||
})
|
||||
|
@ -88,34 +88,18 @@ class App extends Component {
|
||||
|
||||
return (
|
||||
h(Switch, [
|
||||
h(Route, {
|
||||
path: WELCOME_ROUTE,
|
||||
exact,
|
||||
component: WelcomeScreen,
|
||||
}),
|
||||
h(Route, {
|
||||
path: INITIALIZE_ROUTE,
|
||||
component: InitializeScreen,
|
||||
}),
|
||||
h(Route, { path: INITIALIZE_ROUTE, component: InitializeScreen }),
|
||||
h(Initialized, {
|
||||
path: REVEAL_SEED_ROUTE,
|
||||
exact,
|
||||
component: RevealSeedPage,
|
||||
mascaraComponent: MascaraSeedScreen,
|
||||
}),
|
||||
h(Initialized, {
|
||||
path: CONFIRM_SEED_ROUTE,
|
||||
exact,
|
||||
mascaraComponent: MascaraConfirmSeedScreen,
|
||||
}),
|
||||
// h(Initialized, { path: CONFIRM_SEED_ROUTE, exact, component: MascaraConfirmSeedScreen }),
|
||||
h(Initialized, { path: UNLOCK_ROUTE, exact, component: UnlockPage }),
|
||||
h(Initialized, { path: SETTINGS_ROUTE, component: Settings }),
|
||||
h(Initialized, { path: RESTORE_VAULT_ROUTE, exact, component: RestoreVaultPage }),
|
||||
h(Initialized, {
|
||||
path: NOTICE_ROUTE,
|
||||
exact,
|
||||
component: MascaraNoticeScreen,
|
||||
}),
|
||||
h(Initialized, { path: NOTICE_ROUTE, exact, component: NoticeScreen }),
|
||||
h(Authenticated, { path: CONFIRM_TRANSACTION_ROUTE, component: ConfirmTxScreen }),
|
||||
h(Authenticated, { path: SEND_ROUTE, exact, component: SendTransactionScreen2 }),
|
||||
h(Authenticated, { path: ADD_TOKEN_ROUTE, exact, component: AddTokenPage }),
|
||||
@ -322,7 +306,7 @@ class App extends Component {
|
||||
|
||||
]),
|
||||
|
||||
isUnlocked && h('div.account-menu__icon', { onClick: this.context.toggleAccountMenu }, [
|
||||
isUnlocked && h('div.account-menu__icon', { onClick: this.props.toggleAccountMenu }, [
|
||||
h(Identicon, {
|
||||
address: this.props.selectedAddress,
|
||||
diameter: 32,
|
||||
|
@ -384,7 +384,7 @@ AddTokenScreen.prototype.render = function () {
|
||||
return h('div.add-token', [
|
||||
h('div.add-token__header', [
|
||||
h('div.add-token__header__cancel', {
|
||||
onClick: () => history.goBack(),
|
||||
onClick: () => history.push(DEFAULT_ROUTE),
|
||||
}, [
|
||||
h('i.fa.fa-angle-left.fa-lg'),
|
||||
h('span', this.context.t('cancel')),
|
||||
@ -417,7 +417,7 @@ AddTokenScreen.prototype.render = function () {
|
||||
|
||||
!isShowingConfirmation && h('div.add-token__buttons', [
|
||||
h('button.btn-secondary--lg.add-token__cancel-button', {
|
||||
onClick: () => history.goBack(),
|
||||
onClick: () => history.push(DEFAULT_ROUTE),
|
||||
}, this.context.t('cancel')),
|
||||
h('button.btn-primary--lg.add-token__confirm-button', {
|
||||
onClick: this.onNext,
|
||||
|
@ -35,11 +35,11 @@ class Home extends Component {
|
||||
unapprovedTypedMessagesCount = 0,
|
||||
} = this.props
|
||||
|
||||
console.log('IN HOME COMPONENDIMOUNT')
|
||||
console.log('HOME MOUNTED')
|
||||
|
||||
// unapprovedTxs and unapproved messages
|
||||
if (Object.keys(unapprovedTxs).length ||
|
||||
unapprovedTypedMessagesCount + unapprovedMsgCount + unapprovedPersonalMsgCount > 0) {
|
||||
console.log('IN HOME SHOULD REDIRECT')
|
||||
this.props.history.push(CONFIRM_TRANSACTION_ROUTE)
|
||||
}
|
||||
}
|
||||
@ -55,6 +55,15 @@ class Home extends Component {
|
||||
seedWords,
|
||||
} = this.props
|
||||
|
||||
// notices
|
||||
if (!noActiveNotices || (lostAccounts && lostAccounts.length > 0)) {
|
||||
return h(Redirect, {
|
||||
to: {
|
||||
pathname: NOTICE_ROUTE,
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
// seed words
|
||||
if (seedWords) {
|
||||
log.debug('rendering seed words')
|
||||
@ -74,15 +83,6 @@ class Home extends Component {
|
||||
})
|
||||
}
|
||||
|
||||
// notices
|
||||
if (!noActiveNotices || (lostAccounts && lostAccounts.length > 0)) {
|
||||
return h(Redirect, {
|
||||
to: {
|
||||
pathname: NOTICE_ROUTE,
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
// if (!props.noActiveNotices) {
|
||||
// log.debug('rendering notice screen for unread notices.')
|
||||
// return h(NoticeScreen, {
|
||||
|
@ -24,7 +24,7 @@ class RestoreVaultPage extends PersistentForm {
|
||||
|
||||
cancel () {
|
||||
this.props.unMarkPasswordForgotten()
|
||||
.then(this.props.history.goBack())
|
||||
.then(this.props.history.push(DEFAULT_ROUTE))
|
||||
}
|
||||
|
||||
createNewVaultAndRestore () {
|
||||
|
@ -133,7 +133,7 @@ class RevealSeedPage extends Component {
|
||||
}, [
|
||||
// cancel
|
||||
h('button.primary', {
|
||||
onClick: () => history.goBack(),
|
||||
onClick: () => history.push(DEFAULT_ROUTE),
|
||||
}, 'CANCEL'),
|
||||
|
||||
// submit
|
||||
|
@ -14,9 +14,13 @@ const SIGNATURE_REQUEST_ROUTE = '/confirm-transaction/signature-request'
|
||||
const NOTICE_ROUTE = '/notice'
|
||||
const WELCOME_ROUTE = '/welcome'
|
||||
const INITIALIZE_ROUTE = '/initialize'
|
||||
const INITIALIZE_CREATE_PASSWORD_ROUTE = '/initialize/create-password'
|
||||
const INITIALIZE_IMPORT_ACCOUNT_ROUTE = '/initialize/import-account'
|
||||
const INITIALIZE_IMPORT_WITH_SEED_PHRASE_ROUTE = '/initialize/import-with-seed-phrase'
|
||||
const INITIALIZE_UNIQUE_IMAGE_ROUTE = '/initialize/unique-image'
|
||||
const INITIALIZE_NOTICE_ROUTE = '/initialize/notice'
|
||||
const INITIALIZE_BACKUP_PHRASE_ROUTE = '/initialize/backup-phrase'
|
||||
const INITIALIZE_CONFIRM_SEED_ROUTE = '/initialize/confirm-phrase'
|
||||
|
||||
module.exports = {
|
||||
DEFAULT_ROUTE,
|
||||
@ -35,7 +39,11 @@ module.exports = {
|
||||
SIGNATURE_REQUEST_ROUTE,
|
||||
WELCOME_ROUTE,
|
||||
INITIALIZE_ROUTE,
|
||||
INITIALIZE_CREATE_PASSWORD_ROUTE,
|
||||
INITIALIZE_IMPORT_ACCOUNT_ROUTE,
|
||||
INITIALIZE_IMPORT_WITH_SEED_PHRASE_ROUTE,
|
||||
INITIALIZE_UNIQUE_IMAGE_ROUTE,
|
||||
INITIALIZE_NOTICE_ROUTE,
|
||||
INITIALIZE_BACKUP_PHRASE_ROUTE,
|
||||
INITIALIZE_CONFIRM_SEED_ROUTE,
|
||||
}
|
||||
|
@ -29,7 +29,7 @@ const {
|
||||
isTokenBalanceSufficient,
|
||||
} = require('./components/send/send-utils')
|
||||
const { isValidAddress } = require('./util')
|
||||
const { CONFIRM_TRANSACTION_ROUTE } = require('./routes')
|
||||
const { CONFIRM_TRANSACTION_ROUTE, DEFAULT_ROUTE } = require('./routes')
|
||||
|
||||
SendTransactionScreen.contextTypes = {
|
||||
t: PropTypes.func,
|
||||
@ -201,7 +201,7 @@ SendTransactionScreen.prototype.renderHeader = function () {
|
||||
h('div.page-container__header-close', {
|
||||
onClick: () => {
|
||||
clearSend()
|
||||
history.goBack()
|
||||
history.push(DEFAULT_ROUTE)
|
||||
},
|
||||
}),
|
||||
|
||||
@ -521,7 +521,7 @@ SendTransactionScreen.prototype.renderFooter = function () {
|
||||
h('button.btn-secondary--lg.page-container__footer-button', {
|
||||
onClick: () => {
|
||||
clearSend()
|
||||
history.goBack()
|
||||
history.push(DEFAULT_ROUTE)
|
||||
},
|
||||
}, this.context.t('cancel')),
|
||||
h('button.btn-primary--lg.page-container__footer-button', {
|
||||
|
@ -3,9 +3,11 @@ import h from 'react-hyperscript'
|
||||
import { Component } from 'react'
|
||||
import PropTypes from 'prop-types'
|
||||
import {connect} from 'react-redux'
|
||||
import { withRouter } from 'react-router-dom'
|
||||
import { compose } from 'recompose'
|
||||
import {closeWelcomeScreen} from './actions'
|
||||
import Mascot from './components/mascot'
|
||||
import { INITIALIZE_ROUTE } from './routes'
|
||||
import { INITIALIZE_CREATE_PASSWORD_ROUTE } from './routes'
|
||||
|
||||
class WelcomeScreen extends Component {
|
||||
static propTypes = {
|
||||
@ -18,9 +20,18 @@ class WelcomeScreen extends Component {
|
||||
this.animationEventEmitter = new EventEmitter()
|
||||
}
|
||||
|
||||
componentWillMount () {
|
||||
const { history, welcomeScreenSeen } = this.props
|
||||
|
||||
if (welcomeScreenSeen) {
|
||||
console.log('SEENT', welcomeScreenSeen)
|
||||
history.push(INITIALIZE_CREATE_PASSWORD_ROUTE)
|
||||
}
|
||||
}
|
||||
|
||||
initiateAccountCreation = () => {
|
||||
this.props.closeWelcomeScreen()
|
||||
this.props.history.push(INITIALIZE_ROUTE)
|
||||
this.props.history.push(INITIALIZE_CREATE_PASSWORD_ROUTE)
|
||||
}
|
||||
|
||||
render () {
|
||||
@ -51,9 +62,18 @@ class WelcomeScreen extends Component {
|
||||
}
|
||||
}
|
||||
|
||||
export default connect(
|
||||
null,
|
||||
dispatch => ({
|
||||
closeWelcomeScreen: () => dispatch(closeWelcomeScreen()),
|
||||
})
|
||||
const mapStateToProps = ({ metamask: { welcomeScreenSeen } }) => {
|
||||
return {
|
||||
welcomeScreenSeen,
|
||||
}
|
||||
}
|
||||
|
||||
export default compose(
|
||||
withRouter,
|
||||
connect(
|
||||
mapStateToProps,
|
||||
dispatch => ({
|
||||
closeWelcomeScreen: () => dispatch(closeWelcomeScreen()),
|
||||
})
|
||||
)
|
||||
)(WelcomeScreen)
|
||||
|
Loading…
Reference in New Issue
Block a user