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}