1package repo
2
3import (
4 "bytes"
5 "smoothie/git"
6 "text/template"
7
8 "github.com/charmbracelet/bubbles/viewport"
9 tea "github.com/charmbracelet/bubbletea"
10 "github.com/charmbracelet/glamour"
11)
12
13type ErrMsg struct {
14 Error error
15}
16
17type Bubble struct {
18 templateObject interface{}
19 repoSource *git.RepoSource
20 name string
21 repo *git.Repo
22 readmeViewport *ViewportBubble
23}
24
25func NewBubble(rs *git.RepoSource, name string, width int, height int, tmp interface{}) *Bubble {
26 return &Bubble{
27 templateObject: tmp,
28 repoSource: rs,
29 name: name,
30 readmeViewport: &ViewportBubble{
31 Viewport: &viewport.Model{
32 Width: width,
33 Height: height,
34 },
35 },
36 }
37}
38
39func (b *Bubble) Init() tea.Cmd {
40 return b.setupCmd
41}
42
43func (b *Bubble) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
44 var cmds []tea.Cmd
45 rv, cmd := b.readmeViewport.Update(msg)
46 b.readmeViewport = rv.(*ViewportBubble)
47 if cmd != nil {
48 cmds = append(cmds, cmd)
49 }
50 return b, tea.Batch(cmds...)
51}
52
53func (b *Bubble) View() string {
54 return b.readmeViewport.View()
55}
56
57func (b *Bubble) setupCmd() tea.Msg {
58 r, err := b.repoSource.GetRepo(b.name)
59 if err != nil {
60 return ErrMsg{err}
61 }
62 md := r.Readme
63 if b.templateObject != nil {
64 md, err = b.templatize(md)
65 if err != nil {
66 return ErrMsg{err}
67 }
68 }
69 md, err = b.glamourize(md)
70 if err != nil {
71 return ErrMsg{err}
72 }
73 b.readmeViewport.Viewport.GotoTop()
74 b.readmeViewport.Viewport.SetContent(md)
75 return nil
76}
77
78func (b *Bubble) templatize(mdt string) (string, error) {
79 t, err := template.New("readme").Parse(mdt)
80 if err != nil {
81 return "", err
82 }
83 buf := &bytes.Buffer{}
84 err = t.Execute(buf, b.templateObject)
85 if err != nil {
86 return "", err
87 }
88 return buf.String(), nil
89}
90
91func (b *Bubble) glamourize(md string) (string, error) {
92 tr, err := glamour.NewTermRenderer(
93 glamour.WithAutoStyle(),
94 glamour.WithWordWrap(b.readmeViewport.Viewport.Width),
95 )
96 if err != nil {
97 return "", err
98 }
99 mdt, err := tr.Render(md)
100 if err != nil {
101 return "", err
102 }
103 return mdt, nil
104}