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}