Skip to content

Commit

Permalink
refactor - reselect / sagas
Browse files Browse the repository at this point in the history
  • Loading branch information
Lyncee59 committed May 8, 2018
1 parent e9b68db commit 219d04b
Show file tree
Hide file tree
Showing 18 changed files with 218 additions and 166 deletions.
@@ -1,7 +1,7 @@
import React from 'react'
import styled from 'styled-components'
import { FormattedMessage, FormattedHTMLMessage } from 'react-intl'
import { Image, Text } from 'blockchain-info-components'
import { Image, Link, Text } from 'blockchain-info-components'

const Wrapper = styled.div`
display: flex;
Expand Down Expand Up @@ -32,7 +32,13 @@ class EmptyTxContainer extends React.PureComponent {
<FormattedMessage id='scenes.transactions.empty.content.header' defaultMessage="Oops, we couldn't find any transactions!" />
</Header>
<Text size='18px' weight={300}>
<FormattedHTMLMessage id='scenes.transactions.empty.content.body' defaultMessage='Please try filtering by a different criteria or <a href="https://support.blockchain.com/" target="_blank" referrer="noreferrer">reach out to us</a> if you need help.' />
<FormattedHTMLMessage id='scenes.transactions.empty.content.body' defaultMessage='Please try filtering by a different criteria or ' />
</Text>
<Link href='https://support.blockchain.com/' target='_blank' referrer='noreferrer'>
<FormattedMessage id='scenes.transactions.empty.content.body2' defaultMessage='reach out to us ' />
</Link>
<Text size='18px' weight={300}>
<FormattedMessage id='scenes.transactions.empty.content.body3' defaultMessage='if you need help.' />
</Text>
</Empty>
</Wrapper>
Expand Down
Expand Up @@ -11,7 +11,7 @@ const NotAsked = props => (
)

NotAsked.propTypes = {
handleClick: PropTypes.string.isRequired
handleClick: PropTypes.func.isRequired
}

export default NotAsked
Expand Up @@ -17,10 +17,15 @@ class ListItemContainer extends React.PureComponent {
}

handleEditDescription (value) {
if (this.props.coin === 'ETH') {
this.props.ethereumActions.setTxNotesEthereum(this.props.transaction.hash, value)
} else {
this.props.walletActions.setTransactionNote(this.props.transaction.hash, value)
switch (this.props.coin) {
case 'ETH': {
this.props.ethereumActions.setTxNotesEthereum(this.props.transaction.hash, value)
break
}
case 'BTC': {
this.props.walletActions.setTransactionNote(this.props.transaction.hash, value)
break
}
}
}

Expand Down
@@ -0,0 +1,2 @@

export const ETH_TRANSACTIONS_INITIALIZED = '@EVENT.ETH_TRANSACTIONS_INITIALIZED'
@@ -0,0 +1,4 @@

import * as AT from './actionTypes'

export const initialized = () => ({ type: AT.ETH_TRANSACTIONS_INITIALIZED })
@@ -0,0 +1,14 @@
import { takeEvery } from 'redux-saga/effects'
import * as AT from './actionTypes'
import * as actionTypes from '../../actionTypes'
import sagas from './sagas'

export default ({ coreSagas }) => {
const ethTransactionsSagas = sagas({ coreSagas })

return function * () {
yield takeEvery(AT.ETH_TRANSACTIONS_INITIALIZED, ethTransactionsSagas.initialized)
yield takeEvery(actionTypes.form.CHANGE, ethTransactionsSagas.formChanged)
yield takeEvery(actionTypes.scroll.UPDATE_SCROLL, ethTransactionsSagas.scrollUpdated)
}
}
@@ -0,0 +1,52 @@
import { select, put } from 'redux-saga/effects'
import { equals, path, prop } from 'ramda'
import { Remote } from 'blockchain-wallet-v4/src'
import { actions, selectors } from 'data'

export default ({ coreSagas }) => {
const initialized = function * () {
try {
const initialValues = {
status: '',
search: ''
}
yield put(actions.form.initialize('ethTransactions', initialValues))
const ethTransactionsR = yield select(selectors.core.data.eth.getTransactions)
if (!Remote.Success.is(ethTransactionsR)) yield put(actions.core.data.eth.fetchTransactions())
} catch (e) {
console.log(e)
}
}

const scrollUpdated = function * (action) {
try {
const threshold = 250
const { yMax, yOffset } = action.payload
if (yMax - yOffset < threshold) {
yield put(actions.core.data.eth.fetchTransactions(false))
}
} catch (e) {
console.log(e)
}
}

const formChanged = function * (action) {
try {
const form = path(['meta', 'form'], action)
const field = path(['meta', 'field'], action)
if (!equals('ethTransactions', form)) return
switch (field) {
case 'source':
yield put(actions.core.data.eth.fetchTransactions())
}
} catch (e) {
console.log(e)
}
}

return {
initialized,
formChanged,
scrollUpdated
}
}
Expand Up @@ -30,29 +30,27 @@ const TransactionIcon = styled(Icon)`
justify-content: center;
`

const Empty = props => {
return (
<Wrapper>
<EtherWelcome />
<Transactions>
<Text size='20px' weight={300} capitalize>
<TransactionIcon name='transactions' />
<FormattedMessage id='scenes.transactions.ether.content.empty.transactions' defaultMessage='Your transactions' />
</Text>
<Text size='14px' weight={300}>
<FormattedMessage id='scenes.transactions.ether.content.empty.explain' defaultMessage='Transactions occur when you receive and send ether.' />
</Text>
<Separator />
</Transactions>
<Ether>
<LinkContainer to='/exchange'>
<IconButton name='exchange' nature='empty' uppercase>
<FormattedMessage id='scenes.transactions.ether.content.empty.getether' defaultMessage='Get ether' />
</IconButton>
</LinkContainer>
</Ether>
</Wrapper>
)
}
const Empty = props => (
<Wrapper>
<EtherWelcome />
<Transactions>
<Text size='20px' weight={300} capitalize>
<TransactionIcon name='transactions' />
<FormattedMessage id='scenes.transactions.ether.content.empty.transactions' defaultMessage='Your transactions' />
</Text>
<Text size='14px' weight={300}>
<FormattedMessage id='scenes.transactions.ether.content.empty.explain' defaultMessage='Transactions occur when you receive and send ether.' />
</Text>
<Separator />
</Transactions>
<Ether>
<LinkContainer to='/exchange'>
<IconButton name='exchange' nature='empty' uppercase>
<FormattedMessage id='scenes.transactions.ether.content.empty.getether' defaultMessage='Get ether' />
</IconButton>
</LinkContainer>
</Ether>
</Wrapper>
)

export default Empty

This file was deleted.

@@ -1,27 +1,20 @@
import React from 'react'
import PropTypes from 'prop-types'
import styled from 'styled-components'

import TransactionListItem from 'components/TransactionListItem'
import Error from './template.error'
import Loading from './template.loading'
import Success from './template.success'

const Wrapper = styled.div`
display: flex;
flex-direction: column;
justify-content: flex-start;
align-items: flex-start;
width: 100%;
`
class List extends React.PureComponent {
render () {
const { data } = this.props

const TransactionList = (props) => {
return (
<Wrapper>
{ props.transactions.map((transaction, index) => <TransactionListItem key={index} transaction={transaction} coin='ETH' minConfirmations={12} />)}
</Wrapper>
)
return data.cata({
Success: (value) => <Success transactions={value} />,
Failure: (message) => <Error>{message}</Error>,
Loading: () => <Loading />,
NotAsked: () => <Loading />
})
}
}

TransactionList.propTypes = {
transactions: PropTypes.array.isRequired
}

export default TransactionList
export default List
Expand Up @@ -8,29 +8,29 @@ const ActivityListSkeleton = styled(SkeletonRectangle)`
flex-direction: column;
align-items: start;
box-sizing: border-box;
padding-top: 25px;
padding-top: 10px;
`
const ActivitySkeleton = styled.div`
flex: 1;
width: 100%;
padding: 0 15px;
padding: 0 10px;
& > :first-child { margin-bottom: 5px; }
`

export default () => {
return (
<ActivityListSkeleton height='450px' width='100%;' bgColor='white'>
<ActivitySkeleton>
<SkeletonRectangle width='50%' height='30px' bgColor='white-blue' />
<SkeletonRectangle width='calc(100% - 30px)' height='80px' bgColor='white-blue' />
<SkeletonRectangle width='50%' height='25px' bgColor='white-blue' />
<SkeletonRectangle width='calc(100% - 30px)' height='75px' bgColor='white-blue' />
</ActivitySkeleton>
<ActivitySkeleton>
<SkeletonRectangle width='50%' height='30px' bgColor='white-blue' />
<SkeletonRectangle width='calc(100% - 30px)' height='80px' bgColor='white-blue' />
<SkeletonRectangle width='50%' height='25px' bgColor='white-blue' />
<SkeletonRectangle width='calc(100% - 30px)' height='75px' bgColor='white-blue' />
</ActivitySkeleton>
<ActivitySkeleton>
<SkeletonRectangle width='50%' height='30px' bgColor='white-blue' />
<SkeletonRectangle width='calc(100% - 30px)' height='80px' bgColor='white-blue' />
<SkeletonRectangle width='50%' height='25px' bgColor='white-blue' />
<SkeletonRectangle width='calc(100% - 30px)' height='75px' bgColor='white-blue' />
</ActivitySkeleton>
</ActivityListSkeleton>
)
Expand Down
@@ -0,0 +1,27 @@
import React from 'react'
import styled from 'styled-components'
import PropTypes from 'prop-types'

import TransactionListItem from 'components/TransactionListItem'

const Wrapper = styled.div`
display: flex;
flex-direction: column;
justify-content: flex-start;
align-items: flex-start;
width: 100%;
`

const Success = props => {
return (
<Wrapper>
{props.transactions.map((transaction, index) => <TransactionListItem key={index} transaction={transaction} coin='ETH' minConfirmations={12} />)}
</Wrapper>
)
}

Success.propTypes = {
transactions: PropTypes.array.isRequired
}

export default Success
@@ -1,49 +1,28 @@
import React from 'react'
import { connect } from 'react-redux'
import { bindActionCreators } from 'redux'
import { equals } from 'ramda'

import { Remote } from 'blockchain-wallet-v4/src'
import { getData } from './selectors'
import { actions } from 'data'
import { getContext, getData } from './selectors'
import Error from './template.error'
import Loading from './template.loading'
import Success from './template.success'
import Content from './template'

class ContentContainer extends React.PureComponent {
componentWillMount () {
const { context, data } = this.props
if (Remote.Success.is(context) && Remote.NotAsked.is(data)) {
context.map(x => this.props.dataEthereumActions.fetchData(x))
}
}

componentWillReceiveProps (nextProps) {
if (!equals(this.props.context, nextProps.context)) {
nextProps.context.map(x => this.props.dataEthereumActions.fetchData(x))
}
componentDidMount () {
this.props.actions.initialized()
}

render () {
const { data } = this.props

return data.cata({
Success: (value) => <Success isEmpty={equals(value.total, 0)} search={value.search} transactions={value.transactions} />,
Failure: (message) => <Error>{message}</Error>,
Loading: () => <Loading />,
NotAsked: () => <Loading />
})
const { empty, list, search } = this.props
return <Content empty={empty} search={search} list={list} />
}
}

const mapStateToProps = (state) => ({
data: getData(state),
context: getContext(state)
const mapStateToProps = state => ({
...getData(state)
})

const mapDispatchToProps = (dispatch) => ({
dataEthereumActions: bindActionCreators(actions.core.data.ethereum, dispatch),
kvStoreEthereumActions: bindActionCreators(actions.core.kvStore.ethereum, dispatch)
actions: bindActionCreators(actions.components.btcTransactions, dispatch)
})

export default connect(mapStateToProps, mapDispatchToProps)(ContentContainer)

0 comments on commit 219d04b

Please sign in to comment.