1package statusbar
2
3import (
4 tea "github.com/charmbracelet/bubbletea"
5 "github.com/charmbracelet/lipgloss"
6 "github.com/charmbracelet/soft-serve/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 Branch string
16}
17
18// StatusBar is a status bar model.
19type StatusBar struct {
20 common common.Common
21 msg StatusBarMsg
22}
23
24// Model is an interface that supports setting the status bar information.
25type Model interface {
26 StatusBarValue() string
27 StatusBarInfo() string
28}
29
30// New creates a new status bar component.
31func New(c common.Common) *StatusBar {
32 s := &StatusBar{
33 common: c,
34 }
35 return s
36}
37
38// SetSize implements common.Component.
39func (s *StatusBar) SetSize(width, height int) {
40 s.common.Width = width
41 s.common.Height = height
42}
43
44// Init implements tea.Model.
45func (s *StatusBar) Init() tea.Cmd {
46 return nil
47}
48
49// Update implements tea.Model.
50func (s *StatusBar) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
51 switch msg := msg.(type) {
52 case StatusBarMsg:
53 s.msg = msg
54 }
55 return s, nil
56}
57
58// View implements tea.Model.
59func (s *StatusBar) View() string {
60 st := s.common.Styles
61 w := lipgloss.Width
62 help := st.StatusBarHelp.Render("? Help")
63 key := st.StatusBarKey.Render(s.msg.Key)
64 info := ""
65 if s.msg.Info != "" {
66 info = st.StatusBarInfo.Render(s.msg.Info)
67 }
68 branch := st.StatusBarBranch.Render(s.msg.Branch)
69 maxWidth := s.common.Width - w(key) - w(info) - w(branch) - w(help)
70 v := truncate.StringWithTail(s.msg.Value, uint(maxWidth-st.StatusBarValue.GetHorizontalFrameSize()), "…")
71 value := st.StatusBarValue.
72 Width(maxWidth).
73 Render(v)
74
75 return lipgloss.NewStyle().MaxWidth(s.common.Width).
76 Render(
77 lipgloss.JoinHorizontal(lipgloss.Top,
78 key,
79 value,
80 info,
81 branch,
82 help,
83 ),
84 )
85}