This commit is contained in:
Cam Michie 2026-08-05 17:12:22 +08:00 committed by GitHub
commit b3fe57a778
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 104 additions and 22 deletions

View file

@ -3,10 +3,47 @@ package ui
import (
"cmp"
"slices"
"time"
)
func sortMarkdowns(mds []*markdown) {
slices.SortStableFunc(mds, func(a, b *markdown) int {
return cmp.Compare(a.Note, b.Note)
})
type sortOrder bool
const (
ascending sortOrder = true
descending sortOrder = false
)
func sortMarkdowns(mds []*markdown, sortByDate bool, ascending sortOrder) {
if sortByDate {
if ascending {
slices.SortStableFunc(mds, func(a, b *markdown) int {
return compareTime(a.Modtime, b.Modtime)
})
} else {
slices.SortStableFunc(mds, func(a, b *markdown) int {
return -compareTime(a.Modtime, b.Modtime)
})
}
} else {
if ascending {
slices.SortStableFunc(mds, func(a, b *markdown) int {
return cmp.Compare(a.Note, b.Note)
})
} else {
slices.SortStableFunc(mds, func(a, b *markdown) int {
return -cmp.Compare(a.Note, b.Note)
})
}
}
}
func compareTime(a, b time.Time) int {
switch {
case a.Before(b):
return -1
case a.After(b):
return 1
default:
return 0
}
}

View file

@ -147,6 +147,8 @@ type stashModel struct {
showStatusMessage bool
statusMessage statusMessage
statusMessageTimer *time.Timer
sortByDate bool
sortAscending bool
// Available document sections we can cycle through. We use a slice, rather
// than a map, because order is important.
@ -220,7 +222,7 @@ func (m *stashModel) resetFiltering() {
m.filterInput.Reset()
m.filteredMarkdowns = nil
sortMarkdowns(m.markdowns)
sortMarkdowns(m.markdowns, m.sortByDate, sortOrder(m.sortAscending))
// If the filtered section is present (it's always at the end) slice it out
// of the sections slice to remove it from the UI.
@ -293,15 +295,9 @@ func (m stashModel) selectedMarkdown() *markdown {
// Adds markdown documents to the model.
func (m *stashModel) addMarkdowns(mds ...*markdown) {
if len(mds) == 0 {
return
}
m.markdowns = append(m.markdowns, mds...)
if !m.filterApplied() {
sortMarkdowns(m.markdowns)
}
m.filteredMarkdowns = m.markdowns
sortMarkdowns(m.filteredMarkdowns, m.sortByDate, sortOrder(m.sortAscending))
m.updatePagination()
}
@ -389,11 +385,13 @@ func newStashModel(common *commonModel) stashModel {
}
m := stashModel{
common: common,
spinner: sp,
filterInput: si,
serverPage: 1,
sections: s,
common: common,
spinner: sp,
filterInput: si,
serverPage: 1,
sections: s,
sortAscending: true,
sortByDate: false,
}
return m
@ -568,6 +566,42 @@ func (m *stashModel) handleDocumentBrowsing(msg tea.Msg) tea.Cmd {
m.viewState = stashStateShowingError
return nil
}
case "y":
m.sortByDate = true
m.sortAscending = !m.sortAscending
sortMarkdowns(m.filteredMarkdowns, m.sortByDate, sortOrder(m.sortAscending))
m.statusMessage = statusMessage{
status: normalStatusMessage,
message: fmt.Sprintf("Sorted by date %s",
map[bool]string{
true: "(oldest first)",
false: "(newest first)",
}[m.sortAscending],
),
}
m.showStatusMessage = true
cmds = append(cmds, func() tea.Msg {
return statusMessageTimeoutMsg(stashContext)
})
case "t":
m.sortByDate = false
m.sortAscending = !m.sortAscending
sortMarkdowns(m.filteredMarkdowns, m.sortByDate, sortOrder(m.sortAscending))
m.statusMessage = statusMessage{
status: normalStatusMessage,
message: fmt.Sprintf("Sorted by title %s",
map[bool]string{
true: "(A to Z)",
false: "(Z to A)",
}[m.sortAscending],
),
}
m.showStatusMessage = true
cmds = append(cmds, func() tea.Msg {
return statusMessageTimeoutMsg(stashContext)
})
}
}
@ -583,7 +617,7 @@ func (m *stashModel) handleDocumentBrowsing(msg tea.Msg) tea.Cmd {
switch key.String() {
case "b", "u":
m.paginator().PrevPage()
case "f", "d":
case "d", "f":
m.paginator().NextPage()
}
}
@ -867,8 +901,10 @@ func loadLocalMarkdown(md *markdown) tea.Cmd {
func filterMarkdowns(m stashModel) tea.Cmd {
return func() tea.Msg {
if m.filterInput.Value() == "" || !m.filterApplied() {
return filteredMarkdownMsg(m.markdowns) // return everything
if m.filterInput.Value() == "" {
m.filteredMarkdowns = m.markdowns
sortMarkdowns(m.filteredMarkdowns, m.sortByDate, sortOrder(m.sortAscending))
return filteredMarkdownMsg(m.filteredMarkdowns)
}
targets := []string{}

View file

@ -106,12 +106,21 @@ func (m stashModel) helpView() (string, int) {
editHelp []string
sectionHelp []string
appHelp []string
sortHelp []string
)
if numDocs > 0 && m.showFullHelp {
navHelp = []string{"enter", "open", "j/k ↑/↓", "choose"}
}
// Only show sort help in full help view
if numDocs > 0 && m.showFullHelp {
sortHelp = []string{
"y", "toggle date sort",
"t", "toggle title sort",
}
}
if len(m.sections) > 1 {
if m.showFullHelp {
navHelp = append(navHelp, "tab/shift+tab", "section")
@ -149,7 +158,7 @@ func (m stashModel) helpView() (string, int) {
if m.filterState != filtering {
appHelp = append(appHelp, "?", "close help")
}
return m.renderHelp(navHelp, filterHelp, append(selectionHelp, editHelp...), sectionHelp, appHelp)
return m.renderHelp(navHelp, sortHelp, filterHelp, append(selectionHelp, editHelp...), sectionHelp, appHelp)
}
// Mini help