Also make news stashable from the pager

This commit is contained in:
Christian Rocha 2020-12-10 11:26:26 -05:00
commit 03d93169f2
3 changed files with 36 additions and 21 deletions

View file

@ -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
}

View file

@ -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)
}
}

View file

@ -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))