Browse Source

Merge pull request #153 from loeck/master

Flat AccountData, create serialize/deserialize
master
Meriadec Pillet 7 years ago
committed by GitHub
parent
commit
d95346df94
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 3
      .eslintrc
  2. 5
      src/actions/accounts.js
  3. 61
      src/components/AccountPage.js
  4. 16
      src/components/DashboardPage/AccountCard.js
  5. 4
      src/components/DashboardPage/index.js
  6. 6
      src/components/SelectAccount/index.js
  7. 15
      src/components/SelectAccount/stories.js
  8. 2
      src/components/SideBar/index.js
  9. 41
      src/components/TransactionsList/index.js
  10. 6
      src/components/TransactionsList/stories.js
  11. 6
      src/components/modals/AddAccount/index.js
  12. 31
      src/components/modals/Receive.js
  13. 2
      src/components/modals/SettingsAccount.js
  14. 11
      src/helpers/btc.js
  15. 88
      src/helpers/db.js
  16. 4
      src/middlewares/db.js
  17. 63
      src/reducers/accounts.js
  18. 18
      src/renderer/events.js
  19. 24
      src/types/common.js

3
.eslintrc

@ -16,6 +16,7 @@
}, },
"rules": { "rules": {
"camelcase": 0, "camelcase": 0,
"global-require": 0,
"import/no-extraneous-dependencies": 0, "import/no-extraneous-dependencies": 0,
"import/no-named-as-default": 0, "import/no-named-as-default": 0,
"import/prefer-default-export": 0, "import/prefer-default-export": 0,
@ -28,8 +29,8 @@
"no-return-assign": 0, "no-return-assign": 0,
"no-shadow": 0, "no-shadow": 0,
"no-underscore-dangle": 0, "no-underscore-dangle": 0,
"no-use-before-define": 0,
"no-void": 0, "no-void": 0,
"global-require": 0,
"react/forbid-prop-types": 0, "react/forbid-prop-types": 0,
"react/jsx-curly-brace-presence": 0, "react/jsx-curly-brace-presence": 0,
"react/jsx-filename-extension": 0, "react/jsx-filename-extension": 0,

5
src/actions/accounts.js

@ -1,8 +1,9 @@
// @flow // @flow
import db from 'helpers/db'
import sortBy from 'lodash/sortBy' import sortBy from 'lodash/sortBy'
import db from 'helpers/db'
import type { Dispatch } from 'redux' import type { Dispatch } from 'redux'
import type { Account } from 'types/common' import type { Account } from 'types/common'
@ -13,7 +14,7 @@ function sortAccounts(accounts, orderAccounts) {
const accountsSorted = sortBy(accounts, a => { const accountsSorted = sortBy(accounts, a => {
if (order === 'balance') { if (order === 'balance') {
return a.data.balance return a.balance
} }
return a[order] return a[order]

61
src/components/AccountPage.js

@ -1,6 +1,6 @@
// @flow // @flow
import React, { PureComponent, Fragment } from 'react' import React, { PureComponent } from 'react'
import { compose } from 'redux' import { compose } from 'redux'
import { connect } from 'react-redux' import { connect } from 'react-redux'
import { translate } from 'react-i18next' import { translate } from 'react-i18next'
@ -9,11 +9,11 @@ import { Redirect } from 'react-router'
import { MODAL_SEND, MODAL_RECEIVE, MODAL_SETTINGS_ACCOUNT } from 'constants' import { MODAL_SEND, MODAL_RECEIVE, MODAL_SETTINGS_ACCOUNT } from 'constants'
import type { MapStateToProps } from 'react-redux' import type { MapStateToProps } from 'react-redux'
import type { T, Account, AccountData } from 'types/common' import type { T, Account } from 'types/common'
import { formatBTC } from 'helpers/format' import { formatBTC } from 'helpers/format'
import { getAccountById, getAccountData } from 'reducers/accounts' import { getAccountById } from 'reducers/accounts'
import { openModal } from 'reducers/modals' import { openModal } from 'reducers/modals'
import Box, { Card } from 'components/base/Box' import Box, { Card } from 'components/base/Box'
@ -26,29 +26,20 @@ import TransactionsList from 'components/TransactionsList'
type Props = { type Props = {
t: T, t: T,
account: Account, account: Account,
accountData: AccountData,
openModal: Function, openModal: Function,
} }
const mapStateToProps: MapStateToProps<*, *, *> = (state, props) => ({ const mapStateToProps: MapStateToProps<*, *, *> = (state, props) => ({
account: getAccountById(state, props.match.params.id), account: getAccountById(state, props.match.params.id),
accountData: getAccountData(state, props.match.params.id),
}) })
const mapDispatchToProps = { const mapDispatchToProps = {
openModal, openModal,
} }
function enrichTransactionsWithAccount(transactions, account) {
return transactions.map(t => ({
...t,
account,
}))
}
class AccountPage extends PureComponent<Props> { class AccountPage extends PureComponent<Props> {
render() { render() {
const { account, accountData, openModal, t } = this.props const { account, openModal, t } = this.props
// Don't even throw if we jumped in wrong account route // Don't even throw if we jumped in wrong account route
if (!account) { if (!account) {
@ -86,33 +77,27 @@ class AccountPage extends PureComponent<Props> {
/> />
</Box> </Box>
</Box> </Box>
{accountData && ( <Box horizontal flow={3}>
<Fragment> <Box grow>
<Box horizontal flow={3}> <Card
<Box grow> title={t('AccountPage.balance')}
<Card style={{ height: 435 }}
title={t('AccountPage.balance')} alignItems="center"
style={{ height: 435 }} justifyContent="center"
alignItems="center" >
justifyContent="center" <Text fontSize={5}>{formatBTC(account.balance)}</Text>
> </Card>
<Text fontSize={5}>{formatBTC(accountData.balance)}</Text> </Box>
</Card>
</Box>
<Box style={{ width: 300 }}> <Box style={{ width: 300 }}>
<Card title={t('AccountPage.receive')} flow={3}> <Card title={t('AccountPage.receive')} flow={3}>
<ReceiveBox path={accountData.path} address={accountData.address} /> <ReceiveBox path={account.path} address={account.address} />
</Card>
</Box>
</Box>
<Card p={0} px={4} title={t('AccountPage.lastOperations')}>
<TransactionsList
transactions={enrichTransactionsWithAccount(accountData.transactions, account)}
/>
</Card> </Card>
</Fragment> </Box>
)} </Box>
<Card p={0} px={4} title={t('AccountPage.lastOperations')}>
<TransactionsList transactions={account.transactions} />
</Card>
</Box> </Box>
) )
} }

16
src/components/DashboardPage/AccountCard.js

@ -37,15 +37,13 @@ const AccountCard = ({
</Box> </Box>
<Bar size={1} color="argile" /> <Bar size={1} color="argile" />
<Box grow justifyContent="center" color="dark"> <Box grow justifyContent="center" color="dark">
{account.data && ( <FormattedVal
<FormattedVal alwaysShowSign={false}
alwaysShowSign={false} color="dark"
color="dark" unit={account.unit}
unit={account.unit} showCode
showCode val={account.balance}
val={account.data.balance} />
/>
)}
</Box> </Box>
<AreaChart <AreaChart
tiny tiny

4
src/components/DashboardPage/index.js

@ -90,7 +90,7 @@ const mergeFakeDatas = fakeDatas =>
const getAllTransactions = accounts => { const getAllTransactions = accounts => {
const allTransactions = accounts.reduce((result, account) => { const allTransactions = accounts.reduce((result, account) => {
const transactions = get(account, 'data.transactions', []) const transactions = get(account, 'transactions', [])
result = [ result = [
...result, ...result,
@ -103,7 +103,7 @@ const getAllTransactions = accounts => {
return result return result
}, []) }, [])
return sortBy(allTransactions, t => t.received_at) return sortBy(allTransactions, t => t.receivedAt)
.reverse() .reverse()
.slice(0, ALL_TRANSACTIONS_LIMIT) .slice(0, ALL_TRANSACTIONS_LIMIT)
} }

6
src/components/SelectAccount/index.js

@ -7,7 +7,7 @@ import { translate } from 'react-i18next'
import noop from 'lodash/noop' import noop from 'lodash/noop'
import type { MapStateToProps } from 'react-redux' import type { MapStateToProps } from 'react-redux'
import type { T, Account } from 'types/common' import type { T, Accounts, Account } from 'types/common'
import { formatBTC } from 'helpers/format' import { formatBTC } from 'helpers/format'
@ -30,14 +30,14 @@ const renderItem = item => (
</Box> </Box>
<Box> <Box>
<Text color="mouse" fontSize={0}> <Text color="mouse" fontSize={0}>
{formatBTC(item.data.balance)} {formatBTC(item.balance)}
</Text> </Text>
</Box> </Box>
</Box> </Box>
) )
type Props = { type Props = {
accounts: Array<Account>, accounts: Accounts,
onChange?: () => Account | void, onChange?: () => Account | void,
value?: Account | null, value?: Account | null,
t: T, t: T,

15
src/components/SelectAccount/stories.js

@ -12,17 +12,16 @@ const stories = storiesOf('Components/SelectAccount', module)
const accounts = [...Array(20)].map(() => ({ const accounts = [...Array(20)].map(() => ({
id: chance.string(), id: chance.string(),
name: chance.name(), address: chance.string(),
addresses: [],
balance: chance.floating({ min: 0, max: 20 }),
coinType: 0, coinType: 0,
currency: getCurrencyByCoinType(0), currency: getCurrencyByCoinType(0),
index: chance.integer({ min: 0, max: 20 }),
name: chance.name(),
path: '',
transactions: [],
unit: getDefaultUnitByCoinType(0), unit: getDefaultUnitByCoinType(0),
data: {
address: chance.string(),
balance: chance.floating({ min: 0, max: 20 }),
currentIndex: chance.integer({ min: 0, max: 20 }),
path: '',
transactions: [],
},
})) }))
type State = { type State = {

2
src/components/SideBar/index.js

@ -110,7 +110,7 @@ class SideBar extends PureComponent<Props> {
color="warmGrey" color="warmGrey"
unit={account.unit} unit={account.unit}
showCode showCode
val={account.data ? account.data.balance : 0} val={account.balance || 0}
/> />
} }
iconActiveColor={account.currency.color} iconActiveColor={account.currency.color}

41
src/components/TransactionsList/index.js

@ -73,11 +73,13 @@ const Cell = styled(Box).attrs({
const Transaction = ({ const Transaction = ({
onAccountClick, onAccountClick,
tx, tx,
withAccounts,
}: { }: {
onAccountClick?: Function, onAccountClick?: Function,
tx: TransactionType, tx: TransactionType,
withAccounts?: boolean,
}) => { }) => {
const time = moment(tx.received_at) const time = moment(tx.receivedAt)
const Icon = getIconByCoinType(get(tx, 'account.currency.coinType')) const Icon = getIconByCoinType(get(tx, 'account.currency.coinType'))
return ( return (
<TransactionRaw> <TransactionRaw>
@ -87,22 +89,23 @@ const Transaction = ({
<Hour>{time.format('HH:mm')}</Hour> <Hour>{time.format('HH:mm')}</Hour>
</Box> </Box>
</Cell> </Cell>
{tx.account && ( {withAccounts &&
<Cell tx.account && (
size={ACCOUNT_COL_SIZE} <Cell
horizontal size={ACCOUNT_COL_SIZE}
flow={2} horizontal
style={{ cursor: 'pointer' }} flow={2}
onClick={() => onAccountClick && onAccountClick(tx.account)} style={{ cursor: 'pointer' }}
> onClick={() => onAccountClick && onAccountClick(tx.account)}
<Box alignItems="center" justifyContent="center" style={{ color: '#fcb653' }}> >
{Icon && <Icon size={16} />} <Box alignItems="center" justifyContent="center" style={{ color: '#fcb653' }}>
</Box> {Icon && <Icon size={16} />}
<Box ff="Open Sans|SemiBold" fontSize={4} color="dark"> </Box>
{tx.account.name} <Box ff="Open Sans|SemiBold" fontSize={4} color="dark">
</Box> {tx.account.name}
</Cell> </Box>
)} </Cell>
)}
<Cell <Cell
grow grow
shrink shrink
@ -117,7 +120,7 @@ const Transaction = ({
{tx.balance > 0 ? 'From' : 'To'} {tx.balance > 0 ? 'From' : 'To'}
</Box> </Box>
<Box color="dark" ff="Open Sans" fontSize={3}> <Box color="dark" ff="Open Sans" fontSize={3}>
{tx.balance > 0 ? get(tx, 'inputs.0.address') : get(tx, 'outputs.0.address')} {tx.address}
</Box> </Box>
</Cell> </Cell>
<Cell size={AMOUNT_COL_SIZE} justifyContent="flex-end"> <Cell size={AMOUNT_COL_SIZE} justifyContent="flex-end">
@ -135,6 +138,7 @@ const Transaction = ({
Transaction.defaultProps = { Transaction.defaultProps = {
onAccountClick: noop, onAccountClick: noop,
withAccounts: false,
} }
type Props = { type Props = {
@ -181,6 +185,7 @@ class TransactionsList extends Component<Props> {
{transactions.map(t => ( {transactions.map(t => (
<Transaction <Transaction
key={`{${t.hash}-${t.account ? t.account.id : ''}`} key={`{${t.hash}-${t.account ? t.account.id : ''}`}
withAccounts={withAccounts}
onAccountClick={onAccountClick} onAccountClick={onAccountClick}
tx={t} tx={t}
/> />

6
src/components/TransactionsList/stories.js

@ -9,14 +9,16 @@ const stories = storiesOf('Components/TransactionsList', module)
const transactions = [ const transactions = [
{ {
address: '5c6ea1716520c7d6e038d36a3223faced3c',
hash: '5c6ea1716520c7d6e038d36a3223faced3c4b8f7ffb69d9fb5bd527d562fdb62', hash: '5c6ea1716520c7d6e038d36a3223faced3c4b8f7ffb69d9fb5bd527d562fdb62',
balance: 130000000, balance: 130000000,
received_at: '2018-01-09T16:03:52Z', receivedAt: '2018-01-09T16:03:52Z',
}, },
{ {
address: '27416a48caab90fab053b507b8b6b9d4',
hash: '27416a48caab90fab053b507b8b6b9d48fba75421d3bfdbae4b85f64024bc9c4', hash: '27416a48caab90fab053b507b8b6b9d48fba75421d3bfdbae4b85f64024bc9c4',
balance: 65000000, balance: 65000000,
received_at: '2018-01-09T16:02:40Z', receivedAt: '2018-01-09T16:02:40Z',
}, },
] ]

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

@ -260,7 +260,7 @@ class AddAccountModal extends PureComponent<Props, State> {
...defaultState, ...defaultState,
}) })
addAccount = ({ id, name, ...data }) => { addAccount = account => {
const { currency } = this.state const { currency } = this.state
const { addAccount } = this.props const { addAccount } = this.props
@ -269,12 +269,10 @@ class AddAccountModal extends PureComponent<Props, State> {
} }
addAccount({ addAccount({
id, ...account,
name,
coinType: currency.coinType, coinType: currency.coinType,
currency, currency,
unit: getDefaultUnitByCoinType(currency.coinType), unit: getDefaultUnitByCoinType(currency.coinType),
data,
}) })
} }

31
src/components/modals/Receive.js

@ -1,6 +1,6 @@
// @flow // @flow
import React, { PureComponent, Fragment } from 'react' import React, { PureComponent } from 'react'
import { translate } from 'react-i18next' import { translate } from 'react-i18next'
import get from 'lodash/get' import get from 'lodash/get'
@ -62,7 +62,6 @@ class ReceiveModal extends PureComponent<Props, State> {
onHide={this.handleHide} onHide={this.handleHide}
render={({ data, onClose }) => { render={({ data, onClose }) => {
const account = this.getAccount(data) const account = this.getAccount(data)
const accountData = get(account, 'data', {})
return ( return (
<ModalBody onClose={onClose} flow={3}> <ModalBody onClose={onClose} flow={3}>
@ -73,24 +72,16 @@ class ReceiveModal extends PureComponent<Props, State> {
<Label>Account</Label> <Label>Account</Label>
<SelectAccount value={account} onChange={this.handleChangeInput('account')} /> <SelectAccount value={account} onChange={this.handleChangeInput('account')} />
</Box> </Box>
{accountData && ( <Box flow={1}>
<Fragment> <Label>Request amount</Label>
<Box flow={1}> <Input
<Label>Request amount</Label> type="number"
<Input min={0}
type="number" max={account.balance / 1e8}
min={0} onChange={this.handleChangeInput('amount')}
max={accountData.balance / 1e8} />
onChange={this.handleChangeInput('amount')} </Box>
/> <ReceiveBox path={account.path} amount={amount} address={account.address || ''} />
</Box>
<ReceiveBox
path={accountData.path}
amount={amount}
address={accountData.address || ''}
/>
</Fragment>
)}
<Box horizontal justifyContent="center"> <Box horizontal justifyContent="center">
<Button primary onClick={onClose}> <Button primary onClick={onClose}>
Close Close

2
src/components/modals/SettingsAccount.js

@ -48,7 +48,7 @@ const defaultState = {
} }
function hasNoTransactions(account: Account) { function hasNoTransactions(account: Account) {
return get(account, 'data.transactions.length', 0) === 0 return get(account, 'transactions.length', 0) === 0
} }
class SettingsAccount extends PureComponent<Props, State> { class SettingsAccount extends PureComponent<Props, State> {

11
src/helpers/btc.js

@ -133,11 +133,16 @@ export async function getAccount({
return { return {
address: currentAddress.address, address: currentAddress.address,
allAddresses, addresses: allAddresses,
balance, balance,
currentIndex: currentAddress.index, index: currentAddress.index,
path: `${path}/${getPath('external', currentAddress.index + 1)}`, path: `${path}/${getPath('external', currentAddress.index + 1)}`,
transactions, transactions: transactions.map(t => ({
address: t.balance > 0 ? t.inputs[0].address : t.outputs[0].address,
balance: t.balance,
hash: t.hash,
receivedAt: t.received_at,
})),
} }
}) })

88
src/helpers/db.js

@ -1,7 +1,15 @@
// @flow
import Store from 'electron-store' import Store from 'electron-store'
import set from 'lodash/set' import set from 'lodash/set'
import get from 'lodash/get' import get from 'lodash/get'
import { getCurrencyByCoinType } from '@ledgerhq/currencies'
import type { Accounts } from 'types/common'
type DBKey = 'settings' | 'accounts'
const encryptionKey = {} const encryptionKey = {}
const store = key => const store = key =>
@ -13,13 +21,61 @@ const store = key =>
encryptionKey: encryptionKey[key], encryptionKey: encryptionKey[key],
}) })
export function setEncryptionKey(key, value) { export function setEncryptionKey(key: DBKey, value?: string) {
encryptionKey[key] = value encryptionKey[key] = value
} }
export function serializeAccounts(accounts: Accounts) {
return accounts.map(account => ({
id: account.id,
address: account.address,
addresses: account.addresses,
balance: account.balance,
coinType: account.coinType,
currency: getCurrencyByCoinType(account.coinType),
index: account.index,
name: account.name,
path: account.path,
unit: account.unit,
transactions: account.transactions.map(t => ({
...t,
account,
})),
}))
}
export function deserializeAccounts(accounts: Accounts) {
return accounts.map(account => ({
id: account.id,
address: account.address,
addresses: account.addresses,
balance: account.balance,
coinType: account.coinType,
index: account.index,
name: account.name,
path: account.path,
transactions: account.transactions.map(({ account, ...t }) => t),
unit: account.unit,
}))
}
function middleware(type, key, data: any) {
if (key === 'accounts') {
if (type === 'get') {
data = serializeAccounts(data)
}
if (type === 'set') {
data = deserializeAccounts(data)
}
}
return data
}
export default { export default {
// If the db doesn't exists for that key, init it, with the default value provided // If the db doesn't exists for that key, init it, with the default value provided
init: (key, defaults) => { init: (key: DBKey, defaults: any) => {
const db = store(key) const db = store(key)
const data = db.get('data') const data = db.get('data')
if (!data) { if (!data) {
@ -27,28 +83,40 @@ export default {
} }
}, },
get: (key, defaults) => { get: (key: DBKey, defaults: any): any => {
const db = store(key) const db = store(key)
return db.get('data', defaults) const data = db.get('data', defaults)
return middleware('get', key, data)
}, },
set: (key, val) => { set: (key: DBKey, val: any) => {
const db = store(key) const db = store(key)
val = middleware('set', key, val)
db.set('data', val) db.set('data', val)
return db.get('data')
return val
}, },
getIn: (key, path, defaultValue) => { getIn: (key: DBKey, path: string, defaultValue: any) => {
const db = store(key) const db = store(key)
const data = db.get('data')
let data = db.get('data')
data = middleware('get', key, data)
return get(data, path, defaultValue) return get(data, path, defaultValue)
}, },
setIn: (key, path, val) => { setIn: (key: DBKey, path: string, val: any) => {
const db = store(key) const db = store(key)
const data = db.get('data') const data = db.get('data')
val = middleware('set', key, val)
set(data, path, val) set(data, path, val)
db.set('data', data) db.set('data', data)
return db.get('data')
return val
}, },
} }

4
src/middlewares/db.js

@ -17,6 +17,8 @@ export default store => next => action => {
const state = getState() const state = getState()
const { settings } = state const { settings } = state
const accounts = getAccounts(state)
db.set('settings', settings) db.set('settings', settings)
db.set('accounts', getAccounts(state)) db.set('accounts', accounts)
} }

63
src/reducers/accounts.js

@ -7,32 +7,21 @@ import get from 'lodash/get'
import reduce from 'lodash/reduce' import reduce from 'lodash/reduce'
import type { State } from 'reducers' import type { State } from 'reducers'
import type { Account, Accounts, AccountData } from 'types/common' import type { Account, Accounts } from 'types/common'
export type AccountsState = Accounts export type AccountsState = Accounts
const state: AccountsState = [] const state: AccountsState = []
function orderAccountsTransactions(account: Account) { function orderAccountsTransactions(account: Account) {
const transactions = get(account.data, 'transactions', []) const { transactions } = account
transactions.sort((a, b) => new Date(b.received_at) - new Date(a.received_at)) transactions.sort((a, b) => new Date(b.receivedAt) - new Date(a.receivedAt))
return { return {
...account, ...account,
data: { transactions,
...account.data,
transactions,
},
} }
} }
const defaultAccountData: AccountData = {
address: '',
balance: 0,
currentIndex: 0,
path: '',
transactions: [],
}
const handlers: Object = { const handlers: Object = {
SET_ACCOUNTS: ( SET_ACCOUNTS: (
state: AccountsState, state: AccountsState,
@ -42,16 +31,7 @@ const handlers: Object = {
ADD_ACCOUNT: ( ADD_ACCOUNT: (
state: AccountsState, state: AccountsState,
{ payload: account }: { payload: Account }, { payload: account }: { payload: Account },
): AccountsState => { ): AccountsState => [...state, orderAccountsTransactions(account)],
account = orderAccountsTransactions({
...account,
data: {
...defaultAccountData,
...account.data,
},
})
return [...state, account]
},
UPDATE_ACCOUNT: ( UPDATE_ACCOUNT: (
state: AccountsState, state: AccountsState,
@ -62,28 +42,17 @@ const handlers: Object = {
return existingAccount return existingAccount
} }
const existingData = get(existingAccount, 'data', {}) const { transactions, index } = account
const data = get(account, 'data', {})
const transactions = get(data, 'transactions', [])
const currentIndex = data.currentIndex
? data.currentIndex
: get(existingData, 'currentIndex', 0)
const updatedAccount = { const updatedAccount = {
...existingAccount, ...existingAccount,
...account, ...account,
data: { balance: transactions.reduce((result, v) => {
...existingData, result += v.balance
...data, return result
balance: transactions.reduce((result, v) => { }, 0),
result += v.balance index: index || get(existingAccount, 'currentIndex', 0),
return result transactions,
}, 0),
currentIndex,
transactions,
},
} }
return orderAccountsTransactions(updatedAccount) return orderAccountsTransactions(updatedAccount)
@ -99,7 +68,7 @@ export function getTotalBalance(state: { accounts: AccountsState }) {
return reduce( return reduce(
state.accounts, state.accounts,
(result, account) => { (result, account) => {
result += get(account, 'data.balance', 0) result += get(account, 'balance', 0)
return result return result
}, },
0, 0,
@ -123,12 +92,8 @@ export function getAccountById(state: { accounts: AccountsState }, id: string):
return account || null return account || null
} }
export function getAccountData(state: State, id: string): AccountData | null {
return get(getAccountById(state, id), 'data', null)
}
export function canCreateAccount(state: State): boolean { export function canCreateAccount(state: State): boolean {
return every(getAccounts(state), a => get(a, 'data.transactions.length', 0) > 0) return every(getAccounts(state), a => get(a, 'transactions.length', 0) > 0)
} }
export default handleActions(handlers, state) export default handleActions(handlers, state)

18
src/renderer/events.js

@ -13,7 +13,7 @@ import { CHECK_UPDATE_TIMEOUT, SYNC_ACCOUNT_TIMEOUT } from 'constants'
import { updateDevices, addDevice, removeDevice } from 'actions/devices' import { updateDevices, addDevice, removeDevice } from 'actions/devices'
import { updateAccount } from 'actions/accounts' import { updateAccount } from 'actions/accounts'
import { setUpdateStatus } from 'reducers/update' import { setUpdateStatus } from 'reducers/update'
import { getAccountData, getAccounts, getAccountById } from 'reducers/accounts' import { getAccounts, getAccountById } from 'reducers/accounts'
import { isLocked } from 'reducers/application' import { isLocked } from 'reducers/application'
import i18n from 'renderer/i18n' import i18n from 'renderer/i18n'
@ -53,12 +53,12 @@ export function startSyncAccounts(accounts: Accounts) {
syncAccounts = true syncAccounts = true
sendEvent('accounts', 'sync.all', { sendEvent('accounts', 'sync.all', {
accounts: accounts.map(account => { accounts: accounts.map(account => {
const currentIndex = get(account, 'data.currentIndex', 0) const index = get(account, 'index', 0)
const allAddresses = get(account, 'data.allAddresses', []) const addresses = get(account, 'addresses', [])
return { return {
id: account.id, id: account.id,
allAddresses, allAddresses: addresses,
currentIndex, currentIndex: index,
} }
}), }),
}) })
@ -87,8 +87,7 @@ export default ({ store, locked }: { store: Object, locked: boolean }) => {
if (syncAccounts) { if (syncAccounts) {
const state = store.getState() const state = store.getState()
const currentAccount = getAccountById(state, account.id) || {} const currentAccount = getAccountById(state, account.id) || {}
const currentAccountData = getAccountData(state, account.id) || {} const currentAccountTransactions = get(currentAccount, 'transactions', [])
const currentAccountTransactions = get(currentAccountData, 'transactions', [])
const transactions = uniqBy( const transactions = uniqBy(
[...currentAccountTransactions, ...account.transactions], [...currentAccountTransactions, ...account.transactions],
@ -100,10 +99,7 @@ export default ({ store, locked }: { store: Object, locked: boolean }) => {
store.dispatch( store.dispatch(
updateAccount({ updateAccount({
...account, ...account,
data: { transactions,
...account.data,
transactions,
},
}), }),
) )
} }

24
src/types/common.js

@ -13,29 +13,27 @@ export type Devices = Array<Device>
// -------------------- Transactions // -------------------- Transactions
export type Transaction = { export type Transaction = {
account?: Object, account?: Account,
address: string,
balance: number, balance: number,
hash: string, hash: string,
received_at: string, receivedAt: string,
} }
// -------------------- Accounts // -------------------- Accounts
export type AccountData = {
address: string,
balance: number,
currentIndex: number,
path: string,
transactions: Array<Transaction>,
}
export type Account = { export type Account = {
address: string,
addresses: Array<string>,
archived?: boolean, archived?: boolean,
data?: AccountData, balance: number,
id: string,
name: string,
coinType: number, coinType: number,
currency: Currency, currency: Currency,
id: string,
index: number,
name: string,
path: string,
transactions: Array<Transaction>,
unit: Unit, unit: Unit,
} }

Loading…
Cancel
Save