Browse Source

Merge branch 'master' into getAddressForCurrency

master
Gaëtan Renaudeau 7 years ago
committed by GitHub
parent
commit
21de772b14
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 2
      src/bridge/BridgeSyncContext.js
  2. 21
      src/components/IsUnlocked.js
  3. 18
      src/components/modals/AddAccount/index.js
  4. 1
      src/config/constants.js
  5. 2
      src/internals/manager/constants.js
  6. 7
      src/middlewares/db.js
  7. 33
      src/reducers/settings.js
  8. 104
      src/renderer/events.js

2
src/bridge/BridgeSyncContext.js

@ -157,6 +157,8 @@ class Provider extends Component<BridgeSyncProviderOwnProps, BridgeSync> {
setTimeout(syncLoop, 2 * 1000)
}
// TODO we might want to call sync straight away when new accounts got added (it will happen every 10s anyway)
api: BridgeSync
render() {

21
src/components/IsUnlocked.js

@ -6,7 +6,6 @@ import { connect } from 'react-redux'
import { compose } from 'redux'
import styled from 'styled-components'
import { translate } from 'react-i18next'
import type { Account } from '@ledgerhq/live-common/lib/types'
import type { Settings, T } from 'types/common'
import IconLockScreen from 'icons/LockScreen'
@ -15,11 +14,9 @@ import { ErrorMessageInput } from 'components/base/Input'
import get from 'lodash/get'
import { startSyncAccounts, stopSyncAccounts } from 'renderer/events'
import { setEncryptionKey } from 'helpers/db'
import { fetchAccounts } from 'actions/accounts'
import { getAccounts } from 'reducers/accounts'
import { isLocked, unlock } from 'reducers/application'
import Box from 'components/base/Box'
@ -30,7 +27,6 @@ type InputValue = {
}
type Props = {
accounts: Account[],
children: any,
fetchAccounts: Function,
isLocked: boolean,
@ -44,7 +40,6 @@ type State = {
}
const mapStateToProps = state => ({
accounts: getAccounts(state),
isLocked: isLocked(state),
settings: state.settings,
})
@ -84,22 +79,6 @@ class IsUnlocked extends Component<Props, State> {
...defaultState,
}
componentWillMount() {
if (this.props.isLocked) {
stopSyncAccounts()
}
}
componentWillReceiveProps(nextProps) {
if (this.props.isLocked && !nextProps.isLocked) {
startSyncAccounts(nextProps.accounts)
}
if (!this.props.isLocked && nextProps.isLocked) {
stopSyncAccounts()
}
}
shouldComponentUpdate(nextProps) {
if (nextProps.isLocked) {
return true

18
src/components/modals/AddAccount/index.js

@ -22,6 +22,7 @@ import Button from 'components/base/Button'
import Modal, { ModalContent, ModalTitle, ModalFooter, ModalBody } from 'components/base/Modal'
import StepConnectDevice from 'components/modals/StepConnectDevice'
import { getBridgeForCurrency } from 'bridge'
import CounterValues from 'helpers/countervalues'
import StepCurrency from './01-step-currency'
import StepImport from './03-step-import'
@ -53,6 +54,7 @@ type Props = {
closeModal: Function,
t: T,
updateAccount: Function,
counterValuesPolling: *,
}
type State = {
@ -164,6 +166,8 @@ class AddAccountModal extends PureComponent<Props, State> {
selectedAccounts.forEach(a => updateAccount({ ...a, archived: false }))
this.setState({ selectedAccounts: [] })
closeModal(MODAL_ADD_ACCOUNT)
this.props.counterValuesPolling.poll()
this.props.counterValuesPolling.flush()
}
handleNextStep = () => {
@ -288,4 +292,16 @@ class AddAccountModal extends PureComponent<Props, State> {
}
}
export default compose(connect(mapStateToProps, mapDispatchToProps), translate())(AddAccountModal)
// FIXME This is kinda ugly architecture right now.
// I think we should delegate more work to individual steps
// e.g. each step is responsible to connect to redux, not at top level.
const AddAccountModalAndCounterValues = props => (
<CounterValues.PollingConsumer>
{cvPolling => <AddAccountModal counterValuesPolling={cvPolling} {...props} />}
</CounterValues.PollingConsumer>
)
export default compose(connect(mapStateToProps, mapDispatchToProps), translate())(
AddAccountModalAndCounterValues,
)

1
src/config/constants.js

@ -1,5 +1,4 @@
export const CHECK_UPDATE_DELAY = 5e3
export const SYNC_ACCOUNT_DELAY = 3e3
export const MODAL_ADD_ACCOUNT = 'MODAL_ADD_ACCOUNT'
export const MODAL_OPERATION_DETAILS = 'MODAL_OPERATION_DETAILS'

2
src/internals/manager/constants.js

@ -1,6 +1,6 @@
// Socket endpoint
export const BASE_SOCKET_URL = 'ws://api.ledgerwallet.com/update/install'
export const BASE_SOCKET_URL = 'ws://api.ledgerwallet.com/update'
// If you want to test locally with https://github.com/LedgerHQ/ledger-update-python-api
// export const BASE_SOCKET_URL = 'ws://localhost:3001/update'

7
src/middlewares/db.js

@ -3,7 +3,7 @@
import db from 'helpers/db'
import { getAccounts } from 'reducers/accounts'
import { settingsExportSelector } from 'reducers/settings'
import { settingsExportSelector, areSettingsLoaded } from 'reducers/settings'
import CounterValues from 'helpers/countervalues'
export default store => next => action => {
@ -11,8 +11,8 @@ export default store => next => action => {
const [, type] = action.type.split(':')
store.dispatch({ type, payload: action.payload })
const state = store.getState()
db.set('settings', settingsExportSelector(state))
db.set('accounts', getAccounts(state))
// ^ TODO ultimately we'll do same for accounts to drop DB: pattern
} else {
const oldState = store.getState()
const res = next(action)
@ -20,6 +20,9 @@ export default store => next => action => {
if (oldState.countervalues !== newState.countervalues) {
db.set('countervalues', CounterValues.exportSelector(newState))
}
if (areSettingsLoaded(newState) && oldState.settings !== newState.settings) {
db.set('settings', settingsExportSelector(newState))
}
return res
}
}

33
src/reducers/settings.js

@ -14,6 +14,7 @@ import type { Settings, CurrencySettings } from 'types/common'
import type { State } from 'reducers'
export type SettingsState = {
loaded: boolean, // is the settings loaded from db (it not we don't save them)
hasCompletedOnboarding: boolean,
counterValue: string,
language: string,
@ -35,21 +36,6 @@ const localeSplit = window.navigator.language.split('-')
const language = (localeSplit[0] || 'en').toLowerCase()
const region = (localeSplit[1] || 'US').toUpperCase()
const defaultState: SettingsState = {
hasCompletedOnboarding: false,
counterValue: 'USD',
language,
orderAccounts: 'balance|asc',
password: {
isEnabled: false,
value: '',
},
marketIndicator: 'western',
currenciesSettings: {},
region,
developerMode: false,
}
const CURRENCY_DEFAULTS_SETTINGS: CurrencySettings = {
confirmationsToSpend: 10,
minConfirmationsToSpend: 10, // FIXME DROP
@ -65,7 +51,19 @@ const CURRENCY_DEFAULTS_SETTINGS: CurrencySettings = {
}
const state: SettingsState = {
...defaultState,
hasCompletedOnboarding: false,
counterValue: 'USD',
language,
orderAccounts: 'balance|asc',
password: {
isEnabled: false,
value: '',
},
marketIndicator: 'western',
currenciesSettings: {},
region,
developerMode: false,
loaded: false,
}
function asCryptoCurrency(c: Currency): ?CryptoCurrency {
@ -107,6 +105,7 @@ const handlers: Object = {
FETCH_SETTINGS: (state: SettingsState, { payload: settings }: { payload: Settings }) => ({
...state,
...settings,
loaded: true,
}),
}
@ -144,6 +143,8 @@ export const localeSelector = (state: State) => {
export const getOrderAccounts = (state: State) => state.settings.orderAccounts
export const areSettingsLoaded = (state: State) => state.settings.loaded
export const currencySettingsSelector = (
state: State,
currency: CryptoCurrency,

104
src/renderer/events.js

@ -5,15 +5,11 @@
import { ipcRenderer } from 'electron'
import objectPath from 'object-path'
import debug from 'debug'
import type { Account } from '@ledgerhq/live-common/lib/types'
import { CHECK_UPDATE_DELAY, SYNC_ACCOUNT_DELAY } from 'config/constants'
import { CHECK_UPDATE_DELAY } from 'config/constants'
import { getAccounts, getAccountById } from 'reducers/accounts'
import { isLocked } from 'reducers/application'
import { setUpdateStatus } from 'reducers/update'
import { updateAccount } from 'actions/accounts'
import { addDevice, removeDevice } from 'actions/devices'
import i18n from 'renderer/i18n/electron'
@ -24,16 +20,11 @@ const d = {
update: debug('lwd:update'),
}
const { DISABLED_SYNC, DISABLED_AUTO_SYNC } = process.env
type MsgPayload = {
type: string,
data: any,
}
let syncAccountsInProgress = false
let syncAccountsTimeout
export function sendEvent(channel: string, msgType: string, data: any) {
ipcRenderer.send(channel, {
type: msgType,
@ -48,68 +39,12 @@ export function sendSyncEvent(channel: string, msgType: string, data: any): any
})
}
export default ({ store, locked }: { store: Object, locked: boolean }) => {
export default ({ store }: { store: Object, locked: boolean }) => {
const handlers = {
dispatch: ({ type, payload }) => store.dispatch({ type, payload }),
application: {
changeLanguage: lang => i18n.changeLanguage(lang),
},
account: {
sync: {
success: account => {
if (syncAccountsInProgress) {
const state = store.getState()
const existingAccount = getAccountById(state, account.id)
if (!existingAccount) {
return
}
const { name, balance, balanceByDay, operations } = existingAccount
if (account.operations.length > 0) {
d.sync(`Update account - ${name}`)
const updatedAccount = {
...account,
balance: balance + account.balance,
balanceByDay: Object.keys(balanceByDay).reduce((result, k) => {
result[k] = balanceByDay[k] + (account.balanceByDay[k] || 0)
return result
}, {}),
index: account.index || existingAccount.index,
operations: [...operations, ...account.operations],
}
store.dispatch(updateAccount(updatedAccount))
}
}
},
},
},
accounts: {
sync: {
start: () => {
if (!syncAccountsInProgress) {
const state = store.getState()
const accounts = getAccounts(state)
const locked = isLocked(state)
if (!locked && !DISABLED_SYNC) {
startSyncAccounts(accounts)
}
}
},
stop: stopSyncAccounts,
success: () => {
if (syncAccountsInProgress && !DISABLED_AUTO_SYNC) {
d.sync('Sync accounts - success')
syncAccountsTimeout = setTimeout(() => {
const accounts = getAccounts(store.getState())
startSyncAccounts(accounts)
}, SYNC_ACCOUNT_DELAY)
}
},
},
},
device: {
add: device => {
d.device('Device - add')
@ -145,47 +80,12 @@ export default ({ store, locked }: { store: Object, locked: boolean }) => {
// Start detection when we plug/unplug devices
sendEvent('devices', 'listen')
const state = store.getState()
if (!locked) {
const accounts = getAccounts(state)
// Start accounts sync only if we have accounts
if (accounts.length > 0 && !DISABLED_SYNC) {
startSyncAccounts(accounts)
}
}
if (__PROD__) {
// Start check of eventual updates
checkUpdates()
}
}
export function startSyncAccounts(accounts: Account[]) {
d.sync('Sync accounts - start')
syncAccountsInProgress = true
sendEvent('accounts', 'sync', {
accounts: accounts.map(account => {
const { id, currency, walletPath, addresses, index, operations } = account
return {
id,
currencyId: currency.id,
allAddresses: addresses,
currentIndex: index,
walletPath,
operations,
}
}),
})
}
export function stopSyncAccounts() {
d.sync('Sync accounts - stop')
syncAccountsInProgress = false
clearTimeout(syncAccountsTimeout)
}
export function checkUpdates() {
d.update('Update - check')
setTimeout(() => sendEvent('msg', 'updater.init'), CHECK_UPDATE_DELAY)

Loading…
Cancel
Save