c2ea63dd16
Status bar with entity count and context-sensitive key hints. Help overlay via ? key. Tag filter via # with cursor-navigable tag list. Todo toggle (x), pin (!), promote (p), demote (D), copy (c), edit (e) via $EDITOR. Delete confirmation with 3s timeout. Date-grouped list with completed todo and pinned indicators. Esc clears active tag filter. Adds CompletedAt/ClearCompleted to EntityUpdate for todo toggling.
85 lines
1.4 KiB
Go
85 lines
1.4 KiB
Go
package tui
|
|
|
|
import (
|
|
"fmt"
|
|
"strings"
|
|
|
|
"github.com/lerko/nib/internal/db"
|
|
)
|
|
|
|
type filterModel struct {
|
|
tags []db.TagCount
|
|
cursor int
|
|
height int
|
|
}
|
|
|
|
func newFilterModel() filterModel {
|
|
return filterModel{}
|
|
}
|
|
|
|
func (f *filterModel) setTags(tags []db.TagCount) {
|
|
f.tags = tags
|
|
f.cursor = 0
|
|
}
|
|
|
|
func (f *filterModel) setHeight(h int) {
|
|
f.height = h
|
|
}
|
|
|
|
func (f filterModel) selectedTag() string {
|
|
if len(f.tags) == 0 || f.cursor >= len(f.tags) {
|
|
return ""
|
|
}
|
|
return f.tags[f.cursor].Tag
|
|
}
|
|
|
|
func (f filterModel) update(key string) filterModel {
|
|
switch key {
|
|
case "up", "k":
|
|
if f.cursor > 0 {
|
|
f.cursor--
|
|
}
|
|
case "down", "j":
|
|
if f.cursor < len(f.tags)-1 {
|
|
f.cursor++
|
|
}
|
|
}
|
|
return f
|
|
}
|
|
|
|
func (f filterModel) view(width int) string {
|
|
if len(f.tags) == 0 {
|
|
return statusStyle.Render("no tags")
|
|
}
|
|
|
|
var b strings.Builder
|
|
b.WriteString(titleStyle.Render("filter by tag"))
|
|
b.WriteString("\n\n")
|
|
|
|
visible := f.height - 4
|
|
if visible <= 0 {
|
|
visible = 10
|
|
}
|
|
|
|
offset := 0
|
|
if f.cursor >= visible {
|
|
offset = f.cursor - visible + 1
|
|
}
|
|
end := min(offset+visible, len(f.tags))
|
|
|
|
for i := offset; i < end; i++ {
|
|
tc := f.tags[i]
|
|
tag := fmt.Sprintf("#%-20s %d", tc.Tag, tc.Count)
|
|
if i == f.cursor {
|
|
b.WriteString(selectedItemStyle.Render(" " + tagStyle.Render(tag)))
|
|
} else {
|
|
b.WriteString(listItemStyle.Render(tagStyle.Render(tag)))
|
|
}
|
|
if i < end-1 {
|
|
b.WriteString("\n")
|
|
}
|
|
}
|
|
|
|
return b.String()
|
|
}
|