Skip to content

Commit

Permalink
feat(component): add tabs to show xpubs for all lockbox coin types
Browse files Browse the repository at this point in the history
  • Loading branch information
schnogz committed Dec 10, 2018
1 parent 036a49c commit f9d03b0
Show file tree
Hide file tree
Showing 5 changed files with 182 additions and 72 deletions.
Original file line number Diff line number Diff line change
@@ -1,12 +1,50 @@
import React from 'react'
import { actions } from 'data'
import { connect } from 'react-redux'
import { bindActionCreators, compose } from 'redux'

import { getData } from './selectors'
import modalEnhancer from 'providers/ModalEnhancer'
import ShowLockboxXPubs from './template'

class ShowLockboxXPubsContainer extends React.PureComponent {
state = {
activeTab: 'btc'
}
setActive = tab => {
this.setState({ activeTab: tab })
}
render () {
return <ShowLockboxXPubs {...this.props} />
return this.props.data.cata({
Success: val => (
<ShowLockboxXPubs
activeTab={this.state.activeTab}
setActive={this.setActive}
coins={val}
{...this.props}
/>
),
Failure: () => <div />,
Loading: () => <div />,
NotAsked: () => <div />
})
}
}

export default modalEnhancer('ShowLockboxXPubs')(ShowLockboxXPubsContainer)
const mapStateToProps = (state, ownProps) => ({
data: getData(state, ownProps.deviceIndex)
})

const mapDispatchToProps = dispatch => ({
modalActions: bindActionCreators(actions.modals, dispatch)
})

const enhance = compose(
modalEnhancer('ShowLockboxXPubs'),
connect(
mapStateToProps,
mapDispatchToProps
)
)

export default enhance(ShowLockboxXPubsContainer)
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { createDeepEqualSelector } from 'services/ReselectHelper'

import { Remote } from 'blockchain-wallet-v4/src'
import { selectors } from 'data'

export const getData = (state, deviceIndex) =>
createDeepEqualSelector(
[
selectors.core.kvStore.lockbox.getLockboxBtcDefaultAccount,
selectors.core.kvStore.lockbox.getLockboxBchXpub,
selectors.core.kvStore.lockbox.getEthContextForDevice,
selectors.core.kvStore.lockbox.getXlmContextForDevice
],
(btcR, bchR, ethR, xlmR) => {
const btc = btcR.getOrElse({})
const bch = bchR.getOrElse({})
const eth = ethR.getOrElse([])
const xlm = xlmR.getOrElse([])
return Remote.of({
btc: btc.xpub,
bch,
eth: eth[0],
xlm: xlm[0]
})
}
)(state, deviceIndex)
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,11 @@ import PropTypes from 'prop-types'
import styled from 'styled-components'
import QRCodeReact from 'qrcode.react'
import { FormattedMessage } from 'react-intl'
import { keys } from 'ramda'

import {
Banner,
Icon,
Modal,
ModalHeader,
ModalBody,
Expand All @@ -14,35 +16,74 @@ import {
Button
} from 'blockchain-info-components'

const CoinName = styled(Text)`
margin-bottom: 5px;
`
const CoinRow = styled.div`
const Content = styled.div`
display: flex;
flex-direction: row;
flex-direction: column;
width: 100%;
justify-content: space-between;
`
const XPubTextWrapper = styled.div`
display: flex;
flex-direction: row;
height: 120px;
min-height: 120px;
margin-right: 20px;
align-items: center;
`
const WarningBanner = styled(Banner)`
margin-bottom: 25px;
margin-bottom: 20px;
`
const XPubText = styled(Text)`
background-color: ${props => props.theme['white-blue']};
padding: 25px 15px 0;
padding: 25px;
margin-bottom: 20px;
color: #4b4d4e;
word-break: break-all;
width: 80%;
`
const Tabs = styled.div`
display: flex;
border-bottom: 2px solid ${props => props.theme['gray-1']};
margin-bottom: 35px;
`
const Tab = styled.div`
width: 33%;
display: flex;
padding: 10px 5px;
position: relative;
align-items: center;
justify-content: center;
cursor: pointer;
@media (min-width: 768px) {
padding: 15px 5px;
}
&:after {
display: block;
content: '';
width: 100%;
left: 0;
bottom: -2px;
position: absolute;
transform: scaleX(0);
transition: transform 0.3s;
border-bottom: solid 2px ${props => props.theme['gray-6']};
}
> * {
transition: color 0.3s;
}
&.active,
&:hover {
&:after {
transform: scaleX(1);
}
}
`
const TabHeader = styled(Text)`
font-weight: 300;
@media (min-width: 768px) {
font-size: 20px;
}
`
const TabIcon = styled(Icon)`
margin-right: 10px;
@media (min-width: 768px) {
font-size: ${props => props.size || '20px'};
}
`

const PromptLockbox = props => {
const { btcXPub, bchXPub, closeAll, position, total } = props
const { activeTab, coins, setActive, closeAll, position, total } = props

return (
<Modal size='large' position={position} total={total}>
Expand All @@ -61,24 +102,49 @@ const PromptLockbox = props => {
/>
</Text>
</WarningBanner>
<CoinName>Bitcoin (BTC)</CoinName>
<CoinRow style={{ marginBottom: '20px' }}>
<XPubTextWrapper>
<XPubText size='12px' weight='300'>
{btcXPub}
</XPubText>
</XPubTextWrapper>
<QRCodeReact value={btcXPub} size={100} />
</CoinRow>
<CoinName>Bitcoin Cash (BCH)</CoinName>
<CoinRow>
<XPubTextWrapper>
<Tabs>
{keys(coins).map(coin => {
return (
<Tab
className={activeTab === coin ? 'active' : ''}
onClick={() => setActive(coin)}
>
<TabIcon
name={coin + '-circle-filled'}
size='28px'
color={coin}
/>
<TabHeader>
<span>{coin.toUpperCase()}</span>
</TabHeader>
</Tab>
)
})}
</Tabs>
{coins[activeTab] ? (
<Content>
<XPubText size='12px' weight='300'>
{bchXPub}
{coins[activeTab]}
</XPubText>
</XPubTextWrapper>
<QRCodeReact value={bchXPub} size={100} />
</CoinRow>
<QRCodeReact value={coins[activeTab]} size={150} />
</Content>
) : (
<Content style={{ textAlign: 'center' }}>
<Text size='16px'>
<FormattedMessage
id='modals.lockbox.showxpubs.notfound'
defaultMessage='Failed to derive the xPub!'
/>
</Text>
<Text size='16px' style={{ marginTop: '10px' }}>
<FormattedMessage
id='modals.lockbox.showxpubs.notfound2'
defaultMessage='Ensure {coin} has been added to your Lockbox.'
values={{ coin: activeTab.toUpperCase() }}
/>
</Text>
</Content>
)}
</ModalBody>
<ModalFooter align='right'>
<Button nature='primary' onClick={closeAll}>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,27 +13,21 @@ import {
Text
} from 'blockchain-info-components'

const Wrapper = styled.div`
const Content = styled.div`
display: flex;
flex-direction: row;
flex-direction: column;
width: 100%;
`
const XPubTextWrapper = styled.div`
display: flex;
flex-direction: row;
height: 120px;
min-height: 120px;
margin-right: 20px;
`
const WarningBanner = styled(Banner)`
margin-bottom: 25px;
align-items: center;
`
const XPubText = styled(Text)`
background-color: ${props => props.theme['white-blue']};
padding: 25px 15px 0;
padding: 25px;
margin-bottom: 20px;
color: #4b4d4e;
word-break: break-all;
width: 80%;
`
const WarningBanner = styled(Banner)`
margin-bottom: 25px;
`

const ShowXPubTemplate = ({ position, total, closeAll, xpub }) => (
Expand All @@ -53,14 +47,12 @@ const ShowXPubTemplate = ({ position, total, closeAll, xpub }) => (
/>
</Text>
</WarningBanner>
<Wrapper>
<XPubTextWrapper>
<XPubText size='12px' weight='300'>
{xpub}
</XPubText>
</XPubTextWrapper>
<QRCodeReact value={xpub} size={100} />
</Wrapper>
<Content>
<XPubText size='12px' weight='300'>
{xpub}
</XPubText>
<QRCodeReact value={xpub} size={150} />
</Content>
</ModalBody>
<ModalFooter align='right'>
<Button nature='primary' onClick={closeAll}>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,14 @@
import React from 'react'
import { actions, selectors } from 'data'
import { actions } from 'data'
import { connect } from 'react-redux'
import { bindActionCreators } from 'redux'
import { prop } from 'ramda'

import ShowXpubs from './template'

class ShowXPubsContainer extends React.PureComponent {
onShowXPubs = () => {
this.props.modalActions.showModal('ShowLockboxXPubs', {
btcXPub: this.props.btcXPub,
bchXPub: this.props.bchXPub
deviceIndex: this.props.deviceIndex
})
}

Expand All @@ -19,21 +17,11 @@ class ShowXPubsContainer extends React.PureComponent {
}
}

const mapStateToProps = (state, ownProps) => ({
btcXPub: selectors.core.kvStore.lockbox
.getLockboxBtcDefaultAccount(state, ownProps.deviceIndex)
.map(prop('xpub'))
.getOrFail(),
bchXPub: selectors.core.kvStore.lockbox
.getLockboxBchXpub(state, ownProps.deviceIndex)
.getOrFail()
})

const mapDispatchToProps = dispatch => ({
modalActions: bindActionCreators(actions.modals, dispatch)
})

export default connect(
mapStateToProps,
null,
mapDispatchToProps
)(ShowXPubsContainer)

0 comments on commit f9d03b0

Please sign in to comment.