Improve markdown stashing and spinner logic in file listing

This commit is contained in:
Christian Rocha 2020-12-10 20:20:43 -05:00
parent 617f0980d8
commit 6953c06b46
2 changed files with 40 additions and 49 deletions

View file

@ -115,7 +115,6 @@ type stashModel struct {
noteInput textinput.Model noteInput textinput.Model
filterInput textinput.Model filterInput textinput.Model
stashFullyLoaded bool // have we loaded all available stashed documents from the server? stashFullyLoaded bool // have we loaded all available stashed documents from the server?
loadingFromNetwork bool // are we currently loading something from the network?
viewState stashViewState viewState stashViewState
filterState filterState filterState filterState
selectionState selectionState selectionState selectionState
@ -461,14 +460,13 @@ func newStashModel(general *general) stashModel {
} }
m := stashModel{ m := stashModel{
general: general, general: general,
spinner: sp, spinner: sp,
noteInput: ni, noteInput: ni,
filterInput: si, filterInput: si,
serverPage: 1, serverPage: 1,
loaded: NewDocTypeSet(), loaded: NewDocTypeSet(),
loadingFromNetwork: true, sections: s,
sections: s,
} }
return m return m
@ -487,7 +485,6 @@ func (m stashModel) update(msg tea.Msg) (stashModel, tea.Cmd) {
m.err = msg.err m.err = msg.err
m.loaded.Add(StashedDoc) // still done, albeit unsuccessfully m.loaded.Add(StashedDoc) // still done, albeit unsuccessfully
m.stashFullyLoaded = true m.stashFullyLoaded = true
m.loadingFromNetwork = false
case newsLoadErrMsg: case newsLoadErrMsg:
m.err = msg.err m.err = msg.err
@ -507,7 +504,6 @@ func (m stashModel) update(msg tea.Msg) (stashModel, tea.Cmd) {
switch msg := msg.(type) { switch msg := msg.(type) {
case gotStashMsg: case gotStashMsg:
m.loaded.Add(StashedDoc) m.loaded.Add(StashedDoc)
m.loadingFromNetwork = false
docs = wrapMarkdowns(StashedDoc, msg) docs = wrapMarkdowns(StashedDoc, msg)
if len(msg) == 0 { if len(msg) == 0 {
@ -551,13 +547,12 @@ func (m stashModel) update(msg tea.Msg) (stashModel, tea.Cmd) {
return m, nil return m, nil
case spinner.TickMsg: case spinner.TickMsg:
condition := !m.loadingDone() || loading := !m.loadingDone()
m.loadingFromNetwork || stashing := m.general.isStashing()
m.viewState == stashStateLoadingDocument || openingDocument := m.viewState == stashStateLoadingDocument
len(m.general.filesStashed) > 0 || spinnerVisible := m.spinner.Visible()
m.spinner.Visible()
if condition { if loading || stashing || openingDocument || spinnerVisible {
newSpinnerModel, cmd := m.spinner.Update(msg) newSpinnerModel, cmd := m.spinner.Update(msg)
m.spinner = newSpinnerModel m.spinner = newSpinnerModel
cmds = append(cmds, cmd) cmds = append(cmds, cmd)
@ -572,15 +567,13 @@ func (m stashModel) update(msg tea.Msg) (stashModel, tea.Cmd) {
} }
} }
// Note: mechanical stuff related to stash success is handled in the parent
// update function.
case stashSuccessMsg: case stashSuccessMsg:
md := markdown(msg)
m.addMarkdowns(&md)
if m.isFiltering() {
cmds = append(cmds, filterMarkdowns(m))
}
cmds = append(cmds, m.newStatusMessage("Stashed!")) cmds = append(cmds, m.newStatusMessage("Stashed!"))
// Note: mechanical stuff related to stash failure is handled in the parent
// update function.
case stashFailMsg: case stashFailMsg:
cmds = append(cmds, m.newStatusMessage("Couldnt stash :(")) cmds = append(cmds, m.newStatusMessage("Couldnt stash :("))
@ -747,6 +740,7 @@ func (m *stashModel) handleDocumentBrowsing(msg tea.Msg) tea.Cmd {
// Checks passed; perform the stash // Checks passed; perform the stash
m.general.filesStashed[md.localID] = struct{}{} m.general.filesStashed[md.localID] = struct{}{}
m.general.filesStashing[md.localID] = struct{}{}
cmds = append(cmds, stashDocument(m.general.cc, *md)) cmds = append(cmds, stashDocument(m.general.cc, *md))
if m.loadingDone() && !m.spinner.Visible() { if m.loadingDone() && !m.spinner.Visible() {
@ -812,14 +806,6 @@ func (m *stashModel) handleDocumentBrowsing(msg tea.Msg) tea.Cmd {
m.setCursor(max(0, itemsOnPage-1)) m.setCursor(max(0, itemsOnPage-1))
} }
// If we're on the last page and we haven't loaded everything, get
// more stuff.
if m.paginator().OnLastPage() && !m.loadingFromNetwork && !m.stashFullyLoaded {
m.serverPage++
m.loadingFromNetwork = true
cmds = append(cmds, loadStash(*m))
}
return tea.Batch(cmds...) return tea.Batch(cmds...)
} }
@ -973,7 +959,7 @@ func (m stashModel) view() string {
case stashStateReady: case stashStateReady:
loadingIndicator := " " loadingIndicator := " "
if !m.localOnly() && (!m.loadingDone() || m.loadingFromNetwork || m.spinner.Visible()) { if !m.localOnly() && (!m.loadingDone() || m.spinner.Visible()) {
loadingIndicator = m.spinner.View() loadingIndicator = m.spinner.View()
} }

View file

@ -169,6 +169,14 @@ type general struct {
// Local IDs of files stashed this session. We treat this like a set, // Local IDs of files stashed this session. We treat this like a set,
// ignoring the value portion with an empty struct. // ignoring the value portion with an empty struct.
filesStashed map[ksuid.KSUID]struct{} filesStashed map[ksuid.KSUID]struct{}
// Files currently being stashed. We remove files from this set once
// a stash operation has either succeeded or failed.
filesStashing map[ksuid.KSUID]struct{}
}
func (g general) isStashing() bool {
return len(g.filesStashing) > 0
} }
type model struct { type model struct {
@ -199,7 +207,7 @@ func (m *model) unloadDocument() []tea.Cmd {
batch = append(batch, tea.ClearScrollArea) batch = append(batch, tea.ClearScrollArea)
} }
if !m.stash.loadingDone() || m.stash.loadingFromNetwork { if !m.stash.loadingDone() {
batch = append(batch, spinner.Tick) batch = append(batch, spinner.Tick)
} }
return batch return batch
@ -219,9 +227,10 @@ func newModel(cfg Config) tea.Model {
} }
general := general{ general := general{
cfg: cfg, cfg: cfg,
authStatus: authConnecting, authStatus: authConnecting,
filesStashed: make(map[ksuid.KSUID]struct{}), filesStashed: make(map[ksuid.KSUID]struct{}),
filesStashing: make(map[ksuid.KSUID]struct{}),
} }
return model{ return model{
@ -362,7 +371,6 @@ func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
// Even though it failed, news/stash loading is finished // Even though it failed, news/stash loading is finished
m.stash.loaded.Add(StashedDoc, NewsDoc) m.stash.loaded.Add(StashedDoc, NewsDoc)
m.stash.loadingFromNetwork = false
} }
case keygenFailedMsg: case keygenFailedMsg:
@ -377,7 +385,6 @@ func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
// Even though it failed, news/stash loading is finished // Even though it failed, news/stash loading is finished
m.stash.loaded.Add(StashedDoc, NewsDoc) m.stash.loaded.Add(StashedDoc, NewsDoc)
m.stash.loadingFromNetwork = false
case keygenSuccessMsg: case keygenSuccessMsg:
// The keygen's done, so let's try initializing the charm client again // The keygen's done, so let's try initializing the charm client again
@ -429,22 +436,20 @@ func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
cmds = append(cmds, findNextLocalFile(m)) cmds = append(cmds, findNextLocalFile(m))
case stashSuccessMsg: case stashSuccessMsg:
// Something was stashed outside the file listing view. Update the // Common handling that should happen regardless of application state
// stash listing but don't run an actual update on the stash since we md := markdown(msg)
// don't want to trigger the status message and generally don't want m.stash.addMarkdowns(&md)
// any other effects. m.general.filesStashed[msg.localID] = struct{}{}
if m.state == stateShowDocument { delete(m.general.filesStashing, md.localID)
md := markdown(msg)
m.stash.addMarkdowns(&md)
m.general.filesStashed[msg.localID] = struct{}{}
if m.stash.isFiltering() { if m.stash.isFiltering() {
cmds = append(cmds, filterMarkdowns(m.stash)) cmds = append(cmds, filterMarkdowns(m.stash))
}
} }
case stashFailMsg: case stashFailMsg:
// Common handling that should happen regardless of application state
delete(m.general.filesStashed, msg.markdown.localID) delete(m.general.filesStashed, msg.markdown.localID)
delete(m.general.filesStashing, msg.markdown.localID)
case filteredMarkdownMsg: case filteredMarkdownMsg:
if m.state == stateShowDocument { if m.state == stateShowDocument {