Files
nib-v1/internal/tui/promote.go
lerko ce335cabd6 feat(tui): add cards view, mode switching, promote picker, and card detail
Stream/cards toggle with 1/2 keys. Cards view with intent filtering
(tab cycles grab/read/fill/all), sort cycling (s key), pinned-first
ordering, and affordance badges. Promote picker (p key) with card type
selection and auto-detection from body content. Detail view renders
card_data per type: checklist steps, template slots, decision fields,
link URLs.

Extracts generateCardData to internal/carddata for reuse across cmd
and tui packages.
2026-05-17 21:14:14 -04:00

85 lines
1.8 KiB
Go

package tui
import (
"github.com/lerko/nib/internal/carddata"
"github.com/lerko/nib/internal/db"
"github.com/lerko/nib/internal/display"
)
type promoteOption struct {
cardType db.CardType
label string
group string
}
var promoteOptions = []promoteOption{
{db.CardSnippet, "snippet", "grab"},
{db.CardNote, "note", "read"},
{db.CardLink, "link", "read"},
{db.CardDecision, "decision", "read"},
{db.CardTemplate, "template", "fill"},
{db.CardChecklist, "checklist", "fill"},
}
type promoteModel struct {
cursor int
entityID string
body string
suggested *db.CardType
}
func newPromoteModel(entityID, body string) promoteModel {
return promoteModel{
entityID: entityID,
body: body,
suggested: carddata.DetectCardType(body),
}
}
func (p promoteModel) selectedType() db.CardType {
return promoteOptions[p.cursor].cardType
}
func (p promoteModel) update(key string) promoteModel {
switch key {
case "up", "k":
if p.cursor > 0 {
p.cursor--
}
case "down", "j":
if p.cursor < len(promoteOptions)-1 {
p.cursor++
}
}
return p
}
func (p promoteModel) view(width int) string {
var b string
b += titleStyle.Render("promote to card") + "\n\n"
currentGroup := ""
for i, opt := range promoteOptions {
if opt.group != currentGroup {
currentGroup = opt.group
b += dateHeaderStyle.Render("── "+currentGroup+" ──") + "\n"
}
glyph := display.DisplayGlyph(db.GlyphNote, &opt.cardType)
label := glyph + " " + opt.label
if p.suggested != nil && *p.suggested == opt.cardType {
label += " " + affordanceStyle.Render("*")
}
if i == p.cursor {
b += selectedItemStyle.Render(" "+label) + "\n"
} else {
b += listItemStyle.Render(label) + "\n"
}
}
b += "\n" + helpStyle.Render("enter:select esc:cancel")
return b
}