Skip to content
This repository has been archived by the owner on Jun 16, 2022. It is now read-only.

Ensure sqlite folder is removed after clear cache / hard reset #1585

Merged
merged 3 commits into from
Oct 17, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 11 additions & 3 deletions src/components/SettingsPage/CleanButton.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,13 @@
import React, { Fragment, PureComponent } from 'react'
import { connect } from 'react-redux'
import { translate } from 'react-i18next'
import logger from 'logger'
import type { T } from 'types/common'
import { cleanAccountsCache } from 'actions/accounts'
import Button from 'components/base/Button'
import { ConfirmModal } from 'components/base/Modal'
import { softReset } from 'helpers/reset'
import ResetFallbackModal from './ResetFallbackModal'

const mapDispatchToProps = {
cleanAccountsCache,
Expand All @@ -20,32 +22,36 @@ type Props = {

type State = {
opened: boolean,
fallbackOpened: boolean,
isLoading: boolean,
}

class CleanButton extends PureComponent<Props, State> {
state = {
opened: false,
fallbackOpened: false,
isLoading: false,
}

open = () => this.setState({ opened: true })

close = () => this.setState({ opened: false })
closeFallback = () => this.setState({ fallbackOpened: false })

action = async () => {
if (this.state.isLoading) return
try {
this.setState({ isLoading: true })
await softReset({ cleanAccountsCache: this.props.cleanAccountsCache })
} finally {
this.setState({ isLoading: false })
} catch (err) {
meriadec marked this conversation as resolved.
Show resolved Hide resolved
logger.error(err)
this.setState({ isLoading: false, fallbackOpened: true })
}
}

render() {
const { t } = this.props
const { opened, isLoading } = this.state
const { opened, isLoading, fallbackOpened } = this.state
return (
<Fragment>
<Button small primary onClick={this.open} event="ClearCacheIntent">
Expand All @@ -63,6 +69,8 @@ class CleanButton extends PureComponent<Props, State> {
subTitle={t('common.areYouSure')}
desc={t('settings.softResetModal.desc')}
/>

<ResetFallbackModal isOpened={fallbackOpened} onClose={this.closeFallback} />
</Fragment>
)
}
Expand Down
13 changes: 11 additions & 2 deletions src/components/SettingsPage/ResetButton.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,14 @@ import React, { Fragment, PureComponent } from 'react'
import styled from 'styled-components'
import { remote } from 'electron'
import { translate } from 'react-i18next'
import logger from 'logger'
import type { T } from 'types/common'
import { hardReset } from 'helpers/reset'
import Box from 'components/base/Box'
import Button from 'components/base/Button'
import { ConfirmModal } from 'components/base/Modal'
import IconTriangleWarning from 'icons/TriangleWarning'
import ResetFallbackModal from './ResetFallbackModal'

type Props = {
t: T,
Expand All @@ -18,30 +20,35 @@ type Props = {
type State = {
opened: boolean,
pending: boolean,
fallbackOpened: boolean,
}

class ResetButton extends PureComponent<Props, State> {
state = {
opened: false,
pending: false,
fallbackOpened: false,
}

open = () => this.setState({ opened: true })
close = () => this.setState({ opened: false })
closeFallback = () => this.setState({ fallbackOpened: false })

action = async () => {
this.setState({ pending: true })
try {
await hardReset()
remote.getCurrentWindow().webContents.reloadIgnoringCache()
} catch (err) {
this.setState({ pending: false })
logger.error(err)
this.setState({ pending: false, fallbackOpened: true })
meriadec marked this conversation as resolved.
Show resolved Hide resolved
}
}

render() {
const { t } = this.props
const { opened, pending } = this.state
const { opened, pending, fallbackOpened } = this.state

return (
<Fragment>
<Button small danger onClick={this.open} event="HardResetIntent">
Expand All @@ -66,6 +73,8 @@ class ResetButton extends PureComponent<Props, State> {
</IconWrapperCircle>
)}
/>

<ResetFallbackModal isOpened={fallbackOpened} onClose={this.closeFallback} />
</Fragment>
)
}
Expand Down
43 changes: 43 additions & 0 deletions src/components/SettingsPage/ResetFallbackModal.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
// @flow

import React, { PureComponent } from 'react'
import { translate } from 'react-i18next'

import { ConfirmModal } from 'components/base/Modal'
import { openUserDataFolderAndQuit } from 'helpers/reset'

type Props = {
t: *,
isOpened: boolean,
onClose: () => *,
}

class ResetFallbackModal extends PureComponent<Props> {
render() {
const { t, isOpened, onClose } = this.props
return (
<ConfirmModal
centered
isOpened={isOpened}
onConfirm={openUserDataFolderAndQuit}
onClose={onClose}
onReject={onClose}
confirmText={'Open folder'}
title={t('settings.resetFallbackModal.title')}
desc={
<div>
<p>{t('settings.resetFallbackModal.part1')}</p>
<p style={{ fontWeight: 'bold' }}>
{t('settings.resetFallbackModal.part2')}
{t('settings.resetFallbackModal.part3')}
{t('settings.resetFallbackModal.part4')}
</p>
<p style={{ marginTop: 20 }}>{t('settings.resetFallbackModal.part5')}</p>
</div>
}
/>
)
}
}

export default translate()(ResetFallbackModal)
1 change: 1 addition & 0 deletions src/config/errors.js
Original file line number Diff line number Diff line change
Expand Up @@ -50,3 +50,4 @@ export const FeeNotLoaded = createCustomErrorClass('FeeNotLoaded')
// db stuff, no need to translate
export const NoDBPathGiven = createCustomErrorClass('NoDBPathGiven')
export const DBWrongPassword = createCustomErrorClass('DBWrongPassword')
export const DBNotReset = createCustomErrorClass('DBNotReset')
15 changes: 13 additions & 2 deletions src/helpers/reset.js
Original file line number Diff line number Diff line change
@@ -1,17 +1,23 @@
// @flow

import fs from 'fs'
import { shell, remote } from 'electron'
import path from 'path'
import rimraf from 'rimraf'
import resolveUserDataDirectory from 'helpers/resolveUserDataDirectory'
import { disable as disableDBMiddleware } from 'middlewares/db'
import db from 'helpers/db'
import { delay } from 'helpers/promise'
import killInternalProcess from 'commands/killInternalProcess'
import { DBNotReset } from 'config/errors'

async function resetLibcoreDatabase() {
await killInternalProcess.send().toPromise()
const dbpath = path.resolve(resolveUserDataDirectory(), 'sqlite/')
rimraf.sync(dbpath, { glob: false })
if (fs.existsSync(dbpath)) {
throw new DBNotReset()
}
}

function reload() {
Expand All @@ -24,14 +30,19 @@ export async function hardReset() {
disableDBMiddleware()
db.resetAll()
await delay(500)
resetLibcoreDatabase()
await resetLibcoreDatabase()
reload()
}

export async function softReset({ cleanAccountsCache }: *) {
cleanAccountsCache()
await delay(500)
await db.cleanCache()
resetLibcoreDatabase()
await resetLibcoreDatabase()
reload()
}

export async function openUserDataFolderAndQuit() {
meriadec marked this conversation as resolved.
Show resolved Hide resolved
shell.openItem(resolveUserDataDirectory())
remote.app.quit()
}
8 changes: 8 additions & 0 deletions static/i18n/en/app.json
Original file line number Diff line number Diff line change
Expand Up @@ -406,6 +406,14 @@
"title": "Clear cache",
"desc": "Clearing the Ledger Live cache forces network resynchronization. Your settings and accounts are not affected. The private keys to access your crypto assets in the blockchain remain secure on your Ledger device and on your Recovery sheet."
},
"resetFallbackModal": {
"title": "User action required",
"part1": "Could not delete cache folder. Please delete the folder manually:",
"part2": "Click the Open folder button, the ",
"part3": "app will close",
"part4": ", and manually delete the \"sqlite\" folder.",
"part5": "Then you can restart the app normally."
},
"removeAccountModal": {
"title": "Remove account",
"desc": "The account will no longer be included in your portfolio. This operation does not affect your assets. Accounts can always be re-added."
Expand Down