mirror of
https://github.com/charmbracelet/glow
synced 2024-11-10 14:14:17 +00:00
Properly render one page of the stash
This commit is contained in:
parent
c7e584c68e
commit
d2e2da70e2
2 changed files with 85 additions and 22 deletions
92
ui/stash.go
92
ui/stash.go
|
@ -7,6 +7,7 @@ import (
|
|||
"strings"
|
||||
|
||||
"github.com/charmbracelet/boba"
|
||||
"github.com/charmbracelet/boba/paginator"
|
||||
"github.com/charmbracelet/boba/spinner"
|
||||
"github.com/charmbracelet/charm"
|
||||
"github.com/charmbracelet/charm/ui/common"
|
||||
|
@ -14,6 +15,12 @@ import (
|
|||
te "github.com/muesli/termenv"
|
||||
)
|
||||
|
||||
const (
|
||||
itemHeight = 3
|
||||
topPadding = 3
|
||||
bottomPadding = 2
|
||||
)
|
||||
|
||||
// MSG
|
||||
|
||||
type stashErrMsg error
|
||||
|
@ -32,13 +39,33 @@ const (
|
|||
)
|
||||
|
||||
type stashModel struct {
|
||||
cc *charm.Client
|
||||
err error
|
||||
state stashState
|
||||
documents []*charm.Markdown
|
||||
page int
|
||||
spinner spinner.Model
|
||||
index int
|
||||
cc *charm.Client
|
||||
err error
|
||||
state stashState
|
||||
documents []*charm.Markdown
|
||||
spinner spinner.Model
|
||||
index int
|
||||
terminalWidth int
|
||||
terminalHeight int
|
||||
|
||||
// This handles the local pagination, which is different than the page
|
||||
// we're fetching from on the server side
|
||||
paginator paginator.Model
|
||||
|
||||
// Page we're fetching items from on the server, which is different from
|
||||
// the local pagination. Generally, the server will return more items than
|
||||
// we can display at a time so we can paginate locally without having to
|
||||
// fetch every time.
|
||||
page int
|
||||
}
|
||||
|
||||
func (m *stashModel) SetSize(width, height int) {
|
||||
m.terminalWidth = width
|
||||
m.terminalHeight = height
|
||||
|
||||
// Update the paginator
|
||||
perPage := (m.terminalHeight - topPadding - bottomPadding) / itemHeight
|
||||
m.paginator.PerPage = perPage
|
||||
}
|
||||
|
||||
// INIT
|
||||
|
@ -47,12 +74,13 @@ func stashInit(cc *charm.Client) (stashModel, boba.Cmd) {
|
|||
s := spinner.NewModel()
|
||||
s.Type = spinner.Dot
|
||||
s.ForegroundColor = common.SpinnerColor
|
||||
s.CustomMsgFunc = newSpinnerTickMsg
|
||||
s.CustomMsgFunc = func() boba.Msg { return stashSpinnerTickMsg{} }
|
||||
|
||||
m := stashModel{
|
||||
cc: cc,
|
||||
spinner: s,
|
||||
page: 1,
|
||||
cc: cc,
|
||||
spinner: s,
|
||||
page: 1,
|
||||
paginator: paginator.NewModel(),
|
||||
}
|
||||
|
||||
return m, boba.Batch(
|
||||
|
@ -60,9 +88,6 @@ func stashInit(cc *charm.Client) (stashModel, boba.Cmd) {
|
|||
spinner.Tick(s),
|
||||
)
|
||||
}
|
||||
func newSpinnerTickMsg() boba.Msg {
|
||||
return stashSpinnerTickMsg{}
|
||||
}
|
||||
|
||||
// UPDATE
|
||||
|
||||
|
@ -70,6 +95,11 @@ func stashUpdate(msg boba.Msg, m stashModel) (stashModel, boba.Cmd) {
|
|||
switch msg := msg.(type) {
|
||||
|
||||
case boba.KeyMsg:
|
||||
// Don't respond to keystrokes if we're still loading
|
||||
if m.state == stashStateInit {
|
||||
return m, nil
|
||||
}
|
||||
|
||||
switch msg.String() {
|
||||
|
||||
case "k":
|
||||
|
@ -99,8 +129,9 @@ func stashUpdate(msg boba.Msg, m stashModel) (stashModel, boba.Cmd) {
|
|||
|
||||
case gotStashMsg:
|
||||
sort.Sort(charm.MarkdownsByCreatedAt(msg)) // sort by date
|
||||
m.documents = msg
|
||||
m.documents = append(m.documents, msg...)
|
||||
m.state = stashStateLoaded
|
||||
m.paginator.SetTotalPages(len(m.documents))
|
||||
return m, nil
|
||||
|
||||
case stashSpinnerTickMsg:
|
||||
|
@ -128,7 +159,16 @@ func stashView(m stashModel) string {
|
|||
s += stashEmtpyView(m)
|
||||
break
|
||||
}
|
||||
s += stashPopulatedView(m)
|
||||
|
||||
// Blank lines we'll need to fill with newlines fo the viewport is
|
||||
// properly filled
|
||||
numBlankLines := (m.terminalHeight - topPadding - bottomPadding) % itemHeight
|
||||
blankLines := ""
|
||||
if numBlankLines > 0 {
|
||||
blankLines = strings.Repeat("\n", numBlankLines)
|
||||
}
|
||||
|
||||
s += stashPopulatedView(m) + blankLines + helpView(m)
|
||||
}
|
||||
return "\n" + indent.String(s, 2)
|
||||
}
|
||||
|
@ -138,16 +178,30 @@ func stashEmtpyView(m stashModel) string {
|
|||
}
|
||||
|
||||
func stashPopulatedView(m stashModel) string {
|
||||
start, end := m.paginator.GetSliceBounds(len(m.documents))
|
||||
docs := m.documents[start:end]
|
||||
|
||||
s := "Here's your markdown stash:\n\n"
|
||||
for i, v := range m.documents {
|
||||
for i, v := range docs {
|
||||
state := common.StateNormal
|
||||
if i == m.index {
|
||||
state = common.StateSelected
|
||||
}
|
||||
s += stashListItemView(*v).render(state) + "\n\n"
|
||||
}
|
||||
s = strings.TrimSpace(s)
|
||||
return s
|
||||
return strings.TrimSpace(s)
|
||||
}
|
||||
|
||||
func helpView(m stashModel) string {
|
||||
h := []string{"enter: open"}
|
||||
if len(m.documents) > 0 {
|
||||
h = append(h, "j/k, ↑/↓: choose")
|
||||
}
|
||||
if m.paginator.TotalPages > 1 {
|
||||
h = append(h, "h/l, ←/→: page")
|
||||
}
|
||||
h = append(h, []string{"x: delete", "esc: exit"}...)
|
||||
return common.HelpView(h...)
|
||||
}
|
||||
|
||||
type stashListItemView charm.Markdown
|
||||
|
|
15
ui/ui.go
15
ui/ui.go
|
@ -98,9 +98,7 @@ func initialize() (boba.Model, boba.Cmd) {
|
|||
}, boba.Batch(
|
||||
newCharmClient,
|
||||
spinner.Tick(s),
|
||||
boba.GetTerminalSize(func(w, h int, err error) boba.TerminalSizeMsg {
|
||||
return terminalSizeMsg{width: w, height: h, err: err}
|
||||
}),
|
||||
getTerminalSize(),
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -130,6 +128,10 @@ func update(msg boba.Msg, mdl boba.Model) (boba.Model, boba.Cmd) {
|
|||
|
||||
case "ctrl+c":
|
||||
return m, boba.Quit
|
||||
|
||||
// Re-render
|
||||
case "ctrl+l":
|
||||
return m, getTerminalSize()
|
||||
}
|
||||
|
||||
case fatalErrMsg:
|
||||
|
@ -148,6 +150,7 @@ func update(msg boba.Msg, mdl boba.Model) (boba.Model, boba.Cmd) {
|
|||
w, h := msg.Size()
|
||||
m.terminalWidth = w
|
||||
m.terminalHeight = h
|
||||
m.stash.SetSize(w, h)
|
||||
return m, nil
|
||||
|
||||
case sshAuthErrMsg:
|
||||
|
@ -183,6 +186,7 @@ func update(msg boba.Msg, mdl boba.Model) (boba.Model, boba.Cmd) {
|
|||
m.cc = msg
|
||||
m.state = stateShowStash
|
||||
m.stash, cmd = stashInit(m.cc)
|
||||
m.stash.SetSize(m.terminalWidth, m.terminalHeight)
|
||||
return m, cmd
|
||||
|
||||
case gotStashedItemMsg:
|
||||
|
@ -293,6 +297,11 @@ func statusBarView(m model) string {
|
|||
}
|
||||
|
||||
// COMMANDS
|
||||
func getTerminalSize() boba.Cmd {
|
||||
return boba.GetTerminalSize(func(w, h int, err error) boba.TerminalSizeMsg {
|
||||
return terminalSizeMsg{width: w, height: h, err: err}
|
||||
})
|
||||
}
|
||||
|
||||
func newCharmClient() boba.Msg {
|
||||
cfg, err := charm.ConfigFromEnv()
|
||||
|
|
Loading…
Reference in a new issue