bubble.go

 1package about
 2
 3import (
 4	"github.com/charmbracelet/bubbles/viewport"
 5	tea "github.com/charmbracelet/bubbletea"
 6	"github.com/charmbracelet/soft-serve/internal/tui/bubbles/git/types"
 7	vp "github.com/charmbracelet/soft-serve/internal/tui/bubbles/git/viewport"
 8	"github.com/charmbracelet/soft-serve/internal/tui/style"
 9)
10
11type Bubble struct {
12	readmeViewport *vp.ViewportBubble
13	repo           types.Repo
14	styles         *style.Styles
15	height         int
16	heightMargin   int
17	width          int
18	widthMargin    int
19}
20
21func NewBubble(repo types.Repo, styles *style.Styles, width, wm, height, hm int) *Bubble {
22	b := &Bubble{
23		readmeViewport: &vp.ViewportBubble{
24			Viewport: &viewport.Model{},
25		},
26		repo:         repo,
27		styles:       styles,
28		widthMargin:  wm,
29		heightMargin: hm,
30	}
31	b.SetSize(width, height)
32	return b
33}
34func (b *Bubble) Init() tea.Cmd {
35	return b.setupCmd
36}
37
38func (b *Bubble) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
39	var cmds []tea.Cmd
40	switch msg := msg.(type) {
41	case tea.WindowSizeMsg:
42		b.SetSize(msg.Width, msg.Height)
43		// XXX: if we find that longer readmes take more than a few
44		// milliseconds to render we may need to move Glamour rendering into a
45		// command.
46		md, err := b.glamourize()
47		if err != nil {
48			return b, nil
49		}
50		b.readmeViewport.Viewport.SetContent(md)
51	case tea.KeyMsg:
52		switch msg.String() {
53		case "R":
54			b.GotoTop()
55		}
56	}
57	rv, cmd := b.readmeViewport.Update(msg)
58	b.readmeViewport = rv.(*vp.ViewportBubble)
59	cmds = append(cmds, cmd)
60	return b, tea.Batch(cmds...)
61}
62
63func (b *Bubble) SetSize(w, h int) {
64	b.width = w
65	b.height = h
66	b.readmeViewport.Viewport.Width = w - b.widthMargin
67	b.readmeViewport.Viewport.Height = h - b.heightMargin
68}
69
70func (b *Bubble) GotoTop() {
71	b.readmeViewport.Viewport.GotoTop()
72}
73
74func (b *Bubble) View() string {
75	return b.readmeViewport.View()
76}
77
78func (b *Bubble) Help() []types.HelpEntry {
79	return nil
80}
81
82func (b *Bubble) glamourize() (string, error) {
83	w := b.width - b.widthMargin - b.styles.RepoBody.GetHorizontalFrameSize()
84	return types.Glamourize(w, b.repo.GetReadme())
85}
86
87func (b *Bubble) setupCmd() tea.Msg {
88	md, err := b.glamourize()
89	if err != nil {
90		return types.ErrMsg{err}
91	}
92	b.readmeViewport.Viewport.SetContent(md)
93	b.GotoTop()
94	return nil
95}