Skip to content

Commit 84692c7

Browse files
committed
feat(neuron-ui): show confirmations on the History View
1 parent a03bc44 commit 84692c7

6 files changed

Lines changed: 144 additions & 16 deletions

File tree

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

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,12 @@ import { useSearch } from './hooks'
1313

1414
const History = ({
1515
app: {
16+
tipBlockNumber: chainBlockNumber,
1617
loadings: { transactionList: isLoading, updateDescription: isUpdatingDescription },
1718
},
1819
wallet: { id },
1920
chain: {
21+
tipBlockNumber: syncedBlockNumber,
2022
transactions: { pageNo = 1, pageSize = 15, totalCount = 0, items = [] },
2123
},
2224
history,
@@ -33,6 +35,10 @@ const History = ({
3335
}, [id, history])
3436
const onSearch = useCallback(() => history.push(`${Routes.History}?keywords=${keywords}`), [history, keywords])
3537

38+
const tipBlockNumber = useMemo(() => {
39+
return Math.max(+syncedBlockNumber, +chainBlockNumber).toString()
40+
}, [syncedBlockNumber, chainBlockNumber])
41+
3642
const List = useMemo(() => {
3743
return (
3844
<Stack>
@@ -51,6 +57,7 @@ const History = ({
5157
isUpdatingDescription={isUpdatingDescription}
5258
walletID={id}
5359
items={items}
60+
tipBlockNumber={tipBlockNumber}
5461
dispatch={dispatch}
5562
/>
5663
<Pagination
@@ -83,6 +90,7 @@ const History = ({
8390
isUpdatingDescription,
8491
id,
8592
items,
93+
tipBlockNumber,
8694
dispatch,
8795
pageNo,
8896
totalCount,

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

Lines changed: 81 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,14 @@ import { StateDispatch } from 'states/stateProvider/reducer'
1616
import { contextMenu, showTransactionDetails } from 'services/remote'
1717

1818
import { useLocalDescription } from 'utils/hooks'
19-
import { shannonToCKBFormatter, uniformTimeFormatter as timeFormatter, uniformTimeFormatter } from 'utils/formatters'
19+
import {
20+
shannonToCKBFormatter,
21+
uniformTimeFormatter as timeFormatter,
22+
uniformTimeFormatter,
23+
localNumberFormatter,
24+
} from 'utils/formatters'
2025
import { onRenderRow } from 'utils/fabricUIRender'
26+
import { CONFIRMATION_THRESHOLD } from 'utils/const'
2127

2228
const theme = getTheme()
2329

@@ -50,12 +56,14 @@ const TransactionList = ({
5056
isUpdatingDescription = false,
5157
items = [],
5258
walletID,
59+
tipBlockNumber,
5360
dispatch,
5461
}: {
5562
isLoading?: boolean
5663
isUpdatingDescription?: boolean
5764
walletID: string
5865
items: State.Transaction[]
66+
tipBlockNumber: string
5967
dispatch: StateDispatch
6068
}) => {
6169
const [t] = useTranslation()
@@ -71,35 +79,95 @@ const TransactionList = ({
7179
const transactionColumns: IColumn[] = useMemo(
7280
(): IColumn[] =>
7381
[
74-
{ name: t('history.type'), key: 'type', fieldName: 'type', minWidth: MIN_CELL_WIDTH, maxWidth: 50 },
82+
{
83+
name: t('history.type'),
84+
key: 'type',
85+
fieldName: 'type',
86+
minWidth: MIN_CELL_WIDTH,
87+
maxWidth: 50,
88+
onRender: (item?: FormatTransaction) => {
89+
if (!item) {
90+
return null
91+
}
92+
const type = t(`history.${item.type}`)
93+
return <span title={type}>{type}</span>
94+
},
95+
},
7596
{
7697
name: t('history.timestamp'),
7798
key: 'timestamp',
7899
fieldName: 'timestamp',
79100
minWidth: 80,
80101
maxWidth: 80,
81102
onRender: (item?: FormatTransaction) => {
82-
return item ? <span>{uniformTimeFormatter(item.timestamp || item.createdAt).split(' ')[1]}</span> : null
103+
if (!item) {
104+
return null
105+
}
106+
const time = uniformTimeFormatter(item.timestamp || item.createdAt).split(' ')[1]
107+
return <span title={time}>{time}</span>
83108
},
84109
},
85110
{
86111
name: t('history.transaction-hash'),
87112
key: 'hash',
88113
fieldName: 'hash',
114+
minWidth: 150,
115+
maxWidth: 150,
116+
onRender: (item?: FormatTransaction) => {
117+
if (!item) {
118+
return '-'
119+
}
120+
return (
121+
<span className="text-overflow monospacedFont" title={item.hash}>
122+
{`${item.hash.slice(0, 8)}...${item.hash.slice(-6)}`}
123+
</span>
124+
)
125+
},
126+
},
127+
{
128+
name: t('history.confirmations'),
129+
key: 'confirmation',
89130
minWidth: 100,
90-
maxWidth: 600,
131+
maxWidth: +tipBlockNumber > 1e12 ? undefined : 150,
91132
onRender: (item?: FormatTransaction) => {
92-
if (item) {
93-
return (
94-
<span className="text-overflow monospacedFont" title={item.hash}>
95-
{item.hash}
96-
</span>
97-
)
133+
if (!item || item.status !== 'success') {
134+
return null
98135
}
99-
return '-'
136+
const confirmationCount = 1 + +tipBlockNumber - +item.blockNumber
137+
if (confirmationCount < CONFIRMATION_THRESHOLD) {
138+
return t(`history.confirming-with-count`, {
139+
confirmations: `${confirmationCount} / ${CONFIRMATION_THRESHOLD}`,
140+
})
141+
}
142+
const confirmations = localNumberFormatter(confirmationCount)
143+
return (
144+
<span title={`${confirmations}`} className="text-overflow">
145+
{confirmations}
146+
</span>
147+
)
148+
},
149+
},
150+
{
151+
name: t('history.status'),
152+
key: 'status',
153+
fieldName: 'status',
154+
minWidth: 80,
155+
maxWidth: 80,
156+
onRender: (item?: FormatTransaction) => {
157+
if (!item) {
158+
return null
159+
}
160+
if (item.status !== 'success') {
161+
const status = t(`history.${item.status}`)
162+
return <span title={status}>{status}</span>
163+
}
164+
const confirmationCount = 1 + +tipBlockNumber - +item.blockNumber
165+
if (confirmationCount < CONFIRMATION_THRESHOLD) {
166+
return t(`history.confirming`)
167+
}
168+
return t(`history.success`)
100169
},
101170
},
102-
{ name: t('history.status'), key: 'status', fieldName: 'status', minWidth: 50, maxWidth: 50 },
103171
{
104172
name: t('history.description'),
105173
key: 'description',
@@ -151,6 +219,7 @@ const TransactionList = ({
151219
},
152220
].map((col): IColumn => ({ fieldName: col.key, ariaLabel: col.name, ...col })),
153221
[
222+
tipBlockNumber,
154223
localDescription,
155224
onDescriptionChange,
156225
onDescriptionFieldBlur,

packages/neuron-ui/src/locales/en.json

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -126,11 +126,17 @@
126126
"last": "Last",
127127
"description": "Description",
128128
"status": "Status",
129+
"pending": "Pending",
130+
"success": "Success",
131+
"failed": "Failed",
132+
"confirming": "Confirming",
129133
"blockNumber": "Block Number",
130134
"basic-information": "Basic Information",
131135
"search": {
132136
"placeholder": "Search tx hash, address or date (yyyy-mm-dd)"
133-
}
137+
},
138+
"confirmations": "Confirmations",
139+
"confirming-with-count": "{{confirmations}} confirmations"
134140
},
135141
"transaction": {
136142
"goBack": "Go back"

packages/neuron-ui/src/locales/zh.json

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -126,11 +126,17 @@
126126
"last": "最后一页",
127127
"description": "标签",
128128
"status": "状态",
129+
"pending": "已提交",
130+
"success": "成功",
131+
"failed": "失败",
132+
"confirming": "确认中",
129133
"blockNumber": "区块高度",
130134
"basic-information": "基本信息",
131135
"search": {
132136
"placeholder": "使用交易哈希、地址或日期(yyyy-mm-dd)进行搜索"
133-
}
137+
},
138+
"confirmations": "确认次数",
139+
"confirming-with-count": " 已确认 {{confirmations}} 次"
134140
},
135141
"transaction": {
136142
"goBack": "返回"

packages/neuron-ui/src/stories/TransactionList.stories.tsx

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,21 @@ import transactions from './data/transactions'
66
const stories = storiesOf('TransactionList', module)
77
Object.entries(transactions).forEach(([title, list]) => {
88
stories.add(title, () => (
9-
<TransactionList isLoading={false} isUpdatingDescription={false} walletID="1" items={list} dispatch={() => {}} />
9+
<TransactionList
10+
isLoading={false}
11+
tipBlockNumber="123"
12+
isUpdatingDescription={false}
13+
walletID="1"
14+
items={list}
15+
dispatch={() => {}}
16+
/>
1017
))
1118
})
1219

1320
stories.add('Wtih empty pending list', () => (
1421
<TransactionList
1522
isLoading={false}
23+
tipBlockNumber="123"
1624
isUpdatingDescription={false}
1725
walletID="1"
1826
items={transactions['Content List'].filter(item => item.status !== 'pending')}
@@ -21,5 +29,14 @@ stories.add('Wtih empty pending list', () => (
2129
))
2230

2331
stories.add('Shimmered List', () => {
24-
return <TransactionList isLoading={false} isUpdatingDescription={false} walletID="1" items={[]} dispatch={() => {}} />
32+
return (
33+
<TransactionList
34+
isLoading={false}
35+
tipBlockNumber="123"
36+
isUpdatingDescription={false}
37+
walletID="1"
38+
items={[]}
39+
dispatch={() => {}}
40+
/>
41+
)
2542
})

packages/neuron-ui/src/stories/data/transactions.ts

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,28 @@ const transactions: {
2525
blockNumber: '120',
2626
status: 'pending',
2727
},
28+
{
29+
type: 'send',
30+
createdAt: (new Date(1565240655845).getTime() - 100000).toString(),
31+
updatedAt: '',
32+
timestamp: '',
33+
value: '-10000',
34+
hash: '0x70abeeaa2ed08b7d7659341a122b9a2f2ede99bb6bd0df7398d7ffe488beab11',
35+
description: 'description of send transaction',
36+
blockNumber: '120',
37+
status: 'success',
38+
},
39+
{
40+
type: 'receive',
41+
createdAt: (new Date(1565240655845).getTime() - 200000).toString(),
42+
updatedAt: '',
43+
timestamp: '',
44+
value: '10000',
45+
hash: '0x70abeeaa2ed08b7d7659341a122b9a2f2ede99bb6bd0df7398d7ffe488beab22',
46+
description: 'description of receive transaction',
47+
blockNumber: '120',
48+
status: 'success',
49+
},
2850
{
2951
type: 'send',
3052
createdAt: '',

0 commit comments

Comments
 (0)