Skip to content

Commit cc28d86

Browse files
committed
Add 'f' key for full screen log viewing
1 parent 7038edb commit cc28d86

File tree

7 files changed

+468
-183
lines changed

7 files changed

+468
-183
lines changed

README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ A powerful, real-time log analysis terminal UI inspired by k9s. Analyze log stre
3434
- **Real-time charts** - Word frequency, attributes, severity distribution, and time series
3535
- **Keyboard + mouse navigation** - Vim-style shortcuts plus click-to-navigate and scroll wheel support
3636
- **Smart log viewer** - Auto-scroll with intelligent pause/resume behavior
37+
- **Fullscreen log viewer** - Press `f` to open a dedicated fullscreen modal for log browsing with all navigation features
3738
- **Global pause control** - Spacebar pauses entire dashboard while buffering logs
3839
- **Modal details** - Deep dive into individual log entries with expandable views
3940
- **Log Counts analysis** - Detailed modal with heatmap visualization, pattern analysis by severity, and service distribution
@@ -233,6 +234,7 @@ cat logs.json | gonzo --ai-model="gpt-4"
233234
| `Space` | Pause/unpause entire dashboard |
234235
| `/` | Enter filter mode (regex supported) |
235236
| `s` | Search and highlight text in logs |
237+
| `f` | Open fullscreen log viewer modal |
236238
| `c` | Toggle Host/Service columns in log view |
237239
| `r` | Reset all data (manual reset) |
238240
| `u` / `U` | Cycle update intervals (forward/backward) |
@@ -608,6 +610,8 @@ Found a bug? Please [open an issue](https://github.com/control-theory/gonzo/issu
608610
609611
If you find this project useful, please consider giving it a star! It helps others discover the tool.
610612
613+
[![Star History Chart](https://api.star-history.com/svg?repos=control-theory/gonzo&type=Date)](https://www.star-history.com/#control-theory/gonzo&Date)
614+
611615
---
612616
613617
<p align="center">

internal/tui/components.go

Lines changed: 33 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -242,26 +242,8 @@ func (m *DashboardModel) renderFilter() string {
242242
return minimalFilterStyle.Render(title + " " + content)
243243
}
244244

245-
// renderLogScroll renders the scrolling log section
246-
func (m *DashboardModel) renderLogScroll(height int) string {
247-
// Use most of terminal width for logs
248-
logWidth := m.width - 2 // Account for borders and minimal padding
249-
if logWidth < 40 {
250-
logWidth = 40 // Higher minimum for readability
251-
}
252-
253-
// Highlight border when log section is active
254-
borderColor := ColorNavy
255-
if m.activeSection == SectionLogs {
256-
borderColor = ColorBlue
257-
}
258-
259-
style := sectionStyle.
260-
Width(logWidth).
261-
Height(height).
262-
Border(lipgloss.NormalBorder()).
263-
BorderForeground(borderColor)
264-
245+
// renderLogScrollContent generates the log content without border wrapper
246+
func (m *DashboardModel) renderLogScrollContent(height int, logWidth int) []string {
265247
var logLines []string
266248

267249
// Add paused indicator and help text when log section is active
@@ -295,10 +277,10 @@ func (m *DashboardModel) renderLogScroll(height int) string {
295277
maxLines = 1
296278
}
297279

298-
// When in log section, don't auto-scroll to latest
299-
if m.activeSection != SectionLogs && len(m.logEntries) > maxLines {
280+
// When in log section or log viewer modal, don't auto-scroll to latest
281+
if m.activeSection != SectionLogs && !m.showLogViewerModal && len(m.logEntries) > maxLines {
300282
startIdx = len(m.logEntries) - maxLines
301-
} else if m.activeSection == SectionLogs {
283+
} else if m.activeSection == SectionLogs || m.showLogViewerModal {
302284
// Keep selected log in view
303285
if m.selectedLogIndex >= 0 && m.selectedLogIndex < len(m.logEntries) {
304286
// Center selected log if possible
@@ -316,8 +298,8 @@ func (m *DashboardModel) renderLogScroll(height int) string {
316298
entry := m.logEntries[i]
317299
formatted := m.formatLogEntry(entry, logWidth)
318300

319-
// Highlight selected log when in log section
320-
if m.activeSection == SectionLogs && i == m.selectedLogIndex {
301+
// Highlight selected log when in log section or log viewer modal
302+
if (m.activeSection == SectionLogs || m.showLogViewerModal) && i == m.selectedLogIndex {
321303
selectedStyle := lipgloss.NewStyle().
322304
Background(ColorBlue).
323305
Foreground(ColorWhite)
@@ -348,5 +330,31 @@ func (m *DashboardModel) renderLogScroll(height int) string {
348330
logLines = append(logLines, instructions...)
349331
}
350332

333+
return logLines
334+
}
335+
336+
// renderLogScroll renders the scrolling log section
337+
func (m *DashboardModel) renderLogScroll(height int) string {
338+
// Use most of terminal width for logs
339+
logWidth := m.width - 2 // Account for borders and minimal padding
340+
if logWidth < 40 {
341+
logWidth = 40 // Higher minimum for readability
342+
}
343+
344+
// Highlight border when log section is active
345+
borderColor := ColorNavy
346+
if m.activeSection == SectionLogs {
347+
borderColor = ColorBlue
348+
}
349+
350+
style := sectionStyle.
351+
Width(logWidth).
352+
Height(height).
353+
Border(lipgloss.NormalBorder()).
354+
BorderForeground(borderColor)
355+
356+
// Get log content
357+
logLines := m.renderLogScrollContent(height, logWidth)
358+
351359
return style.Render(lipgloss.JoinVertical(lipgloss.Left, logLines...))
352360
}

0 commit comments

Comments
 (0)