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