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/ui/common"
11 "github.com/charmbracelet/soft-serve/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 },
66 }
67 return b
68}
69
70// Init implements tea.Model.
71func (r *Readme) Init() tea.Cmd {
72 return r.updateReadmeCmd
73}
74
75// Update implements tea.Model.
76func (r *Readme) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
77 cmds := make([]tea.Cmd, 0)
78 switch msg := msg.(type) {
79 case RepoMsg:
80 r.repo = msg
81 case RefMsg:
82 r.ref = msg
83 cmds = append(cmds, r.Init())
84 case EmptyRepoMsg:
85 r.code.SetContent(defaultEmptyRepoMsg(r.common.Config(),
86 r.repo.Name()), ".md")
87 }
88 c, cmd := r.code.Update(msg)
89 r.code = c.(*code.Code)
90 if cmd != nil {
91 cmds = append(cmds, cmd)
92 }
93 return r, tea.Batch(cmds...)
94}
95
96// View implements tea.Model.
97func (r *Readme) View() string {
98 return r.code.View()
99}
100
101// StatusBarValue implements statusbar.StatusBar.
102func (r *Readme) StatusBarValue() string {
103 dir := filepath.Dir(r.readmePath)
104 if dir == "." {
105 return ""
106 }
107 return dir
108}
109
110// StatusBarInfo implements statusbar.StatusBar.
111func (r *Readme) StatusBarInfo() string {
112 return fmt.Sprintf("☰ %.f%%", r.code.ScrollPercent()*100)
113}
114
115func (r *Readme) updateReadmeCmd() tea.Msg {
116 m := ReadmeMsg{}
117 if r.repo == nil {
118 return common.ErrorCmd(common.ErrMissingRepo)
119 }
120 rm, rp, _ := backend.Readme(r.repo)
121 r.readmePath = rp
122 r.code.GotoTop()
123 cmd := r.code.SetContent(rm, rp)
124 if cmd != nil {
125 m.Msg = cmd()
126 }
127 return m
128}