Skip to content

Commit

Permalink
fix(Partner Labels): refactor
Browse files Browse the repository at this point in the history
  • Loading branch information
Philip Welber committed Jul 1, 2018
1 parent a91a794 commit 1f3c2d4
Show file tree
Hide file tree
Showing 25 changed files with 75 additions and 78 deletions.
Expand Up @@ -2,8 +2,6 @@ import React from 'react'
import PropTypes from 'prop-types'
import { FormattedMessage } from 'react-intl'
import styled from 'styled-components'
import { contains, any } from 'ramda'

import { Banner } from 'blockchain-info-components'

const LabelContainer = styled.div`
Expand All @@ -14,28 +12,14 @@ const PartnerBanner = styled(Banner)`
`

const PartnerLabel = props => {
const { txHash, txType, shiftTrades, buysellTrades, buysellPartner } = props

const shiftMatch = shiftTrades.map(trade => {
if (trade.hashIn === txHash) return 'shift-deposit'
if (trade.hashOut === txHash) return 'shift-receive'
})
const isShift = (match) => match === 'shift-deposit' || match === 'shift-receive'
const { txType, partnerLabel, buysellPartner } = props

const buysellMatch = buysellTrades && buysellTrades.map(trade => {
if (trade.tx_hash === txHash) {
if (txType === 'sent') return 'sold-via'
if (txType === 'received') return 'bought-via'
}
})
const isBuysell = (match) => match === 'sold-via' || match === 'bought-via'

if (any(isShift)(shiftMatch)) {
if (partnerLabel === 'shift') {
return (
<LabelContainer mobileSize='14px' size='16px' weight={500} color={props.type} uppercase>
<PartnerBanner>
{
contains('shift-deposit', shiftMatch)
txType === 'sent'
? <FormattedMessage id='components.txlistitem.partnerlabel.depositedshapeshift' defaultMessage='ShapeShift Deposit' />
: <FormattedMessage id='components.txlistitem.partnerlabel.receivedshapeshift' defaultMessage='Received from ShapeShift' />
}
Expand All @@ -44,16 +28,16 @@ const PartnerLabel = props => {
)
}

if (buysellTrades && any(isBuysell)(buysellMatch)) {
if (partnerLabel === 'buy-sell' && buysellPartner) {
return (
<LabelContainer mobileSize='14px' size='16px' weight={500} color={props.type} uppercase>
<Banner partnerLabel>
<PartnerBanner partnerLabel>
{
contains('sold-via', buysellMatch)
txType === 'sent'
? <FormattedMessage id='components.txlistitem.partnerlabel.soldvia' defaultMessage='Sold via {partner}' values={{ partner: buysellPartner }} />
: <FormattedMessage id='components.txlistitem.partnerlabel.boughtvia' defaultMessage='Bought via {partner}' values={{ partner: buysellPartner }} />
}
</Banner>
</PartnerBanner>
</LabelContainer>
)
}
Expand Down
Expand Up @@ -113,8 +113,7 @@ const dateHelper = (time) => {
}

const TransactionListItem = (props) => {
const { handleCoinToggle, transaction, handleEditDescription, coin, minConfirmations, shiftTrades, buysellTrades, buysellPartner } = props
const hasLabel = prop('length', shiftTrades) || prop('length', buysellTrades)
const { handleCoinToggle, transaction, handleEditDescription, coin, minConfirmations, buysellPartner } = props

return (
<TransactionRowContainer>
Expand All @@ -130,8 +129,8 @@ const TransactionListItem = (props) => {
</BannerWrapper>
)}
{
hasLabel
? <PartnerLabel txHash={transaction.hash} txType={transaction.type} shiftTrades={shiftTrades} buysellTrades={buysellTrades} buysellPartner={buysellPartner} />
prop('partnerLabel', transaction)
? <PartnerLabel txType={prop('type', transaction)} partnerLabel={prop('partnerLabel', transaction)} buysellPartner={buysellPartner} />
: null
}
</StatusColumn>
Expand Down
Expand Up @@ -47,13 +47,9 @@ class SiftScience extends Component {
const helperDomain = path(['domains', 'walletHelper'], walletOptions)
const sfoxSiftScience = path(['platforms', 'web', 'sfox', 'config', 'siftScience'], walletOptions)

let url = `${helperDomain}/wallet-helper/sift-science/#/key/${sfoxSiftScience}/user/${userId.getOrElse()}`
let url = `${helperDomain}/wallet-helper/sift-science/#/key/${sfoxSiftScience}/user/${userId}`
url += tradeId ? `/trade/${tradeId}` : ''

if (!userId.getOrElse(null)) {
return null
}

if (siftScienceEnabled) {
return (
<SiftScienceIframe
Expand All @@ -69,7 +65,7 @@ class SiftScience extends Component {

const mapStateToProps = (state) => ({
walletOptions: path(['walletOptionsPath'], state),
userId: selectors.core.kvStore.buySell.getSfoxUser(state).getOrElse(undefined),
userId: selectors.core.kvStore.buySell.getSfoxUser(state).getOrElse(null),
siftScienceEnabled: path(['sfoxSignup', 'siftScienceEnabled'], state),
trades: selectors.core.data.sfox.getTrades(state).getOrElse([])
})
Expand Down
Expand Up @@ -6,10 +6,10 @@ import Success from './template.success'

class Pages extends React.PureComponent {
render () {
const { data, shiftTrades } = this.props
const { data } = this.props

return data.cata({
Success: (value) => <Success transactions={value} shiftTrades={shiftTrades} />,
Success: (value) => <Success transactions={value} />,
Failure: () => <DataError onClick={() => this.props.onRefresh()} />,
Loading: () => <Loading />,
NotAsked: () => <Loading />
Expand Down
Expand Up @@ -15,7 +15,7 @@ const Wrapper = styled.div`
const Success = props => {
return (
<Wrapper>
{props.transactions.map((transaction, index) => <TransactionListItem key={transaction.hash} transaction={transaction} coin='BCH' minConfirmations={3} shiftTrades={props.shiftTrades} />)}
{props.transactions.map((transaction, index) => <TransactionListItem key={transaction.hash} transaction={transaction} coin='BCH' minConfirmations={3} />)}
</Wrapper>
)
}
Expand Down
Expand Up @@ -22,8 +22,8 @@ class ContentContainer extends React.PureComponent {
}

render () {
const { empty, pages, search, shiftTrades } = this.props
return <Content empty={empty} search={search} pages={pages} onRefresh={this.handleRefresh} shiftTrades={shiftTrades} />
const { empty, pages, search } = this.props
return <Content empty={empty} search={search} pages={pages} onRefresh={this.handleRefresh} />
}
}

Expand Down
Expand Up @@ -13,8 +13,7 @@ const filterTransactions = curry((status, criteria, transactions) => {
export const getData = createSelector(
[
selectors.form.getFormValues('bchTransactions'),
selectors.core.common.bch.getWalletTransactions,
selectors.core.kvStore.shapeShift.getTrades
selectors.core.common.bch.getWalletTransactions
],
(formValues, pages, trades) => {
const empty = (page) => isEmpty(page.data)
Expand All @@ -27,8 +26,7 @@ export const getData = createSelector(
return {
pages: filteredPages,
empty: all(empty)(filteredPages),
search: search.length > 0 || status !== '',
shiftTrades: trades.getOrElse([])
search: search.length > 0 || status !== ''
}
}
)
Expand Up @@ -17,7 +17,7 @@ const Success = props => {
<Wrapper>
{props.empty
? props.search ? <EmptyTx /> : <Empty />
: props.pages.map((value, index) => <Pages key={index} data={value} onRefresh={props.onRefresh} shiftTrades={props.shiftTrades} />)
: props.pages.map((value, index) => <Pages key={index} data={value} onRefresh={props.onRefresh} />)
}
</Wrapper>
)
Expand Down
Expand Up @@ -6,10 +6,10 @@ import Success from './template.success'

class Pages extends React.PureComponent {
render () {
const { data, shiftTrades, buysellTrades, buysellPartner } = this.props
const { data, buysellPartner } = this.props

return data.cata({
Success: (value) => <Success transactions={value} shiftTrades={shiftTrades} buysellTrades={buysellTrades} buysellPartner={buysellPartner} />,
Success: (value) => <Success transactions={value} buysellPartner={buysellPartner} />,
Failure: () => <DataError onClick={() => this.props.onRefresh()} />,
Loading: () => <Loading />,
NotAsked: () => <Loading />
Expand Down
Expand Up @@ -20,8 +20,6 @@ const Success = props => {
transaction={transaction}
coin='BTC'
minConfirmations={3}
shiftTrades={props.shiftTrades}
buysellTrades={props.buysellTrades}
buysellPartner={props.buysellPartner}
/>)}
</Wrapper>
Expand Down
Expand Up @@ -22,9 +22,9 @@ class ContentContainer extends React.PureComponent {
}

render () {
const { empty, pages, search, shiftTrades, buysellTrades, buysellPartner } = this.props
const { empty, pages, search, buysellPartner } = this.props

return <Content empty={empty} search={search} pages={pages} onRefresh={this.handleRefresh} shiftTrades={shiftTrades} buysellTrades={buysellTrades} buysellPartner={buysellPartner} />
return <Content empty={empty} search={search} pages={pages} onRefresh={this.handleRefresh} buysellPartner={buysellPartner} />
}
}

Expand Down
Expand Up @@ -15,12 +15,9 @@ export const getData = createSelector(
[
selectors.form.getFormValues('btcTransactions'),
selectors.core.common.btc.getWalletTransactions,
selectors.core.kvStore.shapeShift.getTrades,
selectors.core.kvStore.buySell.getSfoxTrades,
selectors.core.kvStore.buySell.getCoinifyTrades,
selectors.core.kvStore.buySell.getMetadata
],
(formValues, pages, trades, sfoxTrades, coinifyTrades, buysellMetadata) => {
(formValues, pages, buysellMetadata) => {
const empty = (page) => isEmpty(page.data)
const search = propOr('', 'search', formValues)
const status = propOr('', 'status', formValues)
Expand All @@ -33,8 +30,6 @@ export const getData = createSelector(
pages: filteredPages,
empty: all(empty)(filteredPages),
search: search.length > 0 || status !== '',
shiftTrades: trades.getOrElse([]),
buysellTrades: sfoxTrades.getOrElse([]).concat(coinifyTrades.getOrElse([])),
buysellPartner: hasAccount(partnerData)
}
}
Expand Down
Expand Up @@ -17,7 +17,7 @@ const Success = props => {
<Wrapper>
{props.empty
? props.search ? <EmptyTx /> : <Empty />
: props.pages.map((value, index) => <Pages key={index} data={value} onRefresh={props.onRefresh} shiftTrades={props.shiftTrades} buysellTrades={props.buysellTrades} buysellPartner={props.buysellPartner} />)
: props.pages.map((value, index) => <Pages key={index} data={value} onRefresh={props.onRefresh} buysellPartner={props.buysellPartner} />)
}
</Wrapper>
)
Expand Down
Expand Up @@ -6,10 +6,10 @@ import Success from './template.success'

class Pages extends React.PureComponent {
render () {
const { data, shiftTrades } = this.props
const { data } = this.props

return data.cata({
Success: (value) => <Success transactions={value} shiftTrades={shiftTrades} />,
Success: (value) => <Success transactions={value} />,
Failure: () => <DataError onClick={() => this.props.onRefresh()} />,
Loading: () => <Loading />,
NotAsked: () => <Loading />
Expand Down
Expand Up @@ -15,7 +15,7 @@ const Wrapper = styled.div`
const Success = props => {
return (
<Wrapper>
{props.transactions.map((transaction, index) => <TransactionListItem key={transaction.hash} transaction={transaction} coin='ETH' minConfirmations={12} shiftTrades={props.shiftTrades} />)}
{props.transactions.map((transaction, index) => <TransactionListItem key={transaction.hash} transaction={transaction} coin='ETH' minConfirmations={12} />)}
</Wrapper>
)
}
Expand Down
Expand Up @@ -22,8 +22,8 @@ class ContentContainer extends React.PureComponent {
}

render () {
const { empty, pages, search, shiftTrades } = this.props
return <Content empty={empty} search={search} pages={pages} onRefresh={this.handleRefresh} shiftTrades={shiftTrades} />
const { empty, pages, search } = this.props
return <Content empty={empty} search={search} pages={pages} onRefresh={this.handleRefresh} />
}
}

Expand Down
Expand Up @@ -13,10 +13,9 @@ const filterTransactions = curry((status, criteria, transactions) => {
export const getData = createSelector(
[
selectors.form.getFormValues('ethTransactions'),
selectors.core.common.eth.getWalletTransactions,
selectors.core.kvStore.shapeShift.getTrades
selectors.core.common.eth.getWalletTransactions
],
(formValues, pages, trades) => {
(formValues, pages) => {
const empty = (page) => isEmpty(page.data)
const search = propOr('', 'search', formValues)
const status = propOr('', 'status', formValues)
Expand All @@ -27,8 +26,7 @@ export const getData = createSelector(
return {
pages: filteredPages,
empty: all(empty)(filteredPages),
search: search.length > 0 || status !== '',
shiftTrades: trades.getOrElse([])
search: search.length > 0 || status !== ''
}
}
)
Expand Up @@ -17,7 +17,7 @@ const Success = props => {
<Wrapper>
{props.empty
? props.search ? <EmptyTx /> : <Empty />
: props.pages.map((value, index) => <Pages key={index} data={value} onRefresh={props.onRefresh} shiftTrades={props.shiftTrades} />)
: props.pages.map((value, index) => <Pages key={index} data={value} onRefresh={props.onRefresh} />)
}
</Wrapper>
)
Expand Down
Expand Up @@ -7,6 +7,7 @@ import Remote from '../../../remote'
import { getAccountsList, getBchTxNote } from '../../kvStore/bch/selectors.js'
import { toCashAddr } from '../../../utils/bch'
import { isValidBitcoinAddress } from '../../../utils/bitcoin'
import { getShapeshiftTxHashMatch } from '../../kvStore/shapeShift/selectors'

const mTransformTx = transactions.bitcoin.transformTx

Expand Down Expand Up @@ -114,10 +115,11 @@ export const getWalletTransactions = state => {
// [Remote([tx])] == [Page] == Pages
const getDescription = (hash) => getBchTxNote(state, hash).getOrElse('')
const pages = getTransactions(state)
const getPartnerLabel = hash => getShapeshiftTxHashMatch(state, hash)
// mTransformTx :: wallet -> blockHeight -> Tx
// ProcessPage :: wallet -> blockHeight -> [Tx] -> [Tx]
const ProcessTxs = (wallet, block, txList) =>
map(mTransformTx.bind(undefined, wallet, block, getDescription, undefined), txList)
map(mTransformTx.bind(undefined, wallet, block, getDescription, getPartnerLabel), txList)
// ProcessRemotePage :: Page -> Page
const ProcessPage = lift(ProcessTxs)(walletR, blockHeightR)
const txs = map(ProcessPage, pages)
Expand Down
13 changes: 8 additions & 5 deletions packages/blockchain-wallet-v4/src/redux/common/btc/selectors.js
@@ -1,13 +1,14 @@
import { Wallet, HDWallet, HDAccountList, HDAccount, TXNotes } from '../../../types'
import { keys, compose, assoc, isNil, map, max, path, prop, curry, split, values, sequence, lift } from 'ramda'
import memoize from 'fast-memoize'
import { getAddresses, getChangeIndex, getReceiveIndex, getHeight, getTransactions } from '../../data/bitcoin/selectors.js'
import { getAddressLabel, getMetadata } from '../../kvStore/btc/selectors'
import { getAddressLabel } from '../../kvStore/btc/selectors'
import { getBuySellTxHashMatch } from '../../kvStore/buySell/selectors'
import { getShapeshiftTxHashMatch } from '../../kvStore/shapeShift/selectors'
import * as transactions from '../../../transactions'
import * as walletSelectors from '../../wallet/selectors'
import Remote from '../../../remote'

const mTransformTx = memoize(transactions.bitcoin.transformTx)
const mTransformTx = transactions.bitcoin.transformTx

const _getAccounts = selector => state => {
const balancesR = getAddresses(state)
Expand Down Expand Up @@ -113,12 +114,14 @@ export const getWalletTransactions = state => {
// [Remote([tx])] == [Page] == Pages
const getDescription = (hash, to) => TXNotes.selectNote(hash, Wallet.selectTxNotes(wallet)) || getAddressLabel(to, state).getOrElse('')

const getPartnerLabel = hash => getShapeshiftTxHashMatch(state, hash) || getBuySellTxHashMatch(state, hash)

const pages = getTransactions(state)
const metadata = getMetadata(state)

// mTransformTx :: wallet -> blockHeight -> Tx
// ProcessPage :: wallet -> blockHeight -> [Tx] -> [Tx]
const ProcessTxs = (wallet, block, txList) =>
map(mTransformTx.bind(undefined, wallet, block, getDescription, metadata), txList)
map(mTransformTx.bind(undefined, wallet, block, getDescription, getPartnerLabel), txList)
// ProcessRemotePage :: Page -> Page
const ProcessPage = lift(ProcessTxs)(walletR, blockHeightR)
return map(ProcessPage, pages)
Expand Down
Expand Up @@ -2,6 +2,7 @@ import { lift, map, path, prop } from 'ramda'
import { getAddresses, getTransactions, getHeight } from '../../data/ethereum/selectors.js'
import { getAccounts } from '../../kvStore/ethereum/selectors.js'
import * as transactions from '../../../transactions'
import { getShapeshiftTxHashMatch } from '../../kvStore/shapeShift/selectors'

export const getAccountBalances = (state) => {
const digest = (addresses, account) => ({
Expand Down Expand Up @@ -30,8 +31,9 @@ export const getWalletTransactions = (state) => {
const blockHeightR = getHeight(state)
const addressesR = accountsR.map(map(prop('addr')))
const pages = getTransactions(state)
const getPartnerLabel = hash => getShapeshiftTxHashMatch(state, hash)
const ProcessTxs = (addresses, blockHeight, txList) => {
return map(mTransformTx(addresses, blockHeight, state), txList)
return map(mTransformTx(addresses, blockHeight, state, getPartnerLabel), txList)
}
const ProcessPage = lift(ProcessTxs)(addressesR, blockHeightR)
return map(ProcessPage, pages)
Expand Down
@@ -1,4 +1,4 @@
import { path } from 'ramda'
import { path, concat, contains } from 'ramda'
import { BUYSELL } from '../config'
import { kvStorePath } from '../../paths'

Expand All @@ -9,3 +9,10 @@ export const getSfoxTrades = state => getMetadata(state).map(path(['value', 'sfo
export const getSfoxUser = state => getMetadata(state).map(path(['value', 'sfox', 'user']))

export const getCoinifyTrades = state => getMetadata(state).map(path(['value', 'coinify', 'trades']))

export const getBuySellTxHashMatch = (state, hash) => getMetadata(state).map(data => {
const allTrades = concat(getSfoxTrades(state).getOrElse([]), getCoinifyTrades(state).getOrElse([]))
const tradeHashes = allTrades.map(t => t.tx_hash)
const shouldHaveLabel = contains(hash, tradeHashes)
return shouldHaveLabel && 'buy-sell'
}).getOrElse(false)

0 comments on commit 1f3c2d4

Please sign in to comment.