From 03d93169f2f15699b1465c95eef992d72475829c Mon Sep 17 00:00:00 2001 From: Christian Rocha Date: Thu, 10 Dec 2020 11:26:26 -0500 Subject: [PATCH] Also make news stashable from the pager --- ui/pager.go | 27 ++++++++++++++++++++------- ui/stash.go | 19 +++++++------------ ui/ui.go | 11 +++++++++-- 3 files changed, 36 insertions(+), 21 deletions(-) diff --git a/ui/pager.go b/ui/pager.go index 6eaa041..b243cc5 100644 --- a/ui/pager.go +++ b/ui/pager.go @@ -243,13 +243,21 @@ func (m pagerModel) update(msg tea.Msg) (pagerModel, tea.Cmd) { break } + md := m.currentDocument + + _, alreadyStashed := m.general.filesStashed[md.localID] + if alreadyStashed { + cmds = append(cmds, m.showStatusMessage("Already stashed")) + break + } + // Stash a local document - if m.state != pagerStateStashing && m.currentDocument.markdownType == LocalDoc { + if m.state != pagerStateStashing && stashableDocTypes.Contains(md.markdownType) { m.state = pagerStateStashing m.spinner.Start() cmds = append( cmds, - stashDocument(m.general.cc, m.currentDocument), + stashDocument(m.general.cc, md), spinner.Tick, ) } @@ -263,15 +271,18 @@ func (m pagerModel) update(msg tea.Msg) (pagerModel, tea.Cmd) { case spinner.TickMsg: if m.state == pagerStateStashing || m.spinner.Visible() { + // If we're still stashing, or if the spinner still needs to + // finish, spin it along. newSpinnerModel, cmd := m.spinner.Update(msg) m.spinner = newSpinnerModel cmds = append(cmds, cmd) } else if m.state == pagerStateStashSuccess && !m.spinner.Visible() { + // If the spinner's finished and we haven't told the user the + // stash was successful, do that. m.state = pagerStateBrowse m.currentDocument = *m.stashedDocument m.stashedDocument = nil - cmd := m.showStatusMessage("Stashed!") - cmds = append(cmds, cmd) + cmds = append(cmds, m.showStatusMessage("Stashed!")) } // Glow has rendered the content @@ -293,11 +304,14 @@ func (m pagerModel) update(msg tea.Msg) (pagerModel, tea.Cmd) { // item to the stash listing. m.state = pagerStateStashSuccess if !m.spinner.Visible() { + // The spinner has finished spinning, so tell the user the stash + // was successful. m.state = pagerStateBrowse m.currentDocument = markdown(msg) - cmd := m.showStatusMessage("Stashed!") - cmds = append(cmds, cmd) + cmds = append(cmds, m.showStatusMessage("Stashed!")) } else { + // The spinner is still spinning, so just take note of the newly + // stashed document for now. md := markdown(msg) m.stashedDocument = &md } @@ -306,7 +320,6 @@ func (m pagerModel) update(msg tea.Msg) (pagerModel, tea.Cmd) { // TODO case statusMessageTimeoutMsg: - // Hide the status message bar m.state = pagerStateBrowse } diff --git a/ui/stash.go b/ui/stash.go index b001d8e..9d4cd51 100644 --- a/ui/stash.go +++ b/ui/stash.go @@ -18,7 +18,6 @@ import ( "github.com/muesli/reflow/ansi" te "github.com/muesli/termenv" "github.com/sahilm/fuzzy" - "github.com/segmentio/ksuid" ) const ( @@ -143,10 +142,6 @@ type stashModel struct { // reason, this field should be considered ephemeral. filteredMarkdowns []*markdown - // Paths to files stashed this session. We treat this like a set, ignoring - // the value portion with an empty struct. - filesStashed map[ksuid.KSUID]struct{} - // Page we're fetching stash 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 @@ -473,7 +468,6 @@ func newStashModel(general *general) stashModel { serverPage: 1, loaded: NewDocTypeSet(), loadingFromNetwork: true, - filesStashed: make(map[ksuid.KSUID]struct{}), sections: s, } @@ -560,7 +554,7 @@ func (m stashModel) update(msg tea.Msg) (stashModel, tea.Cmd) { condition := !m.loadingDone() || m.loadingFromNetwork || m.viewState == stashStateLoadingDocument || - len(m.filesStashed) > 0 || + len(m.general.filesStashed) > 0 || m.spinner.Visible() if condition { @@ -733,7 +727,7 @@ func (m *stashModel) handleDocumentBrowsing(msg tea.Msg) tea.Cmd { md := m.selectedMarkdown() - if _, alreadyStashed := m.filesStashed[md.localID]; alreadyStashed { + if _, alreadyStashed := m.general.filesStashed[md.localID]; alreadyStashed { cmds = append(cmds, m.newStatusMessage("Already stashed")) break } @@ -746,7 +740,7 @@ func (m *stashModel) handleDocumentBrowsing(msg tea.Msg) tea.Cmd { } // Checks passed; perform the stash - m.filesStashed[md.localID] = struct{}{} + m.general.filesStashed[md.localID] = struct{}{} cmds = append(cmds, stashDocument(m.general.cc, *md)) if m.loadingDone() && !m.spinner.Visible() { @@ -835,7 +829,7 @@ func (m *stashModel) handleDeleteConfirmation(msg tea.Msg) tea.Cmd { } // Remove from the things-we-stashed-this-session set - delete(m.filesStashed, md.localID) + delete(m.general.filesStashed, md.localID) // Delete optimistically and remove the stashed item before // we've received a success response. @@ -1201,7 +1195,7 @@ func (m stashModel) populatedView() string { // loadRemoteMarkdown is a command for loading markdown from the server. func loadRemoteMarkdown(cc *charm.Client, md *markdown) tea.Cmd { return func() tea.Msg { - md, err := loadMarkdownFromCharm(cc, md.ID, md.markdownType) + newMD, err := loadMarkdownFromCharm(cc, md.ID, md.markdownType) if err != nil { if debug { log.Printf("error loading %s markdown (ID %d, Note: '%s'): %v", md.markdownType, md.ID, md.Note, err) @@ -1212,7 +1206,8 @@ func loadRemoteMarkdown(cc *charm.Client, md *markdown) tea.Cmd { note: md.Note, } } - return fetchedMarkdownMsg(md) + newMD.localID = md.localID + return fetchedMarkdownMsg(newMD) } } diff --git a/ui/ui.go b/ui/ui.go index cf76d1a..a417d3a 100644 --- a/ui/ui.go +++ b/ui/ui.go @@ -19,6 +19,7 @@ import ( runewidth "github.com/mattn/go-runewidth" "github.com/muesli/gitcha" te "github.com/muesli/termenv" + "github.com/segmentio/ksuid" ) const ( @@ -157,6 +158,10 @@ type general struct { authStatus authStatus width int height int + + // Local IDs of files stashed this session. We treat this like a set, + // ignoring the value portion with an empty struct. + filesStashed map[ksuid.KSUID]struct{} } type model struct { @@ -207,8 +212,9 @@ func newModel(cfg Config) tea.Model { } general := general{ - cfg: cfg, - authStatus: authConnecting, + cfg: cfg, + authStatus: authConnecting, + filesStashed: make(map[ksuid.KSUID]struct{}), } return model{ @@ -422,6 +428,7 @@ func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) { if m.state == stateShowDocument { md := markdown(msg) m.stash.addMarkdowns(&md) + m.general.filesStashed[msg.localID] = struct{}{} if m.stash.isFiltering() { cmds = append(cmds, filterMarkdowns(m.stash))