readme.go

  1package repo
  2
  3import (
  4	"fmt"
  5	"path/filepath"
  6
  7	"github.com/charmbracelet/bubbles/key"
  8	tea "github.com/charmbracelet/bubbletea"
  9	"github.com/charmbracelet/soft-serve/server/backend"
 10	"github.com/charmbracelet/soft-serve/server/ui/common"
 11	"github.com/charmbracelet/soft-serve/server/ui/components/code"
 12)
 13
 14// ReadmeMsg is a message sent when the readme is loaded.
 15type ReadmeMsg struct {
 16	Msg tea.Msg
 17}
 18
 19// Readme is the readme component page.
 20type Readme struct {
 21	common     common.Common
 22	code       *code.Code
 23	ref        RefMsg
 24	repo       backend.Repository
 25	readmePath string
 26}
 27
 28// NewReadme creates a new readme model.
 29func NewReadme(common common.Common) *Readme {
 30	readme := code.New(common, "", "")
 31	readme.NoContentStyle = readme.NoContentStyle.Copy().SetString("No readme found.")
 32	return &Readme{
 33		code:   readme,
 34		common: common,
 35	}
 36}
 37
 38// SetSize implements common.Component.
 39func (r *Readme) SetSize(width, height int) {
 40	r.common.SetSize(width, height)
 41	r.code.SetSize(width, height)
 42}
 43
 44// ShortHelp implements help.KeyMap.
 45func (r *Readme) ShortHelp() []key.Binding {
 46	b := []key.Binding{
 47		r.common.KeyMap.UpDown,
 48	}
 49	return b
 50}
 51
 52// FullHelp implements help.KeyMap.
 53func (r *Readme) FullHelp() [][]key.Binding {
 54	k := r.code.KeyMap
 55	b := [][]key.Binding{
 56		{
 57			k.PageDown,
 58			k.PageUp,
 59			k.HalfPageDown,
 60			k.HalfPageUp,
 61		},
 62		{
 63			k.Down,
 64			k.Up,
 65			r.common.KeyMap.GotoTop,
 66			r.common.KeyMap.GotoBottom,
 67		},
 68	}
 69	return b
 70}
 71
 72// Init implements tea.Model.
 73func (r *Readme) Init() tea.Cmd {
 74	return r.updateReadmeCmd
 75}
 76
 77// Update implements tea.Model.
 78func (r *Readme) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
 79	cmds := make([]tea.Cmd, 0)
 80	switch msg := msg.(type) {
 81	case RepoMsg:
 82		r.repo = msg
 83	case RefMsg:
 84		r.ref = msg
 85		cmds = append(cmds, r.Init())
 86	case EmptyRepoMsg:
 87		r.code.SetContent(defaultEmptyRepoMsg(r.common.Config(), r.repo.Name()), ".md")
 88	}
 89	c, cmd := r.code.Update(msg)
 90	r.code = c.(*code.Code)
 91	if cmd != nil {
 92		cmds = append(cmds, cmd)
 93	}
 94	return r, tea.Batch(cmds...)
 95}
 96
 97// View implements tea.Model.
 98func (r *Readme) View() string {
 99	return r.code.View()
100}
101
102// StatusBarValue implements statusbar.StatusBar.
103func (r *Readme) StatusBarValue() string {
104	dir := filepath.Dir(r.readmePath)
105	if dir == "." {
106		return ""
107	}
108	return dir
109}
110
111// StatusBarInfo implements statusbar.StatusBar.
112func (r *Readme) StatusBarInfo() string {
113	return fmt.Sprintf("☰ %.f%%", r.code.ScrollPercent()*100)
114}
115
116func (r *Readme) updateReadmeCmd() tea.Msg {
117	m := ReadmeMsg{}
118	if r.repo == nil {
119		return common.ErrorCmd(common.ErrMissingRepo)
120	}
121	rm, rp, _ := backend.Readme(r.repo)
122	r.readmePath = rp
123	r.code.GotoTop()
124	cmd := r.code.SetContent(rm, rp)
125	if cmd != nil {
126		m.Msg = cmd()
127	}
128	return m
129}