diff --git a/.github/workflows/add-replied-label.yml b/.github/workflows/add-replied-label.yml index 0dc24712f5..5e596dd725 100644 --- a/.github/workflows/add-replied-label.yml +++ b/.github/workflows/add-replied-label.yml @@ -7,26 +7,53 @@ on: jobs: add-label: runs-on: ubuntu-latest + permissions: + issues: write steps: - id: check-access - name: Check if the commenter has write access + name: Check if the commenter is a collaborator uses: actions/github-script@v4 with: script: | - const response = await github.repos.checkCollaborator({ + try{ + const response = await github.repos.checkCollaborator({ + owner: context.repo.owner, + repo: context.repo.repo, + username: context.payload.comment.user.login, + }) + return response.status === 204 + } catch { + return false + } + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + - id: check-issue + name: Check if the comment is replied in an issue + uses: actions/github-script@v4 + with: + script: | + const response = await github.issues.get({ owner: context.repo.owner, repo: context.repo.repo, - username: context.payload.comment.user.login, + issue_number: context.issue.number, }) - return { hasWriteAccess: response.data.permission === 'write' } + return response.data.pull_request === undefined env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - id: add-label name: Add 'replied' label - if: steps.check-access.outputs.hasWriteAccess - uses: actions-ecosystem/action-add-label@v1 + if: ${{ steps.check-access.outputs.result == 'true' && steps.check-issue.outputs.result == 'true' }} + uses: actions/github-script@v4 with: - repo-token: ${{ secrets.GITHUB_TOKEN }} - issue-number: ${{ github.event.issue.number }} - label: replied + script: | + await github.issues.addLabels({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: context.issue.number, + labels: process.env.labels.split(', '), + }) + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + labels: 'replied' diff --git a/packages/neuron-ui/src/containers/Notification/index.tsx b/packages/neuron-ui/src/containers/Notification/index.tsx index f23cbb0588..8efab67577 100644 --- a/packages/neuron-ui/src/containers/Notification/index.tsx +++ b/packages/neuron-ui/src/containers/Notification/index.tsx @@ -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' @@ -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') => { @@ -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] @@ -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() + useDidMount(() => { + getCkbNodeDataPath().then(res => { + if (isSuccessResponse(res) && res.result) { + setCkbDataPath(res.result) + } + }) + }) + + const onOpenDataDir = useCallback(() => { + if (ckbDataPath) { + shell.openPath(ckbDataPath) + } + }, [ckbDataPath]) + return (
{showTopAlert && notification ? ( @@ -197,7 +218,7 @@ export const NoticeContent = () => { ) })} - +
) diff --git a/packages/neuron-ui/src/locales/en.json b/packages/neuron-ui/src/locales/en.json index 7f0fecd41f..be611a6196 100644 --- a/packages/neuron-ui/src/locales/en.json +++ b/packages/neuron-ui/src/locales/en.json @@ -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": { diff --git a/packages/neuron-ui/src/locales/zh-tw.json b/packages/neuron-ui/src/locales/zh-tw.json index d45a4fe26f..ad2508617b 100644 --- a/packages/neuron-ui/src/locales/zh-tw.json +++ b/packages/neuron-ui/src/locales/zh-tw.json @@ -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": { diff --git a/packages/neuron-ui/src/locales/zh.json b/packages/neuron-ui/src/locales/zh.json index aa817d5a31..5cd4ba3825 100644 --- a/packages/neuron-ui/src/locales/zh.json +++ b/packages/neuron-ui/src/locales/zh.json @@ -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": { diff --git a/packages/neuron-ui/src/services/subjects.ts b/packages/neuron-ui/src/services/subjects.ts index 6a486a420b..628d367feb 100644 --- a/packages/neuron-ui/src/services/subjects.ts +++ b/packages/neuron-ui/src/services/subjects.ts @@ -65,7 +65,7 @@ export const Navigation = SubjectConstructor('navigation') export const SetLocale = SubjectConstructor('set-locale') export const DeviceSignIndex = SubjectConstructor('device-sign-index') export const MultisigOutputUpdate = SubjectConstructor('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, diff --git a/packages/neuron-ui/src/stories/GlobalDialog.stories.tsx b/packages/neuron-ui/src/stories/GlobalDialog.stories.tsx index 561f9ea6c4..7d1e9d8750 100644 --- a/packages/neuron-ui/src/stories/GlobalDialog.stories.tsx +++ b/packages/neuron-ui/src/stories/GlobalDialog.stories.tsx @@ -9,6 +9,6 @@ const types: State.GlobalDialogType[] = ['unlock-success', 'rebuild-sync', null] types.forEach(type => { stories.add(type || 'Null', () => { - return + return }) }) diff --git a/packages/neuron-ui/src/utils/const.ts b/packages/neuron-ui/src/utils/const.ts index 419adb3478..69d33c9b2f 100644 --- a/packages/neuron-ui/src/utils/const.ts +++ b/packages/neuron-ui/src/utils/const.ts @@ -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 = { AcpOnLina: '0x0fb343953ee78c9986b091defb6252154e0bb51044fd2879fde5b27314506111', diff --git a/packages/neuron-ui/src/utils/hooks/index.ts b/packages/neuron-ui/src/utils/hooks/index.ts index f30eeb3d0d..47576ee7f5 100644 --- a/packages/neuron-ui/src/utils/hooks/index.ts +++ b/packages/neuron-ui/src/utils/hooks/index.ts @@ -433,27 +433,30 @@ export const useOnHandleNetwork = ({ history }: { history: ReturnType + 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) => { diff --git a/packages/neuron-ui/src/widgets/GlobalDialog/index.tsx b/packages/neuron-ui/src/widgets/GlobalDialog/index.tsx index 4c9796b20c..1201039e74 100644 --- a/packages/neuron-ui/src/widgets/GlobalDialog/index.tsx +++ b/packages/neuron-ui/src/widgets/GlobalDialog/index.tsx @@ -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 (
@@ -23,8 +23,10 @@ const RebuildSync = ({ onDismiss, onOk }: { onDismiss: React.MouseEventHandler; .map((s: string) => (

{s}

))} +

{t('messages.migrate-warning')}

@@ -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) { @@ -47,7 +50,7 @@ const GlobalDialog = ({ onDismiss, type, onOk }: GlobalDialogProps) => { } case 'rebuild-sync': { maskClosable = false - content = + content = break } default: { diff --git a/packages/neuron-wallet/src/main.ts b/packages/neuron-wallet/src/main.ts index d9f8c57179..e358754995 100644 --- a/packages/neuron-wallet/src/main.ts +++ b/packages/neuron-wallet/src/main.ts @@ -17,7 +17,7 @@ if (singleInstanceLock) { }) app.on('before-quit', async () => { - logger.info('App:\tNeuron will exist') + logger.info('App:\tNeuron will exit') await appController.end() })