In a filter, deleting docs stashed in-session converts them to local ones

This commit is contained in:
Christian Rocha 2020-12-16 15:12:48 -05:00
parent 12f3209238
commit 2a688fc71e
6 changed files with 59 additions and 38 deletions

View file

@ -17,7 +17,7 @@ import (
// markdown wraps charm.Markdown. // markdown wraps charm.Markdown.
type markdown struct { type markdown struct {
markdownType DocType docType DocType
// Stash identifier. This exists so we can keep track of documents stashed // Stash identifier. This exists so we can keep track of documents stashed
// in-session as they relate to their original, non-stashed counterparts. // in-session as they relate to their original, non-stashed counterparts.
@ -34,6 +34,11 @@ type markdown struct {
// those that have been stashed in this session. // those that have been stashed in this session.
localPath string localPath string
// Modified time of the local file. This will also be stored in
// Markdown.CreatedAt, however we also retain it here incase we need to
// convert this document back to a local document after it's been stashed.
localModTime time.Time
// Value we filter against. This exists so that we can maintain positions // Value we filter against. This exists so that we can maintain positions
// of filtered items if notes are edited while a filter is active. This // of filtered items if notes are edited while a filter is active. This
// field is ephemeral, and should only be referenced during filtering. // field is ephemeral, and should only be referenced during filtering.
@ -65,7 +70,7 @@ func (m *markdown) buildFilterValue() {
// shouldSortAsLocal returns whether or not this markdown should be sorted as though // shouldSortAsLocal returns whether or not this markdown should be sorted as though
// it's a local markdown document. // it's a local markdown document.
func (m markdown) shouldSortAsLocal() bool { func (m markdown) shouldSortAsLocal() bool {
return m.markdownType == LocalDoc || m.markdownType == ConvertedDoc return m.docType == LocalDoc || m.docType == ConvertedDoc
} }
// Sort documents with local files first, then by date. // Sort documents with local files first, then by date.
@ -120,8 +125,8 @@ func normalize(in string) (string, error) {
func wrapMarkdowns(t DocType, md []*charm.Markdown) (m []*markdown) { func wrapMarkdowns(t DocType, md []*charm.Markdown) (m []*markdown) {
for _, v := range md { for _, v := range md {
m = append(m, &markdown{ m = append(m, &markdown{
markdownType: t, docType: t,
Markdown: *v, Markdown: *v,
}) })
} }
return m return m

View file

@ -212,8 +212,8 @@ func (m pagerModel) update(msg tea.Msg) (pagerModel, tea.Cmd) {
cmds = append(cmds, viewport.Sync(m.viewport)) cmds = append(cmds, viewport.Sync(m.viewport))
} }
case "m": case "m":
isStashed := m.currentDocument.markdownType == StashedDoc || isStashed := m.currentDocument.docType == StashedDoc ||
m.currentDocument.markdownType == ConvertedDoc m.currentDocument.docType == ConvertedDoc
// Users can only set the note on user-stashed markdown // Users can only set the note on user-stashed markdown
if !isStashed { if !isStashed {
@ -249,7 +249,7 @@ func (m pagerModel) update(msg tea.Msg) (pagerModel, tea.Cmd) {
} }
// Stash a local document // Stash a local document
if m.state != pagerStateStashing && stashableDocTypes.Contains(md.markdownType) { if m.state != pagerStateStashing && stashableDocTypes.Contains(md.docType) {
m.state = pagerStateStashing m.state = pagerStateStashing
m.spinner.Start() m.spinner.Start()
cmds = append( cmds = append(
@ -358,7 +358,7 @@ func (m pagerModel) statusBarView(b *strings.Builder) {
percentToStringMagnitude float64 = 100.0 percentToStringMagnitude float64 = 100.0
) )
var ( var (
isStashed bool = m.currentDocument.markdownType == StashedDoc || m.currentDocument.markdownType == ConvertedDoc isStashed bool = m.currentDocument.docType == StashedDoc || m.currentDocument.docType == ConvertedDoc
showStatusMessage bool = m.state == pagerStateStatusMessage showStatusMessage bool = m.state == pagerStateStatusMessage
) )
@ -450,7 +450,7 @@ func (m pagerModel) setNoteView(b *strings.Builder) {
func (m pagerModel) helpView() (s string) { func (m pagerModel) helpView() (s string) {
memoOrStash := "m set memo" memoOrStash := "m set memo"
if m.common.authStatus == authOK && m.currentDocument.markdownType == LocalDoc { if m.common.authStatus == authOK && m.currentDocument.docType == LocalDoc {
memoOrStash = "s stash this document" memoOrStash = "s stash this document"
} }
@ -463,7 +463,7 @@ func (m pagerModel) helpView() (s string) {
"q quit", "q quit",
} }
if m.currentDocument.markdownType == NewsDoc { if m.currentDocument.docType == NewsDoc {
deleteFromStringSlice(col1, 3) deleteFromStringSlice(col1, 3)
} }

View file

@ -346,7 +346,7 @@ func (m stashModel) countMarkdowns(t DocType) (found int) {
} }
for i := 0; i < len(mds); i++ { for i := 0; i < len(mds); i++ {
if mds[i].markdownType == t { if mds[i].docType == t {
found++ found++
} }
} }
@ -363,7 +363,7 @@ func (m stashModel) getMarkdownByType(types ...DocType) []*markdown {
for _, t := range types { for _, t := range types {
for _, md := range m.markdowns { for _, md := range m.markdowns {
if md.markdownType == t { if md.docType == t {
agg = append(agg, md) agg = append(agg, md)
} }
} }
@ -401,7 +401,7 @@ func (m *stashModel) openMarkdown(md *markdown) tea.Cmd {
var cmd tea.Cmd var cmd tea.Cmd
m.viewState = stashStateLoadingDocument m.viewState = stashStateLoadingDocument
if md.markdownType == LocalDoc { if md.docType == LocalDoc {
cmd = loadLocalMarkdown(md) cmd = loadLocalMarkdown(md)
} else { } else {
cmd = loadRemoteMarkdown(m.common.cc, md) cmd = loadRemoteMarkdown(m.common.cc, md)
@ -783,7 +783,7 @@ func (m *stashModel) handleDocumentBrowsing(msg tea.Msg) tea.Cmd {
} }
md := m.selectedMarkdown() md := m.selectedMarkdown()
isUserMarkdown := md.markdownType == StashedDoc || md.markdownType == ConvertedDoc isUserMarkdown := md.docType == StashedDoc || md.docType == ConvertedDoc
isSettingNote := m.selectionState == selectionSettingNote isSettingNote := m.selectionState == selectionSettingNote
isPromptingDelete := m.selectionState == selectionPromptingDelete isPromptingDelete := m.selectionState == selectionPromptingDelete
@ -803,7 +803,7 @@ func (m *stashModel) handleDocumentBrowsing(msg tea.Msg) tea.Cmd {
md := m.selectedMarkdown() md := m.selectedMarkdown()
// Is this a document we're allowed to stash? // Is this a document we're allowed to stash?
if !stashableDocTypes.Contains(md.markdownType) { if !stashableDocTypes.Contains(md.docType) {
break break
} }
@ -857,7 +857,7 @@ func (m *stashModel) handleDocumentBrowsing(msg tea.Msg) tea.Cmd {
break break
} }
t := md.markdownType t := md.docType
if t == StashedDoc || t == ConvertedDoc { if t == StashedDoc || t == ConvertedDoc {
m.selectionState = selectionPromptingDelete m.selectionState = selectionPromptingDelete
} }
@ -914,7 +914,7 @@ func (m *stashModel) handleDeleteConfirmation(msg tea.Msg) tea.Cmd {
smd := m.selectedMarkdown() smd := m.selectedMarkdown()
for i, md := range m.markdowns { for _, md := range m.markdowns {
if md.uniqueID != smd.uniqueID { if md.uniqueID != smd.uniqueID {
continue continue
} }
@ -924,7 +924,7 @@ func (m *stashModel) handleDeleteConfirmation(msg tea.Msg) tea.Cmd {
// Delete optimistically and remove the stashed item before // Delete optimistically and remove the stashed item before
// we've received a success response. // we've received a success response.
mds, err := deleteMarkdown(m.markdowns, m.markdowns[i]) mds, err := deleteMarkdown(m.markdowns, md)
if err == nil { if err == nil {
m.markdowns = mds m.markdowns = mds
} }
@ -934,14 +934,29 @@ func (m *stashModel) handleDeleteConfirmation(msg tea.Msg) tea.Cmd {
// Also optimistically delete from filtered markdowns // Also optimistically delete from filtered markdowns
if m.filterApplied() { if m.filterApplied() {
for i, md := range m.filteredMarkdowns { for _, md := range m.filteredMarkdowns {
if md.uniqueID != smd.uniqueID { if md.uniqueID != smd.uniqueID {
continue continue
} }
mds, err := deleteMarkdown(m.filteredMarkdowns, m.filteredMarkdowns[i])
if err == nil { switch md.docType {
m.filteredMarkdowns = mds
// If the document was stashed in this session, convert it
// back to "local" document
case ConvertedDoc:
md.docType = LocalDoc
md.Note = stripAbsolutePath(md.localPath, m.common.cwd)
md.CreatedAt = md.localModTime
// Otherwise, remove the document from the listing
default:
mds, err := deleteMarkdown(m.filteredMarkdowns, md)
if err == nil {
m.filteredMarkdowns = mds
}
} }
break break
} }
} }
@ -1329,10 +1344,10 @@ func (m stashModel) populatedView() string {
// loadRemoteMarkdown is a command for loading markdown from the server. // loadRemoteMarkdown is a command for loading markdown from the server.
func loadRemoteMarkdown(cc *charm.Client, md *markdown) tea.Cmd { func loadRemoteMarkdown(cc *charm.Client, md *markdown) tea.Cmd {
return func() tea.Msg { return func() tea.Msg {
newMD, err := fetchMarkdown(cc, md.ID, md.markdownType) newMD, err := fetchMarkdown(cc, md.ID, md.docType)
if err != nil { if err != nil {
if debug { if debug {
log.Printf("error loading %s markdown (ID %d, Note: '%s'): %v", md.markdownType, md.ID, md.Note, err) log.Printf("error loading %s markdown (ID %d, Note: '%s'): %v", md.docType, md.ID, md.Note, err)
} }
return markdownFetchFailedMsg{ return markdownFetchFailedMsg{
err: err, err: err,
@ -1347,7 +1362,7 @@ func loadRemoteMarkdown(cc *charm.Client, md *markdown) tea.Cmd {
func loadLocalMarkdown(md *markdown) tea.Cmd { func loadLocalMarkdown(md *markdown) tea.Cmd {
return func() tea.Msg { return func() tea.Msg {
if md.markdownType != LocalDoc { if md.docType != LocalDoc {
return errMsg{errors.New("could not load local file: not a local file")} return errMsg{errors.New("could not load local file: not a local file")}
} }
if md.localPath == "" { if md.localPath == "" {
@ -1425,8 +1440,8 @@ func fetchMarkdown(cc *charm.Client, id int, t DocType) (*markdown, error) {
} }
return &markdown{ return &markdown{
markdownType: t, docType: t,
Markdown: *md, Markdown: *md,
}, nil }, nil
} }

View file

@ -120,8 +120,8 @@ func (m stashModel) helpView() (string, int) {
if numDocs > 0 { if numDocs > 0 {
md := m.selectedMarkdown() md := m.selectedMarkdown()
isStashed = md != nil && md.markdownType == StashedDoc isStashed = md != nil && md.docType == StashedDoc
isStashable = md != nil && md.markdownType == LocalDoc && m.online() isStashable = md != nil && md.docType == LocalDoc && m.online()
} }
if numDocs > 0 && m.showFullHelp { if numDocs > 0 && m.showFullHelp {

View file

@ -27,7 +27,7 @@ func stashItemView(b *strings.Builder, m stashModel, index int, md *markdown) {
icon = "" icon = ""
) )
switch md.markdownType { switch md.docType {
case NewsDoc: case NewsDoc:
if title == "" { if title == "" {
title = "News" title = "News"
@ -81,7 +81,7 @@ func stashItemView(b *strings.Builder, m stashModel, index int, md *markdown) {
} else { } else {
// Regular (non-selected) items // Regular (non-selected) items
if md.markdownType == NewsDoc { if md.docType == NewsDoc {
gutter = " " gutter = " "
if isFiltering && m.filterInput.Value() == "" { if isFiltering && m.filterInput.Value() == "" {

View file

@ -412,7 +412,7 @@ func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
if m.stash.filterApplied() { if m.stash.filterApplied() {
for _, v := range m.stash.filteredMarkdowns { for _, v := range m.stash.filteredMarkdowns {
if v.stashID == msg.stashID && v.markdownType == ConvertedDoc { if v.stashID == msg.stashID && v.docType == ConvertedDoc {
// Add the server-side ID we got back so we can do things // Add the server-side ID we got back so we can do things
// like rename and stash it. // like rename and stash it.
v.ID = msg.ID v.ID = msg.ID
@ -658,7 +658,7 @@ func stashDocument(cc *charm.Client, md markdown) tea.Cmd {
// be loaded. But...if it turnsout the document body really is empty // be loaded. But...if it turnsout the document body really is empty
// then we'll stash it anyway. // then we'll stash it anyway.
if len(md.Body) == 0 { if len(md.Body) == 0 {
switch md.markdownType { switch md.docType {
case LocalDoc: case LocalDoc:
data, err := ioutil.ReadFile(md.localPath) data, err := ioutil.ReadFile(md.localPath)
@ -671,14 +671,14 @@ func stashDocument(cc *charm.Client, md markdown) tea.Cmd {
md.Body = string(data) md.Body = string(data)
case NewsDoc: case NewsDoc:
newMD, err := fetchMarkdown(cc, md.ID, md.markdownType) newMD, err := fetchMarkdown(cc, md.ID, md.docType)
if err != nil { if err != nil {
return stashFailMsg{err, md} return stashFailMsg{err, md}
} }
md.Body = newMD.Body md.Body = newMD.Body
default: default:
err := fmt.Errorf("user is attempting to stash an unsupported markdown type: %s", md.markdownType) err := fmt.Errorf("user is attempting to stash an unsupported markdown type: %s", md.docType)
if debug { if debug {
log.Println(err) log.Println(err)
} }
@ -719,8 +719,9 @@ func waitForStatusMessageTimeout(appCtx applicationContext, t *time.Timer) tea.C
// a directory, but we trust that gitcha has already done that. // a directory, but we trust that gitcha has already done that.
func localFileToMarkdown(cwd string, res gitcha.SearchResult) *markdown { func localFileToMarkdown(cwd string, res gitcha.SearchResult) *markdown {
md := &markdown{ md := &markdown{
markdownType: LocalDoc, docType: LocalDoc,
localPath: res.Path, localPath: res.Path,
localModTime: res.Info.ModTime(),
Markdown: charm.Markdown{ Markdown: charm.Markdown{
Note: stripAbsolutePath(res.Path, cwd), Note: stripAbsolutePath(res.Path, cwd),
CreatedAt: res.Info.ModTime(), CreatedAt: res.Info.ModTime(),
@ -734,11 +735,11 @@ func localFileToMarkdown(cwd string, res gitcha.SearchResult) *markdown {
// that occur as part of stashing. // that occur as part of stashing.
func convertMarkdownToStashed(md *markdown) { func convertMarkdownToStashed(md *markdown) {
// Set the note as the filename without the extension // Set the note as the filename without the extension
if md.markdownType == LocalDoc { if md.docType == LocalDoc {
md.Note = strings.Replace(path.Base(md.localPath), path.Ext(md.localPath), "", 1) md.Note = strings.Replace(path.Base(md.localPath), path.Ext(md.localPath), "", 1)
} }
md.markdownType = ConvertedDoc md.docType = ConvertedDoc
md.CreatedAt = time.Now() md.CreatedAt = time.Now()
} }