Skip to content
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
35 changes: 28 additions & 7 deletions packages/neuron-ui/src/containers/Notification/index.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { useMemo, useCallback, MouseEventHandler } from 'react'
import React, { useMemo, useCallback, MouseEventHandler, useState } from 'react'
import { createPortal } from 'react-dom'
import { useTranslation } from 'react-i18next'
import { Stack, MessageBar, MessageBarType, IconButton, Panel, PanelType, Text } from 'office-ui-fabric-react'
Expand All @@ -11,12 +11,13 @@ import {
dismissNotification,
dismissGlobalDialog,
} from 'states'
import { useOnLocaleChange, useGlobalNotifications, isSuccessResponse } from 'utils'
import { useOnLocaleChange, useGlobalNotifications, isSuccessResponse, useDidMount } from 'utils'
import { shell } from 'electron'

import GlobalDialog from 'widgets/GlobalDialog'
import AlertDialog from 'widgets/AlertDialog'
import { syncRebuildNotification } from 'services/localCache'
import { migrateData } from 'services/remote'
import { getCkbNodeDataPath, migrateData } from 'services/remote'
import styles from './Notification.module.scss'

const notificationType = (type: 'success' | 'warning' | 'alert') => {
Expand Down Expand Up @@ -79,7 +80,8 @@ export const NoticeContent = () => {
const dispatch = useDispatch()
const [t, i18n] = useTranslation()
useOnLocaleChange(i18n)
useGlobalNotifications(dispatch)
const [hasDismissMigrate, setHasDismissMigrate] = useState(false)
useGlobalNotifications(dispatch, hasDismissMigrate)

const notificationsInDesc = useMemo(() => [...notifications].reverse(), [notifications])
const notification: State.Message | undefined = notificationsInDesc[0]
Expand All @@ -101,17 +103,36 @@ export const NoticeContent = () => {

const onGlobalDialogDismiss = useCallback(() => {
dismissGlobalDialog()(dispatch)
}, [dispatch])
if (globalDialog === 'rebuild-sync') {
setHasDismissMigrate(true)
}
}, [dispatch, globalDialog])

const onOk = useCallback(() => {
migrateData().then(res => {
if (isSuccessResponse(res)) {
dismissGlobalDialog()(dispatch)
syncRebuildNotification.save()
}
}).finally(() => {
syncRebuildNotification.save()
})
}, [dispatch])

const [ckbDataPath, setCkbDataPath] = useState<string>()
useDidMount(() => {
getCkbNodeDataPath().then(res => {
if (isSuccessResponse(res) && res.result) {
setCkbDataPath(res.result)
}
})
})

const onOpenDataDir = useCallback(() => {
if (ckbDataPath) {
shell.openPath(ckbDataPath)
}
}, [ckbDataPath])

return (
<div>
{showTopAlert && notification ? (
Expand Down Expand Up @@ -197,7 +218,7 @@ export const NoticeContent = () => {
)
})}
</Panel>
<GlobalDialog type={globalDialog} onDismiss={onGlobalDialogDismiss} onOk={onOk} />
<GlobalDialog type={globalDialog} onDismiss={onGlobalDialogDismiss} onOk={onOk} onBackUp={onOpenDataDir} />
<AlertDialog content={alertDialog} dispatch={dispatch} />
</div>
)
Expand Down
1 change: 1 addition & 0 deletions packages/neuron-ui/src/locales/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -506,6 +506,7 @@
"experimental-message-hardware": "This is an experimental feature. Please pay attention to the risk and use with caution.",
"experimental-message": "This is an experimental feature, it could change at any time. Please use with caution.",
"rebuild-sync": "For better user experience, Neuron has adopted a new storage, which requires a migrating of data (estimated 20 ~ 60min).\nSorry for the inconvenience.",
"migrate-warning": "Warning: The migration process may fail for unknown reasons resulting in resynchronization, please back up manually and start the migration!",
"migrate": "Migrate",
"secp256k1/blake160-address-required": "Secp256k1/blake160 address is required",
"fields": {
Expand Down
1 change: 1 addition & 0 deletions packages/neuron-ui/src/locales/zh-tw.json
Original file line number Diff line number Diff line change
Expand Up @@ -499,6 +499,7 @@
"experimental-message-hardware": "本功能為實驗性功能,請註意風險,謹慎使用。",
"experimental-message": "本頁面為實驗性功能,可能隨時變更。請謹慎使用。",
"rebuild-sync": "為了提供更好的用戶體驗,Neuron 採取了新的存儲方案,該方案需要壹次性遷移數據(預期同步時間為 20~60 分鐘)。\n抱歉給您帶來不便。",
"migrate-warning": "註意:遷移過程中可能由於未知原因失敗導致需要重新同步,請備份完成後開始遷移!",
"migrate": "遷移",
"secp256k1/blake160-address-required": "請輸入 secp256k1/blake160 地址",
"fields": {
Expand Down
1 change: 1 addition & 0 deletions packages/neuron-ui/src/locales/zh.json
Original file line number Diff line number Diff line change
Expand Up @@ -499,6 +499,7 @@
"experimental-message-hardware": "本功能为实验性功能,请注意风险,谨慎使用。",
"experimental-message": "本页面为实验性功能,可能随时变更。请谨慎使用。",
"rebuild-sync": "为了提供更好的用户体验,Neuron 採取了新的存储方案,该方案需要一次性迁移数据(预期同步时间为 20~60 分钟)。\n抱歉给您带来不便。",
"migrate-warning": "注意:迁移过程中可能由于未知原因失败导致需要重新同步,请备份完成后开始迁移!",
"migrate": "迁移",
"secp256k1/blake160-address-required": "请输入 secp256k1/blake160 地址",
"fields": {
Expand Down
2 changes: 1 addition & 1 deletion packages/neuron-ui/src/services/subjects.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ export const Navigation = SubjectConstructor<Subject.URL>('navigation')
export const SetLocale = SubjectConstructor<typeof LOCALES[number]>('set-locale')
export const DeviceSignIndex = SubjectConstructor<Subject.SignIndex>('device-sign-index')
export const MultisigOutputUpdate = SubjectConstructor<string>('multisig-output-update')
export const Migrate = SubjectConstructor<'need-migrate' | 'migrating' | 'failed' | 'finish'>('migrate', true)
export const Migrate = SubjectConstructor<'need-migrate' | 'migrating' | 'failed' | 'finish'>('migrate')

export default {
DataUpdate,
Expand Down
2 changes: 1 addition & 1 deletion packages/neuron-ui/src/stories/GlobalDialog.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,6 @@ const types: State.GlobalDialogType[] = ['unlock-success', 'rebuild-sync', null]

types.forEach(type => {
stories.add(type || 'Null', () => {
return <GlobalDialog type={type} onDismiss={action('Dismiss')} onOk={action('onOk')} />
return <GlobalDialog type={type} onDismiss={action('Dismiss')} onBackUp={action('onBackUp')} onOk={action('onOk')} />
})
})
2 changes: 1 addition & 1 deletion packages/neuron-ui/src/utils/const.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ export const LONG_DATA_PREFIX = '0x02'
export const LONG_TYPE_PREFIX = '0x04'

// times
export const SYNC_REBUILD_SINCE_VERSION = '0.105'
export const SYNC_REBUILD_SINCE_VERSION = '0.108'

export const DEPRECATED_CODE_HASH: Record<string, string> = {
AcpOnLina: '0x0fb343953ee78c9986b091defb6252154e0bb51044fd2879fde5b27314506111',
Expand Down
21 changes: 12 additions & 9 deletions packages/neuron-ui/src/utils/hooks/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -433,27 +433,30 @@ export const useOnHandleNetwork = ({ history }: { history: ReturnType<typeof use
)

export const useGlobalNotifications = (
dispatch: React.Dispatch<{ type: AppActions.SetGlobalDialog; payload: State.GlobalDialogType }>
dispatch: React.Dispatch<{ type: AppActions.SetGlobalDialog; payload: State.GlobalDialogType }>,
hasDismissMigrate: boolean
) => {
useEffect(() => {
const lastVersion = syncRebuildNotification.load()
const isVersionUpdate = isReadyByVersion(CONSTANTS.SYNC_REBUILD_SINCE_VERSION, lastVersion)
if (isVersionUpdate) {
dispatch({
type: AppActions.SetGlobalDialog,
payload: 'rebuild-sync',
})
}
const migrateSubscription = Migrate.subscribe(migrateStatus => {
if (!isVersionUpdate && migrateStatus === 'need-migrate') {
if (migrateStatus !== 'need-migrate') return
if (lastVersion && !isVersionUpdate) {
// means has click migrate for current version, so migrate silent
migrateData()
migrateSubscription.unsubscribe()
} else if (!hasDismissMigrate) {
// means need click ok to migrate
dispatch({
type: AppActions.SetGlobalDialog,
payload: 'rebuild-sync',
})
}
})
return () => {
migrateSubscription.unsubscribe()
}
}, [dispatch])
}, [dispatch, hasDismissMigrate])
}

export const useDidMount = (cb: () => void) => {
Expand Down
9 changes: 6 additions & 3 deletions packages/neuron-ui/src/widgets/GlobalDialog/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ const UnlockSuccess = () => {
)
}

const RebuildSync = ({ onDismiss, onOk }: { onDismiss: React.MouseEventHandler; onOk: React.MouseEventHandler }) => {
const RebuildSync = ({ onDismiss, onBackUp, onOk }: { onDismiss: React.MouseEventHandler; onBackUp: React.MouseEventHandler; onOk: React.MouseEventHandler }) => {
const [t] = useTranslation()
return (
<div style={{ fontWeight: 200 }}>
Expand All @@ -23,8 +23,10 @@ const RebuildSync = ({ onDismiss, onOk }: { onDismiss: React.MouseEventHandler;
.map((s: string) => (
<p key={s}>{s}</p>
))}
<p>{t('messages.migrate-warning')}</p>
<div style={{ textAlign: 'right' }}>
<Button type="cancel" label={t('common.cancel')} onClick={onDismiss} style={{ marginRight: '24px' }} />
<Button type="primary" label={t('common.backup')} onClick={onBackUp} style={{ marginRight: '24px' }} />
<Button type="primary" label={t('messages.migrate')} onClick={onOk} />
</div>
</div>
Expand All @@ -34,10 +36,11 @@ const RebuildSync = ({ onDismiss, onOk }: { onDismiss: React.MouseEventHandler;
interface GlobalDialogProps {
onDismiss: React.MouseEventHandler
onOk: React.MouseEventHandler
onBackUp: React.MouseEventHandler
type: State.GlobalDialogType
}

const GlobalDialog = ({ onDismiss, type, onOk }: GlobalDialogProps) => {
const GlobalDialog = ({ onDismiss, type, onOk, onBackUp }: GlobalDialogProps) => {
let content = null
let maskClosable = true
switch (type) {
Expand All @@ -47,7 +50,7 @@ const GlobalDialog = ({ onDismiss, type, onOk }: GlobalDialogProps) => {
}
case 'rebuild-sync': {
maskClosable = false
content = <RebuildSync onDismiss={onDismiss} onOk={onOk} />
content = <RebuildSync onDismiss={onDismiss} onOk={onOk} onBackUp={onBackUp} />
break
}
default: {
Expand Down