Browse Source

Prevent sync of currencies that are in status KO

gre-patch-1
meriadec 6 years ago
parent
commit
ddfdef709d
No known key found for this signature in database GPG Key ID: 1D2FC2305E2CB399
  1. 9
      src/bridge/BridgeSyncContext.js
  2. 58
      src/components/CurrenciesStatusBanner.js
  3. 59
      src/reducers/currenciesStatus.js
  4. 4
      src/reducers/index.js

9
src/bridge/BridgeSyncContext.js

@ -16,7 +16,9 @@ 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 { SYNC_MAX_CONCURRENT, SYNC_TIMEOUT } from 'config/constants'
import type { CurrencyStatus } from 'reducers/currenciesStatus'
import { getBridgeForCurrency } from '.'
type BridgeSyncProviderProps = {
@ -29,6 +31,7 @@ type BridgeSyncProviderOwnProps = BridgeSyncProviderProps & {
isUpToDate: boolean,
updateAccountWithUpdater: (string, (Account) => Account) => void,
setAccountSyncState: (string, AsyncState) => *,
currenciesStatus: CurrencyStatus[],
}
type AsyncState = {
@ -48,6 +51,7 @@ export type Sync = (action: BehaviorAction) => void
const BridgeSyncContext = React.createContext((_: BehaviorAction) => {})
const mapStateToProps = createStructuredSelector({
currenciesStatus: currenciesStatusSelector,
accounts: accountsSelector,
bridgeSync: bridgeSyncSelector,
isUpToDate: isUpToDateSelector,
@ -73,6 +77,11 @@ class Provider extends Component<BridgeSyncProviderOwnProps, Sync> {
return
}
if (getIsCurrencyDown(this.props.currenciesStatus, account.currency)) {
next()
return
}
const bridge = getBridgeForCurrency(account.currency)
this.props.setAccountSyncState(accountId, { pending: true, error: null })

58
src/components/CurrenciesStatusBanner.js

@ -8,40 +8,33 @@ import { createStructuredSelector } from 'reselect'
import styled from 'styled-components'
import type { Currency } from '@ledgerhq/live-common/lib/types'
import logger from 'logger'
import { colors } from 'styles/theme'
import { openURL } from 'helpers/linking'
import { urls } from 'config/urls'
import { CHECK_CUR_STATUS_INTERVAL } from 'config/constants'
import network from 'api/network'
import IconCross from 'icons/Cross'
import IconTriangleWarning from 'icons/TriangleWarning'
import IconChevronRight from 'icons/ChevronRight'
import { dismissedBannersSelector } from 'reducers/settings'
import { currenciesStatusSelector, fetchCurrenciesStatus } from 'reducers/currenciesStatus'
import { currenciesSelector } from 'reducers/accounts'
import { dismissBanner } from 'actions/settings'
import type { CurrencyStatus } from 'reducers/currenciesStatus'
import Box from 'components/base/Box'
type ResultItem = {
id: string,
status: string,
message: string,
link: string,
nonce: number,
}
const mapStateToProps = createStructuredSelector({
dismissedBanners: dismissedBannersSelector,
accountsCurrencies: currenciesSelector,
currenciesStatus: currenciesStatusSelector,
})
const mapDispatchToProps = {
dismissBanner,
fetchCurrenciesStatus,
}
const getItemKey = (item: ResultItem) => `${item.id}_${item.nonce}`
const getItemKey = (item: CurrencyStatus) => `${item.id}_${item.nonce}`
const CloseIconContainer = styled.div`
position: absolute;
@ -69,18 +62,12 @@ type Props = {
accountsCurrencies: Currency[],
dismissedBanners: string[],
dismissBanner: string => void,
currenciesStatus: CurrencyStatus[],
fetchCurrenciesStatus: () => Promise<void>,
t: *,
}
type State = {
result: ResultItem[],
}
class CurrenciesStatusBanner extends PureComponent<Props, State> {
state = {
result: [],
}
class CurrenciesStatusBanner extends PureComponent<Props> {
componentDidMount() {
this.pollStatus()
}
@ -95,32 +82,17 @@ class CurrenciesStatusBanner extends PureComponent<Props, State> {
unmounted = false
timeout: *
pollStatus = () => {
this.fetchStatus()
pollStatus = async () => {
await this.props.fetchCurrenciesStatus()
if (this.unmounted) return
this.timeout = setTimeout(this.pollStatus, CHECK_CUR_STATUS_INTERVAL)
}
fetchStatus = async () => {
try {
const baseUrl = process.env.LL_STATUS_API || urls.currenciesStatus
const { data } = await network({
method: 'GET',
url: `${baseUrl}/currencies-status`,
})
if (this.unmounted) return
this.setState({ result: data })
} catch (err) {
logger.error(err)
}
}
dismiss = item => this.props.dismissBanner(getItemKey(item))
render() {
const { dismissedBanners, accountsCurrencies, t } = this.props
const { result } = this.state
if (!result) return null
const filtered = result.filter(
const { dismissedBanners, accountsCurrencies, currenciesStatus, t } = this.props
const filtered = currenciesStatus.filter(
item =>
accountsCurrencies.find(cur => cur.id === item.id) &&
dismissedBanners.indexOf(getItemKey(item)) === -1,
@ -135,8 +107,8 @@ class CurrenciesStatusBanner extends PureComponent<Props, State> {
}
class BannerItem extends PureComponent<{
item: ResultItem,
onItemDismiss: ResultItem => void,
item: CurrencyStatus,
onItemDismiss: CurrencyStatus => void,
t: *,
}> {
onLinkClick = () => openURL(this.props.item.link)

59
src/reducers/currenciesStatus.js

@ -0,0 +1,59 @@
// @flow
import { handleActions, createAction } from 'redux-actions'
import type { Currency } from '@ledgerhq/live-common/lib/types'
import network from 'api/network'
import { urls } from 'config/urls'
import logger from 'logger'
import type { State } from './index'
export type CurrencyStatus = {
id: string, // the currency id
status: 'KO' | 'OK',
message: string,
link: string,
nonce: number,
}
export type CurrenciesStatusState = CurrencyStatus[]
const state: CurrenciesStatusState = []
const handlers = {
CURRENCIES_STATUS_SET: (
state: CurrenciesStatusState,
{ payload }: { payload: CurrenciesStatusState },
) => payload,
}
// Actions
const setCurrenciesStatus = createAction('CURRENCIES_STATUS_SET')
export const fetchCurrenciesStatus = () => async (dispatch: *) => {
try {
const baseUrl = process.env.LL_STATUS_API || urls.currenciesStatus
const { data } = await network({
method: 'GET',
url: `${baseUrl}/currencies-status`,
})
dispatch(setCurrenciesStatus(data))
} catch (err) {
logger.error(err)
}
}
// Selectors
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'
}
// Exporting reducer
export default handleActions(handlers, state)

4
src/reducers/index.js

@ -9,6 +9,7 @@ import type { CounterValuesState } from '@ledgerhq/live-common/lib/countervalues
import CounterValues from 'helpers/countervalues'
import accounts from './accounts'
import application from './application'
import currenciesStatus from './currenciesStatus'
import devices from './devices'
import modals from './modals'
import settings from './settings'
@ -24,11 +25,13 @@ import type { SettingsState } from './settings'
import type { UpdateState } from './update'
import type { OnboardingState } from './onboarding'
import type { BridgeSyncState } from './bridgeSync'
import type { CurrenciesStatusState } from './currenciesStatus'
export type State = {
accounts: AccountsState,
application: ApplicationState,
countervalues: CounterValuesState,
currenciesStatus: CurrenciesStatusState,
devices: DevicesState,
modals: ModalsState,
router: LocationShape,
@ -42,6 +45,7 @@ export default combineReducers({
accounts,
application,
countervalues: CounterValues.reducer,
currenciesStatus,
devices,
modals,
router,

Loading…
Cancel
Save