Make stash note editing and deletion independent of main state

This commit is contained in:
Christian Rocha 2020-11-25 22:49:49 -05:00
parent 15494e99b4
commit 7fabcea06d
3 changed files with 46 additions and 35 deletions

View file

@ -43,13 +43,11 @@ type filteredMarkdownMsg []*markdown
// MODEL // MODEL
type stashState int type stashViewState int
const ( const (
stashStateReady stashState = iota stashStateReady stashViewState = iota
stashStatePromptDelete
stashStateLoadingDocument stashStateLoadingDocument
stashStateSettingNote
stashStateShowingError stashStateShowingError
stashStateShowNews stashStateShowNews
) )
@ -62,10 +60,19 @@ const (
filterApplied // a filter is applied and user is not editing filter filterApplied // a filter is applied and user is not editing filter
) )
type selectionState int
const (
selectionIdle = iota
selectionSettingNote
selectionPromptingDelete
)
type stashModel struct { type stashModel struct {
general *general general *general
state stashState state stashViewState
filterState filterState filterState filterState
selectionState selectionState
err error err error
spinner spinner.Model spinner spinner.Model
noteInput textinput.Model noteInput textinput.Model
@ -153,7 +160,7 @@ func (m stashModel) isFiltering() bool {
func (m stashModel) shouldUpdateFilter() bool { func (m stashModel) shouldUpdateFilter() bool {
// If we're in the middle of setting a note don't update the filter so that // If we're in the middle of setting a note don't update the filter so that
// the focus won't jump around. // the focus won't jump around.
return m.isFiltering() && m.state != stashStateSettingNote return m.isFiltering() && m.selectionState != selectionSettingNote
} }
// Sets the total paginator pages according to the amount of markdowns for the // Sets the total paginator pages according to the amount of markdowns for the
@ -518,14 +525,19 @@ func (m stashModel) update(msg tea.Msg) (stashModel, tea.Cmd) {
return m, tea.Batch(cmds...) return m, tea.Batch(cmds...)
} }
switch m.selectionState {
case selectionSettingNote:
cmds = append(cmds, m.handleNoteInput(msg))
return m, tea.Batch(cmds...)
case selectionPromptingDelete:
cmds = append(cmds, m.handleDeleteConfirmation(msg))
return m, tea.Batch(cmds...)
}
// Updates per the current state // Updates per the current state
switch m.state { switch m.state {
case stashStateReady, stashStateShowNews: case stashStateReady, stashStateShowNews:
cmds = append(cmds, m.handleDocumentBrowsing(msg)) cmds = append(cmds, m.handleDocumentBrowsing(msg))
case stashStatePromptDelete:
cmds = append(cmds, m.handleDeleteConfirmation(msg))
case stashStateSettingNote:
cmds = append(cmds, m.handleNoteInput(msg))
case stashStateShowingError: case stashStateShowingError:
// Any key exists the error view // Any key exists the error view
if _, ok := msg.(tea.KeyMsg); ok { if _, ok := msg.(tea.KeyMsg); ok {
@ -607,11 +619,11 @@ func (m *stashModel) handleDocumentBrowsing(msg tea.Msg) tea.Cmd {
md := m.selectedMarkdown() md := m.selectedMarkdown()
isUserMarkdown := md.markdownType == StashedDocument || md.markdownType == ConvertedDocument isUserMarkdown := md.markdownType == StashedDocument || md.markdownType == ConvertedDocument
isSettingNote := m.state == stashStateSettingNote isSettingNote := m.selectionState == selectionSettingNote
isPromptingDelete := m.state == stashStatePromptDelete isPromptingDelete := m.selectionState == selectionPromptingDelete
if isUserMarkdown && !isSettingNote && !isPromptingDelete { if isUserMarkdown && !isSettingNote && !isPromptingDelete {
m.state = stashStateSettingNote m.selectionState = selectionSettingNote
m.noteInput.SetValue(md.Note) m.noteInput.SetValue(md.Note)
m.noteInput.CursorEnd() m.noteInput.CursorEnd()
return textinput.Blink return textinput.Blink
@ -672,16 +684,16 @@ func (m *stashModel) handleDocumentBrowsing(msg tea.Msg) tea.Cmd {
case "x": case "x":
m.hideStatusMessage() m.hideStatusMessage()
if pages == 0 { validState := m.state == stashStateReady &&
m.selectionState == selectionIdle
if pages == 0 && !validState {
break break
} }
t := m.selectedMarkdown().markdownType t := m.selectedMarkdown().markdownType
isUserMarkdown := t == StashedDocument || t == ConvertedDocument if t == StashedDocument || t == ConvertedDocument {
isValidState := m.state != stashStateSettingNote m.selectionState = selectionPromptingDelete
if isUserMarkdown && isValidState {
m.state = stashStatePromptDelete
} }
// Show errors // Show errors
@ -735,7 +747,7 @@ func (m *stashModel) handleDeleteConfirmation(msg tea.Msg) tea.Cmd {
// Confirm deletion // Confirm deletion
case "y": case "y":
if m.state != stashStatePromptDelete { if m.selectionState != selectionPromptingDelete {
break break
} }
@ -762,14 +774,14 @@ func (m *stashModel) handleDeleteConfirmation(msg tea.Msg) tea.Cmd {
} }
} }
// Update pagination m.selectionState = selectionIdle
m.setTotalPages() m.setTotalPages()
return deleteStashedItem(m.general.cc, smd.ID) return deleteStashedItem(m.general.cc, smd.ID)
default: default:
// Any other keys cancels deletion // Any other keys cancels deletion
m.state = stashStateReady m.selectionState = selectionIdle
} }
} }
@ -847,7 +859,7 @@ func (m *stashModel) handleNoteInput(msg tea.Msg) tea.Cmd {
case "esc": case "esc":
// Cancel note // Cancel note
m.noteInput.Reset() m.noteInput.Reset()
m.state = stashStateReady m.selectionState = selectionIdle
case "enter": case "enter":
// Set new note // Set new note
md := m.selectedMarkdown() md := m.selectedMarkdown()
@ -855,7 +867,7 @@ func (m *stashModel) handleNoteInput(msg tea.Msg) tea.Cmd {
cmd := saveDocumentNote(m.general.cc, md.ID, newNote) cmd := saveDocumentNote(m.general.cc, md.ID, newNote)
md.Note = newNote md.Note = newNote
m.noteInput.Reset() m.noteInput.Reset()
m.state = stashStateReady m.selectionState = selectionIdle
return cmd return cmd
} }
} }
@ -881,7 +893,7 @@ func (m stashModel) view() string {
return errorView(m.err, false) return errorView(m.err, false)
case stashStateLoadingDocument: case stashStateLoadingDocument:
s += " " + m.spinner.View() + " Loading document..." s += " " + m.spinner.View() + " Loading document..."
case stashStateReady, stashStateSettingNote, stashStatePromptDelete, stashStateShowNews: case stashStateReady, stashStateShowNews:
loadingIndicator := " " loadingIndicator := " "
if !m.localOnly() && (!m.loadingDone() || m.loadingFromNetwork || m.spinner.Visible()) { if !m.localOnly() && (!m.loadingDone() || m.loadingFromNetwork || m.spinner.Visible()) {
@ -900,10 +912,10 @@ func (m stashModel) view() string {
if m.showStatusMessage { if m.showStatusMessage {
header = greenFg(m.statusMessage) header = greenFg(m.statusMessage)
} else { } else {
switch m.state { switch m.selectionState {
case stashStatePromptDelete: case selectionPromptingDelete:
header = redFg("Delete this item from your stash? ") + faintRedFg("(y/N)") header = redFg("Delete this item from your stash? ") + faintRedFg("(y/N)")
case stashStateSettingNote: case selectionSettingNote:
header = yellowFg("Set the memo for this item?") header = yellowFg("Set the memo for this item?")
} }
} }
@ -1068,9 +1080,9 @@ func stashHelpView(m stashModel) string {
isLocal = md != nil && md.markdownType == LocalDocument isLocal = md != nil && md.markdownType == LocalDocument
} }
if m.state == stashStateSettingNote { if m.selectionState == selectionSettingNote {
h = append(h, "enter: confirm", "esc: cancel") h = append(h, "enter: confirm", "esc: cancel")
} else if m.state == stashStatePromptDelete { } else if m.selectionState == selectionPromptingDelete {
h = append(h, "y: delete", "n: cancel") h = append(h, "y: delete", "n: cancel")
} else if m.filterState == filtering && numDocs == 1 { } else if m.filterState == filtering && numDocs == 1 {
h = append(h, "enter: open", "esc: cancel") h = append(h, "enter: open", "esc: cancel")

View file

@ -55,13 +55,13 @@ func stashItemView(b *strings.Builder, m stashModel, index int, md *markdown) {
if isSelected && !isFiltering || singleFilteredItem { if isSelected && !isFiltering || singleFilteredItem {
// Selected item // Selected item
switch m.state { switch m.selectionState {
case stashStatePromptDelete: case selectionPromptingDelete:
gutter = faintRedFg(verticalLine) gutter = faintRedFg(verticalLine)
icon = faintRedFg(icon) icon = faintRedFg(icon)
title = redFg(title) title = redFg(title)
date = faintRedFg(date) date = faintRedFg(date)
case stashStateSettingNote: case selectionSettingNote:
gutter = dullYellowFg(verticalLine) gutter = dullYellowFg(verticalLine)
icon = "" icon = ""
title = m.noteInput.View() title = m.noteInput.View()

View file

@ -256,8 +256,7 @@ func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
// Send q/esc through in these cases // Send q/esc through in these cases
switch m.stash.state { switch m.stash.state {
case stashStateSettingNote, stashStatePromptDelete, case stashStateShowingError, stashStateShowNews:
stashStateShowingError, stashStateShowNews:
// Q also quits glow when displaying only newsitems. Esc // Q also quits glow when displaying only newsitems. Esc
// still passes through. // still passes through.