feat(tui): always-visible capture bar with focus cycling
Replace drawer-based input with permanent capture bar at bottom. Focus defaults to capture on startup — open nib, start typing. - Remove stateInput; route via focusCapture/focusList/focusDetail - Tab cycles: capture → list → detail (split) → capture - Esc cascades: clear search → clear filter → focus capture - Capture bar shows blinking cursor when focused, dims when not - Intent cycling moved from tab to i (tab now cycles focus) - Parse preview shown inline in status bar while typing - Content area constant height (no layout thrash from drawer)
This commit is contained in:
+17
-47
@@ -19,7 +19,6 @@ type inputResult struct {
|
||||
|
||||
type inputModel struct {
|
||||
ti textinput.Model
|
||||
active bool
|
||||
preview *parse.Result
|
||||
}
|
||||
|
||||
@@ -31,15 +30,8 @@ func newInputModel() inputModel {
|
||||
return inputModel{ti: ti}
|
||||
}
|
||||
|
||||
func (i *inputModel) focus() {
|
||||
i.active = true
|
||||
i.ti.Focus()
|
||||
}
|
||||
|
||||
func (i *inputModel) reset() {
|
||||
i.active = false
|
||||
func (i *inputModel) clearText() {
|
||||
i.ti.SetValue("")
|
||||
i.ti.Blur()
|
||||
i.preview = nil
|
||||
}
|
||||
|
||||
@@ -101,33 +93,21 @@ func (i inputModel) updateKey(msg tea.KeyMsg) inputModel {
|
||||
return i
|
||||
}
|
||||
|
||||
func (i inputModel) view(width int) string {
|
||||
var b strings.Builder
|
||||
label := "capture"
|
||||
prefix := "── "
|
||||
suffix := " "
|
||||
dashCount := width - len(prefix) - len(label) - len(suffix)
|
||||
if dashCount < 0 {
|
||||
dashCount = 0
|
||||
func (i inputModel) viewBar(width int, focused bool) string {
|
||||
tiView := i.ti.View()
|
||||
if focused {
|
||||
return tiView
|
||||
}
|
||||
b.WriteString(drawerBorderStyle.Render(prefix) +
|
||||
hintDescStyle.Render(label) +
|
||||
drawerBorderStyle.Render(suffix+strings.Repeat("─", dashCount)))
|
||||
b.WriteString("\n")
|
||||
b.WriteString(i.ti.View())
|
||||
b.WriteString("\n")
|
||||
b.WriteString(drawerHintsStyle.Render(renderHints([]hint{
|
||||
{"enter", "submit"}, {"esc", "cancel"}, {"?", "search"},
|
||||
{"-", "todo"}, {"@", "event"}, {"!", "reminder"},
|
||||
})))
|
||||
b.WriteString("\n")
|
||||
b.WriteString(i.renderPreview(width))
|
||||
return b.String()
|
||||
val := i.ti.Value()
|
||||
if val != "" {
|
||||
return hintDescStyle.Render("› " + val)
|
||||
}
|
||||
return hintDescStyle.Render("› capture a thought…")
|
||||
}
|
||||
|
||||
func (i inputModel) renderPreview(width int) string {
|
||||
func (i inputModel) previewText() string {
|
||||
if i.preview == nil {
|
||||
return drawerPreviewStyle.Render("")
|
||||
return ""
|
||||
}
|
||||
|
||||
p := i.preview
|
||||
@@ -140,7 +120,7 @@ func (i inputModel) renderPreview(width int) string {
|
||||
for _, t := range p.FilterTags {
|
||||
q += " #" + t
|
||||
}
|
||||
return drawerPreviewStyle.Render("search: " + q)
|
||||
return "search: " + q
|
||||
}
|
||||
|
||||
glyph := glyphForParsed(p.Glyph)
|
||||
@@ -152,22 +132,16 @@ func (i inputModel) renderPreview(width int) string {
|
||||
var parts []string
|
||||
parts = append(parts, glyph, body)
|
||||
for _, t := range p.Tags {
|
||||
parts = append(parts, tagStyle.Render("#"+t))
|
||||
parts = append(parts, "#"+t)
|
||||
}
|
||||
if p.Pin {
|
||||
parts = append(parts, pinnedStyle.Render("•"))
|
||||
parts = append(parts, "•")
|
||||
}
|
||||
if p.CardSuffix != nil {
|
||||
parts = append(parts, affordanceStyle.Render(*p.CardSuffix))
|
||||
parts = append(parts, *p.CardSuffix)
|
||||
}
|
||||
|
||||
line := strings.Join(parts, " ")
|
||||
maxW := width - 4
|
||||
if maxW > 0 && len(stripAnsi(line)) > maxW {
|
||||
line = truncate(line, maxW)
|
||||
}
|
||||
|
||||
return drawerPreviewStyle.Render(line)
|
||||
return strings.Join(parts, " ")
|
||||
}
|
||||
|
||||
func glyphForParsed(glyph string) string {
|
||||
@@ -182,7 +156,3 @@ func glyphForParsed(glyph string) string {
|
||||
return "—"
|
||||
}
|
||||
}
|
||||
|
||||
func drawerLines() int {
|
||||
return 3
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user