diff --git a/src/actions/accounts.js b/src/actions/accounts.js index fa8be05e..6ab98f1c 100644 --- a/src/actions/accounts.js +++ b/src/actions/accounts.js @@ -1,50 +1,14 @@ // @flow -import sortBy from 'lodash/sortBy' import type { Account } from '@ledgerhq/live-common/lib/types' import db from 'helpers/db' -import type { Dispatch } from 'redux' - -function sortAccounts(accounts, orderAccounts) { - const [order, sort] = orderAccounts.split('|') - - const accountsSorted = sortBy(accounts, a => { - if (order === 'balance') { - return a.balance - } - - return a[order] - }) - - if (sort === 'asc') { - accountsSorted.reverse() - } - - return accountsSorted -} - -export type UpdateOrderAccounts = string => (Dispatch<*>, Function) => void -export const updateOrderAccounts: UpdateOrderAccounts = (orderAccounts: string) => ( - dispatch, - getState, -) => { - const { accounts } = getState() - dispatch({ - type: 'DB:SET_ACCOUNTS', - payload: sortAccounts(accounts, orderAccounts), - }) -} - -export type AddAccount = Account => (Function, Function) => void -export const addAccount: AddAccount = payload => (dispatch, getState) => { - const { - settings: { orderAccounts }, - } = getState() - dispatch({ type: 'ADD_ACCOUNT', payload }) - dispatch(updateOrderAccounts(orderAccounts)) -} +export type AddAccount = Account => * +export const addAccount: AddAccount = payload => ({ + type: 'ADD_ACCOUNT', + payload, +}) export type RemoveAccount = Account => { type: string, payload: Account } export const removeAccount: RemoveAccount = payload => ({ @@ -52,16 +16,19 @@ export const removeAccount: RemoveAccount = payload => ({ payload, }) -export type FetchAccounts = () => (Function, Function) => * -export const fetchAccounts: FetchAccounts = () => (dispatch, getState) => { - const { - settings: { orderAccounts }, - } = getState() +export type ReorderAccounts = (string[]) => { type: string, payload: string[] } +export const reorderAccounts: ReorderAccounts = payload => ({ + type: 'DB:REORDER_ACCOUNTS', + payload, +}) + +export type FetchAccounts = () => * +export const fetchAccounts: FetchAccounts = () => { const accounts = db.get('accounts') - dispatch({ + return { type: 'SET_ACCOUNTS', - payload: sortAccounts(accounts, orderAccounts), - }) + payload: accounts, + } } export type UpdateAccountWithUpdater = (accountId: string, (Account) => Account) => * @@ -71,20 +38,13 @@ export const updateAccountWithUpdater: UpdateAccountWithUpdater = (accountId, up payload: { accountId, updater }, }) -export type UpdateAccount = ($Shape) => (Function, Function) => void -export const updateAccount: UpdateAccount = payload => (dispatch, getState) => { - const { - settings: { orderAccounts }, - } = getState() - dispatch({ - type: 'DB:UPDATE_ACCOUNT', - payload: { - updater: account => ({ ...account, ...payload }), - accountId: payload.id, - }, - }) - dispatch(updateOrderAccounts(orderAccounts)) - // TODO should not be here IMO.. feels wrong for perf, probably better to move in reducer too -} +export type UpdateAccount = ($Shape) => * +export const updateAccount: UpdateAccount = payload => ({ + type: 'DB:UPDATE_ACCOUNT', + payload: { + updater: account => ({ ...account, ...payload }), + accountId: payload.id, + }, +}) export const cleanAccountsCache = () => ({ type: 'CLEAN_ACCOUNTS_CACHE' }) diff --git a/src/components/DashboardPage/AccountsOrder.js b/src/components/DashboardPage/AccountsOrder.js index 68f8b171..dd5484c4 100644 --- a/src/components/DashboardPage/AccountsOrder.js +++ b/src/components/DashboardPage/AccountsOrder.js @@ -1,17 +1,20 @@ // @flow import React, { Component } from 'react' +import sortBy from 'lodash/sortBy' import styled from 'styled-components' import { compose } from 'redux' import { translate } from 'react-i18next' import { connect } from 'react-redux' import debounce from 'lodash/debounce' +import type { Account } from '@ledgerhq/live-common/lib/types' import type { T } from 'types/common' import { getOrderAccounts } from 'reducers/settings' - -import { updateOrderAccounts } from 'actions/accounts' +import { createStructuredSelector } from 'reselect' +import { reorderAccounts } from 'actions/accounts' +import { accountsSelector } from 'reducers/accounts' import { saveSettings } from 'actions/settings' import BoldToggle from 'components/base/BoldToggle' @@ -23,6 +26,24 @@ import IconAngleDown from 'icons/AngleDown' import IconArrowDown from 'icons/ArrowDown' import IconArrowUp from 'icons/ArrowUp' +function sortAccounts(accounts: Account[], orderAccounts: string) { + const [order, sort] = orderAccounts.split('|') + + const accountsSorted = sortBy(accounts, a => { + if (order === 'balance') { + return a.balance + } + + return a[order] + }) + + if (sort === 'asc') { + accountsSorted.reverse() + } + + return accountsSorted +} + const OrderIcon = styled(Box).attrs({ alignItems: 'center', justifyContent: 'center', @@ -31,20 +52,22 @@ const OrderIcon = styled(Box).attrs({ opacity: ${p => (p.isActive ? 1 : 0)}; ` -const mapStateToProps = state => ({ - orderAccounts: getOrderAccounts(state), +const mapStateToProps = createStructuredSelector({ + orderAccounts: getOrderAccounts, + accounts: accountsSelector, }) const mapDispatchToProps = { - updateOrderAccounts, + reorderAccounts, saveSettings, } type Props = { t: T, orderAccounts: string, - updateOrderAccounts: Function, - saveSettings: Function, + accounts: Account[], + reorderAccounts: (string[]) => *, + saveSettings: (*) => *, } type State = { @@ -62,10 +85,10 @@ class AccountsOrder extends Component { setAccountOrder = debounce( order => { - const { updateOrderAccounts, saveSettings } = this.props + const { saveSettings } = this.props this.setState({ cachedValue: order }, () => { window.requestIdleCallback(() => { - updateOrderAccounts(order) + this.props.reorderAccounts(sortAccounts(this.props.accounts, order).map(a => a.id)) saveSettings({ orderAccounts: order }) }) }) diff --git a/src/components/DashboardPage/index.js b/src/components/DashboardPage/index.js index 00ecfead..c71e797f 100644 --- a/src/components/DashboardPage/index.js +++ b/src/components/DashboardPage/index.js @@ -16,7 +16,7 @@ import { colors } from 'styles/theme' import { accountsSelector } from 'reducers/accounts' import { counterValueCurrencySelector, localeSelector } from 'reducers/settings' -import { updateOrderAccounts } from 'actions/accounts' +import { reorderAccounts } from 'actions/accounts' import { saveSettings } from 'actions/settings' import UpdateNotifier from 'components/UpdateNotifier' @@ -39,7 +39,7 @@ const mapStateToProps = createStructuredSelector({ const mapDispatchToProps = { push, - updateOrderAccounts, + reorderAccounts, saveSettings, } diff --git a/src/reducers/accounts.js b/src/reducers/accounts.js index 33da8838..b89cc8d5 100644 --- a/src/reducers/accounts.js +++ b/src/reducers/accounts.js @@ -17,6 +17,9 @@ const handlers: Object = { { payload: accounts }: { payload: Account[] }, ): AccountsState => accounts, + REORDER_ACCOUNTS: (state: AccountsState, { payload }: { payload: string[] }) => + state.slice(0).sort((a, b) => payload.indexOf(a.id) - payload.indexOf(b.id)), + ADD_ACCOUNT: ( state: AccountsState, { payload: account }: { payload: Account },