statusbar.go

  1package statusbar
  2
  3import (
  4	tea "github.com/charmbracelet/bubbletea"
  5	"github.com/charmbracelet/lipgloss"
  6	"github.com/charmbracelet/soft-serve/server/ui/common"
  7	"github.com/muesli/reflow/truncate"
  8)
  9
 10// StatusBarMsg is a message sent to the status bar.
 11type StatusBarMsg struct {
 12	Key   string
 13	Value string
 14	Info  string
 15	Extra string
 16}
 17
 18// StatusBar is a status bar model.
 19type StatusBar struct {
 20	common common.Common
 21	key    string
 22	value  string
 23	info   string
 24	extra  string
 25}
 26
 27// Model is an interface that supports setting the status bar information.
 28type Model interface {
 29	StatusBarValue() string
 30	StatusBarInfo() string
 31}
 32
 33// New creates a new status bar component.
 34func New(c common.Common) *StatusBar {
 35	s := &StatusBar{
 36		common: c,
 37	}
 38	return s
 39}
 40
 41// SetSize implements common.Component.
 42func (s *StatusBar) SetSize(width, height int) {
 43	s.common.Width = width
 44	s.common.Height = height
 45}
 46
 47// Init implements tea.Model.
 48func (s *StatusBar) Init() tea.Cmd {
 49	return nil
 50}
 51
 52// Update implements tea.Model.
 53func (s *StatusBar) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
 54	switch msg := msg.(type) {
 55	case StatusBarMsg:
 56		if msg.Key != "" {
 57			s.key = msg.Key
 58		}
 59		if msg.Value != "" {
 60			s.value = msg.Value
 61		}
 62		if msg.Info != "" {
 63			s.info = msg.Info
 64		}
 65		if msg.Extra != "" {
 66			s.extra = msg.Extra
 67		}
 68	}
 69	return s, nil
 70}
 71
 72// View implements tea.Model.
 73func (s *StatusBar) View() string {
 74	st := s.common.Styles
 75	w := lipgloss.Width
 76	help := s.common.Zone.Mark(
 77		"repo-help",
 78		st.StatusBarHelp.Render("? Help"),
 79	)
 80	key := st.StatusBarKey.Render(s.key)
 81	info := ""
 82	if s.info != "" {
 83		info = st.StatusBarInfo.Render(s.info)
 84	}
 85	branch := st.StatusBarBranch.Render(s.extra)
 86	maxWidth := s.common.Width - w(key) - w(info) - w(branch) - w(help)
 87	v := truncate.StringWithTail(s.value, uint(maxWidth-st.StatusBarValue.GetHorizontalFrameSize()), "…")
 88	value := st.StatusBarValue.
 89		Width(maxWidth).
 90		Render(v)
 91
 92	return s.common.Renderer.NewStyle().MaxWidth(s.common.Width).
 93		Render(
 94			lipgloss.JoinHorizontal(lipgloss.Top,
 95				key,
 96				value,
 97				info,
 98				branch,
 99				help,
100			),
101		)
102}