Skip to content

Commit

Permalink
start
Browse files Browse the repository at this point in the history
  • Loading branch information
robinovitch61 committed Nov 10, 2024
1 parent 6a3ee4c commit 9c6f973
Show file tree
Hide file tree
Showing 5 changed files with 54 additions and 36 deletions.
56 changes: 34 additions & 22 deletions internal/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import (
"k8s.io/client-go/kubernetes"
"k8s.io/client-go/tools/clientcmd"
"k8s.io/klog/v2"
"math"
"os"
"strconv"
"strings"
Expand All @@ -50,7 +51,8 @@ type Model struct {
cancel context.CancelFunc
pages map[page.Type]page.GenericPage
containerListeners []model.ContainerListener
currentPageType page.Type
focusedPageType page.Type
rightPageType page.Type
sinceTime model.SinceTime
pendingSinceTime *model.SinceTime
pauseState bool
Expand Down Expand Up @@ -179,7 +181,7 @@ func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
return m, tea.Batch(cmds...)
}

m.pages[m.currentPageType], cmd = m.pages[m.currentPageType].Update(msg)
m.pages[m.focusedPageType], cmd = m.pages[m.focusedPageType].Update(msg)
cmds = append(cmds, cmd)
return m, tea.Batch(cmds...)
}
Expand All @@ -197,19 +199,25 @@ func (m Model) View() string {
errString,
)
}

if !m.initialized {
return ""
}

topBar := m.topBar()
if m.helpText != "" {
centeredHelp := lipgloss.Place(m.width, m.height-m.topBarHeight, lipgloss.Center, lipgloss.Center, m.helpText)
return lipgloss.JoinVertical(lipgloss.Left, topBar, centeredHelp)
}

if m.prompt.Visible {
return lipgloss.JoinVertical(lipgloss.Left, topBar, m.prompt.View())
}

viewLines := strings.Split(m.topBar(), "\n")
pageView := m.pages[m.currentPageType].View()
leftPageView := lipgloss.NewStyle().Border(lipgloss.ThickBorder(), false, true, false, false).Render(m.pages[page.EntitiesPageType].View())
rightPageView := m.pages[m.rightPageType].View()
pageView := lipgloss.JoinHorizontal(lipgloss.Left, leftPageView, rightPageView)
viewLines = append(viewLines, strings.Split(pageView, "\n")...)
if toastHeight := m.toast.ViewHeight(); m.toast.Visible && toastHeight > 0 {
viewLines = viewLines[:len(viewLines)-toastHeight]
Expand Down Expand Up @@ -418,10 +426,11 @@ func (m Model) initialize() (Model, tea.Cmd) {
m.entityTree = model.NewEntityTree(m.allClusterNamespaces)

if m.config.LogsView {
m.currentPageType = page.LogsPageType
m.focusedPageType = page.LogsPageType
} else {
m.currentPageType = page.EntitiesPageType
m.focusedPageType = page.EntitiesPageType
}
m.rightPageType = page.LogsPageType
m.sinceTime = m.config.SinceTime

m.pages = make(map[page.Type]page.GenericPage)
Expand Down Expand Up @@ -465,25 +474,28 @@ func (m Model) initialize() (Model, tea.Cmd) {
func (m Model) handleWindowSizeMsg(width, height int) (Model, tea.Cmd) {
contentHeight := height - m.topBarHeight
m.prompt.SetWidthAndHeight(width, contentHeight)
for k, p := range m.pages {
m.pages[k] = p.WithDimensions(width, contentHeight)
}
leftWidth := int(math.Round(float64(width) * constants.LeftPageWidthFraction))
rightWidth := width - leftWidth - 1
dev.Debug(fmt.Sprintf("width %d, leftWidth: %d, rightWidth: %d, contentHeight: %d", width, leftWidth, rightWidth, contentHeight))
m.pages[page.EntitiesPageType] = m.pages[page.EntitiesPageType].WithDimensions(leftWidth, contentHeight)
m.pages[page.LogsPageType] = m.pages[page.LogsPageType].WithDimensions(rightWidth, contentHeight)
m.pages[page.SingleLogPageType] = m.pages[page.SingleLogPageType].WithDimensions(rightWidth, contentHeight)
return m, nil
}

func (m Model) changeCurrentPage(newPage page.Type) (Model, tea.Cmd) {
switch newPage {
case page.EntitiesPageType:
m.currentPageType = page.EntitiesPageType
m.focusedPageType = page.EntitiesPageType
case page.LogsPageType:
// re-enable stickyness on logs page
m.pages[page.LogsPageType] = m.pages[page.LogsPageType].(page.LogsPage).WithStickyness()
m.currentPageType = page.LogsPageType
m.focusedPageType = page.LogsPageType
case page.SingleLogPageType:
// cancel stickyness on logs page when moving to single log page, otherwise if selection is on the newest log,
// selection changes when new logs arrive and is not purely driven by the user
m.pages[page.LogsPageType] = m.pages[page.LogsPageType].(page.LogsPage).WithNoStickyness()
m.currentPageType = page.SingleLogPageType
m.focusedPageType = page.SingleLogPageType
default:
m.err = fmt.Errorf("unknown page type %d", newPage)
}
Expand Down Expand Up @@ -552,14 +564,14 @@ func (m Model) handleKeyMsg(msg tea.KeyMsg) (Model, tea.Cmd) {
}

// if current page highjacking input, e.g. editing a focused filter, update current page & return
if m.pages[m.currentPageType].HighjackingInput() {
m.pages[m.currentPageType], cmd = m.pages[m.currentPageType].Update(msg)
if m.pages[m.focusedPageType].HighjackingInput() {
m.pages[m.focusedPageType], cmd = m.pages[m.focusedPageType].Update(msg)
cmds = append(cmds, cmd)
return m, tea.Batch(cmds...)
}

// update current page
m.pages[m.currentPageType], cmd = m.pages[m.currentPageType].Update(msg)
m.pages[m.focusedPageType], cmd = m.pages[m.focusedPageType].Update(msg)
cmds = append(cmds, cmd)

// change to selection page
Expand All @@ -578,32 +590,32 @@ func (m Model) handleKeyMsg(msg tea.KeyMsg) (Model, tea.Cmd) {

// save content of current page
if key.Matches(msg, m.keyMap.Save) {
cmds = append(cmds, fileio.GetSaveCommand("", m.pages[m.currentPageType].ContentForFile()))
cmds = append(cmds, fileio.GetSaveCommand("", m.pages[m.focusedPageType].ContentForFile()))
return m, tea.Batch(cmds...)
}

// show help
if key.Matches(msg, m.keyMap.Help) {
m.helpText = m.pages[m.currentPageType].Help()
m.helpText = m.pages[m.focusedPageType].Help()
return m, nil
}

// entities page specific actions
if m.currentPageType == page.EntitiesPageType {
if m.focusedPageType == page.EntitiesPageType {
m, cmd = m.handleEntitiesPageKeyMsg(msg)
cmds = append(cmds, cmd)
return m, tea.Batch(cmds...)
}

// logs page specific actions
if m.currentPageType == page.LogsPageType {
if m.focusedPageType == page.LogsPageType {
m, cmd = m.handleLogsPageKeyMsg(msg)
cmds = append(cmds, cmd)
return m, tea.Batch(cmds...)
}

// single log page specific actions
if m.currentPageType == page.SingleLogPageType {
if m.focusedPageType == page.SingleLogPageType {
m, cmd = m.handleSingleLogPageKeyMsg(msg)
cmds = append(cmds, cmd)
return m, tea.Batch(cmds...)
Expand All @@ -614,7 +626,7 @@ func (m Model) handleKeyMsg(msg tea.KeyMsg) (Model, tea.Cmd) {
func (m Model) handleEntitiesPageKeyMsg(msg tea.KeyMsg) (Model, tea.Cmd) {
// handle pressing enter on selected entity
if key.Matches(msg, m.keyMap.Enter) {
selected, selectionActions := m.pages[m.currentPageType].(page.EntityPage).GetSelectionActions()
selected, selectionActions := m.pages[m.focusedPageType].(page.EntityPage).GetSelectionActions()
if len(selectionActions) > constants.ConfirmSelectionActionsThreshold {
return m.promptToConfirmSelectionActions(selected, selectionActions)
} else {
Expand Down Expand Up @@ -745,8 +757,8 @@ func (m Model) handleSingleLogPageKeyMsg(msg tea.KeyMsg) (Model, tea.Cmd) {
var cmd tea.Cmd
var cmds []tea.Cmd
isClear := key.Matches(msg, m.keyMap.Clear)
notHighjackingInput := !m.pages[m.currentPageType].HighjackingInput()
noAppliedFilter := !m.pages[m.currentPageType].(page.SingleLogPage).HasAppliedFilter()
notHighjackingInput := !m.pages[m.focusedPageType].HighjackingInput()
noAppliedFilter := !m.pages[m.focusedPageType].(page.SingleLogPage).HasAppliedFilter()
if isClear && notHighjackingInput && noAppliedFilter {
m, cmd = m.changeCurrentPage(page.LogsPageType)
cmds = append(cmds, cmd)
Expand Down
3 changes: 3 additions & 0 deletions internal/constants/constants.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@ var AttemptUpdateSinceTimeInterval = 500 * time.Millisecond

// *********************************************************************************************************************

// LeftPageWidthFraction controls the width of the left page as a fraction of the terminal width
const LeftPageWidthFraction = 2. / 5.

// MinCharsEachSideShortNames controls the minimum number of characters to show on each side of container shortnames
const MinCharsEachSideShortNames = 2

Expand Down
4 changes: 0 additions & 4 deletions internal/filter/filter.go
Original file line number Diff line number Diff line change
Expand Up @@ -157,10 +157,6 @@ func (m Model) HasContextualMatches() bool {
return m.FilteringWithContext && len(m.indexesMatchingFilter) > 0
}

func (m Model) ViewHeight() int {
return lipgloss.Height(m.View())
}

func (m Model) HasFilterText() bool {
return m.Value() != ""
}
Expand Down
12 changes: 8 additions & 4 deletions internal/filterable_viewport/filterable_viewport.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import (
"github.com/charmbracelet/bubbles/key"
"github.com/charmbracelet/bubbles/textinput"
tea "github.com/charmbracelet/bubbletea"
"github.com/charmbracelet/lipgloss"
"github.com/robinovitch61/kl/internal/dev"
"github.com/robinovitch61/kl/internal/filter"
"github.com/robinovitch61/kl/internal/keymap"
Expand Down Expand Up @@ -37,13 +36,14 @@ func NewFilterableViewport[T viewport.RenderableComparable](
f := filter.New(filterLabel, width, km)
f.SetFilteringWithContext(filterWithContext)

var vp = viewport.New[T](width, height-f.ViewHeight())
var vp = viewport.New[T](width, height)
vp.FooterStyle = style.Bold
vp.SelectedItemStyle = style.Inverse
vp.HighlightStyle = style.Inverse

vp.SetSelectionEnabled(startSelectionEnabled)
vp.SetWrapText(startWrapOn)
vp.SetHeader([]string{f.View()})

return FilterableViewport[T]{
Filter: f,
Expand All @@ -63,6 +63,10 @@ func (p FilterableViewport[T]) Update(msg tea.Msg) (FilterableViewport[T], tea.C
cmds []tea.Cmd
)

defer func() {
p.viewport.SetHeader(strings.Split(p.Filter.View(), "\n"))
}()

switch msg := msg.(type) {
case tea.KeyMsg:
// clearing the filter is always available regardless of filter focus
Expand Down Expand Up @@ -155,7 +159,7 @@ func (p FilterableViewport[T]) View() string {
} else {
viewportView = p.viewport.View()
}
return lipgloss.JoinVertical(lipgloss.Left, p.Filter.View(), viewportView)
return viewportView
}

func (p FilterableViewport[T]) HighjackingInput() bool {
Expand All @@ -165,7 +169,7 @@ func (p FilterableViewport[T]) HighjackingInput() bool {
func (p FilterableViewport[T]) WithDimensions(width, height int) FilterableViewport[T] {
p.viewport.SetWidth(width)
p.Filter.SetWidth(width)
p.viewport.SetHeight(height - p.Filter.ViewHeight())
p.viewport.SetHeight(height)
return p
}

Expand Down
15 changes: 9 additions & 6 deletions internal/page/logs.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ var _ GenericPage = LogsPage{}
func NewLogsPage(keyMap keymap.KeyMap, width, height int, descending bool) LogsPage {
lc := model.NewPageLogContainer(!descending)
filterableViewport := filterable_viewport.NewFilterableViewport[model.PageLog](
"", // set by updateFilterLabel below
fmt.Sprintf("Logs %s - S for Selection, Enter to Zoom", getOrder(!descending)),
true,
true,
false,
Expand Down Expand Up @@ -269,14 +269,17 @@ func (p *LogsPage) setStickynessBasedOnOrder() {
}

func (p *LogsPage) updateFilterLabel() {
order := "Descending"
if p.logContainer.Ascending() {
order = "Ascending"
}
label := fmt.Sprintf("Logs %s - S for Selection, Enter to Zoom", order)
label := fmt.Sprintf("Logs %s - S for Selection, Enter to Zoom", getOrder(p.logContainer.Ascending()))
p.filterableViewport.Filter.SetLabel(label)
}

func getOrder(ascending bool) string {
if ascending {
return "Ascending"
}
return "Descending"
}

func getLogTimestamp(log model.PageLog, format string) string {
if format == "short" {
return log.Timestamps.Short
Expand Down

0 comments on commit 9c6f973

Please sign in to comment.