From 137876814991d0cd2ad9a212123b1db24ed502a8 Mon Sep 17 00:00:00 2001 From: Chen Yu Date: Wed, 4 Sep 2019 12:02:08 +0800 Subject: [PATCH] feat(neuron-ui): move the miner info from overview to wallet list (#907) * feat(neuron-ui): move the miner info from overview to wallet list * feat(neuron-ui): use text instead of icon button to display the miner info trigger * test(neuron-wallet): update the e2e test according to the new layout of wallet list --- .../src/components/Overview/index.tsx | 89 ++------------ .../src/components/WalletSetting/index.tsx | 111 ++++++++++++++++-- packages/neuron-ui/src/types/App/index.d.ts | 1 + .../src/controllers/app/index.ts | 19 ++- .../src/controllers/wallets/index.ts | 18 ++- .../neuron-wallet/tests-e2e/tests/wallet.ts | 23 ++-- 6 files changed, 158 insertions(+), 103 deletions(-) diff --git a/packages/neuron-ui/src/components/Overview/index.tsx b/packages/neuron-ui/src/components/Overview/index.tsx index cc7eca0a0d..0fff40fbcf 100644 --- a/packages/neuron-ui/src/components/Overview/index.tsx +++ b/packages/neuron-ui/src/components/Overview/index.tsx @@ -17,18 +17,16 @@ import { IDetailsRowStyles, FontSizes, Callout, - MessageBar, - MessageBarType, } from 'office-ui-fabric-react' import PropertyList, { Property } from 'widgets/PropertyList' import { StateWithDispatch } from 'states/stateProvider/reducer' -import { updateTransactionList, addPopup } from 'states/stateProvider/actionCreators' +import { updateTransactionList } from 'states/stateProvider/actionCreators' -import { showTransactionDetails, showErrorMessage } from 'services/remote' +import { showTransactionDetails } from 'services/remote' import { localNumberFormatter, shannonToCKBFormatter, uniformTimeFormatter as timeFormatter } from 'utils/formatters' -import { PAGE_SIZE, Routes, CONFIRMATION_THRESHOLD, ErrorCode } from 'utils/const' +import { PAGE_SIZE, Routes, CONFIRMATION_THRESHOLD } from 'utils/const' import { backToTop } from 'utils/animations' const TITLE_FONT_SIZE = 'xxLarge' @@ -157,20 +155,17 @@ const ActivityList = ({ const Overview = ({ dispatch, app: { tipBlockNumber, chain, epoch, difficulty }, - wallet: { id, name, balance = '', addresses = [] }, + wallet: { id, name, balance = '' }, chain: { tipBlockNumber: syncedBlockNumber, - codeHash = '', transactions: { items = [] }, }, history, }: React.PropsWithoutRef) => { const [t] = useTranslation() const [displayBlockchainInfo, setDisplayBlockchainInfo] = useState(false) - const [displayMinerInfo, setDisplayMinerInfo] = useState(false) const blockchainInfoRef = useRef(null) - const minerInfoRef = useRef(null) useEffect(() => { if (id) { @@ -264,33 +259,11 @@ const Overview = ({ [t, chain, epoch, difficulty, tipBlockNumber] ) - const [showBlockchainStatus, hideBlockchainStatus, showMinerInfo, hideMinerInfo] = useMemo( - () => [ - () => setDisplayBlockchainInfo(true), - () => setDisplayBlockchainInfo(false), - () => setDisplayMinerInfo(true), - () => setDisplayMinerInfo(false), - ], - [setDisplayBlockchainInfo, setDisplayMinerInfo] + const [showBlockchainStatus, hideBlockchainStatus] = useMemo( + () => [() => setDisplayBlockchainInfo(true), () => setDisplayBlockchainInfo(false)], + [setDisplayBlockchainInfo] ) - const defaultAddress = useMemo(() => { - return addresses.find(addr => addr.type === 0 && addr.index === 0) - }, [addresses]) - - const onCopyPubkeyHash = useCallback(() => { - if (defaultAddress) { - window.navigator.clipboard.writeText(defaultAddress.identifier) - hideMinerInfo() - addPopup('lock-arg-copied')(dispatch) - } else { - showErrorMessage( - t(`messages.error`), - t(`messages.codes.${ErrorCode.FieldNotFound}`, { fieldName: `default-address` }) - ) - } - }, [defaultAddress, t, hideMinerInfo, dispatch]) - const activityItems = useMemo( () => items.map(item => { @@ -342,11 +315,6 @@ const Overview = ({ {t('overview.blockchain-status')} -
- - {t('overview.miner-info')} - -
@@ -375,49 +343,6 @@ const Overview = ({ ) : null} - {minerInfoRef.current ? ( - - ) : null} ) } diff --git a/packages/neuron-ui/src/components/WalletSetting/index.tsx b/packages/neuron-ui/src/components/WalletSetting/index.tsx index 5842b2de62..415e86f482 100644 --- a/packages/neuron-ui/src/components/WalletSetting/index.tsx +++ b/packages/neuron-ui/src/components/WalletSetting/index.tsx @@ -1,15 +1,28 @@ -import React, { useCallback } from 'react' +import React, { useState, useCallback, useMemo } from 'react' import { RouteComponentProps } from 'react-router-dom' import { useTranslation } from 'react-i18next' -import { Stack, PrimaryButton, ChoiceGroup, IChoiceGroupOption } from 'office-ui-fabric-react' +import { + Stack, + PrimaryButton, + ChoiceGroup, + IChoiceGroupOption, + Text, + Callout, + MessageBar, + MessageBarType, + ActionButton, + getTheme, +} from 'office-ui-fabric-react' import { StateWithDispatch } from 'states/stateProvider/reducer' -import { setCurrentWallet } from 'states/stateProvider/actionCreators' +import { setCurrentWallet, addPopup } from 'states/stateProvider/actionCreators' import { WalletWizardPath } from 'components/WalletWizard' import { contextMenu } from 'services/remote' -import { Routes, MnemonicAction } from 'utils/const' +import { Routes, MnemonicAction, ErrorCode } from 'utils/const' + +const theme = getTheme() const buttons = [ { @@ -28,11 +41,34 @@ const buttons = [ const WalletSetting = ({ wallet: { id: currentID = '' }, + chain: { codeHash = '' }, settings: { wallets = [] }, dispatch, history, }: React.PropsWithoutRef) => { const [t] = useTranslation() + const [target, setTarget] = useState(null) + const [minerInfo, setMinerInfo] = useState<{ address: string; identifier: string }>({ + address: '', + identifier: '', + }) + + const [showMinerInfo, hideMinerInfo] = useMemo( + () => [ + (info: { address: string; identifier: string }) => setMinerInfo(info), + () => setMinerInfo({ address: '', identifier: '' }), + ], + [setMinerInfo] + ) + + const onCopyPubkeyHash = useCallback(() => { + if (minerInfo) { + window.navigator.clipboard.writeText(minerInfo.identifier) + hideMinerInfo() + addPopup('lock-arg-copied')(dispatch) + } + }, [minerInfo, t, hideMinerInfo, dispatch]) + const onChange = useCallback( (_e, option) => { if (option) { @@ -65,9 +101,29 @@ const WalletSetting = ({ checked: wallet.id === currentID, onRenderLabel: ({ text }: IChoiceGroupOption) => { return ( - - {text} - + + + {text} + + {wallet.minerAddress ? ( + ) => { + e.preventDefault() + setTarget(e.target) + if (wallet.minerAddress) { + showMinerInfo(wallet.minerAddress) + } + }} + styles={{ + root: [{ color: theme.semanticColors.bodySubtext, fontSize: '12px!important' }], + }} + > + {t('overview.miner-info')} + + ) : null} + ) }, }))} @@ -79,6 +135,47 @@ const WalletSetting = ({ ))} + ) } diff --git a/packages/neuron-ui/src/types/App/index.d.ts b/packages/neuron-ui/src/types/App/index.d.ts index 76e9e2682c..c73b5ad88d 100644 --- a/packages/neuron-ui/src/types/App/index.d.ts +++ b/packages/neuron-ui/src/types/App/index.d.ts @@ -107,6 +107,7 @@ declare namespace State { interface WalletIdentity { id: string name: string + minerAddress?: { address: string; identifier: string } } interface Address { diff --git a/packages/neuron-wallet/src/controllers/app/index.ts b/packages/neuron-wallet/src/controllers/app/index.ts index bea0c9dd84..1b4bddd185 100644 --- a/packages/neuron-wallet/src/controllers/app/index.ts +++ b/packages/neuron-wallet/src/controllers/app/index.ts @@ -72,6 +72,23 @@ export default class AppController { SystemScriptSubject.pipe(take(1)).subscribe(({ codeHash: currentCodeHash }) => resolve(currentCodeHash)) }), ]) + + const minerAddresses = await Promise.all( + wallets.map(({ id }) => + WalletsController.getAllAddresses(id).then(addrRes => { + if (addrRes.result) { + const minerAddr = addrRes.result.find(addr => addr.type === 0 && addr.index === 0) + if (minerAddr) { + return { + address: minerAddr.address, + identifier: minerAddr.identifier, + } + } + } + return undefined + }) + ) + ) const addresses: Controller.Address[] = await (currentWallet ? WalletsController.getAllAddresses(currentWallet.id).then(res => res.result) : []) @@ -86,7 +103,7 @@ export default class AppController { : [] const initState = { currentWallet, - wallets: [...wallets.map(({ name, id }) => ({ id, name }))], + wallets: [...wallets.map(({ name, id }, idx: number) => ({ id, name, minerAddress: minerAddresses[idx] }))], currentNetworkID, networks, addresses, diff --git a/packages/neuron-wallet/src/controllers/wallets/index.ts b/packages/neuron-wallet/src/controllers/wallets/index.ts index 0f98884eb9..8b56066e49 100644 --- a/packages/neuron-wallet/src/controllers/wallets/index.ts +++ b/packages/neuron-wallet/src/controllers/wallets/index.ts @@ -35,9 +35,25 @@ export default class WalletsController { if (!wallets) { throw new ServiceHasNoResponse('Wallet') } + const minerAddresses = await Promise.all( + wallets.map(({ id }) => + WalletsController.getAllAddresses(id).then(addrRes => { + if (addrRes.result) { + const minerAddr = addrRes.result.find(addr => addr.type === 0 && addr.index === 0) + if (minerAddr) { + return { + address: minerAddr.address, + identifier: minerAddr.identifier, + } + } + } + return undefined + }) + ) + ) return { status: ResponseCode.Success, - result: wallets.map(({ name, id }) => ({ name, id })), + result: wallets.map(({ name, id }, idx) => ({ name, id, minerAddress: minerAddresses[idx] })), } } diff --git a/packages/neuron-wallet/tests-e2e/tests/wallet.ts b/packages/neuron-wallet/tests-e2e/tests/wallet.ts index d98a2b0605..8deaaa36eb 100644 --- a/packages/neuron-wallet/tests-e2e/tests/wallet.ts +++ b/packages/neuron-wallet/tests-e2e/tests/wallet.ts @@ -1,4 +1,4 @@ -import Application from '../application'; +import Application from '../application' import { createWallet, importWallet } from '../operations' // Start: Guide page @@ -12,7 +12,7 @@ export default (app: Application) => { const createWalletButton = await app.getElementByTagName('button', 'Create a Wallet') expect(createWalletButton).not.toBeNull() await client.elementIdClick(createWalletButton!.ELEMENT) - console.log(`clicked create wallet button ${new Date().toTimeString()}`); + console.info(`clicked create wallet button ${new Date().toTimeString()}`) await createWallet(app) await app.waitUntilLoaded() @@ -27,21 +27,20 @@ export default (app: Application) => { expect(networkElement.value).not.toBeNull() await client.elementIdClick(networkElement.value.ELEMENT) await app.waitUntilLoaded() - console.log(`Go to setting page ${new Date().toLocaleTimeString()}`); - + console.info(`Go to setting page ${new Date().toLocaleTimeString()}`) // Switch to wallet setting const walletSettingButton = await app.getElementByTagName('button', 'Wallets') expect(walletSettingButton).not.toBeNull() await client.elementIdClick(walletSettingButton!.ELEMENT) await app.waitUntilLoaded() - console.log(`Switch to wallet setting ${new Date().toLocaleTimeString()}`); + console.info(`Switch to wallet setting ${new Date().toLocaleTimeString()}`) // Go to import wallet page const importWalletButton = await app.getElementByTagName('button', 'Import Mnemonic Seed') expect(importWalletButton).not.toBeNull() await client.elementIdClick(importWalletButton!.ELEMENT) - console.log(`Go to import wallet page ${new Date().toLocaleTimeString()}`); + console.info(`Go to import wallet page ${new Date().toLocaleTimeString()}`) const mnemonicText = 'refuse ecology globe virus demand gentle couch scrub bulk project chronic dog' await importWallet(app, mnemonicText) @@ -63,7 +62,7 @@ export default (app: Application) => { await app.waitUntilLoaded() // Switch to first wallet - const firstWallet = await app.element('//MAIN/DIV/DIV[3]/DIV/DIV/DIV/DIV/DIV') + const firstWallet = await app.element('label span') expect(firstWallet).not.toBeNull() const firstWalletName = await client.elementIdText(firstWallet.value.ELEMENT) await client.elementIdClick(firstWallet.value.ELEMENT) @@ -84,11 +83,11 @@ export default (app: Application) => { const walletNameElement = await app.element('//MAIN/DIV/H1') expect(walletNameElement.value).not.toBeNull() const walletName = await client.elementIdText(walletNameElement.value.ELEMENT) - + // Click delete wallet menu item await app.clickMenu(['Wallet', 'Delete Current Wallet']) await app.waitUntilLoaded() - + // Input password const inputElement = await app.element('//INPUT') expect(inputElement.value).not.toBeNull() @@ -137,7 +136,7 @@ export default (app: Application) => { await app.setElementValue('', 'Azusa') await app.waitUntilLoaded() const walletNameInputText = await client.elementIdAttribute(walletNameInputElement.value.ELEMENT, 'value') - console.log(`walletNameInputText - ${walletNameInputText.value}`); + console.info(`walletNameInputText - ${walletNameInputText.value}`) // Save const saveButton = await app.getElementByTagName('button', 'Save') expect(saveButton).not.toBeNull() @@ -145,10 +144,10 @@ export default (app: Application) => { await app.waitUntilLoaded() // Check wallet name - const newWalletNameElement = await app.element('//MAIN/DIV/DIV[3]/DIV/DIV/DIV/DIV/DIV[1]') + const newWalletNameElement = await app.element('label span') expect(newWalletNameElement).not.toBeNull() const newWalletName = await client.elementIdText(newWalletNameElement.value.ELEMENT) expect(newWalletName.value).toBe(walletNameInputText.value) - console.log(`newWalletName - ${newWalletName.value}`); + console.info(`newWalletName - ${newWalletName.value}`) }) }