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}