From cc064529793fbb2968e139180eb2dac1c2217d79 Mon Sep 17 00:00:00 2001 From: Keith Date: Wed, 17 Jul 2019 14:14:31 +0800 Subject: [PATCH 01/10] test(neuron-ui): fix data of sync status stories --- packages/neuron-ui/src/stories/SyncStatus.stories.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/neuron-ui/src/stories/SyncStatus.stories.tsx b/packages/neuron-ui/src/stories/SyncStatus.stories.tsx index 984349e9c7..d9258a4a9b 100644 --- a/packages/neuron-ui/src/stories/SyncStatus.stories.tsx +++ b/packages/neuron-ui/src/stories/SyncStatus.stories.tsx @@ -11,7 +11,7 @@ const states = { bufferBlockNumber: 10, }, '0/100': { - tipBlockNumber: '0', + tipBlockNumber: '100', syncedBlockNumber: '0', bufferBlockNumber: 10, }, From 0d1b49fd83be2f942caa0f085175ccd677d61758 Mon Sep 17 00:00:00 2001 From: Keith Date: Wed, 17 Jul 2019 15:36:27 +0800 Subject: [PATCH 02/10] feat(neuron-ui): display blockchain status in the footer --- .../src/components/Overview/index.tsx | 79 ++++--------------- .../neuron-ui/src/containers/Footer/index.tsx | 4 +- packages/neuron-ui/src/locales/en.json | 9 +-- packages/neuron-ui/src/locales/zh.json | 9 +-- 4 files changed, 23 insertions(+), 78 deletions(-) diff --git a/packages/neuron-ui/src/components/Overview/index.tsx b/packages/neuron-ui/src/components/Overview/index.tsx index 40215f9105..4a8d2b9291 100644 --- a/packages/neuron-ui/src/components/Overview/index.tsx +++ b/packages/neuron-ui/src/components/Overview/index.tsx @@ -18,7 +18,7 @@ import { import { StateWithDispatch } from 'states/stateProvider/reducer' import actionCreators from 'states/stateProvider/actionCreators' -import { localNumberFormatter, shannonToCKBFormatter } from 'utils/formatters' +import { shannonToCKBFormatter } from 'utils/formatters' import { PAGE_SIZE, MIN_CELL_WIDTH } from 'utils/const' const timeFormatter = new Intl.DateTimeFormat(undefined, { @@ -79,16 +79,12 @@ const PropertyList = ({ ) const Overview = ({ dispatch, - wallet: { id, balance = '' }, + wallet: { id, name, balance = '' }, chain: { - networkID = '', transactions: { items = [] }, - tipBlockNumber = '0', }, - settings: { networks = [] }, }: React.PropsWithoutRef) => { const [t] = useTranslation() - const currentNetwork = useMemo(() => networks.find(n => n.id === networkID), [networkID, networks]) useEffect(() => { dispatch(actionCreators.getTransactions({ pageNo: 1, pageSize: PAGE_SIZE, keywords: '', walletID: id })) @@ -201,70 +197,27 @@ const Overview = ({ const balanceItems = useMemo( () => [ { - label: t('overview.amount'), + label: t('overview.balance'), value: {`${shannonToCKBFormatter(balance)} CKB`}, }, - { label: t('overview.live-cells'), value: 'mock living cells' }, - { label: t('overview.cell-types'), value: 'mock cell typ' }, ], [t, balance] ) - const blockchainStatusColumns = balanceColumns - - const blockchainStatusItems = useMemo( - () => [ - { label: t('overview.blockchain-identity'), value: 'mock chain id' }, - { label: t('overview.block-number'), value: localNumberFormatter(tipBlockNumber) }, - { label: t('overview.rpc-service'), value: currentNetwork ? currentNetwork.name : '' }, - ], - [t, currentNetwork, tipBlockNumber] - ) - return ( - - - - - {t('overview.balance')} - - - - - - {t('overview.blockchain-status')} - - {currentNetwork ? ( - - ) : null} - - - - - {t('overview.recent-activities')} - - {items.length ? ( - - ) : ( -
{t('overview.no-recent-activities')}
- )} -
+ + + {name} + + + + {t('overview.recent-activities')} + + {items.length ? ( + + ) : ( +
{t('overview.no-recent-activities')}
+ )}
) } diff --git a/packages/neuron-ui/src/containers/Footer/index.tsx b/packages/neuron-ui/src/containers/Footer/index.tsx index 540d175cb7..fb61cf5217 100644 --- a/packages/neuron-ui/src/containers/Footer/index.tsx +++ b/packages/neuron-ui/src/containers/Footer/index.tsx @@ -7,6 +7,7 @@ import { Alert as AlertIcon, Nodes as ConnectIcon } from 'grommet-icons' import { StateWithDispatch } from 'states/stateProvider/reducer' import { ConnectStatus, FULL_SCREENS, Routes } from 'utils/const' +import { localNumberFormatter } from 'utils/formatters' import { NeuronWalletContext } from 'states/stateProvider' const theme = getTheme() @@ -40,9 +41,10 @@ export const SyncStatus = ({ <> {t('sync.syncing')} + {`${localNumberFormatter(syncedBlockNumber) || '0'}/${localNumberFormatter(tipBlockNumber) || '0'}`} ) : ( - t('sync.synced') + <>{`${t('sync.synced')}, ${t('sync.block-number')}: ${localNumberFormatter(tipBlockNumber)}`} )} ) diff --git a/packages/neuron-ui/src/locales/en.json b/packages/neuron-ui/src/locales/en.json index ea9fb2dfba..df2324ccc5 100644 --- a/packages/neuron-ui/src/locales/en.json +++ b/packages/neuron-ui/src/locales/en.json @@ -14,14 +14,8 @@ }, "overview": { "balance": "Balance", - "live-cells": "Live Cells", - "cell-types": "Cell Types", "recent-activities": "Recent Activities", "no-recent-activities": "No Recent Activities", - "blockchain-status": "Blockchain Status", - "blockchain-identity": "Chain Identity", - "block-number": "Block Number", - "rpc-service": "RPC Service", "type": "Type", "datetime": "Date & Time", "status": "Status", @@ -211,7 +205,8 @@ }, "sync": { "syncing": "Syncing", - "synced": "Synced" + "synced": "Synced", + "block-number": "block number" }, "pagination": { "previous-page": "Previous page", diff --git a/packages/neuron-ui/src/locales/zh.json b/packages/neuron-ui/src/locales/zh.json index deda468867..2b5a734cd5 100644 --- a/packages/neuron-ui/src/locales/zh.json +++ b/packages/neuron-ui/src/locales/zh.json @@ -14,14 +14,8 @@ }, "overview": { "balance": "余额", - "live-cells": "可用 Cells", - "cell-types": "Cell 类型", "recent-activities": "近期活动", "no-recent-activities": "近期没有活动", - "blockchain-status": "同步节点状态", - "blockchain-identity": "链的 ID", - "block-number": "区块高度", - "rpc-service": "RPC 服务", "type": "类型", "datetime": "时间", "status": "状态", @@ -211,7 +205,8 @@ }, "sync": { "syncing": "同步中", - "synced": "同步完成" + "synced": "同步完成", + "block-number": "区块高度" }, "pagination": { "previous-page": "上一页", From e2afa4d4d29b728da30725446837a9974c1f8e1a Mon Sep 17 00:00:00 2001 From: Keith Date: Wed, 17 Jul 2019 15:57:33 +0800 Subject: [PATCH 03/10] feat(neuron-ui): display the title of recent activities as the role of 'h2' --- packages/neuron-ui/src/components/Overview/index.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/neuron-ui/src/components/Overview/index.tsx b/packages/neuron-ui/src/components/Overview/index.tsx index 4a8d2b9291..0302deca15 100644 --- a/packages/neuron-ui/src/components/Overview/index.tsx +++ b/packages/neuron-ui/src/components/Overview/index.tsx @@ -210,7 +210,7 @@ const Overview = ({ {name} - + {t('overview.recent-activities')} {items.length ? ( From 624ea5df1d1b1b5e935f462e5c1caf8ebbadf71e Mon Sep 17 00:00:00 2001 From: Keith Date: Wed, 17 Jul 2019 17:45:39 +0800 Subject: [PATCH 04/10] feat(neuron-ui): display balance value just next to its title --- packages/neuron-ui/src/components/Overview/index.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/neuron-ui/src/components/Overview/index.tsx b/packages/neuron-ui/src/components/Overview/index.tsx index 0302deca15..e11e65bcb2 100644 --- a/packages/neuron-ui/src/components/Overview/index.tsx +++ b/packages/neuron-ui/src/components/Overview/index.tsx @@ -178,6 +178,7 @@ const Overview = ({ key: 'label', name: 'label', fieldName: 'label', + maxWidth: 100, }, { key: 'value', From 477f5bdfd7bc04bd43018cb5590fadb6fc7fccbf Mon Sep 17 00:00:00 2001 From: Keith Date: Thu, 18 Jul 2019 11:59:51 +0800 Subject: [PATCH 05/10] refactor(neuron-ui): add margin between progress and percentage of synchronization in the footer --- packages/neuron-ui/src/containers/Footer/index.tsx | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/packages/neuron-ui/src/containers/Footer/index.tsx b/packages/neuron-ui/src/containers/Footer/index.tsx index fb61cf5217..2ea55ab29d 100644 --- a/packages/neuron-ui/src/containers/Footer/index.tsx +++ b/packages/neuron-ui/src/containers/Footer/index.tsx @@ -40,7 +40,10 @@ export const SyncStatus = ({ {+syncedBlockNumber + bufferBlockNumber < +tipBlockNumber ? ( <> {t('sync.syncing')} - + {`${localNumberFormatter(syncedBlockNumber) || '0'}/${localNumberFormatter(tipBlockNumber) || '0'}`} ) : ( From 94568721c236c1ae53388d821f4e329f57dbe819 Mon Sep 17 00:00:00 2001 From: Keith Date: Thu, 18 Jul 2019 12:03:04 +0800 Subject: [PATCH 06/10] feat(neuron-ui): display blockchain status in the overview --- .../src/components/Overview/index.tsx | 103 +++++++++++++++++- .../neuron-ui/src/containers/Main/hooks.ts | 46 +++++--- .../neuron-ui/src/containers/Main/index.tsx | 19 +++- packages/neuron-ui/src/locales/en.json | 6 +- packages/neuron-ui/src/locales/zh.json | 6 +- packages/neuron-ui/src/services/chain.ts | 3 +- .../neuron-ui/src/states/initStates/app.ts | 3 + .../src/states/stateProvider/reducer.ts | 1 + .../src/stories/Overview.stories.tsx | 8 +- packages/neuron-ui/src/types/App/index.d.ts | 3 + 10 files changed, 171 insertions(+), 27 deletions(-) diff --git a/packages/neuron-ui/src/components/Overview/index.tsx b/packages/neuron-ui/src/components/Overview/index.tsx index e11e65bcb2..de51bc24c7 100644 --- a/packages/neuron-ui/src/components/Overview/index.tsx +++ b/packages/neuron-ui/src/components/Overview/index.tsx @@ -1,9 +1,10 @@ -import React, { useCallback, useMemo, useEffect } from 'react' +import React, { useState, useCallback, useMemo, useEffect, useRef } from 'react' import { RouteComponentProps } from 'react-router-dom' import { useTranslation } from 'react-i18next' import { Stack, Text, + DefaultButton, DetailsList, DetailsRow, IColumn, @@ -13,12 +14,13 @@ import { IDetailsRowProps, IDetailsRowStyles, FontSizes, + Callout, } from 'office-ui-fabric-react' import { StateWithDispatch } from 'states/stateProvider/reducer' import actionCreators from 'states/stateProvider/actionCreators' -import { shannonToCKBFormatter } from 'utils/formatters' +import { localNumberFormatter, shannonToCKBFormatter } from 'utils/formatters' import { PAGE_SIZE, MIN_CELL_WIDTH } from 'utils/const' const timeFormatter = new Intl.DateTimeFormat(undefined, { @@ -79,12 +81,18 @@ const PropertyList = ({ ) const Overview = ({ dispatch, + app: { tipBlockNumber, chain, epoch, difficulty }, wallet: { id, name, balance = '' }, chain: { transactions: { items = [] }, }, }: React.PropsWithoutRef) => { const [t] = useTranslation() + const [displayBlockchainInfo, setDisplayBlockchainInfo] = useState(false) + const [displayMinerInfo, setDisplayMinerInfo] = useState(false) + + const blockchainInfoRef = useRef(null) + const minerInfoRef = useRef(null) useEffect(() => { dispatch(actionCreators.getTransactions({ pageNo: 1, pageSize: PAGE_SIZE, keywords: '', walletID: id })) @@ -195,6 +203,30 @@ const Overview = ({ [] ) + const blockchainStatusColumns: IColumn[] = useMemo( + () => + [ + { + key: 'label', + name: 'label', + fieldName: 'label', + maxWidth: 100, + }, + { + key: 'value', + name: 'value', + fieldName: 'value', + }, + ].map(col => ({ + isResizable: true, + minWidth: 200, + fieldName: col.key, + ariaLabel: col.name, + ...col, + })), + [] + ) + const balanceItems = useMemo( () => [ { @@ -204,13 +236,61 @@ const Overview = ({ ], [t, balance] ) + const blockchainStatusItems = useMemo( + () => [ + { + label: t('overview.chain-identity'), + value: chain, + }, + { + label: t('overview.tip-block-number'), + value: localNumberFormatter(tipBlockNumber), + }, + { + label: t('overview.epoch'), + value: epoch, + }, + { + label: t('overview.difficulty'), + value: difficulty, + }, + ], + [t, chain, epoch, difficulty, tipBlockNumber] + ) + + const showBlockchainStatus = useCallback(() => { + setDisplayBlockchainInfo(true) + }, [setDisplayBlockchainInfo]) + const hideBlockchainStatus = useCallback(() => { + setDisplayBlockchainInfo(false) + }, [setDisplayBlockchainInfo]) + const showMinerInfo = useCallback(() => { + setDisplayMinerInfo(true) + }, [setDisplayMinerInfo]) + const hideMinerInfo = useCallback(() => { + setDisplayMinerInfo(false) + }, [setDisplayMinerInfo]) return ( {name} - + + + +
+ + Blockchain Status + +
+
+ + Miner Info + +
+
+
{t('overview.recent-activities')} @@ -219,6 +299,23 @@ const Overview = ({ ) : (
{t('overview.no-recent-activities')}
)} + {blockchainInfoRef.current ? ( + + ) : null} + {minerInfoRef.current ? ( + + ) : null}
) } diff --git a/packages/neuron-ui/src/containers/Main/hooks.ts b/packages/neuron-ui/src/containers/Main/hooks.ts index ad81dabda0..ecf5aa19ec 100644 --- a/packages/neuron-ui/src/containers/Main/hooks.ts +++ b/packages/neuron-ui/src/containers/Main/hooks.ts @@ -16,7 +16,7 @@ import UILayer, { transactionsCall, networksCall, } from 'services/UILayer' -import { ckbCore, getTipBlockNumber } from 'services/chain' +import { ckbCore, getTipBlockNumber, getBlockchainInfo } from 'services/chain' import { Routes, Channel, ConnectStatus } from 'utils/const' import { wallets as walletsCache, @@ -432,17 +432,8 @@ export const useChannelListeners = ({ }) }, [walletID, i18n, chain, dispatch, history]) -export const useSyncTipBlockNumber = ({ - networks, - networkID, - dispatch, -}: { - networks: State.Network[] - networkID: string - dispatch: StateDispatch -}) => { +export const useSyncChainData = ({ chainURL, dispatch }: { chainURL: string; dispatch: StateDispatch }) => { useEffect(() => { - const network = networks.find(n => n.id === networkID) const syncTipNumber = () => getTipBlockNumber() .then(tipBlockNumber => { @@ -452,12 +443,37 @@ export const useSyncTipBlockNumber = ({ }) }) .catch(console.error) + + const syncBlockchainInfo = () => { + getBlockchainInfo() + .then(info => { + if (info) { + const { chain = '', difficulty = '', epoch = '', alerts = [] } = info + if (alerts.length) { + alerts.forEach(a => { + // TODO: display alerts in Notification + console.info(a) + }) + } + dispatch({ + type: AppActions.UpdateChainInfo, + payload: { + chain, + difficulty, + epoch, + }, + }) + } + }) + .catch(console.error) + } clearInterval(timer) - if (network) { - ckbCore.setNode(network.remote) + if (chainURL) { + ckbCore.setNode(chainURL) syncTipNumber() timer = setInterval(() => { syncTipNumber() + syncBlockchainInfo() }, SYNC_INTERVAL_TIME) } else { ckbCore.setNode('') @@ -465,7 +481,7 @@ export const useSyncTipBlockNumber = ({ return () => { clearInterval(timer) } - }, [networks, networkID, dispatch]) + }, [chainURL, dispatch]) } export const useOnCurrentWalletChange = ({ walletID, chain }: { walletID: string; chain: State.Chain }) => { @@ -489,6 +505,6 @@ export const useOnCurrentWalletChange = ({ walletID, chain }: { walletID: string export default { useChannelListeners, - useSyncTipBlockNumber, + useSyncChainData, useOnCurrentWalletChange, } diff --git a/packages/neuron-ui/src/containers/Main/index.tsx b/packages/neuron-ui/src/containers/Main/index.tsx index d1766f7049..a87e548593 100644 --- a/packages/neuron-ui/src/containers/Main/index.tsx +++ b/packages/neuron-ui/src/containers/Main/index.tsx @@ -1,4 +1,4 @@ -import React from 'react' +import React, { useMemo } from 'react' import { Route, RouteComponentProps } from 'react-router-dom' import { useTranslation } from 'react-i18next' @@ -20,7 +20,7 @@ import PasswordRequest from 'components/PasswordRequest' import { Routes } from 'utils/const' -import { useChannelListeners, useSyncTipBlockNumber, useOnCurrentWalletChange } from './hooks' +import { useChannelListeners, useSyncChainData, useOnCurrentWalletChange } from './hooks' export const mainContents: CustomRouter.Route[] = [ { @@ -107,6 +107,10 @@ const MainContent = ({ dispatch, }: React.PropsWithoutRef<{ dispatch: StateDispatch } & RouteComponentProps>) => { const neuronWalletState = useState() + const { + chain: { networkID }, + settings: { networks }, + } = neuronWalletState const [, i18n] = useTranslation() useChannelListeners({ walletID: neuronWalletState.wallet.id, @@ -115,9 +119,14 @@ const MainContent = ({ history, i18n, }) - useSyncTipBlockNumber({ - networkID: neuronWalletState.chain.networkID, - networks: neuronWalletState.settings.networks, + + const chainURL = useMemo(() => { + const network = networks.find(n => n.id === networkID) + return network ? network.remote : '' + }, [networks, networkID]) + + useSyncChainData({ + chainURL, dispatch, }) useOnCurrentWalletChange({ diff --git a/packages/neuron-ui/src/locales/en.json b/packages/neuron-ui/src/locales/en.json index df2324ccc5..a0cc4358ed 100644 --- a/packages/neuron-ui/src/locales/en.json +++ b/packages/neuron-ui/src/locales/en.json @@ -19,7 +19,11 @@ "type": "Type", "datetime": "Date & Time", "status": "Status", - "amount": "Amount" + "amount": "Amount", + "chain-identity": "Chain Identity", + "tip-block-number": "Block Number", + "epoch": "Epoch", + "difficulty": "Difficulty" }, "wizard": { "welcome-to-nervos-neuron": "Welcome to Neuron", diff --git a/packages/neuron-ui/src/locales/zh.json b/packages/neuron-ui/src/locales/zh.json index 2b5a734cd5..17f09ca628 100644 --- a/packages/neuron-ui/src/locales/zh.json +++ b/packages/neuron-ui/src/locales/zh.json @@ -19,7 +19,11 @@ "type": "类型", "datetime": "时间", "status": "状态", - "amount": "金额" + "amount": "金额", + "chain-identity": "链的 ID", + "tip-block-number": "区块高度", + "epoch": "Epoch", + "difficulty": "难度" }, "wizard": { "welcome-to-nervos-ckb": "欢迎使用 Neuron", diff --git a/packages/neuron-ui/src/services/chain.ts b/packages/neuron-ui/src/services/chain.ts index f66aae86fb..71aa296ecf 100644 --- a/packages/neuron-ui/src/services/chain.ts +++ b/packages/neuron-ui/src/services/chain.ts @@ -2,9 +2,10 @@ import CKBCore from '@nervosnetwork/ckb-sdk-core' export const ckbCore = new CKBCore('') -export const { getTipBlockNumber } = ckbCore.rpc +export const { getTipBlockNumber, getBlockchainInfo } = ckbCore.rpc export default { ckbCore, getTipBlockNumber, + getBlockchainInfo, } diff --git a/packages/neuron-ui/src/states/initStates/app.ts b/packages/neuron-ui/src/states/initStates/app.ts index 3b532f3811..a6c65d49a4 100644 --- a/packages/neuron-ui/src/states/initStates/app.ts +++ b/packages/neuron-ui/src/states/initStates/app.ts @@ -2,6 +2,9 @@ import { CapacityUnit } from 'utils/const' const appState: State.App = { tipBlockNumber: '', + chain: '', + difficulty: '', + epoch: '', send: { txID: '', outputs: [ diff --git a/packages/neuron-ui/src/states/stateProvider/reducer.ts b/packages/neuron-ui/src/states/stateProvider/reducer.ts index 0fba308fc5..382787ca1e 100644 --- a/packages/neuron-ui/src/states/stateProvider/reducer.ts +++ b/packages/neuron-ui/src/states/stateProvider/reducer.ts @@ -26,6 +26,7 @@ export enum AppActions { DismissPasswordRequest = 'dismissPasswordRequest', UpdatePassword = 'updatePassword', UpdateTipBlockNumber = 'updateTipBlockNumber', + UpdateChainInfo = 'updateChainInfo', Ignore = 'ignore', } diff --git a/packages/neuron-ui/src/stories/Overview.stories.tsx b/packages/neuron-ui/src/stories/Overview.stories.tsx index e7e5054d2f..8721213178 100644 --- a/packages/neuron-ui/src/stories/Overview.stories.tsx +++ b/packages/neuron-ui/src/stories/Overview.stories.tsx @@ -11,7 +11,13 @@ import transactions from './data/transactions' const stateTemplate = { dispatch: (dispatchAction: any) => action(dispatchAction), ...initStates, - wallet: { ...initStates.wallet, id: 'wallet id', balance: '213' }, + app: { + ...initStates.app, + epoch: '1', + difficulty: '0x111', + chain: 'chain_dev', + }, + wallet: { ...initStates.wallet, id: 'wallet id', name: 'Current Wallet Name', balance: '213' }, chain: { ...initStates.chain, networkID: 'testnet', diff --git a/packages/neuron-ui/src/types/App/index.d.ts b/packages/neuron-ui/src/types/App/index.d.ts index fb293c7635..aad0edd22e 100644 --- a/packages/neuron-ui/src/types/App/index.d.ts +++ b/packages/neuron-ui/src/types/App/index.d.ts @@ -61,6 +61,9 @@ declare namespace State { interface App { tipBlockNumber: string + chain: string + difficulty: string + epoch: string send: Send passwordRequest: { actionType: 'send' | 'backup' | 'delete' | null From 01c3cb6ea7ec0f5cbd4705fea9a920441efec11e Mon Sep 17 00:00:00 2001 From: Keith Date: Thu, 18 Jul 2019 13:05:16 +0800 Subject: [PATCH 07/10] feat(neuron-ui): nav to the welcome view when the current wallet is empty --- .../src/components/LaunchScreen/index.tsx | 6 +-- .../neuron-ui/src/containers/Main/hooks.ts | 41 +++++++++++++------ .../neuron-ui/src/containers/Main/index.tsx | 2 + 3 files changed, 32 insertions(+), 17 deletions(-) diff --git a/packages/neuron-ui/src/components/LaunchScreen/index.tsx b/packages/neuron-ui/src/components/LaunchScreen/index.tsx index c8b9dca3e6..ca7a6e4b88 100644 --- a/packages/neuron-ui/src/components/LaunchScreen/index.tsx +++ b/packages/neuron-ui/src/components/LaunchScreen/index.tsx @@ -9,21 +9,17 @@ import { Routes } from 'utils/const' export const LaunchScreen = ({ wallet: { id = '' }, - settings: { networks = [] }, history, }: React.PropsWithoutRef) => { const { t } = useTranslation() useEffect(() => { - if (!networks.length) { - return - } if (id) { history.push(Routes.Overview) } else { history.push(`${Routes.WalletWizard}${WalletWizardPath.Welcome}`) } - }, [networks.length, id, history]) + }, [id, history]) return ( diff --git a/packages/neuron-ui/src/containers/Main/hooks.ts b/packages/neuron-ui/src/containers/Main/hooks.ts index ecf5aa19ec..f928f4a545 100644 --- a/packages/neuron-ui/src/containers/Main/hooks.ts +++ b/packages/neuron-ui/src/containers/Main/hooks.ts @@ -311,9 +311,6 @@ export const useChannelListeners = ({ payload: { wallets: args.result }, }) walletsCache.save(args.result) - if (!args.result.length) { - history.push(`${Routes.WalletWizard}${WalletWizardPath.Welcome}`) - } break } case WalletsMethod.GetCurrent: { @@ -484,22 +481,42 @@ export const useSyncChainData = ({ chainURL, dispatch }: { chainURL: string; dis }, [chainURL, dispatch]) } -export const useOnCurrentWalletChange = ({ walletID, chain }: { walletID: string; chain: State.Chain }) => { +export const useOnCurrentWalletChange = ({ + walletID, + chain, + dispatch, + history, +}: { + walletID: string + chain: State.Chain + dispatch: StateDispatch + history: any +}) => { useEffect(() => { - walletsCall.getAllAddresses(walletID) - transactionsCall.getAllByKeywords({ - walletID, - keywords: chain.transactions.keywords, - pageNo: chain.transactions.pageNo, - pageSize: chain.transactions.pageSize, - }) - transactionsCall.get(walletID, chain.transaction.hash) + if (walletID) { + walletsCall.getAllAddresses(walletID) + transactionsCall.getAllByKeywords({ + walletID, + keywords: chain.transactions.keywords, + pageNo: chain.transactions.pageNo, + pageSize: chain.transactions.pageSize, + }) + transactionsCall.get(walletID, chain.transaction.hash) + } else { + history.push(`${Routes.WalletWizard}${WalletWizardPath.Welcome}`) + dispatch({ + type: NeuronWalletActions.Wallet, + payload: initStates.wallet, + }) + } }, [ walletID, chain.transactions.pageNo, chain.transactions.pageSize, chain.transactions.keywords, chain.transaction.hash, + dispatch, + history, ]) } diff --git a/packages/neuron-ui/src/containers/Main/index.tsx b/packages/neuron-ui/src/containers/Main/index.tsx index a87e548593..60d273c60d 100644 --- a/packages/neuron-ui/src/containers/Main/index.tsx +++ b/packages/neuron-ui/src/containers/Main/index.tsx @@ -132,6 +132,8 @@ const MainContent = ({ useOnCurrentWalletChange({ walletID: neuronWalletState.wallet.id, chain: neuronWalletState.chain, + dispatch, + history, }) return ( <> From 18eecbf3026e899659ec0213b7a173689ff4c889 Mon Sep 17 00:00:00 2001 From: classicalliu Date: Thu, 18 Jul 2019 13:52:34 +0800 Subject: [PATCH 08/10] chore: return if tx success when fetch --- packages/neuron-wallet/src/services/transactions.ts | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/packages/neuron-wallet/src/services/transactions.ts b/packages/neuron-wallet/src/services/transactions.ts index e7a2590b06..eac1a15f90 100644 --- a/packages/neuron-wallet/src/services/transactions.ts +++ b/packages/neuron-wallet/src/services/transactions.ts @@ -324,6 +324,11 @@ export default class TransactionsService { .getRepository(TransactionEntity) .findOne(transaction.hash, { relations: ['inputs', 'outputs'] }) + // return if success + if (txEntity && txEntity.status === TransactionStatus.Success) { + return txEntity + } + if (txEntity) { // input -> previousOutput => dead // output => live From f92b0b8e149f251446707a40387aa748cc293d44 Mon Sep 17 00:00:00 2001 From: Keith Date: Thu, 18 Jul 2019 14:37:22 +0800 Subject: [PATCH 09/10] feat(neuron-ui): validate mnemonic words before setting password --- .../src/components/WalletWizard/index.tsx | 18 +++++++---- packages/neuron-ui/src/locales/en.json | 4 ++- packages/neuron-ui/src/locales/zh.json | 4 ++- packages/neuron-ui/src/services/remote.ts | 32 +++++++++++++++++++ .../neuron-ui/src/types/global/index.d.ts | 8 ++++- packages/neuron-wallet/src/startup/preload.ts | 4 ++- 6 files changed, 60 insertions(+), 10 deletions(-) create mode 100644 packages/neuron-ui/src/services/remote.ts diff --git a/packages/neuron-ui/src/components/WalletWizard/index.tsx b/packages/neuron-ui/src/components/WalletWizard/index.tsx index a71ccdefab..ca6e7e533d 100644 --- a/packages/neuron-ui/src/components/WalletWizard/index.tsx +++ b/packages/neuron-ui/src/components/WalletWizard/index.tsx @@ -8,6 +8,7 @@ import withWizard, { WizardElementProps, WithWizardState } from 'components/with import { MnemonicAction, BUTTON_GAP } from 'utils/const' import { verifyWalletSubmission } from 'utils/validators' import { helpersCall, walletsCall } from 'services/UILayer' +import { validateMnemonic, showErrorMessage } from 'services/remote' import { registerIcons, buttonGrommetIconStyles } from 'utils/icons' export enum WalletWizardPath { @@ -138,13 +139,18 @@ const Mnemonic = ({ if (isCreate) { history.push(`${rootPath}${WalletWizardPath.Mnemonic}/${MnemonicAction.Verify}`) } else { - history.push( - `${rootPath}${WalletWizardPath.Submission}/${ - type === MnemonicAction.Verify ? MnemonicAction.Create : MnemonicAction.Import - }` - ) + const isMnemonicValid = validateMnemonic(imported) + if (isMnemonicValid) { + history.push( + `${rootPath}${WalletWizardPath.Submission}/${ + type === MnemonicAction.Verify ? MnemonicAction.Create : MnemonicAction.Import + }` + ) + } else { + showErrorMessage(t('messages.error'), t('messages.invalid-mnemonic')) + } } - }, [isCreate, history, rootPath, type]) + }, [isCreate, history, rootPath, type, imported, t]) return ( diff --git a/packages/neuron-ui/src/locales/en.json b/packages/neuron-ui/src/locales/en.json index a0cc4358ed..770fc178f7 100644 --- a/packages/neuron-ui/src/locales/en.json +++ b/packages/neuron-ui/src/locales/en.json @@ -205,7 +205,9 @@ "wallet-created-successfully": "{{name}} created successfully", "wallet-updated-successfully": "{{name}} updated successfully", "wallet-not-found": "Wallet not found", - "no-transactions": "No transactions" + "no-transactions": "No transactions", + "error": "Error", + "invalid-mnemonic": "Invalid mnemonic words" }, "sync": { "syncing": "Syncing", diff --git a/packages/neuron-ui/src/locales/zh.json b/packages/neuron-ui/src/locales/zh.json index 17f09ca628..01a859392c 100644 --- a/packages/neuron-ui/src/locales/zh.json +++ b/packages/neuron-ui/src/locales/zh.json @@ -205,7 +205,9 @@ "wallet-created-successfully": "{{name}} 创建成功", "wallet-updated-successfully": "{{name}} 更新成功", "wallet-not-found": "未找到钱包", - "no-transactions": "没有交易" + "no-transactions": "没有交易", + "error": "错误", + "invalid-mnemonic": "助记词不合法" }, "sync": { "syncing": "同步中", diff --git a/packages/neuron-ui/src/services/remote.ts b/packages/neuron-ui/src/services/remote.ts new file mode 100644 index 0000000000..2e2dd2e9c4 --- /dev/null +++ b/packages/neuron-ui/src/services/remote.ts @@ -0,0 +1,32 @@ +export const validateMnemonic = (mnemonic: string): boolean => { + if (!window.remote) { + console.warn('remote is not supported') + return true + } + const { validateMnemonic: remoteValidateMnemonic } = window.remote.require('./models/keys/mnemonic') + return remoteValidateMnemonic(mnemonic) +} + +export const showMessage = (options: any, callback: Function) => { + if (!window.remote) { + console.warn('remote is not supported') + window.alert(options.message) + } else { + window.remote.require('electron').dialog.showMessageBox(options, callback) + } +} + +export const showErrorMessage = (title: string, content: string) => { + if (!window.remote) { + console.warn('remote is not supported') + window.alert(`${title}: ${content}`) + } else { + window.remote.require('electron').dialog.showErrorBox(title, content) + } +} + +export default { + validateMnemonic, + showMessage, + showErrorMessage, +} diff --git a/packages/neuron-ui/src/types/global/index.d.ts b/packages/neuron-ui/src/types/global/index.d.ts index fe2d5e238f..fb2cbeca70 100644 --- a/packages/neuron-ui/src/types/global/index.d.ts +++ b/packages/neuron-ui/src/types/global/index.d.ts @@ -1,6 +1,12 @@ declare interface Window { clipboard: any - remote: any + remote: { + getCurrentWebContents: Function + getCurrentWindow: Function + getGlobal: (name: string) => any + require: (module: string) => any + process?: any + } require: any bridge: any nativeImage: any diff --git a/packages/neuron-wallet/src/startup/preload.ts b/packages/neuron-wallet/src/startup/preload.ts index c4c3549ea4..7dd1a43602 100644 --- a/packages/neuron-wallet/src/startup/preload.ts +++ b/packages/neuron-wallet/src/startup/preload.ts @@ -1,10 +1,11 @@ -import { ipcRenderer, clipboard, nativeImage } from 'electron' +import { remote, ipcRenderer, clipboard, nativeImage } from 'electron' declare global { interface Window { bridge: any clipboard: Electron.Clipboard nativeImage: any + remote: Electron.Remote } } @@ -34,3 +35,4 @@ if (process.env.NODE_ENV === 'development') { window.clipboard = clipboard window.bridge = window.bridge || bridge window.nativeImage = nativeImage +window.remote = remote From 09a2e00ff8c7c886a9d337254fa2d70386e3cb86 Mon Sep 17 00:00:00 2001 From: James Chen Date: Thu, 18 Jul 2019 15:37:44 +0900 Subject: [PATCH 10/10] chore: Pre-release v0.1.0-alpha.10 --- lerna.json | 2 +- package.json | 2 +- packages/neuron-ui/package.json | 2 +- packages/neuron-wallet/package.json | 4 ++-- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/lerna.json b/lerna.json index c57c4be3d0..a651a94b02 100644 --- a/lerna.json +++ b/lerna.json @@ -2,7 +2,7 @@ "packages": [ "packages/*" ], - "version": "0.1.0-alpha.9", + "version": "0.1.0-alpha.10", "npmClient": "yarn", "useWorkspaces": true } diff --git a/package.json b/package.json index 28d18cbddf..8940af1877 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "@nervosnetwork/neuron", "productName": "Neuron", "description": "CKB Neuron Wallet", - "version": "0.1.0-alpha.9", + "version": "0.1.0-alpha.10", "private": true, "author": { "name": "Nervos Core Dev", diff --git a/packages/neuron-ui/package.json b/packages/neuron-ui/package.json index 7a1f684f47..86132ff33a 100644 --- a/packages/neuron-ui/package.json +++ b/packages/neuron-ui/package.json @@ -1,6 +1,6 @@ { "name": "@nervosnetwork/neuron-ui", - "version": "0.1.0-alpha.9", + "version": "0.1.0-alpha.10", "private": true, "author": { "name": "Nervos Core Dev", diff --git a/packages/neuron-wallet/package.json b/packages/neuron-wallet/package.json index 4b6e02218f..0538303f7a 100644 --- a/packages/neuron-wallet/package.json +++ b/packages/neuron-wallet/package.json @@ -3,7 +3,7 @@ "productName": "Neuron", "description": "CKB Neuron Wallet", "homepage": "https://www.nervos.org/", - "version": "0.1.0-alpha.9", + "version": "0.1.0-alpha.10", "private": true, "author": { "name": "Nervos Core Dev", @@ -48,7 +48,7 @@ }, "devDependencies": { "@nervosnetwork/ckb-types": "0.15.1", - "@nervosnetwork/neuron-ui": "0.1.0-alpha.9", + "@nervosnetwork/neuron-ui": "0.1.0-alpha.10", "@types/async": "3.0.0", "@types/electron-devtools-installer": "2.2.0", "@types/elliptic": "6.4.8",