Browse Source

Merge pull request #504 from meriadec/feature/hard-reset

Feature/hard reset
master
Meriadec Pillet 7 years ago
committed by GitHub
parent
commit
226d9880d1
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 2
      src/commands/index.js
  2. 20
      src/commands/libcoreHardReset.js
  3. 15
      src/components/SettingsPage/sections/Profile.js
  4. 20
      src/components/base/Button/index.js
  5. 14
      src/components/base/Modal/ConfirmModal.js
  6. 14
      src/helpers/hardReset.js
  7. 10
      src/middlewares/db.js
  8. 50
      src/renderer/init.js

2
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<Command<any, any>> = [
installOsuFirmware,
isDashboardOpen,
libcoreGetVersion,
libcoreHardReset,
libcoreScanAccounts,
libcoreSignAndBroadcast,
libcoreSyncAccount,

20
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

15
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<Props, State> {
@ -55,6 +57,7 @@ class TabProfile extends PureComponent<Props, State> {
isSoftResetModalOpened: false,
isPasswordModalOpened: false,
isDisablePasswordModalOpened: false,
isHardResetting: false,
}
setPassword = password => {
@ -89,9 +92,13 @@ class TabProfile extends PureComponent<Props, State> {
}
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<Props, State> {
isHardResetModalOpened,
isPasswordModalOpened,
isDisablePasswordModalOpened,
isHardResetting,
} = this.state
const isPasswordEnabled = settings.password.isEnabled === true
return (
@ -200,6 +208,7 @@ class TabProfile extends PureComponent<Props, State> {
<ConfirmModal
isDanger
isLoading={isHardResetting}
isOpened={isHardResetModalOpened}
onClose={this.handleCloseHardResetModal}
onReject={this.handleCloseHardResetModal}

20
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 (
<Base {...props} onClick={disabled ? undefined : onClick}>
{children}
<Base {...props} onClick={isClickDisabled ? undefined : onClick}>
{isLoading ? <Spinner size={16} /> : children}
</Base>
)
}

14
src/components/base/Modal/ConfirmModal.js

@ -21,6 +21,7 @@ type Props = {
onReject: Function,
onConfirm: Function,
t: T,
isLoading?: boolean,
}
class ConfirmModal extends PureComponent<Props> {
@ -35,6 +36,7 @@ class ConfirmModal extends PureComponent<Props> {
isDanger,
onReject,
onConfirm,
isLoading,
t,
...props
} = this.props
@ -44,9 +46,10 @@ class ConfirmModal extends PureComponent<Props> {
return (
<Modal
isOpened={isOpened}
preventBackdropClick={isLoading}
{...props}
render={({ onClose }) => (
<ModalBody onClose={onClose}>
<ModalBody onClose={isLoading ? undefined : onClose}>
<ModalTitle>{title}</ModalTitle>
<ModalContent>
{subTitle && (
@ -59,8 +62,13 @@ class ConfirmModal extends PureComponent<Props> {
</Box>
</ModalContent>
<ModalFooter horizontal align="center" justify="flex-end" flow={2}>
<Button onClick={onReject}>{realCancelText}</Button>
<Button onClick={onConfirm} primary={!isDanger} danger={isDanger}>
{!isLoading && <Button onClick={onReject}>{realCancelText}</Button>}
<Button
onClick={onConfirm}
primary={!isDanger}
danger={isDanger}
isLoading={isLoading}
>
{realConfirmText}
</Button>
</ModalFooter>

14
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)
}

10
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()

50
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(<AppContainer>{Comp}</AppContainer>, 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(<AppContainer>{Comp}</AppContainer>, 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)

Loading…
Cancel
Save