From 7583f4d14837c83c93c5bc9d80a70d37dc1903a6 Mon Sep 17 00:00:00 2001 From: meriadec Date: Mon, 11 Jun 2018 16:27:01 +0200 Subject: [PATCH 1/3] Add `isLoading` prop in Button and ConfirmModal --- src/components/base/Button/index.js | 20 +++++++++++++++----- src/components/base/Modal/ConfirmModal.js | 14 +++++++++++--- 2 files changed, 26 insertions(+), 8 deletions(-) diff --git a/src/components/base/Button/index.js b/src/components/base/Button/index.js index 0f673f4c..cabd6366 100644 --- a/src/components/base/Button/index.js +++ b/src/components/base/Button/index.js @@ -6,9 +6,10 @@ import { space, fontSize, fontWeight, color } from 'styled-system' import noop from 'lodash/noop' import { darken, lighten } from 'styles/helpers' - import fontFamily from 'styles/styled/fontFamily' +import Spinner from 'components/base/Spinner' + const buttonStyles = { primary: { default: p => ` @@ -73,6 +74,14 @@ const buttonStyles = { padding-right: ${space[1]}px; `, }, + isLoading: { + default: () => ` + padding-left: 40px; + padding-right: 40px; + pointer-events: none; + opacity: 0.7; + `, + }, } function getStyles(props, state) { @@ -127,14 +136,15 @@ type Props = { onClick?: Function, small?: boolean, padded?: boolean, + isLoading?: boolean, } const Button = (props: Props) => { - const { onClick, children, disabled } = props - + const { onClick, children, disabled, isLoading } = props + const isClickDisabled = disabled || isLoading return ( - - {children} + + {isLoading ? : children} ) } diff --git a/src/components/base/Modal/ConfirmModal.js b/src/components/base/Modal/ConfirmModal.js index 1eee3fff..91561a82 100644 --- a/src/components/base/Modal/ConfirmModal.js +++ b/src/components/base/Modal/ConfirmModal.js @@ -21,6 +21,7 @@ type Props = { onReject: Function, onConfirm: Function, t: T, + isLoading?: boolean, } class ConfirmModal extends PureComponent { @@ -35,6 +36,7 @@ class ConfirmModal extends PureComponent { isDanger, onReject, onConfirm, + isLoading, t, ...props } = this.props @@ -44,9 +46,10 @@ class ConfirmModal extends PureComponent { return ( ( - + {title} {subTitle && ( @@ -59,8 +62,13 @@ class ConfirmModal extends PureComponent { - - } + From d1cf946ef0fcbd0cf75daafa774e72bf64d6cd64 Mon Sep 17 00:00:00 2001 From: meriadec Date: Mon, 11 Jun 2018 16:28:55 +0200 Subject: [PATCH 2/3] Implement hard reset on libcore side --- src/commands/index.js | 2 ++ src/commands/libcoreHardReset.js | 20 +++++++++++++++++++ .../SettingsPage/sections/Profile.js | 19 +++++++++++++++--- 3 files changed, 38 insertions(+), 3 deletions(-) create mode 100644 src/commands/libcoreHardReset.js diff --git a/src/commands/index.js b/src/commands/index.js index 91d0df7b..463c7248 100644 --- a/src/commands/index.js +++ b/src/commands/index.js @@ -14,6 +14,7 @@ import installMcu from 'commands/installMcu' import installOsuFirmware from 'commands/installOsuFirmware' import isDashboardOpen from 'commands/isDashboardOpen' import libcoreGetVersion from 'commands/libcoreGetVersion' +import libcoreHardReset from 'commands/libcoreHardReset' import libcoreScanAccounts from 'commands/libcoreScanAccounts' import libcoreSignAndBroadcast from 'commands/libcoreSignAndBroadcast' import libcoreSyncAccount from 'commands/libcoreSyncAccount' @@ -38,6 +39,7 @@ const all: Array> = [ installOsuFirmware, isDashboardOpen, libcoreGetVersion, + libcoreHardReset, libcoreScanAccounts, libcoreSignAndBroadcast, libcoreSyncAccount, diff --git a/src/commands/libcoreHardReset.js b/src/commands/libcoreHardReset.js new file mode 100644 index 00000000..7da0f3c6 --- /dev/null +++ b/src/commands/libcoreHardReset.js @@ -0,0 +1,20 @@ +// @flow + +import { createCommand } from 'helpers/ipc' +import { Observable } from 'rxjs' +import withLibcore from 'helpers/withLibcore' + +const cmd = createCommand('libcoreHardReset', () => + Observable.create(o => { + withLibcore(async (core, njsWalletPool) => { + try { + njsWalletPool.eraseDataSince(new Date(0)) + o.complete() + } catch (e) { + o.error(e) + } + }) + }), +) + +export default cmd diff --git a/src/components/SettingsPage/sections/Profile.js b/src/components/SettingsPage/sections/Profile.js index 27b859b3..70f59d2a 100644 --- a/src/components/SettingsPage/sections/Profile.js +++ b/src/components/SettingsPage/sections/Profile.js @@ -5,6 +5,7 @@ import { connect } from 'react-redux' import { remote } from 'electron' import bcrypt from 'bcryptjs' +import libcoreHardReset from 'commands/libcoreHardReset' import { cleanAccountsCache } from 'actions/accounts' import { unlock } from 'reducers/application' // FIXME should be in actions import db, { setEncryptionKey } from 'helpers/db' @@ -47,6 +48,7 @@ type State = { isSoftResetModalOpened: boolean, isPasswordModalOpened: boolean, isDisablePasswordModalOpened: boolean, + isHardResetting: boolean, } class TabProfile extends PureComponent { @@ -55,6 +57,7 @@ class TabProfile extends PureComponent { isSoftResetModalOpened: false, isPasswordModalOpened: false, isDisablePasswordModalOpened: false, + isHardResetting: false, } setPassword = password => { @@ -89,9 +92,17 @@ class TabProfile extends PureComponent { } handleHardReset = async () => { - db.resetAll() - await delay(500) - remote.getCurrentWindow().webContents.reload() + this.setState({ isHardResetting: true }) + try { + // TODO: wait for the libcoreHardReset to be finished + // actually, libcore doesnt goes back to js thread + await Promise.race([libcoreHardReset.send().toPromise(), delay(500)]) + db.resetAll() + await delay(500) + remote.getCurrentWindow().webContents.reload() + } catch (err) { + this.setState({ isHardResetting: false }) + } } handleChangePasswordCheck = isChecked => { @@ -125,6 +136,7 @@ class TabProfile extends PureComponent { isHardResetModalOpened, isPasswordModalOpened, isDisablePasswordModalOpened, + isHardResetting, } = this.state const isPasswordEnabled = settings.password.isEnabled === true return ( @@ -200,6 +212,7 @@ class TabProfile extends PureComponent { Date: Mon, 11 Jun 2018 17:01:43 +0200 Subject: [PATCH 3/3] Ability to trigger a hard reset with LEDGER_RESET_ALL --- .../SettingsPage/sections/Profile.js | 10 ++-- src/helpers/hardReset.js | 14 ++++++ src/middlewares/db.js | 10 +++- src/renderer/init.js | 50 ++++++++++--------- 4 files changed, 52 insertions(+), 32 deletions(-) create mode 100644 src/helpers/hardReset.js diff --git a/src/components/SettingsPage/sections/Profile.js b/src/components/SettingsPage/sections/Profile.js index 70f59d2a..7522ad3b 100644 --- a/src/components/SettingsPage/sections/Profile.js +++ b/src/components/SettingsPage/sections/Profile.js @@ -5,11 +5,11 @@ import { connect } from 'react-redux' import { remote } from 'electron' import bcrypt from 'bcryptjs' -import libcoreHardReset from 'commands/libcoreHardReset' import { cleanAccountsCache } from 'actions/accounts' import { unlock } from 'reducers/application' // FIXME should be in actions import db, { setEncryptionKey } from 'helpers/db' import { delay } from 'helpers/promise' +import hardReset from 'helpers/hardReset' import type { SettingsState } from 'reducers/settings' import type { T } from 'types/common' @@ -94,12 +94,8 @@ class TabProfile extends PureComponent { handleHardReset = async () => { this.setState({ isHardResetting: true }) try { - // TODO: wait for the libcoreHardReset to be finished - // actually, libcore doesnt goes back to js thread - await Promise.race([libcoreHardReset.send().toPromise(), delay(500)]) - db.resetAll() - await delay(500) - remote.getCurrentWindow().webContents.reload() + await hardReset() + remote.getCurrentWindow().webContents.reloadIgnoringCache() } catch (err) { this.setState({ isHardResetting: false }) } diff --git a/src/helpers/hardReset.js b/src/helpers/hardReset.js new file mode 100644 index 00000000..24477872 --- /dev/null +++ b/src/helpers/hardReset.js @@ -0,0 +1,14 @@ +import libcoreHardReset from 'commands/libcoreHardReset' +import { disable as disableDBMiddleware } from 'middlewares/db' + +import db from 'helpers/db' +import { delay } from 'helpers/promise' + +export default async function hardReset() { + // TODO: wait for the libcoreHardReset to be finished + // actually, libcore doesnt goes back to js thread + await Promise.race([libcoreHardReset.send().toPromise(), delay(500)]) + disableDBMiddleware() + db.resetAll() + await delay(500) +} diff --git a/src/middlewares/db.js b/src/middlewares/db.js index 0af57202..d6b92b5f 100644 --- a/src/middlewares/db.js +++ b/src/middlewares/db.js @@ -6,8 +6,16 @@ import { accountsSelector } from 'reducers/accounts' import { settingsExportSelector, areSettingsLoaded } from 'reducers/settings' import CounterValues from 'helpers/countervalues' +let DB_MIDDLEWARE_ENABLED = true + +// ability to temporary disable the db middleware from outside +export const disable = (ms = 1000) => { + DB_MIDDLEWARE_ENABLED = false + setTimeout(() => (DB_MIDDLEWARE_ENABLED = true), ms) +} + export default store => next => action => { - if (action.type.startsWith('DB:')) { + if (DB_MIDDLEWARE_ENABLED && action.type.startsWith('DB:')) { const [, type] = action.type.split(':') store.dispatch({ type, payload: action.payload }) const state = store.getState() diff --git a/src/renderer/init.js b/src/renderer/init.js index a7db960b..6ef76a10 100644 --- a/src/renderer/init.js +++ b/src/renderer/init.js @@ -20,43 +20,39 @@ import libcoreGetVersion from 'commands/libcoreGetVersion' import db from 'helpers/db' import dbMiddleware from 'middlewares/db' import CounterValues from 'helpers/countervalues' +import hardReset from 'helpers/hardReset' import App from 'components/App' import 'styles/global' -if (process.env.LEDGER_RESET_ALL) { - db.resetAll() -} - -// Init db with defaults if needed -db.init('settings', {}) - -const history = createHistory() -const store = createStore({ history, dbMiddleware }) const rootNode = document.getElementById('app') -const settings = db.get('settings') -store.dispatch(fetchSettings(settings)) +async function init() { + if (process.env.LEDGER_RESET_ALL) { + await hardReset() + } -const countervaluesData = db.get('countervalues') -if (countervaluesData) { - store.dispatch(CounterValues.importAction(countervaluesData)) -} + // Init db with defaults if needed + db.init('settings', {}) -const state = store.getState() -const language = getLanguage(state) -const locked = isLocked(state) + const history = createHistory() + const store = createStore({ history, dbMiddleware }) -moment.locale(language) + const settings = db.get('settings') + store.dispatch(fetchSettings(settings)) -function r(Comp) { - if (rootNode) { - render({Comp}, rootNode) + const countervaluesData = db.get('countervalues') + if (countervaluesData) { + store.dispatch(CounterValues.importAction(countervaluesData)) } -} -async function init() { + const state = store.getState() + const language = getLanguage(state) + const locked = isLocked(state) + + moment.locale(language) + // FIXME IMO init() really should only be for window. any other case is a hack! const isMainWindow = remote.getCurrentWindow().name === 'MainWindow' @@ -92,6 +88,12 @@ async function init() { } } +function r(Comp) { + if (rootNode) { + render({Comp}, rootNode) + } +} + init().catch(e => { // for now we make the app crash instead of pending forever. later we can render the error OR try to recover, but probably this is unrecoverable cases. logger.error(e)