Detailed changes
@@ -107,7 +107,7 @@ func (m *messageListCmp) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
func (m *messageListCmp) View() string {
t := styles.CurrentTheme()
return t.S().Base.
- Padding(1).
+ Padding(1, 1, 0, 1).
Width(m.width).
Height(m.height).
Render(
@@ -508,7 +508,7 @@ func (m *messageListCmp) GetSize() (int, int) {
func (m *messageListCmp) SetSize(width int, height int) tea.Cmd {
m.width = width
m.height = height
- return m.listCmp.SetSize(width-2, height-2) // for padding
+ return m.listCmp.SetSize(width-2, height-1) // for padding
}
// Blur implements MessageListCmp.
@@ -114,12 +114,22 @@ func (m *sidebarCmp) View() string {
t := styles.CurrentTheme()
parts := []string{}
+ style := t.S().Base.
+ Width(m.width).
+ Height(m.height).
+ Padding(1)
+ if m.compactMode {
+ style = style.PaddingTop(0)
+ }
+
if !m.compactMode {
if m.height > LogoHeightBreakpoint {
parts = append(parts, m.logo)
} else {
// Use a smaller logo for smaller screens
- parts = append(parts, m.smallerScreenLogo(), "")
+ parts = append(parts,
+ logo.SmallRender(m.width-style.GetHorizontalFrameSize()),
+ "")
}
}
@@ -159,13 +169,6 @@ func (m *sidebarCmp) View() string {
)
}
- style := t.S().Base.
- Width(m.width).
- Height(m.height).
- Padding(1)
- if m.compactMode {
- style = style.PaddingTop(0)
- }
return style.Render(
lipgloss.JoinVertical(lipgloss.Left, parts...),
)
@@ -934,19 +937,6 @@ func (s *sidebarCmp) currentModelBlock() string {
)
}
-func (m *sidebarCmp) smallerScreenLogo() string {
- t := styles.CurrentTheme()
- title := t.S().Base.Foreground(t.Secondary).Render("Charmβ’")
- title += " " + styles.ApplyBoldForegroundGrad("CRUSH", t.Secondary, t.Primary)
- remainingWidth := m.width - lipgloss.Width(title) - 3
- if remainingWidth > 0 {
- char := "β±"
- lines := strings.Repeat(char, remainingWidth)
- title += " " + t.S().Base.Foreground(t.Primary).Render(lines)
- }
- return title
-}
-
// SetSession implements Sidebar.
func (m *sidebarCmp) SetSession(session session.Session) tea.Cmd {
m.session = session
@@ -143,9 +143,11 @@ func (s *splashCmp) Init() tea.Cmd {
// SetSize implements SplashPage.
func (s *splashCmp) SetSize(width int, height int) tea.Cmd {
+ wasSmallScreen := s.isSmallScreen()
+ rerenderLogo := width != s.width
s.height = height
- if width != s.width {
- s.width = width
+ s.width = width
+ if rerenderLogo || wasSmallScreen != s.isSmallScreen() {
s.logoRendered = s.logoBlock()
}
// remove padding, logo height, gap, title space
@@ -541,9 +543,19 @@ func (s *splashCmp) Cursor() *tea.Cursor {
return nil
}
+func (s *splashCmp) isSmallScreen() bool {
+ // Consider a screen small if either the width is less than 40 or if the
+ // height is less than 20
+ return s.width < 55 || s.height < 20
+}
+
func (s *splashCmp) infoSection() string {
t := styles.CurrentTheme()
- return t.S().Base.PaddingLeft(2).Render(
+ infoStyle := t.S().Base.PaddingLeft(2)
+ if s.isSmallScreen() {
+ infoStyle = infoStyle.MarginTop(1)
+ }
+ return infoStyle.Render(
lipgloss.JoinVertical(
lipgloss.Left,
s.cwd(),
@@ -556,14 +568,25 @@ func (s *splashCmp) infoSection() string {
func (s *splashCmp) logoBlock() string {
t := styles.CurrentTheme()
- return t.S().Base.Padding(0, 2).Width(s.width).Render(
+ logoStyle := t.S().Base.Padding(0, 2).Width(s.width)
+ if s.isSmallScreen() {
+ // If the width is too small, render a smaller version of the logo
+ // NOTE: 20 is not correct because [splashCmp.height] is not the
+ // *actual* window height, instead, it is the height of the splash
+ // component and that depends on other variables like compact mode and
+ // the height of the editor.
+ return logoStyle.Render(
+ logo.SmallRender(s.width - logoStyle.GetHorizontalFrameSize()),
+ )
+ }
+ return logoStyle.Render(
logo.Render(version.Version, false, logo.Opts{
FieldColor: t.Primary,
TitleColorA: t.Secondary,
TitleColorB: t.Primary,
CharmColor: t.Secondary,
VersionColor: t.Primary,
- Width: s.width - 4,
+ Width: s.width - logoStyle.GetHorizontalFrameSize(),
}),
)
}
@@ -44,13 +44,19 @@ func Render(version string, compact bool, o Opts) string {
// Title.
const spacing = 1
- crush := renderWord(spacing, !compact,
+ letterforms := []letterform{
letterC,
letterR,
letterU,
letterSStylized,
letterH,
- )
+ }
+ stretchIndex := -1 // -1 means no stretching.
+ if !compact {
+ stretchIndex = rand.IntN(len(letterforms))
+ }
+
+ crush := renderWord(spacing, stretchIndex, letterforms...)
crushWidth := lipgloss.Width(crush)
b := new(strings.Builder)
for r := range strings.SplitSeq(crush, "\n") {
@@ -110,8 +116,23 @@ func Render(version string, compact bool, o Opts) string {
return logo
}
-// renderWord renders letterforms to fork a word.
-func renderWord(spacing int, stretchRandomLetter bool, letterforms ...letterform) string {
+// SmallRender renders a smaller version of the Crush logo, suitable for
+// smaller windows or sidebar usage.
+func SmallRender(width int) string {
+ t := styles.CurrentTheme()
+ title := t.S().Base.Foreground(t.Secondary).Render("Charmβ’")
+ title = fmt.Sprintf("%s %s", title, styles.ApplyBoldForegroundGrad("Crush", t.Secondary, t.Primary))
+ remainingWidth := width - lipgloss.Width(title) - 1 // 1 for the space after "Crush"
+ if remainingWidth > 0 {
+ lines := strings.Repeat("β±", remainingWidth)
+ title = fmt.Sprintf("%s %s", title, t.S().Base.Foreground(t.Primary).Render(lines))
+ }
+ return title
+}
+
+// renderWord renders letterforms to fork a word. stretchIndex is the index of
+// the letter to stretch, or -1 if no letter should be stretched.
+func renderWord(spacing int, stretchIndex int, letterforms ...letterform) string {
if spacing < 0 {
spacing = 0
}
@@ -119,11 +140,6 @@ func renderWord(spacing int, stretchRandomLetter bool, letterforms ...letterform
renderedLetterforms := make([]string, len(letterforms))
// pick one letter randomly to stretch
- stretchIndex := -1
- if stretchRandomLetter {
- stretchIndex = rand.IntN(len(letterforms)) //nolint:gosec
- }
-
for i, letter := range letterforms {
renderedLetterforms[i] = letter(i == stretchIndex)
}