Skip to content

Commit 2d23d8f

Browse files
authored
fix: filtering in the follow mode (#121)
1 parent d5bbda2 commit 2d23d8f

File tree

8 files changed

+96
-67
lines changed

8 files changed

+96
-67
lines changed

internal/app/app.go

Lines changed: 59 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,32 @@
11
package app
22

33
import (
4+
"sync"
5+
46
"github.com/charmbracelet/bubbles/help"
7+
"github.com/charmbracelet/bubbles/table"
58
tea "github.com/charmbracelet/bubbletea"
69
"github.com/charmbracelet/lipgloss"
710

811
"github.com/hedhyw/json-log-viewer/internal/keymap"
12+
"github.com/hedhyw/json-log-viewer/internal/pkg/events"
913
"github.com/hedhyw/json-log-viewer/internal/pkg/source"
1014

1115
"github.com/hedhyw/json-log-viewer/internal/pkg/config"
1216
)
1317

1418
// Application global state.
1519
type Application struct {
20+
lock *sync.Mutex
21+
1622
FileName string
1723
Config *config.Config
1824

1925
BaseStyle lipgloss.Style
2026
FooterStyle lipgloss.Style
2127

22-
LastWindowSize tea.WindowSizeMsg
23-
Entries source.LazyLogEntries
28+
lastWindowSize tea.WindowSizeMsg
29+
entries source.LazyLogEntries
2430
Version string
2531

2632
keys keymap.KeyMap
@@ -38,13 +44,15 @@ func newApplication(
3844
)
3945

4046
return Application{
47+
lock: &sync.Mutex{},
48+
4149
FileName: fileName,
4250
Config: config,
4351

4452
BaseStyle: getBaseStyle(),
4553
FooterStyle: getFooterStyle(),
4654

47-
LastWindowSize: tea.WindowSizeMsg{
55+
lastWindowSize: tea.WindowSizeMsg{
4856
Width: initialWidth,
4957
Height: initialHeight,
5058
},
@@ -66,3 +74,51 @@ func NewModel(
6674

6775
return newStateInitial(&application)
6876
}
77+
78+
func (app *Application) getLogLevelStyle(
79+
renderedRows []table.Row,
80+
baseStyle lipgloss.Style,
81+
rowID int,
82+
) lipgloss.Style {
83+
if rowID < 0 || rowID >= len(renderedRows) {
84+
return baseStyle
85+
}
86+
87+
row := renderedRows[rowID]
88+
89+
color := getColorForLogLevel(app.getLogLevelFromLogRow(row))
90+
if color == "" {
91+
return baseStyle
92+
}
93+
94+
return baseStyle.Foreground(color)
95+
}
96+
97+
// Update application state.
98+
func (app *Application) Update(msg tea.Msg) {
99+
app.lock.Lock()
100+
defer app.lock.Unlock()
101+
102+
switch msg := msg.(type) {
103+
case tea.WindowSizeMsg:
104+
app.lastWindowSize = msg
105+
case events.LogEntriesUpdateMsg:
106+
app.entries = source.LazyLogEntries(msg)
107+
}
108+
}
109+
110+
// Entries getter.
111+
func (app *Application) Entries() source.LazyLogEntries {
112+
app.lock.Lock()
113+
defer app.lock.Unlock()
114+
115+
return app.entries
116+
}
117+
118+
// LastWindowSize getter.
119+
func (app *Application) LastWindowSize() tea.WindowSizeMsg {
120+
app.lock.Lock()
121+
defer app.lock.Unlock()
122+
123+
return app.lastWindowSize
124+
}

internal/app/helper.go

Lines changed: 0 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -14,35 +14,6 @@ import (
1414
"github.com/hedhyw/json-log-viewer/internal/pkg/source"
1515
)
1616

17-
func (app *Application) getLogLevelStyle(
18-
renderedRows []table.Row,
19-
baseStyle lipgloss.Style,
20-
rowID int,
21-
) lipgloss.Style {
22-
if rowID < 0 || rowID >= len(renderedRows) {
23-
return baseStyle
24-
}
25-
26-
row := renderedRows[rowID]
27-
28-
color := getColorForLogLevel(app.getLogLevelFromLogRow(row))
29-
if color == "" {
30-
return baseStyle
31-
}
32-
33-
return baseStyle.Foreground(color)
34-
}
35-
36-
// Update application state.
37-
func (app *Application) Update(msg tea.Msg) {
38-
switch msg := msg.(type) {
39-
case tea.WindowSizeMsg:
40-
app.LastWindowSize = msg
41-
case events.LogEntriesUpdateMsg:
42-
app.Entries = source.LazyLogEntries(msg)
43-
}
44-
}
45-
4617
func getColorForLogLevel(level source.Level) lipgloss.Color {
4718
switch level {
4819
case source.LevelTrace:

internal/app/lazytable.go

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -119,9 +119,6 @@ func (m lazyTableModel) handleKey(msg tea.KeyMsg, render bool) (lazyTableModel,
119119
if offset != m.offset {
120120
m.offset = offset
121121
render = true
122-
} else {
123-
// we were at the first item, so we should follow the log
124-
m.follow = true
125122
}
126123
}
127124

internal/app/logstable.go

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,16 @@ type logsTableModel struct {
1919
logEntries source.LazyLogEntries
2020
}
2121

22-
func newLogsTableModel(application *Application, logEntries source.LazyLogEntries) logsTableModel {
22+
func newLogsTableModel(
23+
application *Application,
24+
logEntries source.LazyLogEntries,
25+
follow bool,
26+
reverse bool,
27+
) logsTableModel {
2328
tableLogs := table.New(
24-
table.WithColumns(getColumns(application.LastWindowSize.Width, application.Config)),
29+
table.WithColumns(getColumns(application.LastWindowSize().Width, application.Config)),
2530
table.WithFocused(true),
26-
table.WithHeight(application.LastWindowSize.Height),
31+
table.WithHeight(application.LastWindowSize().Height),
2732
)
2833
tableLogs.KeyMap.LineUp = application.keys.Up
2934
tableLogs.KeyMap.LineDown = application.keys.Down
@@ -34,8 +39,8 @@ func newLogsTableModel(application *Application, logEntries source.LazyLogEntrie
3439

3540
lazyTable := lazyTableModel{
3641
Application: application,
37-
reverse: true,
38-
follow: true,
42+
reverse: reverse,
43+
follow: follow,
3944
table: tableLogs,
4045
entries: logEntries,
4146
lastCursor: 0,
@@ -47,7 +52,7 @@ func newLogsTableModel(application *Application, logEntries source.LazyLogEntrie
4752
lazyTable: lazyTable,
4853
logEntries: logEntries,
4954
footerSize: 1,
50-
}.handleWindowSizeMsg(application.LastWindowSize)
55+
}.handleWindowSizeMsg(application.LastWindowSize())
5156

5257
return msg
5358
}

internal/app/statefiltered.go

Lines changed: 11 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -60,8 +60,8 @@ func (s StateFilteredModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
6060
s, msg = s.handleStateFilteredModel()
6161
}
6262

63-
if _, ok := msg.(*events.LogEntriesUpdateMsg); ok {
64-
s, msg = s.handleLogEntriesUpdateMsg()
63+
if _, ok := msg.(events.LogEntriesUpdateMsg); ok {
64+
return s, nil
6565
}
6666

6767
switch typedMsg := msg.(type) {
@@ -73,8 +73,6 @@ func (s StateFilteredModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
7373
if mdl, cmd := s.handleKeyMsg(typedMsg); mdl != nil {
7474
return mdl, cmd
7575
}
76-
default:
77-
s.table, cmdBatch = batched(s.table.Update(typedMsg))(cmdBatch)
7876
}
7977

8078
s.table, cmdBatch = batched(s.table.Update(msg))(cmdBatch)
@@ -95,27 +93,21 @@ func (s StateFilteredModel) handleKeyMsg(msg tea.KeyMsg) (tea.Model, tea.Cmd) {
9593
}
9694
}
9795

98-
func (s StateFilteredModel) handleLogEntriesUpdateMsg() (StateFilteredModel, tea.Msg) {
99-
entries, err := s.Application.Entries.Filter(s.filterText)
100-
if err != nil {
101-
return s, events.ShowError(err)()
102-
}
103-
104-
s.logEntries = entries
105-
106-
return s, events.LogEntriesUpdateMsg(entries)
107-
}
108-
10996
func (s StateFilteredModel) handleStateFilteredModel() (StateFilteredModel, tea.Msg) {
110-
entries, err := s.Application.Entries.Filter(s.filterText)
97+
entries, err := s.Application.Entries().Filter(s.filterText)
11198
if err != nil {
11299
return s, events.ShowError(err)()
113100
}
114101

115102
s.logEntries = entries
116-
s.table = newLogsTableModel(s.Application, entries)
103+
s.table = newLogsTableModel(
104+
s.Application,
105+
entries,
106+
false, // follow.
107+
s.previousState.table.lazyTable.reverse,
108+
)
117109

118-
return s, events.LogEntriesUpdateMsg(entries)
110+
return s, nil
119111
}
120112

121113
func (s StateFilteredModel) handleFilterKeyClickedMsg() (tea.Model, tea.Cmd) {
@@ -136,7 +128,7 @@ func (s StateFilteredModel) getApplication() *Application {
136128
}
137129

138130
func (s StateFilteredModel) refresh() (_ stateModel, cmd tea.Cmd) {
139-
s.table, cmd = s.table.Update(s.Application.LastWindowSize)
131+
s.table, cmd = s.table.Update(s.Application.LastWindowSize())
140132

141133
return s, cmd
142134
}

internal/app/statefiltering.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ func (s StateFilteringModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
7171

7272
func (s StateFilteringModel) handleKeyMsg(msg tea.KeyMsg) (tea.Model, tea.Cmd) {
7373
switch {
74-
case key.Matches(msg, s.keys.Back):
74+
case key.Matches(msg, s.keys.Back) && string(msg.Runes) != "q":
7575
return s.previousState.refresh()
7676
case key.Matches(msg, s.keys.Open):
7777
return s.handleEnterKeyClickedMsg()

internal/app/stateloaded.go

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,12 @@ func newStateViewLogs(
2323
application *Application,
2424
logEntries source.LazyLogEntries,
2525
) StateLoadedModel {
26-
table := newLogsTableModel(application, logEntries)
26+
table := newLogsTableModel(
27+
application,
28+
logEntries,
29+
true, // follow.
30+
true, // reverse.
31+
)
2732

2833
return StateLoadedModel{
2934
Application: application,
@@ -77,7 +82,7 @@ func (s StateLoadedModel) viewHelp() string {
7782
Padding(0, 1).
7883
Render(s.Version)
7984

80-
width := s.Application.LastWindowSize.Width
85+
width := s.Application.LastWindowSize().Width
8186
fillerText := lipgloss.NewStyle().
8287
Background(lipgloss.Color("#353533")).
8388
Width(width - lipgloss.Width(toggleText) - lipgloss.Width(versionText)).
@@ -141,7 +146,7 @@ func (s StateLoadedModel) handleKeyMsg(msg tea.KeyMsg) []tea.Cmd {
141146
}
142147

143148
func (s StateLoadedModel) handleRequestOpenJSON() (tea.Model, tea.Cmd) {
144-
return s, events.OpenJSONRowRequested(s.Entries, s.table.Cursor())
149+
return s, events.OpenJSONRowRequested(s.entries, s.table.Cursor())
145150
}
146151

147152
func (s StateLoadedModel) handleFilterKeyClickedMsg() (tea.Model, tea.Cmd) {
@@ -153,9 +158,12 @@ func (s StateLoadedModel) getApplication() *Application {
153158
}
154159

155160
func (s StateLoadedModel) refresh() (_ stateModel, cmd tea.Cmd) {
156-
s.table, cmd = s.table.Update(s.Application.LastWindowSize)
161+
var cmdFirst, cmdSecond tea.Cmd
157162

158-
return s, cmd
163+
s.table, cmdSecond = s.table.Update(s.Application.LastWindowSize())
164+
s.table, cmdFirst = s.table.Update(events.LogEntriesUpdateMsg(s.Application.Entries()))
165+
166+
return s, tea.Batch(cmdFirst, cmdSecond)
159167
}
160168

161169
// String implements fmt.Stringer.

internal/app/stateviewrow.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ func newStateViewRow(
3030

3131
jsonViewModel, cmd := widgets.NewJSONViewModel(
3232
logEntry.Line,
33-
app.LastWindowSize,
33+
app.LastWindowSize(),
3434
app.keys,
3535
)
3636

0 commit comments

Comments
 (0)