Skip to content

Commit fed1854

Browse files
authored
Merge pull request #3 from jhkimqd/jihwan/monitor-ui
Jihwan/monitor UI
2 parents da791af + eb3a837 commit fed1854

File tree

4 files changed

+134
-12
lines changed

4 files changed

+134
-12
lines changed

cmd/monitor/monitor.go

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,7 @@ type (
9090
const (
9191
monitorModeHelp monitorMode = iota
9292
monitorModeExplorer
93+
monitorModeSelectBlock
9394
monitorModeBlock
9495
monitorModeTransaction
9596
)
@@ -374,11 +375,12 @@ func renderMonitorUI(ctx context.Context, ec *ethclient.Client, ms *monitorStatu
374375

375376
currentMode := monitorModeExplorer
376377

377-
blockTable, blockInfo, transactionList, transactionInformationList, transactionInfo, grid, blockGrid, transactionGrid, skeleton := ui.SetUISkeleton()
378+
blockTable, blockInfo, transactionList, transactionInformationList, transactionInfo, grid, selectGrid, blockGrid, transactionGrid, skeleton := ui.SetUISkeleton()
378379

379380
termWidth, termHeight := termui.TerminalDimensions()
380381
windowSize = termHeight/2 - 4
381382
grid.SetRect(0, 0, termWidth, termHeight)
383+
selectGrid.SetRect(0, 0, termWidth, termHeight)
382384
blockGrid.SetRect(0, 0, termWidth, termHeight)
383385
transactionGrid.SetRect(0, 0, termWidth, termHeight)
384386
// Initial render needed I assume to avoid the first bad redraw
@@ -390,6 +392,22 @@ func renderMonitorUI(ctx context.Context, ec *ethclient.Client, ms *monitorStatu
390392
redraw := func(ms *monitorStatus, force ...bool) {
391393
if currentMode == monitorModeHelp {
392394
// TODO add some help context?
395+
} else if currentMode == monitorModeSelectBlock {
396+
397+
rows, title := ui.GetSelectedBlocksList(renderedBlocks)
398+
blockTable.Rows = rows
399+
blockTable.Title = title
400+
401+
// in monitorSelectModeTransaction, blocks will always be selected
402+
transactionColumnRatio := []int{30, 5, 20, 20, 5, 10}
403+
ms.SelectedBlock = renderedBlocks[len(renderedBlocks)-blockTable.SelectedRow]
404+
blockInfo.Rows = ui.GetSimpleBlockFields(ms.SelectedBlock)
405+
transactionInfo.ColumnWidths = getColumnWidths(transactionColumnRatio, transactionInfo.Dx())
406+
transactionInfo.Rows = ui.GetBlockTxTable(ms.SelectedBlock, ms.ChainID)
407+
transactionInfo.Title = fmt.Sprintf("Latest Transactions for Block #%s", ms.SelectedBlock.Number().String())
408+
409+
termui.Render(selectGrid)
410+
return
393411
} else if currentMode == monitorModeBlock {
394412
// render a block
395413
skeleton.BlockInfo.Rows = ui.GetSimpleBlockFields(ms.SelectedBlock)
@@ -548,18 +566,24 @@ func renderMonitorUI(ctx context.Context, ec *ethclient.Client, ms *monitorStatu
548566
}
549567
} else if currentMode == monitorModeBlock {
550568
currentMode = monitorModeExplorer
569+
blockTable.SelectedRow = 0
570+
} else if currentMode == monitorModeSelectBlock {
571+
currentMode = monitorModeExplorer
572+
blockTable.SelectedRow = 0
551573
} else if currentMode == monitorModeTransaction {
552574
currentMode = monitorModeBlock
575+
blockTable.SelectedRow = 0
553576
}
554577
case "<Enter>":
555-
if currentMode == monitorModeExplorer && blockTable.SelectedRow > 0 {
578+
if (currentMode == monitorModeExplorer || currentMode == monitorModeSelectBlock) && blockTable.SelectedRow > 0 {
556579
currentMode = monitorModeBlock
557580
} else if transactionList.SelectedRow > 0 {
558581
currentMode = monitorModeTransaction
559582
}
560583
case "<Resize>":
561584
payload := e.Payload.(termui.Resize)
562585
grid.SetRect(0, 0, payload.Width, payload.Height)
586+
selectGrid.SetRect(0, 0, payload.Width, payload.Height)
563587
blockGrid.SetRect(0, 0, payload.Width, payload.Height)
564588
transactionGrid.SetRect(0, 0, payload.Width, payload.Height)
565589
_, termHeight = termui.TerminalDimensions()
@@ -578,6 +602,7 @@ func renderMonitorUI(ctx context.Context, ec *ethclient.Client, ms *monitorStatu
578602
if blockTable.SelectedRow == 0 {
579603
blockTable.SelectedRow = 1
580604
setBlock = true
605+
currentMode = monitorModeSelectBlock
581606
break
582607
}
583608

cmd/monitor/ui/ui.go

Lines changed: 101 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ func GetBlocksList(blocks []rpctypes.PolyBlock) ([]string, string) {
105105
zone, _ := time.Now().Zone()
106106
headerVariables := []string{"#", fmt.Sprintf("TIME (%s)", zone), "BLK TIME", "TXN #", "GAS USED", "HASH", "AUTHOR"}
107107

108-
proportion := []int{10, 10, 2, 2, 10, 12}
108+
proportion := []int{10, 20, 10, 10, 10, 80}
109109

110110
header := ""
111111
for i, prop := range proportion {
@@ -146,14 +146,90 @@ func GetBlocksList(blocks []rpctypes.PolyBlock) ([]string, string) {
146146
blockTime = strconv.FormatUint(bs[j].Time()-bs[j-1].Time(), 10)
147147
}
148148

149+
// Default block info row should be full width
149150
recordVariables := []string{
150151
fmt.Sprintf("%d", bs[j].Number()),
151152
ut.Format("02 Jan 06 15:04:05"),
152153
fmt.Sprintf("%ss", blockTime),
153154
fmt.Sprintf("%d", len(bs[j].Transactions())),
154155
fmt.Sprintf("%d", bs[j].GasUsed()),
155-
metrics.TruncateHexString(bs[j].Hash().String(), 14),
156-
metrics.TruncateHexString(author.String(), 14),
156+
bs[j].Hash().String(),
157+
author.String(),
158+
}
159+
160+
record := " "
161+
for i := 0; i < len(recordVariables)-1; i++ {
162+
spaceOffset := len(headerVariables[i]) + proportion[i] - len(recordVariables[i])
163+
if spaceOffset < 0 {
164+
spaceOffset = 0
165+
log.Error().Str("record", recordVariables[i]).Str("column", headerVariables[i]).Msg("Column width exceed header width")
166+
}
167+
record += recordVariables[i] + strings.Repeat(" ", spaceOffset)
168+
}
169+
record += recordVariables[len(recordVariables)-1]
170+
171+
records = append(records, record)
172+
}
173+
return records, header
174+
}
175+
176+
func GetSelectedBlocksList(blocks []rpctypes.PolyBlock) ([]string, string) {
177+
bs := rpctypes.SortableBlocks(blocks)
178+
sort.Sort(bs)
179+
180+
zone, _ := time.Now().Zone()
181+
headerVariables := []string{"#", fmt.Sprintf("TIME (%s)", zone), "BLK TIME", "TXN #", "GAS USED", "HASH", "AUTHOR"}
182+
183+
proportion := []int{10, 20, 10, 10, 10, 25}
184+
185+
header := ""
186+
for i, prop := range proportion {
187+
header += headerVariables[i] + strings.Repeat("─", prop)
188+
}
189+
header += headerVariables[len(headerVariables)-1]
190+
191+
if len(blocks) < 1 {
192+
return nil, header
193+
}
194+
195+
isMined := true
196+
197+
if blocks[0].Miner().String() == "0x0000000000000000000000000000000000000000" {
198+
isMined = false
199+
}
200+
201+
if !isMined {
202+
header = strings.Replace(header, "AUTHOR", "SIGNER", 1)
203+
}
204+
205+
// Set the first row to blank so that there is some space between the blocks
206+
// and the title.
207+
records := []string{""}
208+
209+
for j := len(bs) - 1; j >= 0; j = j - 1 {
210+
author := bs[j].Miner()
211+
ts := bs[j].Time()
212+
ut := time.Unix(int64(ts), 0)
213+
if !isMined {
214+
signer, err := metrics.Ecrecover(&bs[j])
215+
if err == nil {
216+
author = ethcommon.HexToAddress("0x" + hex.EncodeToString(signer))
217+
}
218+
}
219+
blockTime := "-"
220+
if j > 0 {
221+
blockTime = strconv.FormatUint(bs[j].Time()-bs[j-1].Time(), 10)
222+
}
223+
224+
// Default block info row should be full width
225+
recordVariables := []string{
226+
fmt.Sprintf("%d", bs[j].Number()),
227+
ut.Format("02 Jan 06 15:04:05"),
228+
fmt.Sprintf("%ss", blockTime),
229+
fmt.Sprintf("%d", len(bs[j].Transactions())),
230+
fmt.Sprintf("%d", bs[j].GasUsed()),
231+
metrics.TruncateHexString(bs[j].Hash().String(), 24),
232+
metrics.TruncateHexString(author.String(), 24),
157233
}
158234

159235
record := " "
@@ -382,7 +458,7 @@ func GetSimpleReceipt(ctx context.Context, rpc *ethrpc.Client, tx rpctypes.PolyT
382458
return fields
383459
}
384460

385-
func SetUISkeleton() (blockList *widgets.List, blockInfo *widgets.List, transactionList *widgets.List, transactionInformationList *widgets.List, transactionInfo *widgets.Table, grid *ui.Grid, blockGrid *ui.Grid, transactionGrid *ui.Grid, termUi UiSkeleton) {
461+
func SetUISkeleton() (blockList *widgets.List, blockInfo *widgets.List, transactionList *widgets.List, transactionInformationList *widgets.List, transactionInfo *widgets.Table, grid *ui.Grid, selectGrid *ui.Grid, blockGrid *ui.Grid, transactionGrid *ui.Grid, termUi UiSkeleton) {
386462
// help := widgets.NewParagraph()
387463
// help.Title = "Block Headers"
388464
// help.Text = "Use the arrow keys to scroll through the transactions. Press <Esc> to go back to the explorer view"
@@ -437,6 +513,7 @@ func SetUISkeleton() (blockList *widgets.List, blockInfo *widgets.List, transact
437513
slg4.Title = "Gas Used"
438514

439515
grid = ui.NewGrid()
516+
selectGrid = ui.NewGrid()
440517
blockGrid = ui.NewGrid()
441518
transactionGrid = ui.NewGrid()
442519

@@ -480,6 +557,26 @@ func SetUISkeleton() (blockList *widgets.List, blockInfo *widgets.List, transact
480557
ui.NewCol(1.0/5, slg4),
481558
),
482559

560+
ui.NewRow(5.0/10,
561+
ui.NewCol(5.0/5, blockList),
562+
),
563+
564+
ui.NewRow(2.0/10,
565+
ui.NewCol(5.0/5, transactionInfo),
566+
),
567+
)
568+
569+
selectGrid.Set(
570+
ui.NewRow(1.0/10, termUi.Current),
571+
572+
ui.NewRow(2.0/10,
573+
ui.NewCol(1.0/5, slg0),
574+
ui.NewCol(1.0/5, slg1),
575+
ui.NewCol(1.0/5, slg2),
576+
ui.NewCol(1.0/5, slg3),
577+
ui.NewCol(1.0/5, slg4),
578+
),
579+
483580
ui.NewRow(5.0/10,
484581
ui.NewCol(3.0/5, blockList),
485582
ui.NewCol(2.0/5, blockInfo),

go.mod

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ require (
1212
github.com/gizak/termui/v3 v3.1.1-0.20231111080052-b3569a6cd52d
1313
github.com/google/gofuzz v1.2.0
1414
github.com/hashicorp/golang-lru v1.0.2
15-
github.com/jedib0t/go-pretty/v6 v6.5.8
15+
github.com/jedib0t/go-pretty/v6 v6.5.9
1616
github.com/libp2p/go-libp2p v0.31.0
1717
github.com/manifoldco/promptui v0.9.0
1818
github.com/oasisprotocol/curve25519-voi v0.0.0-20230904125328-1f23a7beb09a
@@ -111,7 +111,7 @@ require (
111111
github.com/pelletier/go-toml/v2 v2.1.0 // indirect
112112
github.com/pkg/errors v0.9.1 // indirect
113113
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
114-
github.com/prometheus/client_golang v1.19.0
114+
github.com/prometheus/client_golang v1.19.1
115115
github.com/prometheus/procfs v0.12.0 // indirect
116116
github.com/rivo/uniseg v0.4.7 // indirect
117117
github.com/rogpeppe/go-internal v1.10.0 // indirect

go.sum

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -226,8 +226,8 @@ github.com/ipfs/go-cid v0.4.1 h1:A/T3qGvxi4kpKWWcPC/PgbvDA2bjVLO7n4UeVwnbs/s=
226226
github.com/ipfs/go-cid v0.4.1/go.mod h1:uQHwDeX4c6CtyrFwdqyhpNcxVewur1M7l7fNU7LKwZk=
227227
github.com/jackpal/go-nat-pmp v1.0.2 h1:KzKSgb7qkJvOUTqYl9/Hg/me3pWgBmERKrTGD7BdWus=
228228
github.com/jackpal/go-nat-pmp v1.0.2/go.mod h1:QPH045xvCAeXUZOxsnwmrtiCoxIr9eob+4orBN1SBKc=
229-
github.com/jedib0t/go-pretty/v6 v6.5.8 h1:8BCzJdSvUbaDuRba4YVh+SKMGcAAKdkcF3SVFbrHAtQ=
230-
github.com/jedib0t/go-pretty/v6 v6.5.8/go.mod h1:zbn98qrYlh95FIhwwsbIip0LYpwSG8SUOScs+v9/t0E=
229+
github.com/jedib0t/go-pretty/v6 v6.5.9 h1:ACteMBRrrmm1gMsXe9PSTOClQ63IXDUt03H5U+UV8OU=
230+
github.com/jedib0t/go-pretty/v6 v6.5.9/go.mod h1:zbn98qrYlh95FIhwwsbIip0LYpwSG8SUOScs+v9/t0E=
231231
github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
232232
github.com/jrick/logrotate v1.0.0/go.mod h1:LNinyqDIJnpAur+b8yyulnQw/wDuN1+BYKlTRt3OuAQ=
233233
github.com/k0kubun/go-ansi v0.0.0-20180517002512-3bf9e2903213/go.mod h1:vNUNkEQ1e29fT/6vq2aBdFsgNPmy8qMdSay1npru+Sw=
@@ -326,8 +326,8 @@ github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINE
326326
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
327327
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U=
328328
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
329-
github.com/prometheus/client_golang v1.19.0 h1:ygXvpU1AoN1MhdzckN+PyD9QJOSD4x7kmXYlnfbA6JU=
330-
github.com/prometheus/client_golang v1.19.0/go.mod h1:ZRM9uEAypZakd+q/x7+gmsvXdURP+DABIEIjnmDdp+k=
329+
github.com/prometheus/client_golang v1.19.1 h1:wZWJDwK+NameRJuPGDhlnFgx8e8HN3XHQeLaYJFJBOE=
330+
github.com/prometheus/client_golang v1.19.1/go.mod h1:mP78NwGzrVks5S2H6ab8+ZZGJLZUq1hoULYBAYBw1Ho=
331331
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
332332
github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E=
333333
github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY=

0 commit comments

Comments
 (0)