Stash documents from the stash view

This commit is contained in:
Christian Rocha 2020-08-21 13:39:59 -04:00 committed by Christian Muehlhaeuser
commit 04b6089bd9
3 changed files with 106 additions and 45 deletions

View file

@ -65,7 +65,6 @@ func newStyle(fg, bg string) func(string) string {
type contentRenderedMsg string
type noteSavedMsg *charm.Markdown
type statusMessageTimeoutMsg struct{}
type stashSuccessMsg markdown
type stashErrMsg struct {
err error
@ -228,19 +227,7 @@ func pagerUpdate(msg tea.Msg, m pagerModel) (pagerModel, tea.Cmd) {
// Stash a local document
if m.state != pagerStateStashing && m.currentDocument.markdownType == localMarkdown {
m.state = pagerStateStashing
// Create new markdown based on loaded markdown
md := m.currentDocument
md.markdownType = stashedMarkdown
t := time.Now()
md.CreatedAt = t
// Set the note as the filename without the extension
p := md.localPath
md.Note = strings.Replace(path.Base(p), path.Ext(p), "", 1)
md.localPath = ""
return m, stashDocument(m.cc, md)
return m, stashDocument(m.cc, m.currentDocument)
}
case "?":
m.toggleHelp()
@ -278,8 +265,11 @@ func pagerUpdate(msg tea.Msg, m pagerModel) (pagerModel, tea.Cmd) {
m.state = pagerStateStatusMessage
m.statusMessageHeader = "Stashed!"
m.statusMessageBody = ""
if m.statusMessageTimer != nil {
m.statusMessageTimer.Stop()
}
m.statusMessageTimer = time.NewTimer(time.Second * 3)
cmds = append(cmds, waitForStatusMessageTimeout(m.statusMessageTimer))
cmds = append(cmds, waitForStatusMessageTimeout(pagerContext, m.statusMessageTimer))
case stashErrMsg:
// TODO
@ -474,6 +464,16 @@ func stashDocument(cc *charm.Client, md markdown) tea.Cmd {
return stashErrMsg{err}
}
}
// Turn local markdown into a stashed markdown
md.markdownType = stashedMarkdown
md.CreatedAt = time.Now()
// Set the note as the filename without the extension
p := md.localPath
md.Note = strings.Replace(path.Base(p), path.Ext(p), "", 1)
md.localPath = ""
return func() tea.Msg {
err := cc.StashMarkdown(md.Note, md.Body)
if err != nil {
@ -486,13 +486,6 @@ func stashDocument(cc *charm.Client, md markdown) tea.Cmd {
}
}
func waitForStatusMessageTimeout(t *time.Timer) tea.Cmd {
return func() tea.Msg {
<-t.C
return statusMessageTimeoutMsg{}
}
}
// This is where the magic happens
func glamourRender(m pagerModel, markdown string) (string, error) {

View file

@ -142,6 +142,10 @@ type stashModel struct {
// than we can display at a time so we can paginate locally without having
// to fetch every time.
page int
showStatusMessage bool
statusMessage string
statusMessageTimer *time.Timer
}
func (m *stashModel) setSize(width, height int) {
@ -197,6 +201,13 @@ func (m stashModel) countMarkdowns(t markdownType) (found int) {
return
}
func (m *stashModel) hideStatusMessage() {
m.showStatusMessage = false
if m.statusMessageTimer != nil {
m.statusMessageTimer.Stop()
}
}
// INIT
func newStashModel() stashModel {
@ -289,13 +300,33 @@ func stashUpdate(msg tea.Msg, m stashModel) (stashModel, tea.Cmd) {
m.markdowns[i].Note = msg.Note
}
}
// Something was stashed. Add it to the stash listing.
case stashSuccessMsg:
md := markdown(msg)
m.addMarkdowns(&md)
m.showStatusMessage = true
m.statusMessage = "Stashed!"
if m.statusMessageTimer != nil {
m.statusMessageTimer.Stop()
}
m.statusMessageTimer = time.NewTimer(time.Second * 3)
cmds = append(cmds, waitForStatusMessageTimeout(stashContext, m.statusMessageTimer))
case statusMessageTimeoutMsg:
if applicationContext(msg) == stashContext {
m.hideStatusMessage()
}
}
switch m.state {
case stashStateReady:
switch msg := msg.(type) {
// Handle keys
if msg, ok := msg.(tea.KeyMsg); ok {
case tea.KeyMsg:
switch msg.String() {
case "k", "up":
@ -323,6 +354,8 @@ func stashUpdate(msg tea.Msg, m stashModel) (stashModel, tea.Cmd) {
// Open document
case "enter":
m.hideStatusMessage()
if len(m.markdowns) == 0 {
break
}
@ -342,6 +375,8 @@ func stashUpdate(msg tea.Msg, m stashModel) (stashModel, tea.Cmd) {
// Set note
case "m":
m.hideStatusMessage()
md := m.selectedMarkdown()
isUserMarkdown := md.markdownType == stashedMarkdown
isSettingNote := m.state == stashStateSettingNote
@ -354,8 +389,17 @@ func stashUpdate(msg tea.Msg, m stashModel) (stashModel, tea.Cmd) {
return m, textinput.Blink(m.noteInput)
}
// Stash
case "s":
md := m.selectedMarkdown()
if md != nil && md.markdownType == localMarkdown {
cmds = append(cmds, stashDocument(m.cc, *md))
}
// Prompt for deletion
case "x":
m.hideStatusMessage()
isUserMarkdown := m.selectedMarkdown().markdownType == stashedMarkdown
isValidState := m.state != stashStateSettingNote
@ -500,11 +544,15 @@ func stashView(m stashModel) string {
}
var header string
switch m.state {
case stashStatePromptDelete:
header = redFg("Delete this item? ") + faintRedFg("(y/N)")
case stashStateSettingNote:
header = yellowFg("Set the memo for this item?")
if m.showStatusMessage {
header = greenFg(m.statusMessage)
} else {
switch m.state {
case stashStatePromptDelete:
header = redFg("Delete this item? ") + faintRedFg("(y/N)")
case stashStateSettingNote:
header = yellowFg("Set the memo for this item?")
}
}
// Only draw the normal header if we're not using the header area for
@ -619,11 +667,13 @@ func stashHelpView(m stashModel) string {
var (
h []string
isStashed bool
isLocal bool
)
if len(m.markdowns) > 0 {
md := m.selectedMarkdown()
isStashed = md != nil && md.markdownType == stashedMarkdown
isLocal = md != nil && md.markdownType == localMarkdown
}
if m.state == stashStateSettingNote {
@ -640,13 +690,15 @@ func stashHelpView(m stashModel) string {
if m.paginator.TotalPages > 1 {
h = append(h, "h/l, ←/→: page")
}
if isStashed && len(m.markdowns) > 0 {
if isStashed {
h = append(h, []string{"x: delete", "m: set memo"}...)
} else if isLocal {
h = append(h, "s: stash")
}
if m.err != nil {
h = append(h, []string{"!: errors"}...)
h = append(h, "!: errors")
}
h = append(h, []string{"q: quit"}...)
h = append(h, "q: quit")
}
return stashHelpViewBuilder(m.terminalWidth, h...)
}

View file

@ -6,6 +6,7 @@ import (
"log"
"os"
"strings"
"time"
"github.com/charmbracelet/bubbles/spinner"
tea "github.com/charmbracelet/bubbletea"
@ -52,13 +53,9 @@ func NewProgram(style string, cfg Config) *tea.Program {
type errMsg error
type newCharmClientMsg *charm.Client
type sshAuthErrMsg struct{}
type keygenFailedMsg struct {
err error
}
type keygenFailedMsg struct{ err error }
func (k keygenFailedMsg) Error() string {
return k.err.Error()
}
func (k keygenFailedMsg) Error() string { return k.err.Error() }
type keygenSuccessMsg struct{}
type initLocalFileSearchMsg struct {
@ -70,19 +67,26 @@ type localFileSearchFinished struct{}
type gotStashMsg []*charm.Markdown
type stashLoadErrMsg struct{ err error }
func (s stashLoadErrMsg) Error() string {
return s.err.Error()
}
func (s stashLoadErrMsg) Error() string { return s.err.Error() }
type gotNewsMsg []*charm.Markdown
type newsLoadErrMsg struct{ err error }
func (s newsLoadErrMsg) Error() string {
return s.err.Error()
}
func (s newsLoadErrMsg) Error() string { return s.err.Error() }
type statusMessageTimeoutMsg applicationContext
// MODEL
// Which part of the application something appies to. Occasionally used as an
// arguments to command and messages.
type applicationContext int
const (
stashContext applicationContext = iota
pagerContext
)
type state int
const (
@ -335,8 +339,13 @@ func update(msg tea.Msg, mdl tea.Model) (tea.Model, tea.Cmd) {
// Something was stashed. Update the stash listing. We're caching this
// here, rather than in the stash update function, because stashing
// may have occurred in the pager.
md := markdown(msg)
m.stash.addMarkdowns(&md)
if m.state == stateShowDocument {
newStashModel, cmd := stashUpdate(msg, m.stash)
m.stash = newStashModel
if cmd != nil {
cmds = append(cmds, cmd)
}
}
}
// Process children
@ -497,6 +506,13 @@ func generateSSHKeys() tea.Msg {
return keygenSuccessMsg{}
}
func waitForStatusMessageTimeout(appCtx applicationContext, t *time.Timer) tea.Cmd {
return func() tea.Msg {
<-t.C
return statusMessageTimeoutMsg(appCtx)
}
}
// ETC
// Convert local file path to Markdown. Note that we could be doing things