bubble.go

  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}