/
update.go
138 lines (118 loc) · 4.04 KB
/
update.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
package tui
import (
"context"
"fmt"
"strconv"
"github.com/gdamore/tcell/v2"
"github.com/rivo/tview"
"github.com/strangelove-ventures/interchaintest/v6/internal/blockdb/tui/presenter"
)
// Update should be the argument for *(tview.Application).SetInputCapture.
// The Model potentially updates view state based on the event.
// Update must be called from the main goroutine. Otherwise, view updates will not render or cause data races.
// Per tview documentation, return nil to stop event propagation.
func (m *Model) Update(ctx context.Context) func(event *tcell.EventKey) *tcell.EventKey {
return func(event *tcell.EventKey) *tcell.EventKey {
oldMain := m.stack.Current()
defer m.updateHelp(oldMain)
switch {
case event.Key() == tcell.KeyESC:
if len(m.stack) > 1 { // Stack must be at least 1, so we don't remove all main content views.
m.mainContentView().RemovePage(m.stack.Current().String())
m.stack = m.stack.Pop()
return nil
}
case event.Key() == tcell.KeyEnter && m.stack.Current() == testCasesMain:
// Show tx detail.
tc := m.testCases[m.selectedRow()]
results, err := m.querySvc.Transactions(ctx, tc.ChainPKey)
if err != nil {
m.pushErrorModal(fmt.Errorf("query transactions: %w", err))
return nil
}
m.pushMainView(txDetailMain, newTxDetailView(tc.ChainID, results))
return nil
case event.Rune() == 'm' && m.stack.Current() == testCasesMain:
// Show cosmos messages.
tc := m.testCases[m.selectedRow()]
results, err := m.querySvc.CosmosMessages(ctx, tc.ChainPKey)
if err != nil {
m.pushErrorModal(fmt.Errorf("query cosmos messages: %w", err))
return nil
}
m.pushMainView(cosmosMessagesMain, cosmosMessagesView(tc, results))
return nil
case event.Rune() == '[' && m.stack.Current() == txDetailMain:
goToPrevPage(m.txDetailView().Pages)
return nil
case event.Rune() == ']' && m.stack.Current() == txDetailMain:
gotToNextPage(m.txDetailView().Pages)
return nil
case event.Rune() == '/' && m.stack.Current() == txDetailMain:
m.txDetailView().ToggleSearch()
return nil
case event.Rune() == 'c' && m.stack.Current() == txDetailMain:
if err := m.clipboard(string(presenter.Txs(m.txDetailView().Txs).ToJSON())); err != nil {
m.pushErrorModal(fmt.Errorf("copy to clipboard: %w", err))
}
return nil
case event.Key() == tcell.KeyEnter && m.stack.Current() == txDetailMain:
// Search tx detail.
m.txDetailView().DoSearch()
return nil
}
return event
}
}
func (m *Model) updateHelp(oldMainContent mainContent) {
// Prevent redrawing if nothing has changed.
if oldMainContent == m.stack.Current() {
return
}
help := m.layout.GetItem(0).(*tview.Flex).GetItem(0).(*helpView)
help.Replace(keyMap[m.stack.Current()])
}
func (m *Model) mainContentView() *tview.Pages {
return m.layout.GetItem(1).(*tview.Pages)
}
func (m *Model) pushMainView(main mainContent, view tview.Primitive) {
m.stack = m.stack.Push(main)
m.mainContentView().AddAndSwitchToPage(main.String(), view, true)
}
func (m *Model) pushErrorModal(err error) {
m.pushMainView(errorModalMain, errorModalView(err))
}
func (m *Model) selectedRow() int {
_, view := m.mainContentView().GetFrontPage()
row, _ := view.(*tview.Table).GetSelection()
// Offset by 1 to account for header row.
return row - 1
}
func (m *Model) txDetailView() *txDetailView {
_, primitive := m.mainContentView().GetFrontPage()
return primitive.(*txDetailView)
}
// gotToNextPage assumes a convention where the page name is equal to its index. e.g. "0", "1", "2", etc.
func gotToNextPage(pages *tview.Pages) {
idxStr, _ := pages.GetFrontPage()
idx, err := strconv.Atoi(idxStr)
if err != nil {
panic(err)
}
if idx == pages.GetPageCount()-1 {
return
}
pages.SwitchToPage(strconv.Itoa(idx + 1))
}
// goToPrevPage assumes a convention where the page name is equal to its index. e.g. "0", "1", "2", etc.
func goToPrevPage(pages *tview.Pages) {
idxStr, _ := pages.GetFrontPage()
idx, err := strconv.Atoi(idxStr)
if err != nil {
panic(err)
}
if idx == 0 {
return
}
pages.SwitchToPage(strconv.Itoa(idx - 1))
}