afb6cf89322a4fead4a862c0a5de796b4e2e2718

Author
Christian Rocha <christian@rocha.is>
Committer
Christian Rocha <christian@rocha.is>
Date

Message

Cleanup and reorganize styles, theming prep

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:      "─",