|
@@ -1,3 +1,7 @@
|
|
|
|
|
+// TODO(chart): dynamically render charts to fit height on not set
|
|
|
|
|
+//
|
|
|
|
|
+// TODO(styling): allow end user to define their own styles when hacking.
|
|
|
|
|
+//
|
|
|
// Pingo defines an extensible TUI based on the bubbletea framework (v2). An
|
|
// Pingo defines an extensible TUI based on the bubbletea framework (v2). An
|
|
|
// executable entry point is defined via cmd/pingo.go. For more on this topic,
|
|
// executable entry point is defined via cmd/pingo.go. For more on this topic,
|
|
|
// see the Readme.
|
|
// see the Readme.
|
|
@@ -113,8 +117,8 @@ type ( // tea.Msg signatures
|
|
|
|
|
|
|
|
// Bubbletea model
|
|
// Bubbletea model
|
|
|
type Model struct {
|
|
type Model struct {
|
|
|
- Addresses []Address // as defined in internal/tui/types.go
|
|
|
|
|
- viewport viewport.Model
|
|
|
|
|
|
|
+ Addresses []Address // as defined in internal/tui/types.go
|
|
|
|
|
+ viewport viewport.Model // mark: opinionated render
|
|
|
UpdateSpeed time.Duration
|
|
UpdateSpeed time.Duration
|
|
|
ChartHeight int
|
|
ChartHeight int
|
|
|
Height int
|
|
Height int
|
|
@@ -123,7 +127,7 @@ type Model struct {
|
|
|
|
|
|
|
|
func InitialModel(addresses []string, speed time.Duration, chartHeight int) Model {
|
|
func InitialModel(addresses []string, speed time.Duration, chartHeight int) Model {
|
|
|
var model Model
|
|
var model Model
|
|
|
- model.viewport.MouseWheelEnabled = true
|
|
|
|
|
|
|
+ model.viewport.MouseWheelEnabled = true // mark: opinionated render
|
|
|
model.UpdateSpeed = speed
|
|
model.UpdateSpeed = speed
|
|
|
model.ChartHeight = chartHeight
|
|
model.ChartHeight = chartHeight
|
|
|
|
|
|
|
@@ -146,13 +150,13 @@ func (m Model) Tick() tea.Cmd {
|
|
|
})
|
|
})
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
|
|
|
|
|
|
|
+func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) { // mark: opinionated render
|
|
|
var cmd tea.Cmd
|
|
var cmd tea.Cmd
|
|
|
var cmds []tea.Cmd
|
|
var cmds []tea.Cmd
|
|
|
|
|
|
|
|
switch msg := msg.(type) {
|
|
switch msg := msg.(type) {
|
|
|
// if case is KeyMsg (keypress)
|
|
// if case is KeyMsg (keypress)
|
|
|
- case tea.WindowSizeMsg:
|
|
|
|
|
|
|
+ case tea.WindowSizeMsg: // mark: opinionated render
|
|
|
if m.Width == 0 && m.Height == 0 {
|
|
if m.Width == 0 && m.Height == 0 {
|
|
|
m.viewport = viewport.New(
|
|
m.viewport = viewport.New(
|
|
|
viewport.WithHeight(10),
|
|
viewport.WithHeight(10),
|
|
@@ -170,7 +174,7 @@ func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
|
|
|
m.viewport.SetWidth(m.Width)
|
|
m.viewport.SetWidth(m.Width)
|
|
|
m.viewport.YPosition = 1
|
|
m.viewport.YPosition = 1
|
|
|
|
|
|
|
|
- case tea.KeyPressMsg:
|
|
|
|
|
|
|
+ case tea.KeyPressMsg: // mark: opinionated render
|
|
|
if k := msg.String(); k == "j" { // scroll down
|
|
if k := msg.String(); k == "j" { // scroll down
|
|
|
m.viewport.ScrollDown(1)
|
|
m.viewport.ScrollDown(1)
|
|
|
} else if k == "k" { // scroll up
|
|
} else if k == "k" { // scroll up
|
|
@@ -196,7 +200,7 @@ func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
|
|
|
return m, tea.Batch(cmds...)
|
|
return m, tea.Batch(cmds...)
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-func (m Model) View() tea.View {
|
|
|
|
|
|
|
+func (m Model) View() tea.View { // mark: opinionated render
|
|
|
content := fmt.Sprintf("%s%s\n%s", m.header(), m.viewport.View(), m.footer())
|
|
content := fmt.Sprintf("%s%s\n%s", m.header(), m.viewport.View(), m.footer())
|
|
|
|
|
|
|
|
var v tea.View
|
|
var v tea.View
|
|
@@ -204,7 +208,7 @@ func (m Model) View() tea.View {
|
|
|
v.AltScreen = true
|
|
v.AltScreen = true
|
|
|
return v
|
|
return v
|
|
|
}
|
|
}
|
|
|
-func (m Model) Render() string {
|
|
|
|
|
|
|
+func (m Model) Render() string { // mark: opinionated render
|
|
|
var output string
|
|
var output string
|
|
|
for _, address := range m.Addresses {
|
|
for _, address := range m.Addresses {
|
|
|
if len(address.Results) == 0 {
|
|
if len(address.Results) == 0 {
|
|
@@ -250,13 +254,13 @@ func (m Model) Render() string {
|
|
|
return output
|
|
return output
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-func (m Model) header() string { return titleStyle.Width(m.Width).Render("pingo v0") }
|
|
|
|
|
|
|
+func (m Model) header() string { return titleStyle.Width(m.Width).Render("pingo v0") } // mark: opinionated render
|
|
|
|
|
|
|
|
-func (m Model) footer() string {
|
|
|
|
|
|
|
+func (m Model) footer() string { // mark: opinionated render
|
|
|
return footerStyle.Width(m.Width).Render("j/k: down/up\t|\tq/ctrl-c/esc: quit")
|
|
return footerStyle.Width(m.Width).Render("j/k: down/up\t|\tq/ctrl-c/esc: quit")
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-func (m Model) getVerticalMargin() int { return lipgloss.Height(m.header() + m.footer()) }
|
|
|
|
|
|
|
+func (m Model) getVerticalMargin() int { return lipgloss.Height(m.header() + m.footer()) } // mark: opinionated render
|
|
|
|
|
|
|
|
// Returns a batched set of tea.Cmd functions for each address.
|
|
// Returns a batched set of tea.Cmd functions for each address.
|
|
|
func (m Model) Poll() tea.Cmd {
|
|
func (m Model) Poll() tea.Cmd {
|