afb6cf89322a4fead4a862c0a5de796b4e2e2718
- Author
- Christian Rocha <christian@rocha.is>
- Committer
- Christian Rocha <christian@rocha.is>
- Date
Message
Diff
This diff is truncated to protect this page.
1diff --git a/tui/bubble.go b/tui/bubble.go
2index c18c2a2540916fe3af5455ec588c5266f0d702b1..5c68eb0b01b2e9ffbc752724468c9b4485f79032 100644
3--- a/tui/bubble.go
4+++ b/tui/bubble.go
5@@ -6,6 +6,7 @@ import (
6 "smoothie/tui/bubbles/commits"
7 "smoothie/tui/bubbles/repo"
8 "smoothie/tui/bubbles/selection"
9+ "smoothie/tui/style"
10 "strings"
11
12 tea "github.com/charmbracelet/bubbletea"
13@@ -48,6 +49,7 @@ type SessionConfig struct {
14
15 type Bubble struct {
16 config *Config
17+ styles *style.Styles
18 state sessionState
19 error string
20 width int
21@@ -66,6 +68,7 @@ type Bubble struct {
22 func NewBubble(cfg *Config, sCfg *SessionConfig) *Bubble {
23 b := &Bubble{
24 config: cfg,
25+ styles: style.DefaultStyles(),
26 width: sCfg.Width,
27 height: sCfg.Height,
28 windowChanges: sCfg.WindowChanges,
29@@ -143,10 +146,9 @@ func (b *Bubble) viewForBox(i int) string {
30 switch box := b.boxes[i].(type) {
31 case *selection.Bubble:
32 var s lipgloss.Style
33+ s = b.styles.Menu
34 if isActive {
35- s = menuActiveStyle
36- } else {
37- s = menuStyle
38+ s.Copy().BorderForeground(b.styles.ActiveBorderColor)
39 }
40 return s.Render(box.View())
41 case *repo.Bubble:
42@@ -158,8 +160,8 @@ func (b *Bubble) viewForBox(i int) string {
43 }
44
45 func (b Bubble) headerView() string {
46- w := b.width - appBoxStyle.GetHorizontalFrameSize()
47- return headerStyle.Copy().Width(w).Render(b.config.Name)
48+ w := b.width - b.styles.App.GetHorizontalFrameSize()
49+ return b.styles.Header.Copy().Width(w).Render(b.config.Name)
50 }
51
52 func (b Bubble) footerView() string {
53@@ -179,27 +181,28 @@ func (b Bubble) footerView() string {
54 }
55 }
56 for i, v := range h {
57- fmt.Fprint(w, v)
58+ fmt.Fprint(w, v.Render(b.styles))
59 if i != len(h)-1 {
60- fmt.Fprint(w, helpDivider)
61+ fmt.Fprint(w, b.styles.HelpDivider)
62 }
63 }
64- return footerStyle.Copy().Width(b.width).Render(w.String())
65+ return b.styles.Footer.Copy().Width(b.width).Render(w.String())
66 }
67
68 func (b Bubble) errorView() string {
69- s := lipgloss.JoinHorizontal(
70+ s := b.styles
71+ str := lipgloss.JoinHorizontal(
72 lipgloss.Top,
73- errorHeaderStyle.Render("Bummer"),
74- errorBodyStyle.Render(b.error),
75+ s.ErrorTitle.Render("Bummer"),
76+ s.ErrorBody.Render(b.error),
77 )
78 h := b.height -
79- appBoxStyle.GetVerticalFrameSize() -
80+ s.App.GetVerticalFrameSize() -
81 lipgloss.Height(b.headerView()) -
82 lipgloss.Height(b.footerView()) -
83- contentBoxStyle.GetVerticalFrameSize() +
84- 3 // TODO: figure out why we need this
85- return errorStyle.Copy().Height(h).Render(s)
86+ s.RepoBody.GetVerticalFrameSize() +
87+ 3 // TODO: this is repo header height -- get it dynamically
88+ return s.Error.Copy().Height(h).Render(str)
89 }
90
91 func (b Bubble) View() string {
92@@ -216,7 +219,7 @@ func (b Bubble) View() string {
93 }
94 s.WriteRune('\n')
95 s.WriteString(b.footerView())
96- return appBoxStyle.Render(s.String())
97+ return b.styles.App.Render(s.String())
98 }
99
100 type helpEntry struct {
101@@ -224,6 +227,6 @@ type helpEntry struct {
102 val string
103 }
104
105diff --git a/tui/bubbles/repo/bubble.go b/tui/bubbles/repo/bubble.go
106index e4ea72c6800ebf199b21a956e1873f5c2f2fdb0f..eafba0df5b29ca629df8d0b942e047f811cd54bf 100644
107--- a/tui/bubbles/repo/bubble.go
108+++ b/tui/bubbles/repo/bubble.go
109@@ -4,6 +4,7 @@ import (
110 "bytes"
111 "fmt"
112 "smoothie/git"
113+ "smoothie/tui/style"
114 "strconv"
115 "text/template"
116
117@@ -22,21 +23,18 @@ type ErrMsg struct {
118 }
119
120 type Bubble struct {
121- templateObject interface{}
122- repoSource *git.RepoSource
123- name string
124- repo *git.Repo
125- readmeViewport *ViewportBubble
126- readme string
127- height int
128- heightMargin int
129- width int
130- widthMargin int
131- Active bool
132- TitleStyle lipgloss.Style
133- NoteStyle lipgloss.Style
134- BodyStyle lipgloss.Style
135- ActiveBorderColor lipgloss.Color
136+ templateObject interface{}
137+ repoSource *git.RepoSource
138+ name string
139+ repo *git.Repo
140+ styles *style.Styles
141+ readmeViewport *ViewportBubble
142+ readme string
143+ height int
144+ heightMargin int
145+ width int
146+ widthMargin int
147+ Active bool
148
149 // XXX: ideally, we get these from the parent as a pointer. Currently, we
150 // can't add a *tui.Config because it's an illegal import cycle. One
151@@ -46,11 +44,12 @@ type Bubble struct {
152 Port int64
153 }
154
155-func NewBubble(rs *git.RepoSource, name string, width, wm, height, hm int, tmp interface{}) *Bubble {
156+func NewBubble(rs *git.RepoSource, name string, styles *style.Styles, width, wm, height, hm int, tmp interface{}) *Bubble {
157 b := &Bubble{
158 templateObject: tmp,
159 repoSource: rs,
160 name: name,
161+ styles: styles,
162 heightMargin: hm,
163 widthMargin: wm,
164 readmeViewport: &ViewportBubble{
165@@ -97,11 +96,11 @@ func (b *Bubble) GotoTop() {
166 }
167
168 func (b Bubble) headerView() string {
169- ts := b.TitleStyle
170- ns := b.NoteStyle
171+ ts := b.styles.RepoTitle
172+ ns := b.styles.RepoNote
173 if b.Active {
174- ts = ts.Copy().BorderForeground(b.ActiveBorderColor)
175- ns = ns.Copy().BorderForeground(b.ActiveBorderColor)
176+ ts = ts.Copy().BorderForeground(b.styles.ActiveBorderColor)
177+ ns = ns.Copy().BorderForeground(b.styles.ActiveBorderColor)
178 }
179 n := b.name
180 if n == "config" {
181@@ -114,13 +113,14 @@ func (b Bubble) headerView() string {
182 }
183
184 func (b *Bubble) View() string {
185+ s := b.styles
186 header := b.headerView()
187- bs := b.BodyStyle.Copy()
188+ bs := s.RepoBody.Copy()
189 if b.Active {
190- bs = bs.BorderForeground(b.ActiveBorderColor)
191+ bs = bs.BorderForeground(s.ActiveBorderColor)
192 }
193 body := bs.
194- Width(b.width - b.widthMargin - b.BodyStyle.GetVerticalFrameSize()).
195+ Width(b.width - b.widthMargin - s.RepoBody.GetVerticalFrameSize()).
196 Height(b.height - b.heightMargin - lipgloss.Height(header)).
197 Render(b.readmeViewport.View())
198 return header + body
199diff --git a/tui/bubbles/selection/bubble.go b/tui/bubbles/selection/bubble.go
200index 75736b268d2f9adbb2687a54b180f07553bfad9c..13f94f12b59fea38d97d839681296c8cf98d85e6 100644
201--- a/tui/bubbles/selection/bubble.go
202+++ b/tui/bubbles/selection/bubble.go
203@@ -1,8 +1,9 @@
204 package selection
205
206 import (
207+ "smoothie/tui/style"
208+
209 tea "github.com/charmbracelet/bubbletea"
210- "github.com/charmbracelet/lipgloss"
211 )
212
213 type SelectedMsg struct {
214@@ -16,19 +17,15 @@ type ActiveMsg struct {
215 }
216
217 type Bubble struct {
218- NormalStyle lipgloss.Style
219- SelectedStyle lipgloss.Style
220- Cursor string
221- Items []string
222- SelectedItem int
223+ Items []string
224+ SelectedItem int
225+ styles *style.Styles
226 }
227
228-func NewBubble(items []string, normalStyle, selectedStyle lipgloss.Style, cursor string) *Bubble {
229+func NewBubble(items []string, styles *style.Styles) *Bubble {
230 return &Bubble{
231- NormalStyle: normalStyle,
232- SelectedStyle: selectedStyle,
233- Cursor: cursor,
234- Items: items,
235+ Items: items,
236+ styles: styles,
237 }
238 }
239
240@@ -40,10 +37,10 @@ func (b Bubble) View() string {
241 s := ""
242 for i, item := range b.Items {
243 if i == b.SelectedItem {
244- s += b.Cursor
245- s += b.SelectedStyle.Render(item)
246+ s += b.styles.MenuCursor.String()
247+ s += b.styles.SelectedMenuItem.Render(item)
248 } else {
249- s += b.NormalStyle.Render(item)
250+ s += b.styles.MenuItem.Render(item)
251 }
252 if i < len(b.Items)-1 {
253 s += "\n"
254diff --git a/tui/commands.go b/tui/commands.go
255index 795e1eaec2c2c2aae4c90be900f5657861ca8b53..623cbedbf4c3ef166be5b29df7a35a27ecd2a36a 100644
256--- a/tui/commands.go
257+++ b/tui/commands.go
258@@ -49,18 +49,14 @@ func (b *Bubble) setupCmd() tea.Msg {
259 tmplConfig = b.config
260 }
261 width := b.width
262- boxLeftWidth := menuStyle.GetWidth() + menuStyle.GetHorizontalFrameSize()
263+ boxLeftWidth := b.styles.Menu.GetWidth() + b.styles.Menu.GetHorizontalFrameSize()
264 // TODO: also send this along with a tea.WindowSizeMsg
265 var heightMargin = lipgloss.Height(b.headerView()) +
266 lipgloss.Height(b.footerView()) +
267- contentBoxStyle.GetVerticalFrameSize() +
268- appBoxStyle.GetVerticalMargins() +
269+ b.styles.RepoBody.GetVerticalFrameSize() +
270+ b.styles.App.GetVerticalMargins() +
271 3 // TODO: make this dynamic (this is the height of the repo info)
272- rb := repo.NewBubble(b.repoSource, me.Repo, width, boxLeftWidth, b.height, heightMargin, tmplConfig)
273- rb.TitleStyle = contentBoxTitleStyle
274- rb.NoteStyle = contentBoxNoteStyle
275- rb.BodyStyle = contentBoxStyle
276- rb.ActiveBorderColor = activeBorderColor
277+ rb := repo.NewBubble(b.repoSource, me.Repo, b.styles, width, boxLeftWidth, b.height, heightMargin, tmplConfig)
278 rb.Host = b.config.Host
279 rb.Port = b.config.Port
280 initCmd := rb.Init()
281@@ -73,7 +69,7 @@ func (b *Bubble) setupCmd() tea.Msg {
282 b.repoMenu = append(b.repoMenu, me)
283 rs = append(rs, me.Name)
284 }
285- b.repoSelect = selection.NewBubble(rs, menuItemStyle, selectedMenuItemStyle, menuCursor.String())
286+ b.repoSelect = selection.NewBubble(rs, b.styles)
287 b.boxes[0] = b.repoSelect
288 /*
289 b.commitsLog = commits.NewBubble(
290diff --git a/tui/style.go b/tui/style.go
291deleted file mode 100644
292index 7d25bfbb8b5e6076447270d834a2d341b2b541c8..0000000000000000000000000000000000000000
293--- a/tui/style.go
294+++ /dev/null
295@@ -1,115 +0,0 @@
296-package tui
297-
298-import (
299- "github.com/charmbracelet/lipgloss"
300-)
301-
302-var activeBorderColor = lipgloss.Color("62")
303-var inactiveBorderColor = lipgloss.Color("236")
304-
305-var viewportTitleBorder = lipgloss.Border{
306- Top: "─",
307- Bottom: "─",
308- Left: "│",
309- Right: "│",
310- TopLeft: "╭",
311- TopRight: "┬",
312- BottomLeft: "├",
313- BottomRight: "┴",
314-}
315-
316-var viewportNoteBorder = lipgloss.Border{
317- Top: "─",
318- Bottom: "─",
319- Left: "",
320- Right: "│",
321- TopLeft: "",
322- TopRight: "╮",
323- BottomLeft: "",
324- BottomRight: "┤",
325-}
326-
327-var viewportBodyBorder = lipgloss.Border{
328- Top: "",
329- Bottom: "─",
330- Left: "│",
331- Right: "│",
332- TopLeft: "",
333- TopRight: "",
334- BottomLeft: "╰",
335- BottomRight: "╯",
336-}
337-
338-var appBoxStyle = lipgloss.NewStyle().
339- Margin(1, 2)
340-
341-var headerStyle = lipgloss.NewStyle().
342- Foreground(lipgloss.Color("62")).
343- Align(lipgloss.Right).
344- PaddingRight(1).
345- Bold(true)
346-
347-var menuStyle = lipgloss.NewStyle().
348- BorderStyle(lipgloss.RoundedBorder()).
349- BorderForeground(inactiveBorderColor).
350- Padding(1, 2).
351- MarginRight(1).
352- Width(24)
353-
354-var menuActiveStyle = menuStyle.Copy().
355- BorderStyle(lipgloss.RoundedBorder()).
356- BorderForeground(activeBorderColor)
357-
358-var menuCursor = lipgloss.NewStyle().
359- Foreground(lipgloss.Color("213")).
360- SetString(">")
361-
362-var contentBoxTitleStyle = lipgloss.NewStyle().
363- Border(viewportTitleBorder).
364- BorderForeground(inactiveBorderColor).
365- Padding(0, 2)
366-
367-var contentBoxNoteStyle = lipgloss.NewStyle().
368- Border(viewportNoteBorder, true, true, true, false).
369- BorderForeground(inactiveBorderColor).
370- Padding(0, 2)
371-
372-var contentBoxStyle = lipgloss.NewStyle().
373- BorderStyle(viewportBodyBorder).
374- BorderForeground(inactiveBorderColor).
375- PaddingRight(1)
376-
377-var menuItemStyle = lipgloss.NewStyle().
378- Foreground(lipgloss.Color("252")).
379- PaddingLeft(2)
380-
381-var selectedMenuItemStyle = lipgloss.NewStyle().
382- Foreground(lipgloss.Color("207")).
383- PaddingLeft(1)
384-
385-var footerStyle = lipgloss.NewStyle().
386- MarginTop(1)
387-
388-var helpKeyStyle = lipgloss.NewStyle().
389- Foreground(lipgloss.Color("241"))
390-
391-var helpValueStyle = lipgloss.NewStyle().
392- Foreground(lipgloss.Color("239"))
393-
394-var errorStyle = lipgloss.NewStyle().
395diff --git a/tui/style/style.go b/tui/style/style.go
396new file mode 100644
397index 0000000000000000000000000000000000000000..aad8135b3dedb39245b750c93205a3c41480900c
398--- /dev/null
399+++ b/tui/style/style.go
400@@ -0,0 +1,155 @@
401+package style
402+
403+import (
404+ "github.com/charmbracelet/lipgloss"
405+)
406+
407+// XXX: For now, this is in its own package so that it can be shared between
408+// different packages without incurring an illegal import cycle.
409+
410+type Styles struct {
411+ ActiveBorderColor lipgloss.Color
412+ InactiveBorderColor lipgloss.Color
413+
414+ App lipgloss.Style
415+ Header lipgloss.Style
416+
417+ Menu lipgloss.Style
418+ MenuCursor lipgloss.Style
419+ MenuItem lipgloss.Style
420+ SelectedMenuItem lipgloss.Style
421+
422+ RepoTitleBorder lipgloss.Border
423+ RepoNoteBorder lipgloss.Border
424+ RepoBodyBorder lipgloss.Border
425+
426+ RepoTitle lipgloss.Style
427+ RepoNote lipgloss.Style
428+ RepoBody lipgloss.Style
429+
430+ Footer lipgloss.Style
431+ HelpKey lipgloss.Style
432+ HelpValue lipgloss.Style
433+ HelpDivider lipgloss.Style
434+
435+ Error lipgloss.Style
436+ ErrorTitle lipgloss.Style
437+ ErrorBody lipgloss.Style
438+
439+ Command lipgloss.Style
440+}
441+
442+func DefaultStyles() *Styles {
443+ s := new(Styles)
444+
445+ s.ActiveBorderColor = lipgloss.Color("62")
446+ s.InactiveBorderColor = lipgloss.Color("236")
447+
448+ s.App = lipgloss.NewStyle().
449+ Margin(1, 2)
450+
451+ s.Header = lipgloss.NewStyle().
452+ Foreground(lipgloss.Color("62")).
453+ Align(lipgloss.Right).
454+ Bold(true)
455+
456+ s.Menu = lipgloss.NewStyle().
457+ BorderStyle(lipgloss.RoundedBorder()).
458+ BorderForeground(s.InactiveBorderColor).
459+ Padding(1, 2).
460+ MarginRight(1).
461+ Width(24)
462+
463+ s.MenuCursor = lipgloss.NewStyle().
464+ Foreground(lipgloss.Color("213")).
465+ SetString(">")
466+
467+ s.MenuItem = lipgloss.NewStyle().
468+ Foreground(lipgloss.Color("252")).
469+ PaddingLeft(2)
470+
471+ s.SelectedMenuItem = lipgloss.NewStyle().
472+ Foreground(lipgloss.Color("207")).
473+ PaddingLeft(1)
474+
475+ s.RepoTitleBorder = lipgloss.Border{
476+ Top: "─",
477+ Bottom: "─",
478+ Left: "│",
479+ Right: "│",
480+ TopLeft: "╭",
481+ TopRight: "┬",
482+ BottomLeft: "├",
483+ BottomRight: "┴",
484+ }
485+
486+ s.RepoNoteBorder = lipgloss.Border{
487+ Top: "─",
488+ Bottom: "─",
489+ Left: "",
490+ Right: "│",
491+ TopLeft: "",
492+ TopRight: "╮",
493+ BottomLeft: "",
494+ BottomRight: "┤",
495+ }
496+
497+ s.RepoBodyBorder = lipgloss.Border{
498+ Top: "",
499+ Bottom: "─",