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..7522ad3b 100644 --- a/src/components/SettingsPage/sections/Profile.js +++ b/src/components/SettingsPage/sections/Profile.js @@ -9,6 +9,7 @@ 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' @@ -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,13 @@ class TabProfile extends PureComponent { } handleHardReset = async () => { - db.resetAll() - await delay(500) - remote.getCurrentWindow().webContents.reload() + this.setState({ isHardResetting: true }) + try { + await hardReset() + remote.getCurrentWindow().webContents.reloadIgnoringCache() + } catch (err) { + this.setState({ isHardResetting: false }) + } } handleChangePasswordCheck = isChecked => { @@ -125,6 +132,7 @@ class TabProfile extends PureComponent { isHardResetModalOpened, isPasswordModalOpened, isDisablePasswordModalOpened, + isHardResetting, } = this.state const isPasswordEnabled = settings.password.isEnabled === true return ( @@ -200,6 +208,7 @@ class TabProfile extends PureComponent { ` @@ -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 { - - } + 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)