Detailed changes
@@ -16,10 +16,10 @@ import (
// Code is a code snippet.
type Code struct {
+ *vp.Viewport
common common.Common
content string
extension string
- viewport *vp.Viewport
NoContentStyle lipgloss.Style
}
@@ -29,7 +29,7 @@ func New(c common.Common, content, extension string) *Code {
common: c,
content: content,
extension: extension,
- viewport: vp.New(),
+ Viewport: vp.New(c),
NoContentStyle: c.Styles.CodeNoContent.Copy(),
}
r.SetSize(c.Width, c.Height)
@@ -39,7 +39,7 @@ func New(c common.Common, content, extension string) *Code {
// SetSize implements common.Component.
func (r *Code) SetSize(width, height int) {
r.common.SetSize(width, height)
- r.viewport.SetSize(width, height)
+ r.Viewport.SetSize(width, height)
}
// SetContent sets the content of the Code.
@@ -66,7 +66,7 @@ func (r *Code) Init() tea.Cmd {
for i, l := range s {
s[i] = l + "\x1b[0m"
}
- r.viewport.Viewport.SetContent(strings.Join(s, "\n"))
+ r.Viewport.Model.SetContent(strings.Join(s, "\n"))
return nil
}
@@ -78,8 +78,8 @@ func (r *Code) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
// Recalculate content width and line wrap.
cmds = append(cmds, r.Init())
}
- v, cmd := r.viewport.Update(msg)
- r.viewport = v.(*vp.Viewport)
+ v, cmd := r.Viewport.Update(msg)
+ r.Viewport = v.(*vp.Viewport)
if cmd != nil {
cmds = append(cmds, cmd)
}
@@ -88,52 +88,52 @@ func (r *Code) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
// View implements tea.View.
func (r *Code) View() string {
- return r.viewport.View()
+ return r.Viewport.View()
}
// GotoTop moves the viewport to the top of the log.
func (r *Code) GotoTop() {
- r.viewport.GotoTop()
+ r.Viewport.GotoTop()
}
// GotoBottom moves the viewport to the bottom of the log.
func (r *Code) GotoBottom() {
- r.viewport.GotoBottom()
+ r.Viewport.GotoBottom()
}
// HalfViewDown moves the viewport down by half the viewport height.
func (r *Code) HalfViewDown() {
- r.viewport.HalfViewDown()
+ r.Viewport.HalfViewDown()
}
// HalfViewUp moves the viewport up by half the viewport height.
func (r *Code) HalfViewUp() {
- r.viewport.HalfViewUp()
+ r.Viewport.HalfViewUp()
}
// ViewUp moves the viewport up by a page.
func (r *Code) ViewUp() []string {
- return r.viewport.ViewUp()
+ return r.Viewport.ViewUp()
}
// ViewDown moves the viewport down by a page.
func (r *Code) ViewDown() []string {
- return r.viewport.ViewDown()
+ return r.Viewport.ViewDown()
}
// LineUp moves the viewport up by the given number of lines.
func (r *Code) LineUp(n int) []string {
- return r.viewport.LineUp(n)
+ return r.Viewport.LineUp(n)
}
// LineDown moves the viewport down by the given number of lines.
func (r *Code) LineDown(n int) []string {
- return r.viewport.LineDown(n)
+ return r.Viewport.LineDown(n)
}
// ScrollPercent returns the viewport's scroll percentage.
func (r *Code) ScrollPercent() float64 {
- return r.viewport.ScrollPercent()
+ return r.Viewport.ScrollPercent()
}
func styleConfig() gansi.StyleConfig {
@@ -1,7 +1,10 @@
package footer
import (
+ "strings"
+
"github.com/charmbracelet/bubbles/help"
+ "github.com/charmbracelet/bubbles/key"
tea "github.com/charmbracelet/bubbletea"
"github.com/charmbracelet/soft-serve/ui/common"
)
@@ -25,13 +28,14 @@ func New(c common.Common, keymap help.KeyMap) *Footer {
help: h,
keymap: keymap,
}
+ f.SetSize(c.Width, c.Height)
return f
}
// SetSize implements common.Component.
func (f *Footer) SetSize(width, height int) {
- f.common.Width = width
- f.common.Height = height
+ f.common.SetSize(width, height)
+ f.help.Width = width
}
// Init implements tea.Model.
@@ -41,13 +45,6 @@ func (f *Footer) Init() tea.Cmd {
// Update implements tea.Model.
func (f *Footer) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
- switch msg := msg.(type) {
- case tea.KeyMsg:
- switch msg.String() {
- case "?":
- f.help.ShowAll = !f.help.ShowAll
- }
- }
return f, nil
}
@@ -57,5 +54,31 @@ func (f *Footer) View() string {
return ""
}
s := f.common.Styles.Footer.Copy().Width(f.common.Width)
- return s.Render(f.help.View(f.keymap))
+ helpView := f.help.View(f.keymap)
+ return s.Render(helpView)
+}
+
+// ShortHelp returns the short help key bindings.
+func (f *Footer) ShortHelp() []key.Binding {
+ return f.keymap.ShortHelp()
+}
+
+// FullHelp returns the full help key bindings.
+func (f *Footer) FullHelp() [][]key.Binding {
+ return f.keymap.FullHelp()
+}
+
+// ShowAll returns whether the full help is shown.
+func (f *Footer) ShowAll() bool {
+ return f.help.ShowAll
+}
+
+// SetShowAll sets whether the full help is shown.
+func (f *Footer) SetShowAll(show bool) {
+ f.help.ShowAll = show
+}
+
+// Height returns the height of the footer.
+func (f *Footer) Height() int {
+ return len(strings.Split(f.View(), "\n"))
}
@@ -144,9 +144,16 @@ func (s *Selector) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
s.Model.CursorDown()
}
case tea.KeyMsg:
+ filterState := s.Model.FilterState()
switch {
+ case key.Matches(msg, s.common.KeyMap.Help):
+ if filterState == list.Filtering {
+ return s, tea.Batch(cmds...)
+ }
case key.Matches(msg, s.common.KeyMap.Select):
- cmds = append(cmds, s.selectCmd)
+ if filterState != list.Filtering {
+ cmds = append(cmds, s.selectCmd)
+ }
}
case list.FilterMatchesMsg:
cmds = append(cmds, s.activeFilterCmd)
@@ -1,27 +1,59 @@
package viewport
import (
+ "github.com/charmbracelet/bubbles/key"
"github.com/charmbracelet/bubbles/viewport"
tea "github.com/charmbracelet/bubbletea"
+ "github.com/charmbracelet/soft-serve/ui/common"
)
// Viewport represents a viewport component.
type Viewport struct {
- Viewport *viewport.Model
-}
-
-func New() *Viewport {
+ common common.Common
+ *viewport.Model
+}
+
+// New returns a new Viewport.
+func New(c common.Common) *Viewport {
+ vp := viewport.New(c.Width, c.Height)
+ vp.MouseWheelEnabled = true
+ vp.KeyMap = viewport.KeyMap{
+ PageDown: key.NewBinding(
+ key.WithKeys("pgdown", " ", "f"),
+ key.WithHelp("f/pgdn", "page down"),
+ ),
+ PageUp: key.NewBinding(
+ key.WithKeys("pgup", "b"),
+ key.WithHelp("b/pgup", "page up"),
+ ),
+ HalfPageUp: key.NewBinding(
+ key.WithKeys("u", "ctrl+u"),
+ key.WithHelp("ctrl+u/u", "half page up"),
+ ),
+ HalfPageDown: key.NewBinding(
+ key.WithKeys("d", "ctrl+d"),
+ key.WithHelp("ctrl+d/d", "half page down"),
+ ),
+ Up: key.NewBinding(
+ key.WithKeys("up", "k"),
+ key.WithHelp("↑/k", "up"),
+ ),
+ Down: key.NewBinding(
+ key.WithKeys("down", "j"),
+ key.WithHelp("↓/j", "down"),
+ ),
+ }
return &Viewport{
- Viewport: &viewport.Model{
- MouseWheelEnabled: true,
- },
+ common: c,
+ Model: &vp,
}
}
// SetSize implements common.Component.
func (v *Viewport) SetSize(width, height int) {
- v.Viewport.Width = width
- v.Viewport.Height = height
+ v.common.SetSize(width, height)
+ v.Model.Width = width
+ v.Model.Height = height
}
// Init implements tea.Model.
@@ -31,62 +63,62 @@ func (v *Viewport) Init() tea.Cmd {
// Update implements tea.Model.
func (v *Viewport) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
- vp, cmd := v.Viewport.Update(msg)
- v.Viewport = &vp
+ vp, cmd := v.Model.Update(msg)
+ v.Model = &vp
return v, cmd
}
// View implements tea.Model.
func (v *Viewport) View() string {
- return v.Viewport.View()
+ return v.Model.View()
}
// SetContent sets the viewport's content.
func (v *Viewport) SetContent(content string) {
- v.Viewport.SetContent(content)
+ v.Model.SetContent(content)
}
// GotoTop moves the viewport to the top of the log.
func (v *Viewport) GotoTop() {
- v.Viewport.GotoTop()
+ v.Model.GotoTop()
}
// GotoBottom moves the viewport to the bottom of the log.
func (v *Viewport) GotoBottom() {
- v.Viewport.GotoBottom()
+ v.Model.GotoBottom()
}
// HalfViewDown moves the viewport down by half the viewport height.
func (v *Viewport) HalfViewDown() {
- v.Viewport.HalfViewDown()
+ v.Model.HalfViewDown()
}
// HalfViewUp moves the viewport up by half the viewport height.
func (v *Viewport) HalfViewUp() {
- v.Viewport.HalfViewUp()
+ v.Model.HalfViewUp()
}
// ViewUp moves the viewport up by a page.
func (v *Viewport) ViewUp() []string {
- return v.Viewport.ViewUp()
+ return v.Model.ViewUp()
}
// ViewDown moves the viewport down by a page.
func (v *Viewport) ViewDown() []string {
- return v.Viewport.ViewDown()
+ return v.Model.ViewDown()
}
// LineUp moves the viewport up by the given number of lines.
func (v *Viewport) LineUp(n int) []string {
- return v.Viewport.LineUp(n)
+ return v.Model.LineUp(n)
}
// LineDown moves the viewport down by the given number of lines.
func (v *Viewport) LineDown(n int) []string {
- return v.Viewport.LineDown(n)
+ return v.Model.LineDown(n)
}
// ScrollPercent returns the viewport's scroll percentage.
func (v *Viewport) ScrollPercent() float64 {
- return v.Viewport.ScrollPercent()
+ return v.Model.ScrollPercent()
}
@@ -15,6 +15,10 @@ type KeyMap struct {
Back key.Binding
PrevPage key.Binding
NextPage key.Binding
+ Help key.Binding
+
+ SelectItem key.Binding
+ BackItem key.Binding
}
// DefaultKeyMap returns the default key map.
@@ -152,5 +156,37 @@ func DefaultKeyMap() *KeyMap {
),
)
+ km.Help = key.NewBinding(
+ key.WithKeys(
+ "?",
+ ),
+ key.WithHelp(
+ "?",
+ "toggle help",
+ ),
+ )
+
+ km.SelectItem = key.NewBinding(
+ key.WithKeys(
+ "l",
+ "right",
+ ),
+ key.WithHelp(
+ "→",
+ "select",
+ ),
+ )
+
+ km.BackItem = key.NewBinding(
+ key.WithKeys(
+ "h",
+ "left",
+ ),
+ key.WithHelp(
+ "←",
+ "back",
+ ),
+ )
+
return km
}
@@ -6,6 +6,7 @@ import (
"log"
"path/filepath"
+ "github.com/charmbracelet/bubbles/key"
tea "github.com/charmbracelet/bubbletea"
ggit "github.com/charmbracelet/soft-serve/git"
"github.com/charmbracelet/soft-serve/ui/common"
@@ -80,6 +81,75 @@ func (f *Files) SetSize(width, height int) {
f.code.SetSize(width, height)
}
+// ShortHelp implements help.KeyMap.
+func (f *Files) ShortHelp() []key.Binding {
+ k := f.selector.KeyMap
+ switch f.activeView {
+ case filesViewFiles:
+ return []key.Binding{
+ f.common.KeyMap.SelectItem,
+ f.common.KeyMap.BackItem,
+ k.CursorUp,
+ k.CursorDown,
+ }
+ case filesViewContent:
+ return []key.Binding{
+ f.common.KeyMap.UpDown,
+ f.common.KeyMap.BackItem,
+ }
+ default:
+ return []key.Binding{}
+ }
+}
+
+// FullHelp implements help.KeyMap.
+func (f *Files) FullHelp() [][]key.Binding {
+ b := make([][]key.Binding, 0)
+ switch f.activeView {
+ case filesViewFiles:
+ k := f.selector.KeyMap
+ b = append(b, []key.Binding{
+ f.common.KeyMap.SelectItem,
+ f.common.KeyMap.BackItem,
+ })
+ b = append(b, [][]key.Binding{
+ {},
+ {
+ k.CursorUp,
+ k.CursorDown,
+ },
+ {
+ k.NextPage,
+ k.PrevPage,
+ },
+ {
+ k.GoToStart,
+ k.GoToEnd,
+ },
+ }...)
+ case filesViewContent:
+ k := f.code.KeyMap
+ b = append(b, []key.Binding{
+ f.common.KeyMap.BackItem,
+ })
+ b = append(b, [][]key.Binding{
+ {
+ k.PageDown,
+ k.PageUp,
+ },
+ {
+ k.HalfPageDown,
+ k.HalfPageUp,
+ },
+ {
+ k.Down,
+ k.Up,
+ },
+ }...)
+ }
+ return b
+}
+
// Init implements tea.Model.
func (f *Files) Init() tea.Cmd {
f.path = ""
@@ -57,7 +57,7 @@ type Log struct {
func NewLog(common common.Common) *Log {
l := &Log{
common: common,
- vp: viewport.New(),
+ vp: viewport.New(common),
activeView: logViewCommits,
}
selector := selector.New(common, []selector.IdentifiableItem{}, LogItemDelegate{common.Styles})
@@ -81,43 +81,68 @@ func (l *Log) SetSize(width, height int) {
l.vp.SetSize(width, height)
}
-// ShortHelp implements key.KeyMap.
+// ShortHelp implements help.KeyMap.
func (l *Log) ShortHelp() []key.Binding {
switch l.activeView {
case logViewCommits:
return []key.Binding{
- key.NewBinding(
- key.WithKeys(
- "l",
- "right",
- ),
- key.WithHelp(
- "→",
- "select",
- ),
- ),
+ l.common.KeyMap.SelectItem,
}
case logViewDiff:
return []key.Binding{
l.common.KeyMap.UpDown,
- key.NewBinding(
- key.WithKeys(
- "h",
- "left",
- ),
- key.WithHelp(
- "←",
- "back",
- ),
- ),
+ l.common.KeyMap.BackItem,
}
default:
return []key.Binding{}
}
}
-func (l Log) FullHelp() [][]key.Binding {
- return [][]key.Binding{}
+// FullHelp implements help.KeyMap.
+func (l *Log) FullHelp() [][]key.Binding {
+ k := l.selector.KeyMap
+ b := make([][]key.Binding, 0)
+ switch l.activeView {
+ case logViewCommits:
+ b = append(b, []key.Binding{
+ l.common.KeyMap.SelectItem,
+ l.common.KeyMap.BackItem,
+ })
+ b = append(b, [][]key.Binding{
+ {
+ k.CursorUp,
+ k.CursorDown,
+ },
+ {
+ k.NextPage,
+ k.PrevPage,
+ },
+ {
+ k.GoToStart,
+ k.GoToEnd,
+ },
+ }...)
+ case logViewDiff:
+ k := l.vp.KeyMap
+ b = append(b, []key.Binding{
+ l.common.KeyMap.BackItem,
+ })
+ b = append(b, [][]key.Binding{
+ {
+ k.PageDown,
+ k.PageUp,
+ },
+ {
+ k.HalfPageDown,
+ k.HalfPageUp,
+ },
+ {
+ k.Down,
+ k.Up,
+ },
+ }...)
+ }
+ return b
}
// Init implements tea.Model.
@@ -147,7 +172,10 @@ func (l *Log) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
cmds = append(cmds, l.selector.SetItems(msg))
l.selector.SetPage(l.nextPage)
l.SetSize(l.common.Width, l.common.Height)
- l.activeCommit = l.selector.SelectedItem().(LogItem).Commit
+ i := l.selector.SelectedItem()
+ if i != nil {
+ l.activeCommit = i.(LogItem).Commit
+ }
case tea.KeyMsg, tea.MouseMsg:
switch l.activeView {
case logViewCommits:
@@ -4,6 +4,7 @@ import (
"sort"
"strings"
+ "github.com/charmbracelet/bubbles/key"
tea "github.com/charmbracelet/bubbletea"
ggit "github.com/charmbracelet/soft-serve/git"
"github.com/charmbracelet/soft-serve/ui/common"
@@ -12,11 +13,13 @@ import (
"github.com/charmbracelet/soft-serve/ui/git"
)
+// RefItemsMsg is a message that contains a list of RefItem.
type RefItemsMsg struct {
prefix string
items []selector.IdentifiableItem
}
+// Refs is a component that displays a list of references.
type Refs struct {
common common.Common
selector *selector.Selector
@@ -26,6 +29,7 @@ type Refs struct {
refPrefix string
}
+// NewRefs creates a new Refs component.
func NewRefs(common common.Common, refPrefix string) *Refs {
r := &Refs{
common: common,
@@ -43,15 +47,48 @@ func NewRefs(common common.Common, refPrefix string) *Refs {
return r
}
+// SetSize implements common.Component.
func (r *Refs) SetSize(width, height int) {
r.common.SetSize(width, height)
r.selector.SetSize(width, height)
}
+// ShortHelp implements help.KeyMap.
+func (r *Refs) ShortHelp() []key.Binding {
+ k := r.selector.KeyMap
+ return []key.Binding{
+ r.common.KeyMap.SelectItem,
+ k.CursorUp,
+ k.CursorDown,
+ }
+}
+
+// FullHelp implements help.KeyMap.
+func (r *Refs) FullHelp() [][]key.Binding {
+ k := r.selector.KeyMap
+ return [][]key.Binding{
+ {r.common.KeyMap.SelectItem},
+ {
+ k.CursorUp,
+ k.CursorDown,
+ },
+ {
+ k.NextPage,
+ k.PrevPage,
+ },
+ {
+ k.GoToStart,
+ k.GoToEnd,
+ },
+ }
+}
+
+// Init implements tea.Model.
func (r *Refs) Init() tea.Cmd {
return r.updateItemsCmd
}
+// Update implements tea.Model.
func (r *Refs) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
cmds := make([]tea.Cmd, 0)
switch msg := msg.(type) {
@@ -64,7 +101,10 @@ func (r *Refs) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
cmds = append(cmds, r.Init())
case RefItemsMsg:
cmds = append(cmds, r.selector.SetItems(msg.items))
- r.activeRef = r.selector.SelectedItem().(RefItem).Reference
+ i := r.selector.SelectedItem()
+ if i != nil {
+ r.activeRef = i.(RefItem).Reference
+ }
case selector.ActiveMsg:
switch sel := msg.IdentifiableItem.(type) {
case RefItem:
@@ -93,10 +133,12 @@ func (r *Refs) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
return r, tea.Batch(cmds...)
}
+// View implements tea.Model.
func (r *Refs) View() string {
return r.selector.View()
}
+// StausBarValue implements statusbar.StatusBar.
func (r *Refs) StatusBarValue() string {
if r.activeRef == nil {
return ""
@@ -104,6 +146,7 @@ func (r *Refs) StatusBarValue() string {
return r.activeRef.Name().String()
}
+// StatusBarInfo implements statusbar.StatusBar.
func (r *Refs) StatusBarInfo() string {
return ""
}
@@ -92,19 +92,24 @@ func (r *Repo) SetSize(width, height int) {
}
}
-// ShortHelp implements help.KeyMap.
-func (r *Repo) ShortHelp() []key.Binding {
+func (r *Repo) commonHelp() []key.Binding {
b := make([]key.Binding, 0)
+ back := r.common.KeyMap.Back
+ back.SetHelp("esc", "back to menu")
tab := r.common.KeyMap.Section
tab.SetHelp("tab", "switch tab")
- back := r.common.KeyMap.Back
- back.SetHelp("esc", "repos")
b = append(b, back)
b = append(b, tab)
+ return b
+}
+
+// ShortHelp implements help.KeyMap.
+func (r *Repo) ShortHelp() []key.Binding {
+ b := r.commonHelp()
switch r.activeTab {
case readmeTab:
b = append(b, r.common.KeyMap.UpDown)
- case commitsTab:
+ default:
b = append(b, r.boxes[commitsTab].(help.KeyMap).ShortHelp()...)
}
return b
@@ -113,6 +118,27 @@ func (r *Repo) ShortHelp() []key.Binding {
// FullHelp implements help.KeyMap.
func (r *Repo) FullHelp() [][]key.Binding {
b := make([][]key.Binding, 0)
+ b = append(b, r.commonHelp())
+ switch r.activeTab {
+ case readmeTab:
+ k := r.boxes[readmeTab].(*code.Code).KeyMap
+ b = append(b, [][]key.Binding{
+ {
+ k.PageDown,
+ k.PageUp,
+ },
+ {
+ k.HalfPageDown,
+ k.HalfPageUp,
+ },
+ {
+ k.Down,
+ k.Up,
+ },
+ }...)
+ default:
+ b = append(b, r.boxes[r.activeTab].(help.KeyMap).FullHelp()...)
+ }
return b
}
@@ -62,7 +62,7 @@ func (s *Selection) SetSize(width, height int) {
// +1 to get wrapping to work.
// This is needed because the readme box width has to be -1 from the
// readme style in order for wrapping to not break.
- 2
+ 1
hm := s.common.Styles.ReadmeBox.GetVerticalFrameSize()
s.readme.SetSize(width-wm, height-hm)
s.selector.SetSize(sw, height)
@@ -87,30 +87,51 @@ func (s *Selection) ShortHelp() []key.Binding {
}
// FullHelp implements help.KeyMap.
-// TODO implement full help on ?
func (s *Selection) FullHelp() [][]key.Binding {
- k := s.selector.KeyMap
- return [][]key.Binding{
- {
- k.CursorUp,
- k.CursorDown,
- k.NextPage,
- k.PrevPage,
- k.GoToStart,
- k.GoToEnd,
- },
- {
- k.Filter,
- k.ClearFilter,
- k.CancelWhileFiltering,
- k.AcceptWhileFiltering,
- k.ShowFullHelp,
- k.CloseFullHelp,
- },
- // Ignore the following keys:
- // k.Quit,
- // k.ForceQuit,
+ switch s.activeBox {
+ case readmeBox:
+ k := s.readme.KeyMap
+ return [][]key.Binding{
+ {
+ k.PageDown,
+ k.PageUp,
+ },
+ {
+ k.HalfPageDown,
+ k.HalfPageUp,
+ },
+ {
+ k.Down,
+ k.Up,
+ },
+ }
+ case selectorBox:
+ k := s.selector.KeyMap
+ return [][]key.Binding{
+ {
+ s.common.KeyMap.Select,
+ },
+ {
+ k.CursorUp,
+ k.CursorDown,
+ },
+ {
+ k.NextPage,
+ k.PrevPage,
+ },
+ {
+ k.GoToStart,
+ k.GoToEnd,
+ },
+ {
+ k.Filter,
+ k.ClearFilter,
+ k.CancelWhileFiltering,
+ k.AcceptWhileFiltering,
+ },
+ }
}
+ return [][]key.Binding{}
}
// Init implements tea.Model.
@@ -2,7 +2,6 @@ package ui
import (
"log"
- "strings"
"github.com/charmbracelet/bubbles/key"
tea "github.com/charmbracelet/bubbletea"
@@ -57,7 +56,7 @@ func (ui *UI) getMargins() (wm, hm int) {
wm = ui.common.Styles.App.GetHorizontalFrameSize()
hm = ui.common.Styles.App.GetVerticalFrameSize() +
ui.common.Styles.Header.GetHeight() +
- ui.common.Styles.Footer.GetHeight()
+ ui.footer.Height()
return
}
@@ -70,7 +69,10 @@ func (ui *UI) ShortHelp() []key.Binding {
case loadedState:
b = append(b, ui.pages[ui.activePage].ShortHelp()...)
}
- b = append(b, ui.common.KeyMap.Quit)
+ b = append(b,
+ ui.common.KeyMap.Quit,
+ ui.common.KeyMap.Help,
+ )
return b
}
@@ -83,7 +85,10 @@ func (ui *UI) FullHelp() [][]key.Binding {
case loadedState:
b = append(b, ui.pages[ui.activePage].FullHelp()...)
}
- b = append(b, []key.Binding{ui.common.KeyMap.Quit})
+ b = append(b, []key.Binding{
+ ui.common.KeyMap.Quit,
+ ui.common.KeyMap.Help,
+ })
return b
}
@@ -114,7 +119,6 @@ func (ui *UI) Init() tea.Cmd {
}
// Update implements tea.Model.
-// TODO show full help.
func (ui *UI) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
log.Printf("msg: %T", msg)
cmds := make([]tea.Cmd, 0)
@@ -128,15 +132,20 @@ func (ui *UI) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
cmds = append(cmds, cmd)
}
}
- case tea.KeyMsg:
- switch {
- case key.Matches(msg, ui.common.KeyMap.Back) && ui.error != nil:
- ui.error = nil
- ui.state = loadedState
- case key.Matches(msg, ui.common.KeyMap.Quit):
- return ui, tea.Quit
- case ui.activePage == 1 && key.Matches(msg, ui.common.KeyMap.Back):
- ui.activePage = 0
+ case tea.KeyMsg, tea.MouseMsg:
+ switch msg := msg.(type) {
+ case tea.KeyMsg:
+ switch {
+ case key.Matches(msg, ui.common.KeyMap.Back) && ui.error != nil:
+ ui.error = nil
+ ui.state = loadedState
+ case key.Matches(msg, ui.common.KeyMap.Help):
+ ui.footer.SetShowAll(!ui.footer.ShowAll())
+ case key.Matches(msg, ui.common.KeyMap.Quit):
+ return ui, tea.Quit
+ case ui.activePage == 1 && key.Matches(msg, ui.common.KeyMap.Back):
+ ui.activePage = 0
+ }
}
case common.ErrorMsg:
ui.error = msg
@@ -168,43 +177,45 @@ func (ui *UI) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
cmds = append(cmds, cmd)
}
}
+ // This fixes determining the height margin of the footer.
+ ui.SetSize(ui.common.Width, ui.common.Height)
return ui, tea.Batch(cmds...)
}
// View implements tea.Model.
func (ui *UI) View() string {
- s := strings.Builder{}
+ var view string
+ footer := ui.footer.View()
+ style := ui.common.Styles.App.Copy()
switch ui.state {
case startState:
- s.WriteString("Loading...")
+ view = "Loading..."
case errorState:
err := ui.common.Styles.ErrorTitle.Render("Bummer")
err += ui.common.Styles.ErrorBody.Render(ui.error.Error())
- view := ui.common.Styles.ErrorBody.Copy().
+ view = ui.common.Styles.ErrorBody.Copy().
Width(ui.common.Width -
- ui.common.Styles.App.GetHorizontalFrameSize() -
+ style.GetWidth() -
+ style.GetHorizontalFrameSize() -
ui.common.Styles.ErrorBody.GetHorizontalFrameSize()).
Height(ui.common.Height -
- ui.common.Styles.App.GetVerticalFrameSize() -
+ style.GetHeight() -
+ style.GetVerticalFrameSize() -
ui.common.Styles.Header.GetVerticalFrameSize() - 2).
Render(err)
- s.WriteString(lipgloss.JoinVertical(
- lipgloss.Bottom,
- ui.header.View(),
- view,
- ui.footer.View(),
- ))
case loadedState:
- s.WriteString(lipgloss.JoinVertical(
- lipgloss.Bottom,
- ui.header.View(),
- ui.pages[ui.activePage].View(),
- ui.footer.View(),
- ))
+ view = ui.pages[ui.activePage].View()
default:
- s.WriteString("Unknown state :/ this is a bug!")
+ view = "Unknown state :/ this is a bug!"
}
- return ui.common.Styles.App.Render(s.String())
+ return style.Render(
+ lipgloss.JoinVertical(
+ lipgloss.Bottom,
+ ui.header.View(),
+ view,
+ footer,
+ ),
+ )
}
func (ui *UI) setRepoCmd(rn string) tea.Cmd {