renderCollapsedSidebar renders the sidebar in collapsed mode (at top of screen).
(sl sidebarLayout)
| 470 | |
| 471 | // renderCollapsedSidebar renders the sidebar in collapsed mode (at top of screen). |
| 472 | func (p *chatPage) renderCollapsedSidebar(sl sidebarLayout) string { |
| 473 | // Guard against unset/invalid layout (can happen before WindowSizeMsg is received). |
| 474 | width := max(0, sl.innerWidth) |
| 475 | height := max(0, sl.sidebarHeight) |
| 476 | if width == 0 || height == 0 { |
| 477 | return "" |
| 478 | } |
| 479 | |
| 480 | sidebarView := p.sidebar.View() |
| 481 | sidebarLines := strings.Split(sidebarView, "\n") |
| 482 | |
| 483 | // Place toggle glyph at the far right of the first line |
| 484 | if sl.showToggle() && sl.mode != sidebarVertical && len(sidebarLines) > 0 { |
| 485 | toggleGlyph := styles.MutedStyle.Render("«") |
| 486 | glyphW := lipgloss.Width(toggleGlyph) |
| 487 | padded := lipgloss.NewStyle().Width(width - glyphW).Render(sidebarLines[0]) |
| 488 | sidebarLines[0] = padded + toggleGlyph |
| 489 | } |
| 490 | |
| 491 | // Replace the last line with a subtle divider |
| 492 | divider := styles.FadingStyle.Render(strings.Repeat("─", width)) |
| 493 | if len(sidebarLines) >= height { |
| 494 | sidebarLines[height-1] = divider |
| 495 | } else { |
| 496 | sidebarLines = append(sidebarLines, divider) |
| 497 | } |
| 498 | |
| 499 | sidebarWithDivider := strings.Join(sidebarLines, "\n") |
| 500 | |
| 501 | return lipgloss.NewStyle(). |
| 502 | Width(width). |
| 503 | Height(height). |
| 504 | Align(lipgloss.Left, lipgloss.Top). |
| 505 | Render(sidebarWithDivider) |
| 506 | } |
| 507 | |
| 508 | // View renders the chat page (messages + sidebar only, no editor or resize handle) |
| 509 | func (p *chatPage) View() string { |