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) GotoTop() {
54 b.readmeViewport.Viewport.GotoTop()
55}
56
57func (b *Bubble) View() string {
58 return b.readmeViewport.View()
59}
60
61func (b *Bubble) setupCmd() tea.Msg {
62 r, err := b.repoSource.GetRepo(b.name)
63 if err == git.ErrMissingRepo {
64 return nil
65 }
66 if err != nil {
67 return ErrMsg{err}
68 }
69 md := r.Readme
70 if b.templateObject != nil {
71 md, err = b.templatize(md)
72 if err != nil {
73 return ErrMsg{err}
74 }
75 }
76 md, err = b.glamourize(md)
77 if err != nil {
78 return ErrMsg{err}
79 }
80 b.GotoTop()
81 b.readmeViewport.Viewport.SetContent(md)
82 return nil
83}
84
85func (b *Bubble) templatize(mdt string) (string, error) {
86 t, err := template.New("readme").Parse(mdt)
87 if err != nil {
88 return "", err
89 }
90 buf := &bytes.Buffer{}
91 err = t.Execute(buf, b.templateObject)
92 if err != nil {
93 return "", err
94 }
95 return buf.String(), nil
96}
97
98func (b *Bubble) glamourize(md string) (string, error) {
99 tr, err := glamour.NewTermRenderer(
100 glamour.WithAutoStyle(),
101 glamour.WithWordWrap(b.readmeViewport.Viewport.Width),
102 )
103 if err != nil {
104 return "", err
105 }
106 mdt, err := tr.Render(md)
107 if err != nil {
108 return "", err
109 }
110 return mdt, nil
111}