| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121 |
- package model
- import (
- "strings"
- "time"
- "charm.land/bubbles/v2/help"
- tea "charm.land/bubbletea/v2"
- "charm.land/lipgloss/v2"
- "github.com/charmbracelet/crush/internal/ui/common"
- "github.com/charmbracelet/crush/internal/ui/util"
- uv "github.com/charmbracelet/ultraviolet"
- "github.com/charmbracelet/x/ansi"
- )
- // DefaultStatusTTL is the default time-to-live for status messages.
- const DefaultStatusTTL = 5 * time.Second
- // Status is the status bar and help model.
- type Status struct {
- com *common.Common
- hideHelp bool
- help help.Model
- helpKm help.KeyMap
- msg util.InfoMsg
- }
- // NewStatus creates a new status bar and help model.
- func NewStatus(com *common.Common, km help.KeyMap) *Status {
- s := new(Status)
- s.com = com
- s.help = help.New()
- s.help.Styles = com.Styles.Help
- s.helpKm = km
- return s
- }
- // SetInfoMsg sets the status info message.
- func (s *Status) SetInfoMsg(msg util.InfoMsg) {
- s.msg = msg
- }
- // ClearInfoMsg clears the status info message.
- func (s *Status) ClearInfoMsg() {
- s.msg = util.InfoMsg{}
- }
- // SetWidth sets the width of the status bar and help view.
- func (s *Status) SetWidth(width int) {
- helpStyle := s.com.Styles.Status.Help
- horizontalPadding := helpStyle.GetPaddingLeft() + helpStyle.GetPaddingRight()
- s.help.SetWidth(width - horizontalPadding)
- }
- // ShowingAll returns whether the full help view is shown.
- func (s *Status) ShowingAll() bool {
- return s.help.ShowAll
- }
- // ToggleHelp toggles the full help view.
- func (s *Status) ToggleHelp() {
- s.help.ShowAll = !s.help.ShowAll
- }
- // SetHideHelp sets whether the app is on the onboarding flow.
- func (s *Status) SetHideHelp(hideHelp bool) {
- s.hideHelp = hideHelp
- }
- // Draw draws the status bar onto the screen.
- func (s *Status) Draw(scr uv.Screen, area uv.Rectangle) {
- if !s.hideHelp {
- helpView := s.com.Styles.Status.Help.Render(s.help.View(s.helpKm))
- uv.NewStyledString(helpView).Draw(scr, area)
- }
- // Render notifications
- if s.msg.IsEmpty() {
- return
- }
- var indStyle lipgloss.Style
- var msgStyle lipgloss.Style
- switch s.msg.Type {
- case util.InfoTypeError:
- indStyle = s.com.Styles.Status.ErrorIndicator
- msgStyle = s.com.Styles.Status.ErrorMessage
- case util.InfoTypeWarn:
- indStyle = s.com.Styles.Status.WarnIndicator
- msgStyle = s.com.Styles.Status.WarnMessage
- case util.InfoTypeUpdate:
- indStyle = s.com.Styles.Status.UpdateIndicator
- msgStyle = s.com.Styles.Status.UpdateMessage
- case util.InfoTypeInfo:
- indStyle = s.com.Styles.Status.InfoIndicator
- msgStyle = s.com.Styles.Status.InfoMessage
- case util.InfoTypeSuccess:
- indStyle = s.com.Styles.Status.SuccessIndicator
- msgStyle = s.com.Styles.Status.SuccessMessage
- }
- ind := indStyle.String()
- indWidth := lipgloss.Width(ind)
- msg := strings.Join(strings.Split(s.msg.Msg, "\n"), " ")
- msgWidth := lipgloss.Width(msg)
- msg = ansi.Truncate(msg, area.Dx()-indWidth-msgWidth, "…")
- padWidth := max(0, area.Dx()-indWidth-msgWidth)
- msg += strings.Repeat(" ", padWidth)
- info := msgStyle.Render(msg)
- // Draw the info message over the help view
- uv.NewStyledString(ind+info).Draw(scr, area)
- }
- // clearInfoMsgCmd returns a command that clears the info message after the
- // given TTL.
- func clearInfoMsgCmd(ttl time.Duration) tea.Cmd {
- return tea.Tick(ttl, func(time.Time) tea.Msg {
- return util.ClearStatusMsg{}
- })
- }
|