Archived
Bubble Tea prototype for browsing repositories with many nested git submodules: collapsible tree, pins shown as ref + distance, summarized issue words with severity levels, detail pane, async loading via a Provider interface backed by mock data. Includes docs/ with requirements, state model, UX guide, architecture and decision log, plus AGENTS.md. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
67 lines
1.6 KiB
Go
67 lines
1.6 KiB
Go
// Package footer renders key hints and short-lived status messages.
|
|
package footer
|
|
|
|
import (
|
|
"time"
|
|
|
|
"github.com/charmbracelet/bubbles/help"
|
|
tea "github.com/charmbracelet/bubbletea"
|
|
"github.com/charmbracelet/lipgloss"
|
|
|
|
"submarine/internal/tui/theme"
|
|
)
|
|
|
|
const flashDuration = 2 * time.Second
|
|
|
|
type clearFlashMsg struct{ id int }
|
|
|
|
type Model struct {
|
|
theme theme.Theme
|
|
help help.Model
|
|
keys help.KeyMap
|
|
width int
|
|
flash string
|
|
flashID int
|
|
}
|
|
|
|
func New(t theme.Theme, keys help.KeyMap) Model {
|
|
h := help.New()
|
|
h.Styles.ShortKey = theme.Fg(t.Text).Bold(true)
|
|
h.Styles.ShortDesc = theme.Fg(t.Muted)
|
|
h.Styles.ShortSeparator = theme.Fg(t.Border)
|
|
h.Styles.FullKey = h.Styles.ShortKey
|
|
h.Styles.FullDesc = h.Styles.ShortDesc
|
|
h.Styles.FullSeparator = h.Styles.ShortSeparator
|
|
return Model{theme: t, help: h, keys: keys}
|
|
}
|
|
|
|
func (m *Model) SetWidth(w int) {
|
|
m.width = w
|
|
m.help.Width = w - 2
|
|
}
|
|
|
|
// ToggleHelp switches between short and full key help.
|
|
func (m *Model) ToggleHelp() { m.help.ShowAll = !m.help.ShowAll }
|
|
|
|
// Flash shows msg for a short time instead of the key hints.
|
|
func (m *Model) Flash(msg string) tea.Cmd {
|
|
m.flashID++
|
|
m.flash = msg
|
|
id := m.flashID
|
|
return tea.Tick(flashDuration, func(time.Time) tea.Msg { return clearFlashMsg{id} })
|
|
}
|
|
|
|
func (m *Model) Update(msg tea.Msg) {
|
|
if c, ok := msg.(clearFlashMsg); ok && c.id == m.flashID {
|
|
m.flash = ""
|
|
}
|
|
}
|
|
|
|
func (m Model) View() string {
|
|
style := lipgloss.NewStyle().Width(m.width).Padding(0, 1)
|
|
if m.flash != "" {
|
|
return style.Foreground(m.theme.Warn).Render(m.flash)
|
|
}
|
|
return style.Render(m.help.View(m.keys))
|
|
}
|