diff --git a/packages/neuron-ui/src/components/GeneralSetting/index.tsx b/packages/neuron-ui/src/components/GeneralSetting/index.tsx
index ced18634cf..f535311820 100644
--- a/packages/neuron-ui/src/components/GeneralSetting/index.tsx
+++ b/packages/neuron-ui/src/components/GeneralSetting/index.tsx
@@ -1,8 +1,45 @@
-import React from 'react'
-import { Stack } from 'office-ui-fabric-react'
+import React, { useCallback, useState } from 'react'
+import { useTranslation } from 'react-i18next'
+import { Stack, PrimaryButton, Spinner, Text } from 'office-ui-fabric-react'
+import { StateWithDispatch } from 'states/stateProvider/reducer'
+import { addPopup } from 'states/stateProvider/actionCreators'
+import { clearCellCache } from 'services/remote'
-const GeneralSetting = () => {
- return
+const GeneralSetting = ({ dispatch }: React.PropsWithoutRef) => {
+ const [t] = useTranslation()
+ const [clearing, setClearing] = useState(false)
+
+ const clearCache = useCallback(() => {
+ setClearing(true)
+ setTimeout(() => {
+ clearCellCache().finally(() => {
+ addPopup('clear-cache-successfully')(dispatch)
+ setClearing(false)
+ })
+ }, 100)
+ }, [dispatch])
+
+ return (
+
+
+
+ {clearing ? : t('settings.general.clear-cache')}
+
+
+
+ {t('settings.general.clear-cache-description')}
+
+
+ )
}
GeneralSetting.displayName = 'GeneralSetting'
diff --git a/packages/neuron-ui/src/components/Settings/index.tsx b/packages/neuron-ui/src/components/Settings/index.tsx
index a2d21a06e5..dccb8244b0 100644
--- a/packages/neuron-ui/src/components/Settings/index.tsx
+++ b/packages/neuron-ui/src/components/Settings/index.tsx
@@ -13,7 +13,7 @@ import { WalletWizardPath } from 'components/WalletWizard'
import { Routes } from 'utils/const'
const pivotItems = [
- // { label: 'settings.setting-tabs.general', url: Routes.SettingsGeneral },
+ { label: 'settings.setting-tabs.general', url: Routes.SettingsGeneral },
{ label: 'settings.setting-tabs.wallets', url: Routes.SettingsWallets },
{ label: 'settings.setting-tabs.network', url: Routes.SettingsNetworks },
]
diff --git a/packages/neuron-ui/src/containers/Main/index.tsx b/packages/neuron-ui/src/containers/Main/index.tsx
index 53bd745f0a..a065e52df6 100644
--- a/packages/neuron-ui/src/containers/Main/index.tsx
+++ b/packages/neuron-ui/src/containers/Main/index.tsx
@@ -1,5 +1,5 @@
import React, { useMemo } from 'react'
-import { Route, RouteComponentProps, Switch, Redirect } from 'react-router-dom'
+import { Route, RouteComponentProps } from 'react-router-dom'
import { useTranslation } from 'react-i18next'
import { useState } from 'states/stateProvider'
@@ -102,12 +102,12 @@ export const mainContents: CustomRouter.Route[] = [
exact: false,
comp: ImportKeystore,
},
- // {
- // name: `PasswordRequest`,
- // path: '/',
- // exact: false,
- // comp: PasswordRequest,
- // },
+ {
+ name: `PasswordRequest`,
+ path: '/',
+ exact: false,
+ comp: PasswordRequest,
+ },
{
name: `NervosDAO`,
path: Routes.NervosDAO,
@@ -158,26 +158,16 @@ const MainContent = ({
return (
<>
- {
- return
- }}
- />
-
-
- {mainContents.map(container => (
- {
- return
- }}
- />
- ))}
-
+ {mainContents.map(container => (
+ {
+ return
+ }}
+ />
+ ))}
>
)
}
diff --git a/packages/neuron-ui/src/locales/en.json b/packages/neuron-ui/src/locales/en.json
index 291f2130e6..7521caf19c 100644
--- a/packages/neuron-ui/src/locales/en.json
+++ b/packages/neuron-ui/src/locales/en.json
@@ -178,7 +178,8 @@
"network": "Network"
},
"general": {
- "skip-data-and-type": "Skip the Cells which contain Data or Type Script",
+ "clear-cache": "Clear cache",
+ "clear-cache-description": "Clear cache if you encounter data sync or balance display problems. Neuron will rescan block data.",
"show": "Show",
"hide": "Hide"
},
@@ -257,6 +258,7 @@
"delete-wallet-successfully": "The wallet was deleted",
"create-network-successfully": "The network was created",
"update-network-successfully": "The network was updated",
+ "clear-cache-successfully": "The cache was cleared",
"addr-copied": "Address has been copied to the clipboard",
"qrcode-copied": "QR Code has been copied to the clipboard",
"view-the-run-node-doc": "View the guide in browser",
diff --git a/packages/neuron-ui/src/locales/zh.json b/packages/neuron-ui/src/locales/zh.json
index 2a9cb9b6ea..4809dc1eae 100644
--- a/packages/neuron-ui/src/locales/zh.json
+++ b/packages/neuron-ui/src/locales/zh.json
@@ -178,7 +178,8 @@
"network": "网络"
},
"general": {
- "skip-data-and-type": "忽略包含 Data 或 Type Script 的 Cells",
+ "clear-cache": "清空缓存",
+ "clear-cache-description": "当数据同步或显示出现问题时,可以清空缓存,Neuron 会重新同步所有块数据。",
"show": "显示",
"hide": "隐藏"
},
@@ -257,6 +258,7 @@
"delete-wallet-successfully": "已删除钱包",
"create-network-successfully": "已添加新节点",
"update-network-successfully": "已更新节点信息",
+ "clear-cache-successfully": "已清空数据缓存",
"addr-copied": "已复制地址到剪贴板",
"qrcode-copied": "已复制二维码到剪贴板",
"view-the-run-node-doc": "打开浏览器查看文档",
diff --git a/packages/neuron-ui/src/services/remote/app.ts b/packages/neuron-ui/src/services/remote/app.ts
index 69bb68af3a..238c302074 100644
--- a/packages/neuron-ui/src/services/remote/app.ts
+++ b/packages/neuron-ui/src/services/remote/app.ts
@@ -5,8 +5,11 @@ export const getNeuronWalletState = apiMethodWrapper(api => () => api.load
export const handleViewError = apiMethodWrapper(api => errorMessage => api.handleViewError(errorMessage))
export const contextMenu = apiMethodWrapper<{ type: string; id: string }>(api => params => api.contextMenu(params))
+export const clearCellCache = apiMethodWrapper(api => () => api.clearCellCache())
+
export default {
getNeuronWalletState,
handleViewError,
contextMenu,
+ clearCellCache,
}
diff --git a/packages/neuron-ui/src/states/stateProvider/actionCreators/app.ts b/packages/neuron-ui/src/states/stateProvider/actionCreators/app.ts
index c0446b5e7d..9827d871f3 100644
--- a/packages/neuron-ui/src/states/stateProvider/actionCreators/app.ts
+++ b/packages/neuron-ui/src/states/stateProvider/actionCreators/app.ts
@@ -60,6 +60,7 @@ export const initAppState = () => (dispatch: StateDispatch, history: any) => {
})
}
+// text: an i18n key under `messages`
export const addPopup = (text: string) => (dispatch: StateDispatch) => {
dispatch({
type: AppActions.PopIn,
diff --git a/packages/neuron-ui/src/stories/GeneralSetting.stories.tsx b/packages/neuron-ui/src/stories/GeneralSetting.stories.tsx
index b016ba1553..a8823d6ac1 100644
--- a/packages/neuron-ui/src/stories/GeneralSetting.stories.tsx
+++ b/packages/neuron-ui/src/stories/GeneralSetting.stories.tsx
@@ -2,9 +2,23 @@ import React from 'react'
import { storiesOf } from '@storybook/react'
import { withKnobs } from '@storybook/addon-knobs'
import GeneralSetting from 'components/GeneralSetting'
+import initStates from 'states/initStates'
+
+const states: { [title: string]: boolean } = {
+ 'Clear cell cache on': true,
+ 'Clear cell cache off': false,
+}
const stories = storiesOf('GeneralSettings', module)
+Object.entries(states).forEach(([title]) => {
+ const props = { ...initStates, settings: { ...initStates.settings }, dispatch: () => {} }
+ stories.add(title, () => )
+})
+
stories.addDecorator(withKnobs).add('With knobs', () => {
- return
+ const props = {
+ ...initStates,
+ }
+ return {}} />
})
diff --git a/packages/neuron-wallet/src/controllers/api.ts b/packages/neuron-wallet/src/controllers/api.ts
index 573bc6747d..7316bfbfd4 100644
--- a/packages/neuron-wallet/src/controllers/api.ts
+++ b/packages/neuron-wallet/src/controllers/api.ts
@@ -4,7 +4,7 @@ import env from 'env'
import i18n from 'utils/i18n'
import { popContextMenu } from './app/menu'
import { showWindow } from './app/show-window'
-import { TransactionsController, WalletsController, SyncInfoController, NetworksController } from 'controllers'
+import { TransactionsController, WalletsController, SyncController, NetworksController } from 'controllers'
import { NetworkType, NetworkID, Network } from 'types/network'
import NetworksService from 'services/networks'
import WalletsService from 'services/wallets'
@@ -40,7 +40,7 @@ export default class ApiController {
networksService.getCurrentID(),
networksService.getAll(),
- SyncInfoController.currentBlockNumber()
+ SyncController.currentBlockNumber()
.then(res => {
if (res.status) {
return res.result.currentBlockNumber
@@ -297,4 +297,12 @@ export default class ApiController {
) {
return DaoController.getDaoCells(params)
}
+
+ // settings
+ @MapApiResponse
+ public static async clearCellCache() {
+ await SyncController.stopSyncing()
+ await SyncController.deleteData()
+ return SyncController.startSyncing()
+ }
}
diff --git a/packages/neuron-wallet/src/controllers/index.ts b/packages/neuron-wallet/src/controllers/index.ts
index ece40cf0d7..cf339b4cbc 100644
--- a/packages/neuron-wallet/src/controllers/index.ts
+++ b/packages/neuron-wallet/src/controllers/index.ts
@@ -2,7 +2,7 @@ import AppController from './app'
import NetworksController from './networks'
import WalletsController from './wallets'
import TransactionsController from './transactions'
-import SyncInfoController from './sync-info'
+import SyncController from './sync'
import UpdateController from './update'
import ApiController from './api'
@@ -12,7 +12,7 @@ export {
NetworksController,
WalletsController,
TransactionsController,
- SyncInfoController,
+ SyncController,
UpdateController,
ApiController,
}
diff --git a/packages/neuron-wallet/src/controllers/sync-info.ts b/packages/neuron-wallet/src/controllers/sync-info.ts
deleted file mode 100644
index 786380441e..0000000000
--- a/packages/neuron-wallet/src/controllers/sync-info.ts
+++ /dev/null
@@ -1,16 +0,0 @@
-import BlockNumber from 'services/sync/block-number'
-import { ResponseCode } from 'utils/const'
-
-export default class SyncInfoController {
- public static async currentBlockNumber() {
- const blockNumber = new BlockNumber()
- const current: bigint = await blockNumber.getCurrent()
-
- return {
- status: ResponseCode.Success,
- result: {
- currentBlockNumber: current.toString(),
- },
- }
- }
-}
diff --git a/packages/neuron-wallet/src/controllers/sync.ts b/packages/neuron-wallet/src/controllers/sync.ts
new file mode 100644
index 0000000000..bdae9a1d40
--- /dev/null
+++ b/packages/neuron-wallet/src/controllers/sync.ts
@@ -0,0 +1,45 @@
+import BlockNumber from 'services/sync/block-number'
+import { createSyncBlockTask, killSyncBlockTask } from 'startup/sync-block-task/create'
+import ChainCleaner from 'database/chain/cleaner'
+import { ResponseCode } from 'utils/const'
+
+export default class SyncController {
+ public static async startSyncing() {
+ createSyncBlockTask()
+
+ return {
+ status: ResponseCode.Success,
+ result: true
+ }
+ }
+
+ public static async stopSyncing() {
+ killSyncBlockTask()
+
+ return {
+ status: ResponseCode.Success,
+ result: true
+ }
+ }
+
+ public static async deleteData() {
+ ChainCleaner.clean()
+
+ return {
+ status: ResponseCode.Success,
+ result: true
+ }
+ }
+
+ public static async currentBlockNumber() {
+ const blockNumber = new BlockNumber()
+ const current: bigint = await blockNumber.getCurrent()
+
+ return {
+ status: ResponseCode.Success,
+ result: {
+ currentBlockNumber: current.toString(),
+ },
+ }
+ }
+}
diff --git a/packages/neuron-wallet/src/database/chain/cleaner.ts b/packages/neuron-wallet/src/database/chain/cleaner.ts
new file mode 100644
index 0000000000..30ee82a673
--- /dev/null
+++ b/packages/neuron-wallet/src/database/chain/cleaner.ts
@@ -0,0 +1,21 @@
+import fs from 'fs'
+import path from 'path'
+import env from 'env'
+
+// Clean local sqlite storage
+export default class ChainCleaner {
+ // Delete all sqlite files under cells folder.
+ // It doesn't handle error or throw exception when deleting fails.
+ public static clean() {
+ const folder = path.join(env.fileBasePath, 'cells')
+ fs.readdir(folder, (err, files) => {
+ if (err) {
+ return
+ }
+
+ for (const file of files.filter(f => { return path.extname(f) === '.sqlite' })) {
+ fs.unlink(path.join(folder, file), () => {})
+ }
+ })
+ }
+}
\ No newline at end of file
diff --git a/packages/neuron-wallet/src/database/chain/ormconfig.ts b/packages/neuron-wallet/src/database/chain/ormconfig.ts
index 988f8a6c1d..058b5919b5 100644
--- a/packages/neuron-wallet/src/database/chain/ormconfig.ts
+++ b/packages/neuron-wallet/src/database/chain/ormconfig.ts
@@ -22,9 +22,9 @@ import { AddInputIndexToInput1573461100330 } from './migrations/1573461100330-Ad
export const CONNECTION_NOT_FOUND_NAME = 'ConnectionNotFoundError'
-const dbPath = (networkName: string): string => {
- const name = `cell-${networkName}.sqlite`
- return path.join(env.fileBasePath, 'cells', name)
+const dbPath = (name: string): string => {
+ const filename = `cell-${name}.sqlite`
+ return path.join(env.fileBasePath, 'cells', filename)
}
const connectOptions = async (genesisBlockHash: string): Promise => {
diff --git a/packages/neuron-wallet/src/main.ts b/packages/neuron-wallet/src/main.ts
index 257b253887..95b6030ec8 100644
--- a/packages/neuron-wallet/src/main.ts
+++ b/packages/neuron-wallet/src/main.ts
@@ -1,8 +1,8 @@
import { app } from 'electron'
import AppController from 'controllers/app'
+import SyncController from 'controllers/sync'
import WalletService from 'services/wallets'
-import createSyncBlockTask from 'startup/sync-block-task/create'
import { changeLanguage } from 'utils/i18n'
const appController = new AppController()
@@ -11,7 +11,7 @@ app.on('ready', async () => {
changeLanguage(app.getLocale())
WalletService.getInstance().generateAddressesIfNecessary()
- createSyncBlockTask()
+ SyncController.startSyncing()
appController.openWindow()
})
diff --git a/packages/neuron-wallet/src/services/sync/renderer-params.ts b/packages/neuron-wallet/src/services/sync/renderer-params.ts
index 30f0fee9c9..e426dcb183 100644
--- a/packages/neuron-wallet/src/services/sync/renderer-params.ts
+++ b/packages/neuron-wallet/src/services/sync/renderer-params.ts
@@ -1,5 +1,7 @@
import { remote } from 'electron'
-export const { networkSwitchSubject, nodeService, addressChangeSubject, addressesUsedSubject } = remote.require(
+export const {
+ networkSwitchSubject, nodeService, addressChangeSubject, addressesUsedSubject
+} = remote.require(
'./startup/sync-block-task/params'
)
diff --git a/packages/neuron-wallet/src/startup/sync-block-task/create.ts b/packages/neuron-wallet/src/startup/sync-block-task/create.ts
index 222e8791a9..19b8d04fe9 100644
--- a/packages/neuron-wallet/src/startup/sync-block-task/create.ts
+++ b/packages/neuron-wallet/src/startup/sync-block-task/create.ts
@@ -74,10 +74,17 @@ const loadURL = `file://${path.join(__dirname, 'index.html')}`
export { networkSwitchSubject }
+let syncBlockBackgroundWindow: BrowserWindow | null
+
// create a background task to sync transactions
// this task is a renderer process
-const createSyncBlockTask = () => {
- let syncBlockBackgroundWindow: BrowserWindow | null = new BrowserWindow({
+export const createSyncBlockTask = () => {
+ if (syncBlockBackgroundWindow) {
+ return
+ }
+
+ console.info('Start sync block background process')
+ syncBlockBackgroundWindow = new BrowserWindow({
width: 1366,
height: 768,
show: false,
@@ -86,8 +93,6 @@ const createSyncBlockTask = () => {
},
})
- syncBlockBackgroundWindow.loadURL(loadURL)
-
syncBlockBackgroundWindow.on('ready-to-show', async () => {
if (env.isDevMode && process.env.DEV_SYNC_TASK) {
syncBlockBackgroundWindow!.show()
@@ -100,7 +105,15 @@ const createSyncBlockTask = () => {
syncBlockBackgroundWindow = null
})
+ syncBlockBackgroundWindow.loadURL(loadURL)
+
return syncBlockBackgroundWindow
}
-export default createSyncBlockTask
+export const killSyncBlockTask = async () => {
+ if (syncBlockBackgroundWindow) {
+ console.info('Kill sync block background process')
+ // TODO: kill block number listener
+ syncBlockBackgroundWindow.close()
+ }
+}
diff --git a/packages/neuron-wallet/src/startup/sync-block-task/sync.ts b/packages/neuron-wallet/src/startup/sync-block-task/sync.ts
index 7d0e7d87f8..e0a05985a1 100644
--- a/packages/neuron-wallet/src/startup/sync-block-task/sync.ts
+++ b/packages/neuron-wallet/src/startup/sync-block-task/sync.ts
@@ -79,4 +79,4 @@ export const switchNetwork = async (url: string, genesisBlockHash: string, _chai
})
blockListener.start()
-}
+}
\ No newline at end of file