on main help sign in
update logs
05d0e86Kujtim Hoxha
.gitignore+1−3
@@ -41,7 +41,5 @@ Thumbs.db
41.env
41.env
42.env.local
42.env.local
43
43
44−.opencode
44+.opencode/
45
45
46−internal/assets/diff/index.mjs
47−cmd/test/*
internal/tui/components/logs/details.go+2−27
@@ -22,7 +22,6 @@ type DetailComponent interface {
22
22
23type detailCmp struct {
23type detailCmp struct {
24 width, height int
24 width, height int
25− focused bool
26 currentLog logging.LogMessage
25 currentLog logging.LogMessage
27 viewport viewport.Model
26 viewport viewport.Model
28}
27}
@@ -37,11 +36,6 @@ func (i *detailCmp) Init() tea.Cmd {
37}
36}
38
37
39func (i *detailCmp) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
38func (i *detailCmp) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
40− var (
41− cmd tea.Cmd
42− cmds []tea.Cmd
43− )
44−
45 switch msg := msg.(type) {
39 switch msg := msg.(type) {
46 case selectedLogMsg:
40 case selectedLogMsg:
47 if msg.ID != i.currentLog.ID {
41 if msg.ID != i.currentLog.ID {
@@ -50,12 +44,7 @@ func (i *detailCmp) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
50 }
44 }
51 }
45 }
52
46
53− if i.focused {
54− i.viewport, cmd = i.viewport.Update(msg)
55− cmds = append(cmds, cmd)
56− }
57−
58− return i, tea.Batch(cmds...)
47+ return i, nil
59}
48}
60
49
61func (i *detailCmp) updateContent() {
50func (i *detailCmp) updateContent() {
@@ -123,21 +112,7 @@ func getLevelStyle(level string) lipgloss.Style {
123}
112}
124
113
125func (i *detailCmp) View() string {
114func (i *detailCmp) View() string {
126− return i.viewport.View()
115+ return styles.ForceReplaceBackgroundWithLipgloss(i.viewport.View(), styles.Background)
127−}
128−
129−func (i *detailCmp) Blur() tea.Cmd {
130− i.focused = false
131− return nil
132−}
133−
134−func (i *detailCmp) Focus() tea.Cmd {
135− i.focused = true
136− return nil
137−}
138−
139−func (i *detailCmp) IsFocused() bool {
140− return i.focused
141}
116}
142
117
143func (i *detailCmp) GetSize() (int, int) {
118func (i *detailCmp) GetSize() (int, int) {
internal/tui/components/logs/table.go+22−23
@@ -33,37 +33,35 @@ func (i *tableCmp) Init() tea.Cmd {
33
33
34func (i *tableCmp) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
34func (i *tableCmp) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
35 var cmds []tea.Cmd
35 var cmds []tea.Cmd
36− if i.table.Focused() {
37− switch msg.(type) {
36+ switch msg.(type) {
38− case pubsub.Event[logging.LogMessage]:
37+ case pubsub.Event[logging.LogMessage]:
39− i.setRows()
38+ i.setRows()
40− return i, nil
39+ return i, nil
41− }
40+ }
42− prevSelectedRow := i.table.SelectedRow()
41+ prevSelectedRow := i.table.SelectedRow()
43− t, cmd := i.table.Update(msg)
42+ t, cmd := i.table.Update(msg)
44− cmds = append(cmds, cmd)
43+ cmds = append(cmds, cmd)
45− i.table = t
44+ i.table = t
46− selectedRow := i.table.SelectedRow()
45+ selectedRow := i.table.SelectedRow()
47− if selectedRow != nil {
46+ if selectedRow != nil {
48− if prevSelectedRow == nil || selectedRow[0] == prevSelectedRow[0] {
47+ if prevSelectedRow == nil || selectedRow[0] == prevSelectedRow[0] {
49− var log logging.LogMessage
48+ var log logging.LogMessage
50− for _, row := range logging.List() {
49+ for _, row := range logging.List() {
51− if row.ID == selectedRow[0] {
50+ if row.ID == selectedRow[0] {
52− log = row
51+ log = row
53− break
52+ break
54− }
55− }
56− if log.ID != "" {
57− cmds = append(cmds, util.CmdHandler(selectedLogMsg(log)))
58 }
53 }
59 }
54 }
55+ if log.ID != "" {
56+ cmds = append(cmds, util.CmdHandler(selectedLogMsg(log)))
57+ }
60 }
58 }
61 }
59 }
62 return i, tea.Batch(cmds...)
60 return i, tea.Batch(cmds...)
63}
61}
64
62
65func (i *tableCmp) View() string {
63func (i *tableCmp) View() string {
66− return i.table.View()
64+ return styles.ForceReplaceBackgroundWithLipgloss(i.table.View(), styles.Background)
67}
65}
68
66
69func (i *tableCmp) GetSize() (int, int) {
67func (i *tableCmp) GetSize() (int, int) {
@@ -128,6 +126,7 @@ func NewLogsTable() TableComponent {
128 table.WithColumns(columns),
126 table.WithColumns(columns),
129 table.WithStyles(defaultStyles),
127 table.WithStyles(defaultStyles),
130 )
128 )
129+ tableModel.Focus()
131 return &tableCmp{
130 return &tableCmp{
132 table: tableModel,
131 table: tableModel,
133 }
132 }
internal/tui/page/logs.go+61−16
@@ -1,37 +1,82 @@
1package page
1package page
2
2
3import (
3import (
4+ "github.com/charmbracelet/bubbles/key"
4 tea "github.com/charmbracelet/bubbletea"
5 tea "github.com/charmbracelet/bubbletea"
6+ "github.com/charmbracelet/lipgloss"
5 "github.com/kujtimiihoxha/opencode/internal/tui/components/logs"
7 "github.com/kujtimiihoxha/opencode/internal/tui/components/logs"
6 "github.com/kujtimiihoxha/opencode/internal/tui/layout"
8 "github.com/kujtimiihoxha/opencode/internal/tui/layout"
9+ "github.com/kujtimiihoxha/opencode/internal/tui/styles"
7)
10)
8
11
9var LogsPage PageID = "logs"
12var LogsPage PageID = "logs"
10
13
11−type logsPage struct {
14+type LogPage interface {
12− table logs.TableComponent
15+ tea.Model
13− details logs.DetailComponent
16+ layout.Sizeable
17+ layout.Bindings
14}
18}
15−
19+type logsPage struct {
16−func (p *logsPage) Init() tea.Cmd {
20+ width, height int
17− return nil
21+ table layout.Container
22+ details layout.Container
18}
23}
19
24
20func (p *logsPage) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
25func (p *logsPage) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
26+ switch msg := msg.(type) {
27+ case tea.WindowSizeMsg:
28+ p.width = msg.Width
29+ p.height = msg.Height
30+ p.table.SetSize(msg.Width, msg.Height/2)
31+ p.details.SetSize(msg.Width, msg.Height/2)
32+ }
33+
34+ var cmds []tea.Cmd
35+ table, cmd := p.table.Update(msg)
36+ cmds = append(cmds, cmd)
37+ p.table = table.(layout.Container)
38+ details, cmd := p.details.Update(msg)
39+ cmds = append(cmds, cmd)
40+ p.details = details.(layout.Container)
41+
21− return p, nil
42+ return p, tea.Batch(cmds...)
22}
43}
23
44
24func (p *logsPage) View() string {
45func (p *logsPage) View() string {
46+ style := styles.BaseStyle.Width(p.width).Height(p.height)
47+ return style.Render(lipgloss.JoinVertical(lipgloss.Top,
48+ p.table.View(),
25− return p.table.View() + "\n" + p.details.View()
49+ p.details.View(),
50+ ))
51+}
52+
53+func (p *logsPage) BindingKeys() []key.Binding {
54+ return p.table.BindingKeys()
26}
55}
27
56
28−func NewLogsPage() tea.Model {
57+// GetSize implements LogPage.
29− return layout.NewBentoLayout(
58+func (p *logsPage) GetSize() (int, int) {
30− layout.BentoPanes{
59+ return p.width, p.height
31− layout.BentoRightTopPane: logs.NewLogsTable(),
60+}
32− layout.BentoRightBottomPane: logs.NewLogsDetails(),
61+
62+// SetSize implements LogPage.
63+func (p *logsPage) SetSize(width int, height int) {
64+ p.width = width
65+ p.height = height
66+ p.table.SetSize(width, height/2)
67+ p.details.SetSize(width, height/2)
33− },
68+}
34− layout.WithBentoLayoutCurrentPane(layout.BentoRightTopPane),
69+
35− layout.WithBentoLayoutRightTopHeightRatio(0.5),
70+func (p *logsPage) Init() tea.Cmd {
71+ return tea.Batch(
72+ p.table.Init(),
73+ p.details.Init(),
36 )
74 )
37}
75}
76+
77+func NewLogsPage() LogPage {
78+ return &logsPage{
79+ table: layout.NewContainer(logs.NewLogsTable(), layout.WithBorderAll(), layout.WithBorderColor(styles.ForgroundDim)),
80+ details: layout.NewContainer(logs.NewLogsDetails(), layout.WithBorderAll(), layout.WithBorderColor(styles.ForgroundDim)),
81+ }
82+}