feat(tui): add bubbletea terminal UI with entity list, detail, and capture
Adds `nib tui` command and `make tui` target. Scrollable entity list with j/k navigation, enter for detail view, `a` to capture new entries using the existing parse grammar, and `d` to delete.
This commit is contained in:
@@ -0,0 +1,76 @@
|
||||
package tui
|
||||
|
||||
import (
|
||||
"github.com/charmbracelet/bubbles/textinput"
|
||||
tea "github.com/charmbracelet/bubbletea"
|
||||
|
||||
"github.com/lerko/nib/internal/db"
|
||||
"github.com/lerko/nib/internal/parse"
|
||||
)
|
||||
|
||||
type inputModel struct {
|
||||
ti textinput.Model
|
||||
active bool
|
||||
}
|
||||
|
||||
func newInputModel() inputModel {
|
||||
ti := textinput.New()
|
||||
ti.Placeholder = "capture a thought…"
|
||||
ti.Prompt = inputPromptStyle.Render("› ")
|
||||
ti.CharLimit = 500
|
||||
return inputModel{ti: ti}
|
||||
}
|
||||
|
||||
func (i *inputModel) focus() {
|
||||
i.active = true
|
||||
i.ti.Focus()
|
||||
}
|
||||
|
||||
func (i *inputModel) reset() {
|
||||
i.active = false
|
||||
i.ti.SetValue("")
|
||||
i.ti.Blur()
|
||||
}
|
||||
|
||||
func (i inputModel) submit() *db.Entity {
|
||||
val := i.ti.Value()
|
||||
if val == "" {
|
||||
return nil
|
||||
}
|
||||
|
||||
parsed, err := parse.Parse(val)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
e := &db.Entity{
|
||||
Body: parsed.Body,
|
||||
Title: parsed.Title,
|
||||
Glyph: db.Glyph(parsed.Glyph),
|
||||
Tags: parsed.Tags,
|
||||
}
|
||||
if parsed.TimeAnchor != nil {
|
||||
e.TimeAnchor = parsed.TimeAnchor
|
||||
}
|
||||
if parsed.CardSuffix != nil {
|
||||
ct := db.CardType(*parsed.CardSuffix)
|
||||
e.CardType = &ct
|
||||
}
|
||||
if parsed.Pin {
|
||||
e.Pinned = true
|
||||
}
|
||||
if parsed.Description != nil {
|
||||
e.Description = parsed.Description
|
||||
}
|
||||
|
||||
return e
|
||||
}
|
||||
|
||||
func (i inputModel) updateKey(msg tea.KeyMsg) inputModel {
|
||||
i.ti, _ = i.ti.Update(msg)
|
||||
return i
|
||||
}
|
||||
|
||||
func (i inputModel) view(width int) string {
|
||||
return i.ti.View()
|
||||
}
|
||||
Reference in New Issue
Block a user