Add Go to Coinbase; Show Buy Ether after signup

feature/default_network_editable
Jacky Chan 7 years ago committed by Chi Kei Chan
parent 4ecd28ca9b
commit 85e485128f
  1. 23
      mascara/src/app/first-time/backup-phrase-screen.js
  2. 99
      mascara/src/app/first-time/buy-ether-screen.js
  3. 7
      mascara/src/app/first-time/import-account-screen.js
  4. 1
      mascara/src/app/first-time/index.css
  5. 31
      mascara/src/app/first-time/index.js
  6. 5
      mascara/src/app/first-time/notice-screen.js
  7. 5
      mascara/src/app/first-time/unique-image-screen.js
  8. 2
      ui/app/actions.js
  9. 17
      ui/app/app.js
  10. 9
      ui/app/keychains/hd/create-vault-complete.js

@ -4,6 +4,7 @@ import classnames from 'classnames'
import Identicon from '../../../../ui/app/components/identicon'
import {confirmSeedWords} from '../../../../ui/app/actions'
import Breadcrumbs from './breadcrumbs'
import LoadingScreen from './loading-screen'
const LockIcon = props => (
<svg
@ -36,9 +37,10 @@ const LockIcon = props => (
class BackupPhraseScreen extends Component {
static propTypes = {
isLoading: PropTypes.bool.isRequired,
address: PropTypes.string.isRequired,
seedWords: PropTypes.string.isRequired,
next: PropTypes.func.isRequired
next: PropTypes.func.isRequired,
};
static defaultProps = {
@ -211,19 +213,22 @@ class BackupPhraseScreen extends Component {
}
render() {
return (
<div className="backup-phrase">
{this.renderBack()}
<Identicon address={this.props.address} diameter={70} />
{this.renderContent()}
</div>
)
return this.props.isLoading
? <LoadingScreen loadingMessage="Creating your new account" />
: (
<div className="backup-phrase">
{this.renderBack()}
<Identicon address={this.props.address} diameter={70} />
{this.renderContent()}
</div>
)
}
}
export default connect(
({ metamask: { selectedAddress, seedWords } }) => ({
({ metamask: { selectedAddress, seedWords }, appState: { isLoading } }) => ({
seedWords,
isLoading,
address: selectedAddress
}),
dispatch => ({

@ -2,7 +2,9 @@ import React, {Component, PropTypes} from 'react'
import classnames from 'classnames'
import {connect} from 'react-redux'
import {qrcode} from 'qrcode-npm'
import copyToClipboard from 'copy-to-clipboard'
import Identicon from '../../../../ui/app/components/identicon'
import {buyEth, showAccountDetail} from '../../../../ui/app/actions'
class BuyEtherScreen extends Component {
static OPTION_VALUES = {
@ -28,10 +30,34 @@ class BuyEtherScreen extends Component {
static propTypes = {
address: PropTypes.string,
goToCoinbase: PropTypes.func.isRequired,
showAccountDetail: PropTypes.func.isRequired,
}
state = {
selectedOption: BuyEtherScreen.OPTION_VALUES.COINBASE,
justCopied: false
}
copyToClipboard = () => {
const { address } = this.props;
this.setState({ justCopied: true }, () => copyToClipboard(address))
setTimeout(() => this.setState({ justCopied: false }), 1000)
}
renderSkipStep() {
const {showAccountDetail, address} = this.props
return (
<button
className="first-time-flow__button--tertiary"
onClick={() => showAccountDetail(address)}
>
Skip this step
</button>
)
}
renderCoinbaseLogo() {
@ -59,32 +85,34 @@ class BuyEtherScreen extends Component {
)
}
renderCoinbaseForm() {
return (
<div className="buy-ether__action-content-wrapper">
<div>{this.renderCoinbaseLogo()}</div>
<div className="buy-ether__body-text">Coinbase is the worlds most popular way to buy and sell bitcoin, ethereum, and litecoin.</div>
<a className="first-time-flow__link buy-ether__faq-link">What is Ethereum?</a>
<div className="buy-ether__buttons">
<button
className="first-time-flow__button"
onClick={() => this.goToCoinbase(address)}
>
Buy
</button>
<div className="buy-ether__button-separator-text">or</div>
{this.renderSkipStep()}
</div>
</div>
)
}
renderContent() {
const { OPTION_VALUES } = BuyEtherScreen;
const { address } = this.props;
const { OPTION_VALUES } = BuyEtherScreen
const { address, goToCoinbase } = this.props
const { justCopied } = this.state
switch (this.state.selectedOption) {
case OPTION_VALUES.COINBASE:
return (
<div className="buy-ether__action-content-wrapper">
<div>{this.renderCoinbaseLogo()}</div>
<div className="buy-ether__body-text">Coinbase is the worlds most popular way to buy and sell bitcoin, ethereum, and litecoin.</div>
<a className="first-time-flow__link buy-ether__faq-link">What is Ethereum?</a>
<div className="buy-ether__buttons">
<button
className="first-time-flow__button"
>
Buy
</button>
<div className="buy-ether__button-separator-text">or</div>
<button
className="first-time-flow__button--tertiary"
>
Skip this step
</button>
</div>
</div>
)
return this.renderCoinbaseForm()
case OPTION_VALUES.SHAPESHIFT:
return (
<div className="buy-ether__action-content-wrapper">
@ -97,11 +125,7 @@ class BuyEtherScreen extends Component {
Buy
</button>
<div className="buy-ether__button-separator-text">or</div>
<button
className="first-time-flow__button--tertiary"
>
Skip this step
</button>
{this.renderSkipStep()}
</div>
</div>
)
@ -113,19 +137,17 @@ class BuyEtherScreen extends Component {
<div className="buy-ether__action-content-wrapper">
<div dangerouslySetInnerHTML={{ __html: qrImage.createTableTag(4) }} />
<div className="buy-ether__body-text">Deposit Ether directly into your account.</div>
<div className="buy-ether__small-body-text"> (This is the account address that MetaMask created for you to recieve funds.)</div>
<div className="buy-ether__small-body-text">(This is the account address that MetaMask created for you to recieve funds.)</div>
<div className="buy-ether__buttons">
<button
className="first-time-flow__button"
onClick={this.copyToClipboard}
disabled={justCopied}
>
Copy
{ justCopied ? 'Copied' : 'Copy' }
</button>
<div className="buy-ether__button-separator-text">or</div>
<button
className="first-time-flow__button--tertiary"
>
Skip this step
</button>
{this.renderSkipStep()}
</div>
</div>
)
@ -177,8 +199,11 @@ class BuyEtherScreen extends Component {
}
export default connect(
({ metamask: { identities } }) => ({
address: Object.entries(identities)
.map(([key]) => key)[0]
({ metamask: { selectedAddress } }) => ({
address: selectedAddress
}),
dispatch => ({
goToCoinbase: address => dispatch(buyEth({ network: '1', address, amount: 0 })),
showAccountDetail: address => dispatch(showAccountDetail(address)),
})
)(BuyEtherScreen)

@ -1,7 +1,8 @@
import React, {Component, PropTypes} from 'react'
import {connect} from 'react-redux';
import classnames from 'classnames'
import LoadingScreen from './loading-screen'
import {importNewAccount, hideWarning} from '../../../../ui/app/actions'
import {connect} from 'react-redux';
const Input = ({ label, placeholder, onChange, errorMessage, type = 'text' }) => (
<div className="import-account__input-wrapper">
@ -132,7 +133,9 @@ class ImportAccountScreen extends Component {
const { OPTIONS } = ImportAccountScreen;
const { selectedOption } = this.state;
return (
return isLoading
? <LoadingScreen loadingMessage="Creating your new account" />
: (
<div className="import-account">
<a
className="import-account__back-button"

@ -2,6 +2,7 @@
height: 100vh;
width: 100vw;
background-color: #FFF;
overflow: auto;
}
.create-password,

@ -6,19 +6,22 @@ import NoticeScreen from './notice-screen'
import BackupPhraseScreen from './backup-phrase-screen'
import ImportAccountScreen from './import-account-screen'
import BuyEtherScreen from './buy-ether-screen'
import {buyEthView} from '../../../../ui/app/actions'
class FirstTimeFlow extends Component {
static propTypes = {
isInitialized: PropTypes.bool,
seedWords: PropTypes.string,
noActiveNotices: PropTypes.bool
address: PropTypes.string,
noActiveNotices: PropTypes.bool,
goToBuyEtherView: PropTypes.func.isRequired,
};
static defaultProps = {
isInitialized: false,
seedWords: '',
noActiveNotices: false
noActiveNotices: false,
};
static SCREEN_TYPE = {
@ -28,7 +31,6 @@ class FirstTimeFlow extends Component {
NOTICE: 'notice',
BACK_UP_PHRASE: 'back_up_phrase',
CONFIRM_BACK_UP_PHRASE: 'confirm_back_up_phrase',
BUY_ETHER: 'buy_ether'
};
constructor(props) {
@ -43,7 +45,11 @@ class FirstTimeFlow extends Component {
}
getScreenType() {
const {isInitialized, seedWords, noActiveNotices} = this.props;
const {
isInitialized,
seedWords,
noActiveNotices,
} = this.props;
const {SCREEN_TYPE} = FirstTimeFlow
// return SCREEN_TYPE.IMPORT_ACCOUNT
@ -63,6 +69,7 @@ class FirstTimeFlow extends Component {
renderScreen() {
const {SCREEN_TYPE} = FirstTimeFlow
const {goToBuyEtherView, address} = this.props
switch (this.state.screenType) {
case SCREEN_TYPE.CREATE_PASSWORD:
@ -94,13 +101,7 @@ class FirstTimeFlow extends Component {
case SCREEN_TYPE.BACK_UP_PHRASE:
return (
<BackupPhraseScreen
next={() => this.setScreenType(SCREEN_TYPE.BUY_ETHER)}
/>
)
case SCREEN_TYPE.BUY_ETHER:
return (
<BuyEtherScreen
next={() => goToBuyEtherView(address)}
/>
)
default:
@ -119,10 +120,14 @@ class FirstTimeFlow extends Component {
}
export default connect(
({ metamask: { isInitialized, seedWords, noActiveNotices } }) => ({
({ metamask: { isInitialized, seedWords, noActiveNotices, selectedAddress } }) => ({
isInitialized,
seedWords,
noActiveNotices
noActiveNotices,
address: selectedAddress,
}),
dispatch => ({
goToBuyEtherView: address => dispatch(buyEthView(address))
})
)(FirstTimeFlow)

@ -57,10 +57,9 @@ class NoticeScreen extends Component {
}
export default connect(
({ metamask: { identities, lastUnreadNotice } }) => ({
({ metamask: { selectedAddress, lastUnreadNotice } }) => ({
lastUnreadNotice,
address: Object.entries(identities)
.map(([key]) => key)[0]
address: selectedAddress
}),
dispatch => ({
markNoticeRead: notice => dispatch(markNoticeRead(notice))

@ -33,8 +33,7 @@ class UniqueImageScreen extends Component {
}
export default connect(
({ metamask: { identities } }) => ({
address: Object.entries(identities)
.map(([key]) => key)[0]
({ metamask: { selectedAddress } }) => ({
address: selectedAddress
})
)(UniqueImageScreen)

@ -224,7 +224,7 @@ function confirmSeedWords () {
}
log.info('Seed word cache cleared. ' + account)
dispatch(actions.showAccountDetail(account))
dispatch(actions.showAccountsPage())
resolve(account)
})
})

@ -5,6 +5,7 @@ const h = require('react-hyperscript')
const actions = require('./actions')
// mascara
const MascaraFirstTime = require('../../mascara/src/app/first-time').default
const MascaraBuyEtherScreen = require('../../mascara/src/app/first-time/buy-ether-screen').default
// init
const InitializeMenuScreen = require('./first-time/init-menu')
const NewKeyChainScreen = require('./new-keychain')
@ -130,10 +131,16 @@ App.prototype.renderAppBar = function () {
const isNetworkMenuOpen = state.isNetworkMenuOpen || false
const {isMascara, isOnboarding} = props
// Do not render header if user is in mascara onboarding
if (isMascara && isOnboarding) {
return null
}
// Do not render header if user is in mascara buy ether
if (isMascara && props.currentView.name === 'buyEth') {
return null
}
return (
h('.full-width', {
@ -433,9 +440,9 @@ App.prototype.renderPrimary = function () {
var props = this.props
const {isMascara, isOnboarding} = props
if (isMascara && isOnboarding) {
return h(MascaraFirstTime)
}
// if (isMascara && isOnboarding) {
// return h(MascaraFirstTime)
// }
// notices
if (!props.noActiveNotices) {
@ -534,7 +541,9 @@ App.prototype.renderPrimary = function () {
case 'buyEth':
log.debug('rendering buy ether screen')
return h(BuyView, {key: 'buyEthView'})
return isMascara
? h(MascaraBuyEtherScreen, {key: 'buyEthView'})
: h(BuyView, {key: 'buyEthView'})
case 'qr':
log.debug('rendering show qr screen')

@ -62,7 +62,8 @@ CreateVaultCompleteScreen.prototype.render = function () {
}),
h('button.primary', {
onClick: () => this.confirmSeedWords(),
onClick: () => this.confirmSeedWords()
.then(account => this.showAccountDetail(account)),
style: {
margin: '24px',
fontSize: '0.9em',
@ -82,5 +83,9 @@ CreateVaultCompleteScreen.prototype.render = function () {
}
CreateVaultCompleteScreen.prototype.confirmSeedWords = function () {
this.props.dispatch(actions.confirmSeedWords())
return this.props.dispatch(actions.confirmSeedWords())
}
CreateVaultCompleteScreen.prototype.showAccountDetail = function (account) {
return this.props.dispatch(actions.showAccountDetail(account))
}

Loading…
Cancel
Save