diff --git a/packages/neuron-ui/src/components/DataSetting/hooks.ts b/packages/neuron-ui/src/components/DataSetting/hooks.ts index 44a07d733f..6f7b461a81 100644 --- a/packages/neuron-ui/src/components/DataSetting/hooks.ts +++ b/packages/neuron-ui/src/components/DataSetting/hooks.ts @@ -17,6 +17,8 @@ export const useDataPath = ( type: Parameters[0] ) => { const [t] = useTranslation() + const [isSaving, setIsSaveing] = useState(false) + const [savingType, setSavingType] = useState() const [prevPath, setPrevPath] = useState() const [currentPath, setCurrentPath] = useState() const { dialogRef, openDialog, closeDialog } = useDialogWrapper() @@ -49,14 +51,28 @@ export const useDataPath = ( } }) }, [closeDialog, type]) - const onConfirm = useCallback(() => { - setPath(currentPath!).then(res => { - if (isSuccessResponse(res)) { - setPrevPath(currentPath) - closeDialog() - } - }) - }, [currentPath, closeDialog, setPrevPath, setPath]) + const onConfirm = useCallback( + e => { + const { dataset } = e.currentTarget + setIsSaveing(true) + setSavingType(dataset.syncType) + setPath({ + dataPath: currentPath!, + clearCache: type === 'ckb' && dataset?.resync === 'true', + }) + .then(res => { + if (isSuccessResponse(res)) { + setPrevPath(currentPath) + closeDialog() + } + }) + .finally(() => { + setIsSaveing(false) + setSavingType(null) + }) + }, + [currentPath, closeDialog, setPrevPath, setPath] + ) return { prevPath, currentPath, @@ -64,6 +80,8 @@ export const useDataPath = ( dialogRef, onCancel, onConfirm, + isSaving, + savingType, } } diff --git a/packages/neuron-ui/src/components/DataSetting/index.module.scss b/packages/neuron-ui/src/components/DataSetting/index.module.scss index 63ebb162b1..dcfd558df8 100644 --- a/packages/neuron-ui/src/components/DataSetting/index.module.scss +++ b/packages/neuron-ui/src/components/DataSetting/index.module.scss @@ -9,6 +9,7 @@ .name { font-weight: bold; + display: flex; } .content { @@ -63,4 +64,29 @@ & > svg { flex-shrink: 0; } -} \ No newline at end of file +} + +.infoIconContainer { + position: relative; + display: inline-flex; + align-items: center; + padding-left: 4px; + z-index: 11; + + &::after { + display: none; + position: absolute; + left: -20px; + top: 120%; + content: attr(data-tip); + padding: 4px 12px; + border-radius: 6px; + background: #cccccc; + font-weight: 300; + width: 400px; + } + + &:hover::after { + display: block; + } +} diff --git a/packages/neuron-ui/src/components/DataSetting/index.tsx b/packages/neuron-ui/src/components/DataSetting/index.tsx index eaf994a914..aec1541534 100644 --- a/packages/neuron-ui/src/components/DataSetting/index.tsx +++ b/packages/neuron-ui/src/components/DataSetting/index.tsx @@ -6,8 +6,9 @@ import { useDispatch } from 'states' import { getCkbNodeDataPath, getIndexerDataPath, setCkbNodeDataPath, setIndexerDataPath } from 'services/remote' import { ReactComponent as Attention } from 'widgets/Icons/ExperimentalAttention.svg' import CopyZone from 'widgets/CopyZone' -import { OpenFolder } from 'widgets/Icons/icon' +import { OpenFolder, InfoCircleOutlined } from 'widgets/Icons/icon' import { shell } from 'electron' +import Spinner from 'widgets/Spinner' import { useDataPath } from './hooks' import styles from './index.module.scss' @@ -41,7 +42,7 @@ const itemProps: Record< const SetItem = ({ type }: { type: keyof typeof itemProps }) => { const props = itemProps[type] const [t] = useTranslation() - const { onSetting, prevPath, currentPath, dialogRef, onCancel, onConfirm } = useDataPath( + const { onSetting, prevPath, currentPath, dialogRef, onCancel, onConfirm, isSaving, savingType } = useDataPath( props.getPath, props.setPath, props.type @@ -53,7 +54,15 @@ const SetItem = ({ type }: { type: keyof typeof itemProps }) => { }, [prevPath]) return ( <> -
{t(`settings.data.${props.titleI18nKey}`)}:
+
+ {t(`settings.data.${props.titleI18nKey}`)} + {type === 'ckbNode' ? ( + + + + ) : null} + : +
{prevPath} @@ -65,12 +74,47 @@ const SetItem = ({ type }: { type: keyof typeof itemProps }) => {
{t(`settings.data.${props.tipI18nKey}`, { prevPath, currentPath })}
- {t('settings.data.resync-describe')} + {type === 'ckbNode' + ? t('settings.data.resync-ckb-node-describe') + : t('settings.data.resync-indexer-describe')}
- +
diff --git a/packages/neuron-ui/src/locales/en.json b/packages/neuron-ui/src/locales/en.json index f368780878..216627233f 100644 --- a/packages/neuron-ui/src/locales/en.json +++ b/packages/neuron-ui/src/locales/en.json @@ -372,7 +372,7 @@ } }, "data": { - "ckb-node-data": "CKB Node Data", + "ckb-node-data": "CKB Node Config & Storage", "ckb-indexer-data": "CKB Indexer Data", "set": "Set", "cache": "Cache", @@ -382,10 +382,12 @@ "clearing-cache": "Clearing...", "remove-ckb-data-tip": "Please move CKB Node Data from {{prevPath}} to {{currentPath}} and then click on \"Data have been moved\" to start from the previously synchronized block; Or click on \"Synchronize from scratch\" to start with synchronizing from scratch.", "remove-indexer-data-tip": "Please move Indexer Data from {{prevPath}} to {{currentPath}} and then click on \"Data have been moved\" to start from the previously synchronized block; Or click on \"Synchronize from scratch\" to start with synchronizing from scratch.", - "resync-describe": "Attention: Synchronize from scratch won't remove previously downloaded CKB Node(or Indexer) Data.", + "resync-ckb-node-describe": "Attention: Synchronizing from scratch won't remove previously downloaded CKB Node Data, but it will remove downloaded Indexer Data", + "resync-indexer-describe": "Attention: Synchronizing from scratch won't remove previously downloaded Indexer Data.", "cancel": "Cancel", "move-data-finish": "Data have been moved", - "re-sync": "Synchronize from scratch" + "re-sync": "Synchronize from scratch", + "disabled-set-path": "When the CKB node is started manually, the CKB Node Config and Storage path configuration doesn't take effect" } }, "password-request": { diff --git a/packages/neuron-ui/src/locales/zh-tw.json b/packages/neuron-ui/src/locales/zh-tw.json index 86bd7072c0..1efcb3f965 100644 --- a/packages/neuron-ui/src/locales/zh-tw.json +++ b/packages/neuron-ui/src/locales/zh-tw.json @@ -365,7 +365,7 @@ } }, "data": { - "ckb-node-data": "節點數據", + "ckb-node-data": "節點配置和數據", "ckb-indexer-data": "Indexer 數據", "set": "設置", "cache": "緩存", @@ -376,9 +376,11 @@ "remove-ckb-data-tip": "請將 CKB Node 數據從 {{prevPath}} 移動至 {{currentPath}}然後點擊 \"數據轉移完成\" 開始從已知區塊同步; 否則點擊 \"重新同步\" 開始重新同步.", "remove-indexer-data-tip": "請將 Indexer 數據從 {{prevPath}} 移動至 {{currentPath}}然後點擊 \"數據轉移完成\" 開始從已知區塊同步; 否則點擊 \"重新同步\" 開始重新同步.", "cancel": "取消", - "resync-describe": "註意: 重新同步不會刪除當前已同步的 CKB Node(Indexer) 數據.", + "resync-ckb-node-describe": "註意: 重新同步不會刪除當前已同步的 CKB Node 數據,但會刪除已同步的 Indexer 數據。", + "resync-indexer-describe": "註意: 重新同步不會刪除當前已同步的 Indexer 數據.", "move-data-finish": "數據轉移完成", - "re-sync": "重新同步" + "re-sync": "重新同步", + "disabled-set-path": "手動啟動 CKB 節點時,設置 CKB Node 節點配置和路徑無法生效" } }, "password-request": { diff --git a/packages/neuron-ui/src/locales/zh.json b/packages/neuron-ui/src/locales/zh.json index 186a8c1406..ccd351d180 100644 --- a/packages/neuron-ui/src/locales/zh.json +++ b/packages/neuron-ui/src/locales/zh.json @@ -365,7 +365,7 @@ } }, "data": { - "ckb-node-data": "节点数据", + "ckb-node-data": "节点配置和数据", "ckb-indexer-data": "Indexer 数据", "set": "设置", "cache": "缓存", @@ -375,10 +375,12 @@ "clearing-cache": "清空中...", "remove-ckb-data-tip": "请将 CKB Node 数据从 {{prevPath}} 移动至 {{currentPath}}然后点击 \"数据转移完成\" 开始从已知区块同步; 否则点击 \"重新同步\" 开始重新同步.", "remove-indexer-data-tip": "请将 Indexer 数据从 {{prevPath}} 移动至 {{currentPath}}然后点击 \"数据转移完成\" 开始从已知区块同步; 否则点击 \"重新同步\" 开始重新同步.", - "resync-describe": "注意: 重新同步不会删除当前已同步的 CKB Node(Indexer) 数据.", + "resync-ckb-node-describe": "注意: 重新同步不会删除当前已同步的 CKB Node 数据,但会删除已同步的 Indexer 数据。", + "resync-indexer-describe": "注意: 重新同步不会删除当前已同步的 Indexer 数据.", "cancel": "取消", "move-data-finish": "数据转移完成", - "re-sync": "重新同步" + "re-sync": "重新同步", + "disabled-set-path": "手动启动 CKB 节点时,设置 CKB Node 节点配置和路径无法生效" } }, "password-request": { diff --git a/packages/neuron-ui/src/services/remote/app.ts b/packages/neuron-ui/src/services/remote/app.ts index 76340290cd..20fe5a0c06 100644 --- a/packages/neuron-ui/src/services/remote/app.ts +++ b/packages/neuron-ui/src/services/remote/app.ts @@ -18,9 +18,11 @@ export const handleViewError = remoteApi('handle-view-error') export const showSettings = remoteApi('show-settings') export const setLocale = remoteApi('set-locale') export const getCkbNodeDataPath = remoteApi('get-ckb-node-data-path') -export const setCkbNodeDataPath = remoteApi('set-ckb-node-data-path') +export const setCkbNodeDataPath = remoteApi<{ dataPath: string; clearCache?: boolean }, string>( + 'set-ckb-node-data-path' +) export const getIndexerDataPath = remoteApi('get-indexer-data-path') -export const setIndexerDataPath = remoteApi('set-indexer-data-path') +export const setIndexerDataPath = remoteApi<{ dataPath: string }, string>('set-indexer-data-path') export const stopProcessMonitor = remoteApi<'ckb' | 'ckb-indexer'>('stop-process-monitor') export const startProcessMonitor = remoteApi<'ckb' | 'ckb-indexer'>('start-process-monitor') diff --git a/packages/neuron-wallet/src/controllers/api.ts b/packages/neuron-wallet/src/controllers/api.ts index 2488d9a9e7..33d77cf380 100644 --- a/packages/neuron-wallet/src/controllers/api.ts +++ b/packages/neuron-wallet/src/controllers/api.ts @@ -13,6 +13,8 @@ import { BrowserWindow } from 'electron' import { t } from 'i18next' +import path from 'path' +import fs from 'fs' import env from 'env' import { showWindow } from './app/show-window' import CommonUtils from 'utils/common' @@ -462,9 +464,27 @@ export default class ApiController { } }) - handle('set-ckb-node-data-path', (_, dataPath: string) => { + handle('set-ckb-node-data-path', async (_, { dataPath, clearCache }: { dataPath: string; clearCache: boolean }) => { + let finallyClearCache = clearCache + if (!finallyClearCache && !fs.existsSync(path.join(dataPath, 'ckb.toml'))) { + const { response } = await dialog.showMessageBox(BrowserWindow.getFocusedWindow()!, { + type: 'info', + message: t('messages.no-exist-ckb-node-data', { path: dataPath }), + buttons: [t('common.ok'), t('common.cancel')] + }) + if (response === 1) { + return { + status: ResponseCode.Fail, + } + } else { + finallyClearCache = true + } + } SettingsService.getInstance().ckbDataPath = dataPath - stopMonitor('ckb-indexer') + await stopMonitor('ckb-indexer') + if (finallyClearCache) { + await IndexerService.clearCache(true) + } startMonitor(undefined, true) return { status: ResponseCode.Success, @@ -479,7 +499,7 @@ export default class ApiController { } }) - handle('set-indexer-data-path', (_, dataPath: string) => { + handle('set-indexer-data-path', (_, { dataPath }: { dataPath: string }) => { SettingsService.getInstance().indexerDataPath = dataPath startMonitor('ckb-indexer', true) return { diff --git a/packages/neuron-wallet/src/locales/en.ts b/packages/neuron-wallet/src/locales/en.ts index 482fe0dc5a..2a1b83aff3 100644 --- a/packages/neuron-wallet/src/locales/en.ts +++ b/packages/neuron-wallet/src/locales/en.ts @@ -133,7 +133,8 @@ export default { 'multisig-lock-hash-mismatch': 'The current multisig address does not match the transaction to be approved', 'sudt-acp-have-data': 'The destroying sUDT acp account have amount', 'no-match-address-for-sign': 'Not found matched address', - 'target-lock-error': 'CKB asset account can only transfer to sepe256k1 or acp address' + 'target-lock-error': 'CKB asset account can only transfer to sepe256k1 or acp address', + 'no-exist-ckb-node-data': '{{path}} has no CKB Node config and storage, press ok to synchronize from scratch' }, messageBox: { button: { diff --git a/packages/neuron-wallet/src/locales/zh-tw.ts b/packages/neuron-wallet/src/locales/zh-tw.ts index a55529586c..41e531a3b1 100644 --- a/packages/neuron-wallet/src/locales/zh-tw.ts +++ b/packages/neuron-wallet/src/locales/zh-tw.ts @@ -123,7 +123,8 @@ export default { 'multisig-not-signed': '多簽交易缺少部分簽名', 'sudt-acp-have-data': '待銷毀的 sUDT 賬戶資產不為 0', 'no-match-address-for-sign': '没有找到匹配的地址', - 'target-lock-error': 'CKB 資產只能轉賬到 secp256k1 或者 acp 地址' + 'target-lock-error': 'CKB 資產只能轉賬到 secp256k1 或者 acp 地址', + 'no-exist-ckb-node-data': '{{path}} 目錄下沒有找到 CKB Node 配置和數據, 點擊繼續重新同步' }, messageBox: { button: { diff --git a/packages/neuron-wallet/src/locales/zh.ts b/packages/neuron-wallet/src/locales/zh.ts index 86a2a59832..158abe7ec2 100644 --- a/packages/neuron-wallet/src/locales/zh.ts +++ b/packages/neuron-wallet/src/locales/zh.ts @@ -124,7 +124,8 @@ export default { 'multisig-not-signed': '多签交易缺少部分签名', 'sudt-acp-have-data': '待销毁的 sUDT 账户资产不为 0', 'no-match-address-for-sign': '没有找到匹配的地址', - 'target-lock-error': 'CKB 资产只能转账到 secp256k1 或者 acp 地址' + 'target-lock-error': 'CKB 资产只能转账到 secp256k1 或者 acp 地址', + 'no-exist-ckb-node-data': '{{path}} 目录下没有找到 CKB Node 配置和数据, 点击继续重新同步' }, messageBox: { button: {