summaryrefslogtreecommitdiff
path: root/internal/tui/eventstream
diff options
context:
space:
mode:
authorPaul Buetow <paul@buetow.org>2026-03-05 19:20:18 +0200
committerPaul Buetow <paul@buetow.org>2026-03-05 19:20:18 +0200
commitbab716a6a5931c211fad2f17ee2f67e8d182a7fc (patch)
tree89b16ed3bf85198dd63751d2e1e54537c9340a1b /internal/tui/eventstream
parent96225fb6159212a8851043a08d781aba721b4e78 (diff)
feat(tui): migrate Bubble Tea stack to charm.land v2
Diffstat (limited to 'internal/tui/eventstream')
-rw-r--r--internal/tui/eventstream/exportmodal.go8
-rw-r--r--internal/tui/eventstream/filtermodal.go10
-rw-r--r--internal/tui/eventstream/filtermodal_test.go50
-rw-r--r--internal/tui/eventstream/model.go29
-rw-r--r--internal/tui/eventstream/render.go2
-rw-r--r--internal/tui/eventstream/render_test.go2
-rw-r--r--internal/tui/eventstream/searchmodal.go8
7 files changed, 56 insertions, 53 deletions
diff --git a/internal/tui/eventstream/exportmodal.go b/internal/tui/eventstream/exportmodal.go
index cf020f7..70c57ee 100644
--- a/internal/tui/eventstream/exportmodal.go
+++ b/internal/tui/eventstream/exportmodal.go
@@ -3,9 +3,9 @@ package eventstream
import (
"strings"
- "github.com/charmbracelet/bubbles/textinput"
- tea "github.com/charmbracelet/bubbletea"
- "github.com/charmbracelet/lipgloss"
+ "charm.land/bubbles/v2/textinput"
+ tea "charm.land/bubbletea/v2"
+ "charm.land/lipgloss/v2"
)
type ExportModal struct {
@@ -18,7 +18,7 @@ func NewExportModal() ExportModal {
input := textinput.New()
input.Prompt = ""
input.CharLimit = 0
- input.Width = 44
+ input.SetWidth(44)
return ExportModal{textInput: input}
}
diff --git a/internal/tui/eventstream/filtermodal.go b/internal/tui/eventstream/filtermodal.go
index f98db7f..4090925 100644
--- a/internal/tui/eventstream/filtermodal.go
+++ b/internal/tui/eventstream/filtermodal.go
@@ -5,9 +5,9 @@ import (
"strconv"
"strings"
- "github.com/charmbracelet/bubbles/textinput"
- tea "github.com/charmbracelet/bubbletea"
- "github.com/charmbracelet/lipgloss"
+ "charm.land/bubbles/v2/textinput"
+ tea "charm.land/bubbletea/v2"
+ "charm.land/lipgloss/v2"
)
type fieldKey int
@@ -48,7 +48,7 @@ func NewFilterModal() FilterModal {
input := textinput.New()
input.Prompt = ""
input.CharLimit = 0
- input.Width = 24
+ input.SetWidth(24)
m := FilterModal{textInput: input}
m.fields = defaultFilterFields()
@@ -112,7 +112,7 @@ func (m FilterModal) Update(msg tea.Msg) FilterModal {
m.fields[m.activeField].opIndex = (m.fields[m.activeField].opIndex + 1) % len(compareOps)
}
return m
- case " ":
+ case " ", "space":
if !m.editing && m.fields[m.activeField].fieldKey == fieldErrorsOnly {
if strings.TrimSpace(m.fields[m.activeField].value) == "true" {
m.fields[m.activeField].value = "false"
diff --git a/internal/tui/eventstream/filtermodal_test.go b/internal/tui/eventstream/filtermodal_test.go
index ee53c82..a33cbb1 100644
--- a/internal/tui/eventstream/filtermodal_test.go
+++ b/internal/tui/eventstream/filtermodal_test.go
@@ -3,7 +3,7 @@ package eventstream
import (
"testing"
- tea "github.com/charmbracelet/bubbletea"
+ tea "charm.land/bubbletea/v2"
)
func TestFilterModalOpenClose(t *testing.T) {
@@ -17,7 +17,7 @@ func TestFilterModalOpenClose(t *testing.T) {
t.Fatalf("modal should be visible after open")
}
- m = m.Update(tea.KeyMsg{Type: tea.KeyEsc})
+ m = m.Update(tea.KeyPressMsg{Code: tea.KeyEsc})
if m.Visible() {
t.Fatalf("modal should close on esc")
}
@@ -29,11 +29,11 @@ func TestFilterModalNavigateFields(t *testing.T) {
t.Fatalf("activeField=%d, want 0", m.activeField)
}
- m = m.Update(tea.KeyMsg{Type: tea.KeyRunes, Runes: []rune("j")})
+ m = m.Update(tea.KeyPressMsg{Code: []rune("j")[0], Text: string([]rune("j"))})
if m.activeField != 1 {
t.Fatalf("activeField=%d, want 1", m.activeField)
}
- m = m.Update(tea.KeyMsg{Type: tea.KeyRunes, Runes: []rune("k")})
+ m = m.Update(tea.KeyPressMsg{Code: []rune("k")[0], Text: string([]rune("k"))})
if m.activeField != 0 {
t.Fatalf("activeField=%d, want 0", m.activeField)
}
@@ -43,34 +43,34 @@ func TestFilterModalEditAndBuildFilter(t *testing.T) {
m := NewFilterModal().Open(Filter{})
// Syscall = read
- m = m.Update(tea.KeyMsg{Type: tea.KeyEnter})
- m = m.Update(tea.KeyMsg{Type: tea.KeyRunes, Runes: []rune("read")})
- m = m.Update(tea.KeyMsg{Type: tea.KeyEnter})
+ m = m.Update(tea.KeyPressMsg{Code: tea.KeyEnter})
+ m = m.Update(tea.KeyPressMsg{Code: []rune("read")[0], Text: string([]rune("read"))})
+ m = m.Update(tea.KeyPressMsg{Code: tea.KeyEnter})
// PID >= 123
- m = m.Update(tea.KeyMsg{Type: tea.KeyRunes, Runes: []rune("j")})
- m = m.Update(tea.KeyMsg{Type: tea.KeyRunes, Runes: []rune("j")})
- m = m.Update(tea.KeyMsg{Type: tea.KeyRunes, Runes: []rune("j")})
- m = m.Update(tea.KeyMsg{Type: tea.KeyTab}) // '=' -> '>'
- m = m.Update(tea.KeyMsg{Type: tea.KeyEnter})
- m = m.Update(tea.KeyMsg{Type: tea.KeyRunes, Runes: []rune("123")})
- m = m.Update(tea.KeyMsg{Type: tea.KeyEnter})
+ m = m.Update(tea.KeyPressMsg{Code: []rune("j")[0], Text: string([]rune("j"))})
+ m = m.Update(tea.KeyPressMsg{Code: []rune("j")[0], Text: string([]rune("j"))})
+ m = m.Update(tea.KeyPressMsg{Code: []rune("j")[0], Text: string([]rune("j"))})
+ m = m.Update(tea.KeyPressMsg{Code: tea.KeyTab}) // '=' -> '>'
+ m = m.Update(tea.KeyPressMsg{Code: tea.KeyEnter})
+ m = m.Update(tea.KeyPressMsg{Code: []rune("123")[0], Text: string([]rune("123"))})
+ m = m.Update(tea.KeyPressMsg{Code: tea.KeyEnter})
// Latency >= 1ms
- m = m.Update(tea.KeyMsg{Type: tea.KeyRunes, Runes: []rune("j")})
- m = m.Update(tea.KeyMsg{Type: tea.KeyRunes, Runes: []rune("j")})
- m = m.Update(tea.KeyMsg{Type: tea.KeyTab}) // '=' -> '>='
- m = m.Update(tea.KeyMsg{Type: tea.KeyEnter})
- m = m.Update(tea.KeyMsg{Type: tea.KeyRunes, Runes: []rune("1ms")})
- m = m.Update(tea.KeyMsg{Type: tea.KeyEnter})
+ m = m.Update(tea.KeyPressMsg{Code: []rune("j")[0], Text: string([]rune("j"))})
+ m = m.Update(tea.KeyPressMsg{Code: []rune("j")[0], Text: string([]rune("j"))})
+ m = m.Update(tea.KeyPressMsg{Code: tea.KeyTab}) // '=' -> '>='
+ m = m.Update(tea.KeyPressMsg{Code: tea.KeyEnter})
+ m = m.Update(tea.KeyPressMsg{Code: []rune("1ms")[0], Text: string([]rune("1ms"))})
+ m = m.Update(tea.KeyPressMsg{Code: tea.KeyEnter})
// ErrorsOnly = true
for m.activeField < len(m.fields)-1 {
- m = m.Update(tea.KeyMsg{Type: tea.KeyRunes, Runes: []rune("j")})
+ m = m.Update(tea.KeyPressMsg{Code: []rune("j")[0], Text: string([]rune("j"))})
}
- m = m.Update(tea.KeyMsg{Type: tea.KeySpace})
+ m = m.Update(tea.KeyPressMsg{Code: tea.KeySpace})
- m = m.Update(tea.KeyMsg{Type: tea.KeyEsc})
+ m = m.Update(tea.KeyPressMsg{Code: tea.KeyEsc})
if m.Visible() {
t.Fatalf("modal should close on esc")
}
@@ -98,8 +98,8 @@ func TestFilterModalClearAll(t *testing.T) {
}
m := NewFilterModal().Open(initial)
- m = m.Update(tea.KeyMsg{Type: tea.KeyRunes, Runes: []rune("c")})
- m = m.Update(tea.KeyMsg{Type: tea.KeyEsc})
+ m = m.Update(tea.KeyPressMsg{Code: []rune("c")[0], Text: string([]rune("c"))})
+ m = m.Update(tea.KeyPressMsg{Code: tea.KeyEsc})
f := m.Filter()
if f.IsActive() {
diff --git a/internal/tui/eventstream/model.go b/internal/tui/eventstream/model.go
index d9c4ee3..cb05e47 100644
--- a/internal/tui/eventstream/model.go
+++ b/internal/tui/eventstream/model.go
@@ -6,7 +6,7 @@ import (
"strconv"
"strings"
- tea "github.com/charmbracelet/bubbletea"
+ tea "charm.land/bubbletea/v2"
)
const (
@@ -354,7 +354,7 @@ func (m *Model) HandleKey(keyStr string) bool {
// HandleTeaKey handles stream keys based on Bubble Tea key message types first,
// then falls back to string matching for rune-driven shortcuts.
func (m *Model) HandleTeaKey(msg tea.KeyMsg) bool {
- switch msg.Type {
+ switch msg.Key().Code {
case tea.KeyLeft:
return m.HandleKey("left")
case tea.KeyRight:
@@ -373,9 +373,12 @@ func (m *Model) HandleTeaKey(msg tea.KeyMsg) bool {
return m.HandleKey("esc")
case tea.KeyEnter:
return m.HandleKey("enter")
- case tea.KeyRunes:
- if len(msg.Runes) == 1 {
- return m.HandleKey(string(msg.Runes[0]))
+ default:
+ if msg.Key().Text != "" {
+ runes := []rune(msg.Key().Text)
+ if len(runes) == 1 {
+ return m.HandleKey(msg.Key().Text)
+ }
}
}
return m.HandleKey(msg.String())
@@ -810,23 +813,23 @@ func (m *Model) clampSelection() {
func keyMsgFromString(keyStr string) tea.KeyMsg {
switch keyStr {
case "esc":
- return tea.KeyMsg{Type: tea.KeyEsc}
+ return tea.KeyPressMsg{Code: tea.KeyEsc}
case "enter":
- return tea.KeyMsg{Type: tea.KeyEnter}
+ return tea.KeyPressMsg{Code: tea.KeyEnter}
case "tab":
- return tea.KeyMsg{Type: tea.KeyTab}
+ return tea.KeyPressMsg{Code: tea.KeyTab}
case "up":
- return tea.KeyMsg{Type: tea.KeyUp}
+ return tea.KeyPressMsg{Code: tea.KeyUp}
case "down":
- return tea.KeyMsg{Type: tea.KeyDown}
+ return tea.KeyPressMsg{Code: tea.KeyDown}
case " ", "space":
- return tea.KeyMsg{Type: tea.KeySpace}
+ return tea.KeyPressMsg{Code: tea.KeySpace, Text: " "}
}
if keyStr == "" {
- return tea.KeyMsg{}
+ return tea.KeyPressMsg{}
}
runes := []rune(keyStr)
- return tea.KeyMsg{Type: tea.KeyRunes, Runes: runes}
+ return tea.KeyPressMsg{Code: runes[0], Text: keyStr}
}
func rowNumber(start, total int) int {
diff --git a/internal/tui/eventstream/render.go b/internal/tui/eventstream/render.go
index 1f539c6..f93a63d 100644
--- a/internal/tui/eventstream/render.go
+++ b/internal/tui/eventstream/render.go
@@ -6,7 +6,7 @@ import (
"strconv"
"strings"
- "github.com/charmbracelet/lipgloss"
+ "charm.land/lipgloss/v2"
)
type columnLayout struct {
diff --git a/internal/tui/eventstream/render_test.go b/internal/tui/eventstream/render_test.go
index b020edf..6240c69 100644
--- a/internal/tui/eventstream/render_test.go
+++ b/internal/tui/eventstream/render_test.go
@@ -4,7 +4,7 @@ import (
"strings"
"testing"
- "github.com/charmbracelet/lipgloss"
+ "charm.land/lipgloss/v2"
)
func TestRenderStatusAndFilterLines(t *testing.T) {
diff --git a/internal/tui/eventstream/searchmodal.go b/internal/tui/eventstream/searchmodal.go
index f744d00..94e9cd7 100644
--- a/internal/tui/eventstream/searchmodal.go
+++ b/internal/tui/eventstream/searchmodal.go
@@ -3,9 +3,9 @@ package eventstream
import (
"strings"
- "github.com/charmbracelet/bubbles/textinput"
- tea "github.com/charmbracelet/bubbletea"
- "github.com/charmbracelet/lipgloss"
+ "charm.land/bubbles/v2/textinput"
+ tea "charm.land/bubbletea/v2"
+ "charm.land/lipgloss/v2"
)
type SearchDirection int
@@ -26,7 +26,7 @@ func NewSearchModal() SearchModal {
input := textinput.New()
input.Prompt = ""
input.CharLimit = 0
- input.Width = 44
+ input.SetWidth(44)
return SearchModal{textInput: input, direction: SearchForward}
}