2684eb1d24
CI / test (pull_request) Successful in 2m18s
Press [ in detail view to open link picker showing all [[links]] in the current entry. Enter follows a link, resolving by title then body substring. Navigation history stack enables esc to pop back through followed links before returning to list. Adds Store.ResolveLink() for non-transactional link resolution from the TUI layer.
66 lines
1.2 KiB
Go
66 lines
1.2 KiB
Go
package tui
|
|
|
|
import (
|
|
"strings"
|
|
|
|
"github.com/lerko/nib/internal/link"
|
|
)
|
|
|
|
type linkPickerModel struct {
|
|
links []string
|
|
cursor int
|
|
}
|
|
|
|
func newLinkPicker(body string) linkPickerModel {
|
|
return linkPickerModel{
|
|
links: link.ExtractLinks(body),
|
|
}
|
|
}
|
|
|
|
func (lp linkPickerModel) selected() string {
|
|
if len(lp.links) == 0 || lp.cursor >= len(lp.links) {
|
|
return ""
|
|
}
|
|
return lp.links[lp.cursor]
|
|
}
|
|
|
|
func (lp linkPickerModel) update(key string) linkPickerModel {
|
|
switch key {
|
|
case "up", "k":
|
|
if lp.cursor > 0 {
|
|
lp.cursor--
|
|
}
|
|
case "down", "j":
|
|
if lp.cursor < len(lp.links)-1 {
|
|
lp.cursor++
|
|
}
|
|
}
|
|
return lp
|
|
}
|
|
|
|
func (lp linkPickerModel) view(width int) string {
|
|
var b strings.Builder
|
|
b.WriteString(titleStyle.Render("follow link") + "\n\n")
|
|
|
|
if len(lp.links) == 0 {
|
|
b.WriteString(hintDescStyle.Render(" no [[links]] in this entry"))
|
|
b.WriteString("\n\n")
|
|
b.WriteString(helpStyle.Render("esc:back"))
|
|
return b.String()
|
|
}
|
|
|
|
for i, lt := range lp.links {
|
|
label := "[[" + lt + "]]"
|
|
if i == lp.cursor {
|
|
b.WriteString(selectedItemStyle.Render(" " + label))
|
|
} else {
|
|
b.WriteString(listItemStyle.Render(label))
|
|
}
|
|
b.WriteString("\n")
|
|
}
|
|
|
|
b.WriteString("\n")
|
|
b.WriteString(helpStyle.Render("enter:follow esc:back"))
|
|
return b.String()
|
|
}
|