Skip to content

Commit 1378768

Browse files
authored
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
1 parent c8ce2dd commit 1378768

6 files changed

Lines changed: 158 additions & 103 deletions

File tree

packages/neuron-ui/src/components/Overview/index.tsx

Lines changed: 7 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -17,18 +17,16 @@ import {
1717
IDetailsRowStyles,
1818
FontSizes,
1919
Callout,
20-
MessageBar,
21-
MessageBarType,
2220
} from 'office-ui-fabric-react'
2321
import PropertyList, { Property } from 'widgets/PropertyList'
2422

2523
import { StateWithDispatch } from 'states/stateProvider/reducer'
26-
import { updateTransactionList, addPopup } from 'states/stateProvider/actionCreators'
24+
import { updateTransactionList } from 'states/stateProvider/actionCreators'
2725

28-
import { showTransactionDetails, showErrorMessage } from 'services/remote'
26+
import { showTransactionDetails } from 'services/remote'
2927

3028
import { localNumberFormatter, shannonToCKBFormatter, uniformTimeFormatter as timeFormatter } from 'utils/formatters'
31-
import { PAGE_SIZE, Routes, CONFIRMATION_THRESHOLD, ErrorCode } from 'utils/const'
29+
import { PAGE_SIZE, Routes, CONFIRMATION_THRESHOLD } from 'utils/const'
3230
import { backToTop } from 'utils/animations'
3331

3432
const TITLE_FONT_SIZE = 'xxLarge'
@@ -157,20 +155,17 @@ const ActivityList = ({
157155
const Overview = ({
158156
dispatch,
159157
app: { tipBlockNumber, chain, epoch, difficulty },
160-
wallet: { id, name, balance = '', addresses = [] },
158+
wallet: { id, name, balance = '' },
161159
chain: {
162160
tipBlockNumber: syncedBlockNumber,
163-
codeHash = '',
164161
transactions: { items = [] },
165162
},
166163
history,
167164
}: React.PropsWithoutRef<StateWithDispatch & RouteComponentProps>) => {
168165
const [t] = useTranslation()
169166
const [displayBlockchainInfo, setDisplayBlockchainInfo] = useState(false)
170-
const [displayMinerInfo, setDisplayMinerInfo] = useState(false)
171167

172168
const blockchainInfoRef = useRef<HTMLDivElement>(null)
173-
const minerInfoRef = useRef<HTMLDivElement>(null)
174169

175170
useEffect(() => {
176171
if (id) {
@@ -264,33 +259,11 @@ const Overview = ({
264259
[t, chain, epoch, difficulty, tipBlockNumber]
265260
)
266261

267-
const [showBlockchainStatus, hideBlockchainStatus, showMinerInfo, hideMinerInfo] = useMemo(
268-
() => [
269-
() => setDisplayBlockchainInfo(true),
270-
() => setDisplayBlockchainInfo(false),
271-
() => setDisplayMinerInfo(true),
272-
() => setDisplayMinerInfo(false),
273-
],
274-
[setDisplayBlockchainInfo, setDisplayMinerInfo]
262+
const [showBlockchainStatus, hideBlockchainStatus] = useMemo(
263+
() => [() => setDisplayBlockchainInfo(true), () => setDisplayBlockchainInfo(false)],
264+
[setDisplayBlockchainInfo]
275265
)
276266

277-
const defaultAddress = useMemo(() => {
278-
return addresses.find(addr => addr.type === 0 && addr.index === 0)
279-
}, [addresses])
280-
281-
const onCopyPubkeyHash = useCallback(() => {
282-
if (defaultAddress) {
283-
window.navigator.clipboard.writeText(defaultAddress.identifier)
284-
hideMinerInfo()
285-
addPopup('lock-arg-copied')(dispatch)
286-
} else {
287-
showErrorMessage(
288-
t(`messages.error`),
289-
t(`messages.codes.${ErrorCode.FieldNotFound}`, { fieldName: `default-address` })
290-
)
291-
}
292-
}, [defaultAddress, t, hideMinerInfo, dispatch])
293-
294267
const activityItems = useMemo(
295268
() =>
296269
items.map(item => {
@@ -342,11 +315,6 @@ const Overview = ({
342315
{t('overview.blockchain-status')}
343316
</DefaultButton>
344317
</div>
345-
<div ref={minerInfoRef}>
346-
<DefaultButton onClick={showMinerInfo} styles={{ root: { width: '200px' } }}>
347-
{t('overview.miner-info')}
348-
</DefaultButton>
349-
</div>
350318
</Stack>
351319
</Stack>
352320
<Text as="h2" variant={TITLE_FONT_SIZE}>
@@ -375,49 +343,6 @@ const Overview = ({
375343
</Stack>
376344
</Callout>
377345
) : null}
378-
{minerInfoRef.current ? (
379-
<Callout target={minerInfoRef.current} hidden={!displayMinerInfo} onDismiss={hideMinerInfo} gapSpace={0}>
380-
<Stack tokens={{ padding: 15 }}>
381-
{defaultAddress ? (
382-
<Stack tokens={{ childrenGap: 15 }} styles={{ root: { padding: 5 } }}>
383-
<Stack tokens={{ childrenGap: 15 }}>
384-
<Text variant="small" style={{ fontWeight: 600 }}>
385-
{t('overview.address')}
386-
</Text>
387-
<Text variant="small" className="monospacedFont">
388-
{defaultAddress.address}
389-
</Text>
390-
</Stack>
391-
<Stack tokens={{ childrenGap: 15 }}>
392-
<Text variant="small" style={{ fontWeight: 600 }}>
393-
{t('overview.code-hash')}
394-
</Text>
395-
<Text variant="small" className="monospacedFont">
396-
{codeHash}
397-
</Text>
398-
</Stack>
399-
<Stack tokens={{ childrenGap: 15 }}>
400-
<Text variant="small" style={{ fontWeight: 600 }}>
401-
{t('overview.lock-arg')}
402-
</Text>
403-
<Text variant="small" className="monospacedFont">
404-
{defaultAddress.identifier}
405-
</Text>
406-
</Stack>
407-
<Stack horizontalAlign="end">
408-
<ActionButton iconProps={{ iconName: 'MiniCopy' }} onClick={onCopyPubkeyHash}>
409-
{t('overview.copy-pubkey-hash')}
410-
</ActionButton>
411-
</Stack>
412-
</Stack>
413-
) : (
414-
<MessageBar messageBarType={MessageBarType.error}>
415-
{t(`messages.codes.${ErrorCode.FieldNotFound}`, { fieldName: `default-address` })}
416-
</MessageBar>
417-
)}
418-
</Stack>
419-
</Callout>
420-
) : null}
421346
</Stack>
422347
)
423348
}

packages/neuron-ui/src/components/WalletSetting/index.tsx

Lines changed: 104 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,28 @@
1-
import React, { useCallback } from 'react'
1+
import React, { useState, useCallback, useMemo } from 'react'
22
import { RouteComponentProps } from 'react-router-dom'
33
import { useTranslation } from 'react-i18next'
4-
import { Stack, PrimaryButton, ChoiceGroup, IChoiceGroupOption } from 'office-ui-fabric-react'
4+
import {
5+
Stack,
6+
PrimaryButton,
7+
ChoiceGroup,
8+
IChoiceGroupOption,
9+
Text,
10+
Callout,
11+
MessageBar,
12+
MessageBarType,
13+
ActionButton,
14+
getTheme,
15+
} from 'office-ui-fabric-react'
516

617
import { StateWithDispatch } from 'states/stateProvider/reducer'
7-
import { setCurrentWallet } from 'states/stateProvider/actionCreators'
18+
import { setCurrentWallet, addPopup } from 'states/stateProvider/actionCreators'
819

920
import { WalletWizardPath } from 'components/WalletWizard'
1021

1122
import { contextMenu } from 'services/remote'
12-
import { Routes, MnemonicAction } from 'utils/const'
23+
import { Routes, MnemonicAction, ErrorCode } from 'utils/const'
24+
25+
const theme = getTheme()
1326

1427
const buttons = [
1528
{
@@ -28,11 +41,34 @@ const buttons = [
2841

2942
const WalletSetting = ({
3043
wallet: { id: currentID = '' },
44+
chain: { codeHash = '' },
3145
settings: { wallets = [] },
3246
dispatch,
3347
history,
3448
}: React.PropsWithoutRef<StateWithDispatch & RouteComponentProps>) => {
3549
const [t] = useTranslation()
50+
const [target, setTarget] = useState<any>(null)
51+
const [minerInfo, setMinerInfo] = useState<{ address: string; identifier: string }>({
52+
address: '',
53+
identifier: '',
54+
})
55+
56+
const [showMinerInfo, hideMinerInfo] = useMemo(
57+
() => [
58+
(info: { address: string; identifier: string }) => setMinerInfo(info),
59+
() => setMinerInfo({ address: '', identifier: '' }),
60+
],
61+
[setMinerInfo]
62+
)
63+
64+
const onCopyPubkeyHash = useCallback(() => {
65+
if (minerInfo) {
66+
window.navigator.clipboard.writeText(minerInfo.identifier)
67+
hideMinerInfo()
68+
addPopup('lock-arg-copied')(dispatch)
69+
}
70+
}, [minerInfo, t, hideMinerInfo, dispatch])
71+
3672
const onChange = useCallback(
3773
(_e, option) => {
3874
if (option) {
@@ -65,9 +101,29 @@ const WalletSetting = ({
65101
checked: wallet.id === currentID,
66102
onRenderLabel: ({ text }: IChoiceGroupOption) => {
67103
return (
68-
<span className="ms-ChoiceFieldLabel" onContextMenu={onContextMenu(wallet.id)}>
69-
{text}
70-
</span>
104+
<Stack>
105+
<span className="ms-ChoiceFieldLabel" onContextMenu={onContextMenu(wallet.id)}>
106+
{text}
107+
</span>
108+
{wallet.minerAddress ? (
109+
<Text
110+
variant="tiny"
111+
className="ms-ChoiceFieldLabel"
112+
onClick={(e: React.MouseEvent<HTMLDivElement>) => {
113+
e.preventDefault()
114+
setTarget(e.target)
115+
if (wallet.minerAddress) {
116+
showMinerInfo(wallet.minerAddress)
117+
}
118+
}}
119+
styles={{
120+
root: [{ color: theme.semanticColors.bodySubtext, fontSize: '12px!important' }],
121+
}}
122+
>
123+
{t('overview.miner-info')}
124+
</Text>
125+
) : null}
126+
</Stack>
71127
)
72128
},
73129
}))}
@@ -79,6 +135,47 @@ const WalletSetting = ({
79135
<PrimaryButton key={label} onClick={navTo(url)} text={t(label)} />
80136
))}
81137
</Stack>
138+
<Callout target={target} hidden={!minerInfo.address} onDismiss={hideMinerInfo} gapSpace={0}>
139+
<Stack tokens={{ padding: 15 }}>
140+
{minerInfo.address ? (
141+
<Stack tokens={{ childrenGap: 15 }} styles={{ root: { padding: 5 } }}>
142+
<Stack tokens={{ childrenGap: 15 }}>
143+
<Text variant="small" style={{ fontWeight: 600 }}>
144+
{t('overview.address')}
145+
</Text>
146+
<Text variant="small" className="monospacedFont">
147+
{minerInfo.address}
148+
</Text>
149+
</Stack>
150+
<Stack tokens={{ childrenGap: 15 }}>
151+
<Text variant="small" style={{ fontWeight: 600 }}>
152+
{t('overview.code-hash')}
153+
</Text>
154+
<Text variant="small" className="monospacedFont">
155+
{codeHash}
156+
</Text>
157+
</Stack>
158+
<Stack tokens={{ childrenGap: 15 }}>
159+
<Text variant="small" style={{ fontWeight: 600 }}>
160+
{t('overview.lock-arg')}
161+
</Text>
162+
<Text variant="small" className="monospacedFont">
163+
{minerInfo.identifier}
164+
</Text>
165+
</Stack>
166+
<Stack horizontalAlign="end">
167+
<ActionButton iconProps={{ iconName: 'MiniCopy' }} onClick={onCopyPubkeyHash}>
168+
{t('overview.copy-pubkey-hash')}
169+
</ActionButton>
170+
</Stack>
171+
</Stack>
172+
) : (
173+
<MessageBar messageBarType={MessageBarType.error}>
174+
{t(`messages.codes.${ErrorCode.FieldNotFound}`, { fieldName: `default-address` })}
175+
</MessageBar>
176+
)}
177+
</Stack>
178+
</Callout>
82179
</Stack>
83180
)
84181
}

packages/neuron-ui/src/types/App/index.d.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,7 @@ declare namespace State {
107107
interface WalletIdentity {
108108
id: string
109109
name: string
110+
minerAddress?: { address: string; identifier: string }
110111
}
111112

112113
interface Address {

packages/neuron-wallet/src/controllers/app/index.ts

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,23 @@ export default class AppController {
7272
SystemScriptSubject.pipe(take(1)).subscribe(({ codeHash: currentCodeHash }) => resolve(currentCodeHash))
7373
}),
7474
])
75+
76+
const minerAddresses = await Promise.all(
77+
wallets.map(({ id }) =>
78+
WalletsController.getAllAddresses(id).then(addrRes => {
79+
if (addrRes.result) {
80+
const minerAddr = addrRes.result.find(addr => addr.type === 0 && addr.index === 0)
81+
if (minerAddr) {
82+
return {
83+
address: minerAddr.address,
84+
identifier: minerAddr.identifier,
85+
}
86+
}
87+
}
88+
return undefined
89+
})
90+
)
91+
)
7592
const addresses: Controller.Address[] = await (currentWallet
7693
? WalletsController.getAllAddresses(currentWallet.id).then(res => res.result)
7794
: [])
@@ -86,7 +103,7 @@ export default class AppController {
86103
: []
87104
const initState = {
88105
currentWallet,
89-
wallets: [...wallets.map(({ name, id }) => ({ id, name }))],
106+
wallets: [...wallets.map(({ name, id }, idx: number) => ({ id, name, minerAddress: minerAddresses[idx] }))],
90107
currentNetworkID,
91108
networks,
92109
addresses,

packages/neuron-wallet/src/controllers/wallets/index.ts

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,9 +35,25 @@ export default class WalletsController {
3535
if (!wallets) {
3636
throw new ServiceHasNoResponse('Wallet')
3737
}
38+
const minerAddresses = await Promise.all(
39+
wallets.map(({ id }) =>
40+
WalletsController.getAllAddresses(id).then(addrRes => {
41+
if (addrRes.result) {
42+
const minerAddr = addrRes.result.find(addr => addr.type === 0 && addr.index === 0)
43+
if (minerAddr) {
44+
return {
45+
address: minerAddr.address,
46+
identifier: minerAddr.identifier,
47+
}
48+
}
49+
}
50+
return undefined
51+
})
52+
)
53+
)
3854
return {
3955
status: ResponseCode.Success,
40-
result: wallets.map(({ name, id }) => ({ name, id })),
56+
result: wallets.map(({ name, id }, idx) => ({ name, id, minerAddress: minerAddresses[idx] })),
4157
}
4258
}
4359

0 commit comments

Comments
 (0)