sidebar.go

  1package chat
  2
  3import (
  4	"fmt"
  5
  6	tea "github.com/charmbracelet/bubbletea"
  7	"github.com/charmbracelet/lipgloss"
  8	"github.com/kujtimiihoxha/termai/internal/pubsub"
  9	"github.com/kujtimiihoxha/termai/internal/session"
 10	"github.com/kujtimiihoxha/termai/internal/tui/styles"
 11)
 12
 13type sidebarCmp struct {
 14	width, height int
 15	session       session.Session
 16}
 17
 18func (m *sidebarCmp) Init() tea.Cmd {
 19	return nil
 20}
 21
 22func (m *sidebarCmp) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
 23	switch msg := msg.(type) {
 24	case pubsub.Event[session.Session]:
 25		if msg.Type == pubsub.UpdatedEvent {
 26			if m.session.ID == msg.Payload.ID {
 27				m.session = msg.Payload
 28			}
 29		}
 30	}
 31	return m, nil
 32}
 33
 34func (m *sidebarCmp) View() string {
 35	return styles.BaseStyle.
 36		Width(m.width).
 37		Height(m.height - 1).
 38		Render(
 39			lipgloss.JoinVertical(
 40				lipgloss.Top,
 41				header(m.width),
 42				" ",
 43				m.sessionSection(),
 44				" ",
 45				m.modifiedFiles(),
 46				" ",
 47				lspsConfigured(m.width),
 48			),
 49		)
 50}
 51
 52func (m *sidebarCmp) sessionSection() string {
 53	sessionKey := styles.BaseStyle.Foreground(styles.PrimaryColor).Bold(true).Render("Session")
 54	sessionValue := styles.BaseStyle.
 55		Foreground(styles.Forground).
 56		Width(m.width - lipgloss.Width(sessionKey)).
 57		Render(fmt.Sprintf(": %s", m.session.Title))
 58	return lipgloss.JoinHorizontal(
 59		lipgloss.Left,
 60		sessionKey,
 61		sessionValue,
 62	)
 63}
 64
 65func (m *sidebarCmp) modifiedFile(filePath string, additions, removals int) string {
 66	stats := ""
 67	if additions > 0 && removals > 0 {
 68		stats = styles.BaseStyle.Foreground(styles.ForgroundDim).Render(fmt.Sprintf(" %d additions and  %d removals", additions, removals))
 69	} else if additions > 0 {
 70		stats = styles.BaseStyle.Foreground(styles.ForgroundDim).Render(fmt.Sprintf(" %d additions", additions))
 71	} else if removals > 0 {
 72		stats = styles.BaseStyle.Foreground(styles.ForgroundDim).Render(fmt.Sprintf(" %d removals", removals))
 73	}
 74	filePathStr := styles.BaseStyle.Foreground(styles.Forground).Render(filePath)
 75
 76	return styles.BaseStyle.
 77		Width(m.width).
 78		Render(
 79			lipgloss.JoinHorizontal(
 80				lipgloss.Left,
 81				filePathStr,
 82				stats,
 83			),
 84		)
 85}
 86
 87func (m *sidebarCmp) modifiedFiles() string {
 88	modifiedFiles := styles.BaseStyle.Width(m.width).Foreground(styles.PrimaryColor).Bold(true).Render("Modified Files:")
 89	files := []struct {
 90		path      string
 91		additions int
 92		removals  int
 93	}{
 94		{"file1.txt", 10, 5},
 95		{"file2.txt", 20, 0},
 96		{"file3.txt", 0, 15},
 97	}
 98	var fileViews []string
 99	for _, file := range files {
100		fileViews = append(fileViews, m.modifiedFile(file.path, file.additions, file.removals))
101	}
102
103	return styles.BaseStyle.
104		Width(m.width).
105		Render(
106			lipgloss.JoinVertical(
107				lipgloss.Top,
108				modifiedFiles,
109				lipgloss.JoinVertical(
110					lipgloss.Left,
111					fileViews...,
112				),
113			),
114		)
115}
116
117func (m *sidebarCmp) SetSize(width, height int) {
118	m.width = width
119	m.height = height
120}
121
122func (m *sidebarCmp) GetSize() (int, int) {
123	return m.width, m.height
124}
125
126func NewSidebarCmp(session session.Session) tea.Model {
127	return &sidebarCmp{
128		session: session,
129	}
130}