From 219d04ba991d5ebf493f25738360dd9639bbce9a Mon Sep 17 00:00:00 2001 From: Guillaume Marquilly Date: Tue, 8 May 2018 14:42:40 +0100 Subject: [PATCH] refactor - reselect / sagas --- .../src/components/EmptyTx/index.js | 10 +++- .../ValueWhenReceived/template.notasked.js | 2 +- .../components/TransactionListItem/index.js | 13 +++-- .../components/ethTransactions/actionTypes.js | 2 + .../components/ethTransactions/actions.js | 4 ++ .../ethTransactions/sagaRegister.js | 14 +++++ .../data/components/ethTransactions/sagas.js | 52 +++++++++++++++++++ .../Transactions/Ether/Content/Empty/index.js | 46 ++++++++-------- .../Ether/Content/List/ListItem/index.js | 38 -------------- .../Transactions/Ether/Content/List/index.js | 35 +++++-------- .../Content/{ => List}/template.error.js | 0 .../Content/{ => List}/template.loading.js | 16 +++--- .../Ether/Content/List/template.success.js | 27 ++++++++++ .../Transactions/Ether/Content/index.js | 39 ++++---------- .../Transactions/Ether/Content/selectors.js | 32 ++++++++---- .../Transactions/Ether/Content/template.js | 26 ++++++++++ .../Ether/Content/template.success.js | 26 ---------- .../Transactions/Ether/Menu/template.js | 2 +- 18 files changed, 218 insertions(+), 166 deletions(-) create mode 100644 packages/blockchain-wallet-v4-frontend/src/data/components/ethTransactions/actionTypes.js create mode 100644 packages/blockchain-wallet-v4-frontend/src/data/components/ethTransactions/actions.js create mode 100644 packages/blockchain-wallet-v4-frontend/src/data/components/ethTransactions/sagaRegister.js create mode 100644 packages/blockchain-wallet-v4-frontend/src/data/components/ethTransactions/sagas.js delete mode 100644 packages/blockchain-wallet-v4-frontend/src/scenes/Transactions/Ether/Content/List/ListItem/index.js rename packages/blockchain-wallet-v4-frontend/src/scenes/Transactions/Ether/Content/{ => List}/template.error.js (100%) rename packages/blockchain-wallet-v4-frontend/src/scenes/Transactions/Ether/Content/{ => List}/template.loading.js (65%) create mode 100644 packages/blockchain-wallet-v4-frontend/src/scenes/Transactions/Ether/Content/List/template.success.js create mode 100644 packages/blockchain-wallet-v4-frontend/src/scenes/Transactions/Ether/Content/template.js delete mode 100644 packages/blockchain-wallet-v4-frontend/src/scenes/Transactions/Ether/Content/template.success.js diff --git a/packages/blockchain-wallet-v4-frontend/src/components/EmptyTx/index.js b/packages/blockchain-wallet-v4-frontend/src/components/EmptyTx/index.js index f68a8f4d8a2..b9b948769ed 100644 --- a/packages/blockchain-wallet-v4-frontend/src/components/EmptyTx/index.js +++ b/packages/blockchain-wallet-v4-frontend/src/components/EmptyTx/index.js @@ -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; @@ -32,7 +32,13 @@ class EmptyTxContainer extends React.PureComponent { - + + + + + + + diff --git a/packages/blockchain-wallet-v4-frontend/src/components/TransactionListItem/FiatAtTime/ValueWhenReceived/template.notasked.js b/packages/blockchain-wallet-v4-frontend/src/components/TransactionListItem/FiatAtTime/ValueWhenReceived/template.notasked.js index cafce6c5001..992503ba6b4 100644 --- a/packages/blockchain-wallet-v4-frontend/src/components/TransactionListItem/FiatAtTime/ValueWhenReceived/template.notasked.js +++ b/packages/blockchain-wallet-v4-frontend/src/components/TransactionListItem/FiatAtTime/ValueWhenReceived/template.notasked.js @@ -11,7 +11,7 @@ const NotAsked = props => ( ) NotAsked.propTypes = { - handleClick: PropTypes.string.isRequired + handleClick: PropTypes.func.isRequired } export default NotAsked diff --git a/packages/blockchain-wallet-v4-frontend/src/components/TransactionListItem/index.js b/packages/blockchain-wallet-v4-frontend/src/components/TransactionListItem/index.js index 92c4e8c1735..e4659f62268 100644 --- a/packages/blockchain-wallet-v4-frontend/src/components/TransactionListItem/index.js +++ b/packages/blockchain-wallet-v4-frontend/src/components/TransactionListItem/index.js @@ -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 + } } } diff --git a/packages/blockchain-wallet-v4-frontend/src/data/components/ethTransactions/actionTypes.js b/packages/blockchain-wallet-v4-frontend/src/data/components/ethTransactions/actionTypes.js new file mode 100644 index 00000000000..567c49e667b --- /dev/null +++ b/packages/blockchain-wallet-v4-frontend/src/data/components/ethTransactions/actionTypes.js @@ -0,0 +1,2 @@ + +export const ETH_TRANSACTIONS_INITIALIZED = '@EVENT.ETH_TRANSACTIONS_INITIALIZED' diff --git a/packages/blockchain-wallet-v4-frontend/src/data/components/ethTransactions/actions.js b/packages/blockchain-wallet-v4-frontend/src/data/components/ethTransactions/actions.js new file mode 100644 index 00000000000..db5748f22a0 --- /dev/null +++ b/packages/blockchain-wallet-v4-frontend/src/data/components/ethTransactions/actions.js @@ -0,0 +1,4 @@ + +import * as AT from './actionTypes' + +export const initialized = () => ({ type: AT.ETH_TRANSACTIONS_INITIALIZED }) diff --git a/packages/blockchain-wallet-v4-frontend/src/data/components/ethTransactions/sagaRegister.js b/packages/blockchain-wallet-v4-frontend/src/data/components/ethTransactions/sagaRegister.js new file mode 100644 index 00000000000..841d1f28914 --- /dev/null +++ b/packages/blockchain-wallet-v4-frontend/src/data/components/ethTransactions/sagaRegister.js @@ -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) + } +} diff --git a/packages/blockchain-wallet-v4-frontend/src/data/components/ethTransactions/sagas.js b/packages/blockchain-wallet-v4-frontend/src/data/components/ethTransactions/sagas.js new file mode 100644 index 00000000000..71f837d0e40 --- /dev/null +++ b/packages/blockchain-wallet-v4-frontend/src/data/components/ethTransactions/sagas.js @@ -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 + } +} diff --git a/packages/blockchain-wallet-v4-frontend/src/scenes/Transactions/Ether/Content/Empty/index.js b/packages/blockchain-wallet-v4-frontend/src/scenes/Transactions/Ether/Content/Empty/index.js index 89fca0727f1..6f676bf6d58 100644 --- a/packages/blockchain-wallet-v4-frontend/src/scenes/Transactions/Ether/Content/Empty/index.js +++ b/packages/blockchain-wallet-v4-frontend/src/scenes/Transactions/Ether/Content/Empty/index.js @@ -30,29 +30,27 @@ const TransactionIcon = styled(Icon)` justify-content: center; ` -const Empty = props => { - return ( - - - - - - - - - - - - - - - - - - - - - ) -} +const Empty = props => ( + + + + + + + + + + + + + + + + + + + + +) export default Empty diff --git a/packages/blockchain-wallet-v4-frontend/src/scenes/Transactions/Ether/Content/List/ListItem/index.js b/packages/blockchain-wallet-v4-frontend/src/scenes/Transactions/Ether/Content/List/ListItem/index.js deleted file mode 100644 index ae45ca11622..00000000000 --- a/packages/blockchain-wallet-v4-frontend/src/scenes/Transactions/Ether/Content/List/ListItem/index.js +++ /dev/null @@ -1,38 +0,0 @@ -import React from 'react' -import { connect } from 'react-redux' -import { bindActionCreators } from 'redux' - -import { actions } from 'data' -import ListItem from './template.js' - -class ListItemContainer extends React.PureComponent { - constructor (props) { - super(props) - this.state = { toggled: false } - this.handleToggle = this.handleToggle.bind(this) - this.handleCoinDisplay = this.handleCoinDisplay.bind(this) - this.handleEditDescription = this.handleEditDescription.bind(this) - } - - handleToggle () { - this.setState({ toggled: !this.state.toggled }) - } - - handleCoinDisplay () { - this.props.actions.toggleCoinDisplayed() - } - handleEditDescription (value) { - this.props.ethereumActions.setTxNotesEthereum(this.props.transaction.hash, value) - } - - render () { - return - } -} - -const mapDispatchToProps = (dispatch) => ({ - actions: bindActionCreators(actions.preferences, dispatch), - ethereumActions: bindActionCreators(actions.core.kvStore.ethereum, dispatch) -}) - -export default connect(undefined, mapDispatchToProps)(ListItemContainer) diff --git a/packages/blockchain-wallet-v4-frontend/src/scenes/Transactions/Ether/Content/List/index.js b/packages/blockchain-wallet-v4-frontend/src/scenes/Transactions/Ether/Content/List/index.js index ad1b37d0aaa..6fe369bd312 100644 --- a/packages/blockchain-wallet-v4-frontend/src/scenes/Transactions/Ether/Content/List/index.js +++ b/packages/blockchain-wallet-v4-frontend/src/scenes/Transactions/Ether/Content/List/index.js @@ -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 ( - - { props.transactions.map((transaction, index) => )} - - ) + return data.cata({ + Success: (value) => , + Failure: (message) => {message}, + Loading: () => , + NotAsked: () => + }) + } } -TransactionList.propTypes = { - transactions: PropTypes.array.isRequired -} - -export default TransactionList +export default List diff --git a/packages/blockchain-wallet-v4-frontend/src/scenes/Transactions/Ether/Content/template.error.js b/packages/blockchain-wallet-v4-frontend/src/scenes/Transactions/Ether/Content/List/template.error.js similarity index 100% rename from packages/blockchain-wallet-v4-frontend/src/scenes/Transactions/Ether/Content/template.error.js rename to packages/blockchain-wallet-v4-frontend/src/scenes/Transactions/Ether/Content/List/template.error.js diff --git a/packages/blockchain-wallet-v4-frontend/src/scenes/Transactions/Ether/Content/template.loading.js b/packages/blockchain-wallet-v4-frontend/src/scenes/Transactions/Ether/Content/List/template.loading.js similarity index 65% rename from packages/blockchain-wallet-v4-frontend/src/scenes/Transactions/Ether/Content/template.loading.js rename to packages/blockchain-wallet-v4-frontend/src/scenes/Transactions/Ether/Content/List/template.loading.js index 26dc8d2f30b..7d1e5129415 100644 --- a/packages/blockchain-wallet-v4-frontend/src/scenes/Transactions/Ether/Content/template.loading.js +++ b/packages/blockchain-wallet-v4-frontend/src/scenes/Transactions/Ether/Content/List/template.loading.js @@ -8,12 +8,12 @@ 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; } ` @@ -21,16 +21,16 @@ export default () => { return ( - - + + - - + + - - + + ) diff --git a/packages/blockchain-wallet-v4-frontend/src/scenes/Transactions/Ether/Content/List/template.success.js b/packages/blockchain-wallet-v4-frontend/src/scenes/Transactions/Ether/Content/List/template.success.js new file mode 100644 index 00000000000..449cd7eb0cc --- /dev/null +++ b/packages/blockchain-wallet-v4-frontend/src/scenes/Transactions/Ether/Content/List/template.success.js @@ -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 ( + + {props.transactions.map((transaction, index) => )} + + ) +} + +Success.propTypes = { + transactions: PropTypes.array.isRequired +} + +export default Success diff --git a/packages/blockchain-wallet-v4-frontend/src/scenes/Transactions/Ether/Content/index.js b/packages/blockchain-wallet-v4-frontend/src/scenes/Transactions/Ether/Content/index.js index 9afffea574d..9e533670124 100644 --- a/packages/blockchain-wallet-v4-frontend/src/scenes/Transactions/Ether/Content/index.js +++ b/packages/blockchain-wallet-v4-frontend/src/scenes/Transactions/Ether/Content/index.js @@ -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) => , - Failure: (message) => {message}, - Loading: () => , - NotAsked: () => - }) + const { empty, list, search } = this.props + return } } -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) diff --git a/packages/blockchain-wallet-v4-frontend/src/scenes/Transactions/Ether/Content/selectors.js b/packages/blockchain-wallet-v4-frontend/src/scenes/Transactions/Ether/Content/selectors.js index dab0f900749..122b5b7fe2c 100644 --- a/packages/blockchain-wallet-v4-frontend/src/scenes/Transactions/Ether/Content/selectors.js +++ b/packages/blockchain-wallet-v4-frontend/src/scenes/Transactions/Ether/Content/selectors.js @@ -1,6 +1,7 @@ -import { formValueSelector } from 'redux-form' +import { createSelector } from 'reselect' import { selectors } from 'data' -import { curry, propSatisfies, toUpper, prop, allPass, anyPass, compose, contains, map, filter, length, lift } from 'ramda' +import { curry, isEmpty, propSatisfies, toUpper, prop, allPass, anyPass, compose, contains, map, filter } from 'ramda' +import { Remote } from 'blockchain-wallet-v4/src' const filterTransactions = curry((status, criteria, transactions) => { const isOfType = curry((filter, tx) => propSatisfies(x => filter === '' || toUpper(x) === toUpper(filter), 'type', tx)) @@ -10,13 +11,22 @@ const filterTransactions = curry((status, criteria, transactions) => { return filter(fullPredicate, transactions) }) -export const getData = (state) => { - const status = formValueSelector('etherTransaction')(state, 'status') || '' - const search = formValueSelector('etherTransaction')(state, 'search') || '' - const transactions = selectors.core.common.ethereum.getTransactions(state) - const filtered = transactions.map(filterTransactions(status, search)) - const total = transactions.map(length) - return lift((transactions, total) => ({ transactions, total, search: search.length > 0 }))(filtered, total) -} +export const getData = createSelector( + [ + selectors.form.getFormValues('ethTransactions'), + selectors.core.common.ethereum.getTransactions + ], + (formValues, list) => { + const search = prop('search', formValues) || '' + const status = prop('status', formValues) || '' + const filteredList = list.map(isEmpty).getOrElse(false) + ? Remote.of([]) + : list.map(filterTransactions(status, search)) -export const getContext = selectors.core.kvStore.ethereum.getContext + return { + list: filteredList, + search: search.length > 0, + empty: filteredList.map(isEmpty).getOrElse(false) + } + } +) diff --git a/packages/blockchain-wallet-v4-frontend/src/scenes/Transactions/Ether/Content/template.js b/packages/blockchain-wallet-v4-frontend/src/scenes/Transactions/Ether/Content/template.js new file mode 100644 index 00000000000..9ba35aeae9d --- /dev/null +++ b/packages/blockchain-wallet-v4-frontend/src/scenes/Transactions/Ether/Content/template.js @@ -0,0 +1,26 @@ +import React from 'react' +import styled from 'styled-components' +import EmptyTx from 'components/EmptyTx' +import Empty from './Empty' +import List from './List' + +const Wrapper = styled.div` + display: flex; + flex-direction: column; + justify-content: flex-start; + align-items: center; + width: 100%; +` + +const Success = props => { + return ( + + {props.empty + ? props.search ? : + : + } + + ) +} + +export default Success diff --git a/packages/blockchain-wallet-v4-frontend/src/scenes/Transactions/Ether/Content/template.success.js b/packages/blockchain-wallet-v4-frontend/src/scenes/Transactions/Ether/Content/template.success.js deleted file mode 100644 index 49640fcd37a..00000000000 --- a/packages/blockchain-wallet-v4-frontend/src/scenes/Transactions/Ether/Content/template.success.js +++ /dev/null @@ -1,26 +0,0 @@ -import React from 'react' -import PropTypes from 'prop-types' -import styled from 'styled-components' -import EmptyTx from 'components/EmptyTx' -import Empty from './Empty' -import List from './List' - -const Wrapper = styled.div` - display: flex; -` - -const Success = props => ( - - {props.transactions.length === 0 - ? props.search ? : - : - } - -) - -Success.propTypes = { - isEmpty: PropTypes.bool.isRequired, - transactions: PropTypes.array.isRequired -} - -export default Success diff --git a/packages/blockchain-wallet-v4-frontend/src/scenes/Transactions/Ether/Menu/template.js b/packages/blockchain-wallet-v4-frontend/src/scenes/Transactions/Ether/Menu/template.js index ea9d02502f0..6eecebdba8d 100644 --- a/packages/blockchain-wallet-v4-frontend/src/scenes/Transactions/Ether/Menu/template.js +++ b/packages/blockchain-wallet-v4-frontend/src/scenes/Transactions/Ether/Menu/template.js @@ -101,4 +101,4 @@ const Menu = (props) => { ) } -export default reduxForm({ form: 'etherTransaction' })(Menu) +export default reduxForm({ form: 'ethTransactions' })(Menu)