diff --git a/ui/markdown.go b/ui/markdown.go index 5d2a232..7bb3447 100644 --- a/ui/markdown.go +++ b/ui/markdown.go @@ -17,7 +17,7 @@ import ( // markdown wraps charm.Markdown. type markdown struct { - markdownType DocType + docType DocType // Stash identifier. This exists so we can keep track of documents stashed // 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. 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 // of filtered items if notes are edited while a filter is active. This // 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 // it's a local markdown document. 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. @@ -120,8 +125,8 @@ func normalize(in string) (string, error) { func wrapMarkdowns(t DocType, md []*charm.Markdown) (m []*markdown) { for _, v := range md { m = append(m, &markdown{ - markdownType: t, - Markdown: *v, + docType: t, + Markdown: *v, }) } return m diff --git a/ui/pager.go b/ui/pager.go index 8494c23..876844f 100644 --- a/ui/pager.go +++ b/ui/pager.go @@ -212,8 +212,8 @@ func (m pagerModel) update(msg tea.Msg) (pagerModel, tea.Cmd) { cmds = append(cmds, viewport.Sync(m.viewport)) } case "m": - isStashed := m.currentDocument.markdownType == StashedDoc || - m.currentDocument.markdownType == ConvertedDoc + isStashed := m.currentDocument.docType == StashedDoc || + m.currentDocument.docType == ConvertedDoc // Users can only set the note on user-stashed markdown if !isStashed { @@ -249,7 +249,7 @@ func (m pagerModel) update(msg tea.Msg) (pagerModel, tea.Cmd) { } // Stash a local document - if m.state != pagerStateStashing && stashableDocTypes.Contains(md.markdownType) { + if m.state != pagerStateStashing && stashableDocTypes.Contains(md.docType) { m.state = pagerStateStashing m.spinner.Start() cmds = append( @@ -358,7 +358,7 @@ func (m pagerModel) statusBarView(b *strings.Builder) { percentToStringMagnitude float64 = 100.0 ) 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 ) @@ -450,7 +450,7 @@ func (m pagerModel) setNoteView(b *strings.Builder) { func (m pagerModel) helpView() (s string) { 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" } @@ -463,7 +463,7 @@ func (m pagerModel) helpView() (s string) { "q quit", } - if m.currentDocument.markdownType == NewsDoc { + if m.currentDocument.docType == NewsDoc { deleteFromStringSlice(col1, 3) } diff --git a/ui/stash.go b/ui/stash.go index 3c66bb4..f353d57 100644 --- a/ui/stash.go +++ b/ui/stash.go @@ -346,7 +346,7 @@ func (m stashModel) countMarkdowns(t DocType) (found int) { } for i := 0; i < len(mds); i++ { - if mds[i].markdownType == t { + if mds[i].docType == t { found++ } } @@ -363,7 +363,7 @@ func (m stashModel) getMarkdownByType(types ...DocType) []*markdown { for _, t := range types { for _, md := range m.markdowns { - if md.markdownType == t { + if md.docType == t { agg = append(agg, md) } } @@ -401,7 +401,7 @@ func (m *stashModel) openMarkdown(md *markdown) tea.Cmd { var cmd tea.Cmd m.viewState = stashStateLoadingDocument - if md.markdownType == LocalDoc { + if md.docType == LocalDoc { cmd = loadLocalMarkdown(md) } else { cmd = loadRemoteMarkdown(m.common.cc, md) @@ -783,7 +783,7 @@ func (m *stashModel) handleDocumentBrowsing(msg tea.Msg) tea.Cmd { } md := m.selectedMarkdown() - isUserMarkdown := md.markdownType == StashedDoc || md.markdownType == ConvertedDoc + isUserMarkdown := md.docType == StashedDoc || md.docType == ConvertedDoc isSettingNote := m.selectionState == selectionSettingNote isPromptingDelete := m.selectionState == selectionPromptingDelete @@ -803,7 +803,7 @@ func (m *stashModel) handleDocumentBrowsing(msg tea.Msg) tea.Cmd { md := m.selectedMarkdown() // Is this a document we're allowed to stash? - if !stashableDocTypes.Contains(md.markdownType) { + if !stashableDocTypes.Contains(md.docType) { break } @@ -857,7 +857,7 @@ func (m *stashModel) handleDocumentBrowsing(msg tea.Msg) tea.Cmd { break } - t := md.markdownType + t := md.docType if t == StashedDoc || t == ConvertedDoc { m.selectionState = selectionPromptingDelete } @@ -914,7 +914,7 @@ func (m *stashModel) handleDeleteConfirmation(msg tea.Msg) tea.Cmd { smd := m.selectedMarkdown() - for i, md := range m.markdowns { + for _, md := range m.markdowns { if md.uniqueID != smd.uniqueID { continue } @@ -924,7 +924,7 @@ func (m *stashModel) handleDeleteConfirmation(msg tea.Msg) tea.Cmd { // Delete optimistically and remove the stashed item before // we've received a success response. - mds, err := deleteMarkdown(m.markdowns, m.markdowns[i]) + mds, err := deleteMarkdown(m.markdowns, md) if err == nil { m.markdowns = mds } @@ -934,14 +934,29 @@ func (m *stashModel) handleDeleteConfirmation(msg tea.Msg) tea.Cmd { // Also optimistically delete from filtered markdowns if m.filterApplied() { - for i, md := range m.filteredMarkdowns { + for _, md := range m.filteredMarkdowns { if md.uniqueID != smd.uniqueID { continue } - mds, err := deleteMarkdown(m.filteredMarkdowns, m.filteredMarkdowns[i]) - if err == nil { - m.filteredMarkdowns = mds + + switch md.docType { + + // 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 } } @@ -1329,10 +1344,10 @@ 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 { - newMD, err := fetchMarkdown(cc, md.ID, md.markdownType) + newMD, err := fetchMarkdown(cc, md.ID, md.docType) if err != nil { 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{ err: err, @@ -1347,7 +1362,7 @@ func loadRemoteMarkdown(cc *charm.Client, md *markdown) tea.Cmd { func loadLocalMarkdown(md *markdown) tea.Cmd { 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")} } if md.localPath == "" { @@ -1425,8 +1440,8 @@ func fetchMarkdown(cc *charm.Client, id int, t DocType) (*markdown, error) { } return &markdown{ - markdownType: t, - Markdown: *md, + docType: t, + Markdown: *md, }, nil } diff --git a/ui/stashhelp.go b/ui/stashhelp.go index 4a1bbc1..27a883a 100644 --- a/ui/stashhelp.go +++ b/ui/stashhelp.go @@ -120,8 +120,8 @@ func (m stashModel) helpView() (string, int) { if numDocs > 0 { md := m.selectedMarkdown() - isStashed = md != nil && md.markdownType == StashedDoc - isStashable = md != nil && md.markdownType == LocalDoc && m.online() + isStashed = md != nil && md.docType == StashedDoc + isStashable = md != nil && md.docType == LocalDoc && m.online() } if numDocs > 0 && m.showFullHelp { diff --git a/ui/stashitem.go b/ui/stashitem.go index 4b3d19e..a9d67d6 100644 --- a/ui/stashitem.go +++ b/ui/stashitem.go @@ -27,7 +27,7 @@ func stashItemView(b *strings.Builder, m stashModel, index int, md *markdown) { icon = "" ) - switch md.markdownType { + switch md.docType { case NewsDoc: if title == "" { title = "News" @@ -81,7 +81,7 @@ func stashItemView(b *strings.Builder, m stashModel, index int, md *markdown) { } else { // Regular (non-selected) items - if md.markdownType == NewsDoc { + if md.docType == NewsDoc { gutter = " " if isFiltering && m.filterInput.Value() == "" { diff --git a/ui/ui.go b/ui/ui.go index 38187e3..1bad6d3 100644 --- a/ui/ui.go +++ b/ui/ui.go @@ -412,7 +412,7 @@ func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) { if m.stash.filterApplied() { 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 // like rename and stash it. 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 // then we'll stash it anyway. if len(md.Body) == 0 { - switch md.markdownType { + switch md.docType { case LocalDoc: data, err := ioutil.ReadFile(md.localPath) @@ -671,14 +671,14 @@ func stashDocument(cc *charm.Client, md markdown) tea.Cmd { md.Body = string(data) case NewsDoc: - newMD, err := fetchMarkdown(cc, md.ID, md.markdownType) + newMD, err := fetchMarkdown(cc, md.ID, md.docType) if err != nil { return stashFailMsg{err, md} } md.Body = newMD.Body 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 { 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. func localFileToMarkdown(cwd string, res gitcha.SearchResult) *markdown { md := &markdown{ - markdownType: LocalDoc, + docType: LocalDoc, localPath: res.Path, + localModTime: res.Info.ModTime(), Markdown: charm.Markdown{ Note: stripAbsolutePath(res.Path, cwd), CreatedAt: res.Info.ModTime(), @@ -734,11 +735,11 @@ func localFileToMarkdown(cwd string, res gitcha.SearchResult) *markdown { // that occur as part of stashing. func convertMarkdownToStashed(md *markdown) { // 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.markdownType = ConvertedDoc + md.docType = ConvertedDoc md.CreatedAt = time.Now() }