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