Browse Source

Merge pull request #1649 from gre/coin-disruption-alert

Add disruption alert in Send/Receive/Add Account as well
gre-patch-1
Gaëtan Renaudeau 6 years ago
committed by GitHub
parent
commit
ddecc107c0
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 4
      src/bridge/BridgeSyncContext.js
  2. 69
      src/components/CurrencyDownStatusAlert.js
  3. 8
      src/components/modals/AddAccounts/steps/01-step-choose-currency.js
  4. 3
      src/components/modals/Receive/steps/01-step-account.js
  5. 16
      src/components/modals/Receive/steps/02-step-connect-device.js
  6. 3
      src/components/modals/Send/steps/01-step-amount.js
  7. 4
      src/reducers/accounts.js
  8. 20
      src/reducers/currenciesStatus.js

4
src/bridge/BridgeSyncContext.js

@ -16,7 +16,7 @@ import { setAccountSyncState } from 'actions/bridgeSync'
import { bridgeSyncSelector, syncStateLocalSelector } from 'reducers/bridgeSync'
import type { BridgeSyncState } from 'reducers/bridgeSync'
import { accountsSelector, isUpToDateSelector } from 'reducers/accounts'
import { currenciesStatusSelector, getIsCurrencyDown } from 'reducers/currenciesStatus'
import { currenciesStatusSelector, currencyDownStatusLocal } from 'reducers/currenciesStatus'
import { SYNC_MAX_CONCURRENT, SYNC_TIMEOUT } from 'config/constants'
import type { CurrencyStatus } from 'reducers/currenciesStatus'
import { getBridgeForCurrency } from '.'
@ -77,7 +77,7 @@ class Provider extends Component<BridgeSyncProviderOwnProps, Sync> {
return
}
if (getIsCurrencyDown(this.props.currenciesStatus, account.currency)) {
if (currencyDownStatusLocal(this.props.currenciesStatus, account.currency)) {
next()
return
}

69
src/components/CurrencyDownStatusAlert.js

@ -0,0 +1,69 @@
// @flow
import React, { PureComponent } from 'react'
import { translate } from 'react-i18next'
import styled from 'styled-components'
import { connect } from 'react-redux'
import { createStructuredSelector } from 'reselect'
import type { CryptoCurrency } from '@ledgerhq/live-common/lib/types'
import type { CurrencyStatus } from 'reducers/currenciesStatus'
import { currencyDownStatus } from 'reducers/currenciesStatus'
import { openURL } from 'helpers/linking'
import Box from 'components/base/Box'
import IconTriangleWarning from 'icons/TriangleWarning'
import IconExternalLink from 'icons/ExternalLink'
type Props = {
t: *,
status: ?CurrencyStatus,
}
const CurrencyDownBox = styled(Box).attrs({
horizontal: true,
align: 'center',
color: 'white',
borderRadius: 1,
fontSize: 1,
px: 4,
py: 2,
mb: 4,
})`
background-color: ${p => p.theme.colors.alertRed};
`
const Link = styled.span`
margin-left: 5px;
margin-right: 5px;
text-decoration: underline;
cursor: pointer;
`
class CurrencyDownStatusAlert extends PureComponent<Props> {
onClick = () => {
const { status } = this.props
if (status) openURL(status.link)
}
render() {
const { status, t } = this.props
if (!status) return null
return (
<CurrencyDownBox>
<Box mr={2}>
<IconTriangleWarning height={16} width={16} />
</Box>
<Box style={{ display: 'block' }} ff="Open Sans|SemiBold" fontSize={3} horizontal shrink>
{status.message}
<Link onClick={this.onClick}>{t('common.learnMore')}</Link>
<IconExternalLink size={12} />
</Box>
</CurrencyDownBox>
)
}
}
export default connect(
createStructuredSelector({
status: currencyDownStatus,
}),
)(translate()(CurrencyDownStatusAlert))

8
src/components/modals/AddAccounts/steps/01-step-choose-currency.js

@ -5,12 +5,18 @@ import React, { Fragment } from 'react'
import TrackPage from 'analytics/TrackPage'
import SelectCurrency from 'components/SelectCurrency'
import Button from 'components/base/Button'
import CurrencyDownStatusAlert from 'components/CurrencyDownStatusAlert'
import CurrencyBadge from 'components/base/CurrencyBadge'
import type { StepProps } from '../index'
function StepChooseCurrency({ currency, setCurrency }: StepProps) {
return <SelectCurrency autoFocus onChange={setCurrency} value={currency} />
return (
<Fragment>
{currency ? <CurrencyDownStatusAlert currency={currency} /> : null}
<SelectCurrency autoFocus onChange={setCurrency} value={currency} />
</Fragment>
)
}
export function StepChooseCurrencyFooter({ transitionTo, currency, t }: StepProps) {

3
src/components/modals/Receive/steps/01-step-account.js

@ -7,6 +7,7 @@ import Box from 'components/base/Box'
import Label from 'components/base/Label'
import Button from 'components/base/Button'
import SelectAccount from 'components/SelectAccount'
import CurrencyDownStatusAlert from 'components/CurrencyDownStatusAlert'
import type { StepProps } from '../index'
@ -14,6 +15,8 @@ export default function StepAccount({ t, account, onChangeAccount }: StepProps)
return (
<Box flow={1}>
<TrackPage category="Receive Flow" name="Step 1" />
{account ? <CurrencyDownStatusAlert currency={account.currency} /> : null}
<Label>{t('receive.steps.chooseAccount.label')}</Label>
<SelectAccount autoFocus onChange={onChangeAccount} value={account} />
</Box>

16
src/components/modals/Receive/steps/02-step-connect-device.js

@ -1,21 +1,25 @@
// @flow
import React from 'react'
import React, { Fragment } from 'react'
import Box from 'components/base/Box'
import Button from 'components/base/Button'
import EnsureDeviceApp from 'components/EnsureDeviceApp'
import CurrencyDownStatusAlert from 'components/CurrencyDownStatusAlert'
import TrackPage from 'analytics/TrackPage'
import type { StepProps } from '../index'
export default function StepConnectDevice({ account, onChangeAppOpened }: StepProps) {
return (
<EnsureDeviceApp
account={account}
waitBeforeSuccess={200}
onSuccess={() => onChangeAppOpened(true)}
/>
<Fragment>
{account ? <CurrencyDownStatusAlert currency={account.currency} /> : null}
<EnsureDeviceApp
account={account}
waitBeforeSuccess={200}
onSuccess={() => onChangeAppOpened(true)}
/>
</Fragment>
)
}

3
src/components/modals/Send/steps/01-step-amount.js

@ -13,6 +13,7 @@ import Text from 'components/base/Text'
import CounterValue from 'components/CounterValue'
import Spinner from 'components/base/Spinner'
import TrackPage from 'analytics/TrackPage'
import CurrencyDownStatusAlert from 'components/CurrencyDownStatusAlert'
import RecipientField from '../fields/RecipientField'
import AmountField from '../fields/AmountField'
@ -38,6 +39,8 @@ export default ({
return (
<Box flow={4}>
<TrackPage category="Send Flow" name="Step 1" />
{account ? <CurrencyDownStatusAlert currency={account.currency} /> : null}
<Box flow={1}>
<Label>{t('send.steps.amount.selectAccountDebit')}</Label>
<SelectAccount autoFocus={!openedFromAccount} onChange={onChangeAccount} value={account} />

4
src/reducers/accounts.js

@ -6,7 +6,7 @@ import accountModel from 'helpers/accountModel'
import logger from 'logger'
import type { Account, AccountRaw } from '@ledgerhq/live-common/lib/types'
import { OUTDATED_CONSIDERED_DELAY, DEBUG_SYNC } from 'config/constants'
import { currenciesStatusSelector, getIsCurrencyDown } from './currenciesStatus'
import { currenciesStatusSelector, currencyDownStatusLocal } from './currenciesStatus'
export type AccountsState = Account[]
const state: AccountsState = []
@ -65,7 +65,7 @@ export const activeAccountsSelector = createSelector(
accountsSelector,
currenciesStatusSelector,
(accounts, currenciesStatus) =>
accounts.filter(a => !getIsCurrencyDown(currenciesStatus, a.currency)),
accounts.filter(a => !currencyDownStatusLocal(currenciesStatus, a.currency)),
)
export const isUpToDateSelector = createSelector(activeAccountsSelector, accounts =>

20
src/reducers/currenciesStatus.js

@ -1,7 +1,8 @@
// @flow
import { handleActions, createAction } from 'redux-actions'
import type { Currency } from '@ledgerhq/live-common/lib/types'
import { createSelector } from 'reselect'
import type { CryptoCurrency } from '@ledgerhq/live-common/lib/types'
import network from 'api/network'
import { urls } from 'config/urls'
@ -11,7 +12,6 @@ import type { State } from './index'
export type CurrencyStatus = {
id: string, // the currency id
status: 'KO' | 'OK',
message: string,
link: string,
nonce: number,
@ -47,11 +47,17 @@ export const fetchCurrenciesStatus = () => async (dispatch: *) => {
export const currenciesStatusSelector = (state: State) => state.currenciesStatus
// It's not a *real* selector, but it's better than having this logic inside component
export const getIsCurrencyDown = (currenciesStatus: CurrenciesStatusState, currency: Currency) => {
const item = currenciesStatus.find(c => c.id === currency.id)
return !!item && item.status === 'KO'
}
// if there is a status, it means that currency is disrupted, the status is returned.
export const currencyDownStatusLocal = (
currenciesStatus: CurrenciesStatusState,
currency: CryptoCurrency,
): ?CurrencyStatus => currenciesStatus.find(c => c.id === currency.id)
export const currencyDownStatus = createSelector(
currenciesStatusSelector,
(_, { currency }) => currency,
currencyDownStatusLocal,
)
// Exporting reducer

Loading…
Cancel
Save