1package model
2
3import (
4 "time"
5
6 "charm.land/bubbles/v2/help"
7 tea "charm.land/bubbletea/v2"
8 "charm.land/lipgloss/v2"
9 "github.com/charmbracelet/crush/internal/ui/common"
10 "github.com/charmbracelet/crush/internal/uiutil"
11 uv "github.com/charmbracelet/ultraviolet"
12 "github.com/charmbracelet/x/ansi"
13)
14
15// DefaultStatusTTL is the default time-to-live for status messages.
16const DefaultStatusTTL = 5 * time.Second
17
18// Status is the status bar and help model.
19type Status struct {
20 com *common.Common
21 help help.Model
22 helpKm help.KeyMap
23 msg uiutil.InfoMsg
24}
25
26// NewStatus creates a new status bar and help model.
27func NewStatus(com *common.Common, km help.KeyMap) *Status {
28 s := new(Status)
29 s.com = com
30 s.help = help.New()
31 s.help.Styles = com.Styles.Help
32 s.helpKm = km
33 return s
34}
35
36// SetInfoMsg sets the status info message.
37func (s *Status) SetInfoMsg(msg uiutil.InfoMsg) {
38 s.msg = msg
39}
40
41// ClearInfoMsg clears the status info message.
42func (s *Status) ClearInfoMsg() {
43 s.msg = uiutil.InfoMsg{}
44}
45
46// SetWidth sets the width of the status bar and help view.
47func (s *Status) SetWidth(width int) {
48 s.help.SetWidth(width)
49}
50
51// ShowingAll returns whether the full help view is shown.
52func (s *Status) ShowingAll() bool {
53 return s.help.ShowAll
54}
55
56// ToggleHelp toggles the full help view.
57func (s *Status) ToggleHelp() {
58 s.help.ShowAll = !s.help.ShowAll
59}
60
61// Draw draws the status bar onto the screen.
62func (s *Status) Draw(scr uv.Screen, area uv.Rectangle) {
63 helpView := s.com.Styles.Status.Help.Render(s.help.View(s.helpKm))
64 uv.NewStyledString(helpView).Draw(scr, area)
65
66 // Render notifications
67 if s.msg.IsEmpty() {
68 return
69 }
70
71 var indStyle lipgloss.Style
72 var msgStyle lipgloss.Style
73 switch s.msg.Type {
74 case uiutil.InfoTypeError:
75 indStyle = s.com.Styles.Status.ErrorIndicator
76 msgStyle = s.com.Styles.Status.ErrorMessage
77 case uiutil.InfoTypeWarn:
78 indStyle = s.com.Styles.Status.WarnIndicator
79 msgStyle = s.com.Styles.Status.WarnMessage
80 case uiutil.InfoTypeUpdate:
81 indStyle = s.com.Styles.Status.UpdateIndicator
82 msgStyle = s.com.Styles.Status.UpdateMessage
83 case uiutil.InfoTypeInfo:
84 indStyle = s.com.Styles.Status.InfoIndicator
85 msgStyle = s.com.Styles.Status.InfoMessage
86 case uiutil.InfoTypeSuccess:
87 indStyle = s.com.Styles.Status.SuccessIndicator
88 msgStyle = s.com.Styles.Status.SuccessMessage
89 }
90
91 ind := indStyle.String()
92 messageWidth := area.Dx() - lipgloss.Width(ind)
93 msg := ansi.Truncate(s.msg.Msg, messageWidth, "…")
94 info := msgStyle.Width(messageWidth).Render(msg)
95
96 // Draw the info message over the help view
97 uv.NewStyledString(ind+info).Draw(scr, area)
98}
99
100// clearInfoMsgCmd returns a command that clears the info message after the
101// given TTL.
102func clearInfoMsgCmd(ttl time.Duration) tea.Cmd {
103 return tea.Tick(ttl, func(time.Time) tea.Msg {
104 return uiutil.ClearStatusMsg{}
105 })
106}