refactor: one copy of the UI's repeated helpers
- Text inputs come from newTextInput; the link and folder prompts share one width. - One starred-first sort for sources, vaults and secrets; accountOf where the account was cut from the label by hand. - One helper each for the reveal and clipboard countdowns' tick and seconds, the "Open with" choices, the vaults-loaded count, and Go to's and the panes' tabs. - The details pane builds its label prefix, indent, note and source once; list rows mark matches with MarkMatches. - The release page opens through openPage, so it now says it opened, as other pages do. - The cache's account filter is built once per load or save, not per key.
This commit is contained in:
18 files changed
+171
-216
No files matched your search
@@ -69,3 +69,20 @@ func TitleStyle(st styles.Styles, focused bool) lipgloss.Style {
|
||||
}
|
||||
return st.TitleBlurred
|
||||
}
|
||||
|
||||
// Tabs draws tab names for a title in style ts, the current one
|
||||
// underlined and the rest muted.
|
||||
func Tabs(st styles.Styles, ts lipgloss.Style, names []string, current int) string {
|
||||
var out string
|
||||
for i, name := range names {
|
||||
if i > 0 {
|
||||
out += ts.Render(" - ")
|
||||
}
|
||||
if i == current {
|
||||
out += ts.Underline(true).Render(name)
|
||||
} else {
|
||||
out += st.Muted.Render(name)
|
||||
}
|
||||
}
|
||||
return out
|
||||
}
|
||||
+27
-21
@@ -188,20 +188,31 @@ func carryStyle(lines []string) []string {
|
||||
return lines
|
||||
}
|
||||
|
||||
var valueIndent = strings.Repeat(" ", 12)
|
||||
|
||||
// fieldLabel starts a detail line: the label, padded so values line up
|
||||
// at valueIndent.
|
||||
func fieldLabel(st styles.Styles, label string) string {
|
||||
return " " + st.Label.Render(fmt.Sprintf("%-10s", label)) + " "
|
||||
}
|
||||
|
||||
// lines renders the body, wrapped to the pane width.
|
||||
func (d Detail) lines(st styles.Styles) []string {
|
||||
inner := max(1, d.w-3)
|
||||
var out []string
|
||||
field := func(label, value string) {
|
||||
prefix := " " + st.Label.Render(fmt.Sprintf("%-10s", label)) + " "
|
||||
indent := strings.Repeat(" ", 12)
|
||||
wrapped := carryStyle(strings.Split(ansi.Hardwrap(value, max(1, inner-11), true), "\n"))
|
||||
out = append(out, prefix+wrapped[0])
|
||||
out = append(out, fieldLabel(st, label)+wrapped[0])
|
||||
for _, w := range wrapped[1:] {
|
||||
out = append(out, indent+w)
|
||||
out = append(out, valueIndent+w)
|
||||
}
|
||||
}
|
||||
muted := st.Muted.Render
|
||||
note := func() {
|
||||
if d.note != "" {
|
||||
field("note", st.Favourite.Render(d.note))
|
||||
}
|
||||
}
|
||||
|
||||
if d.container == nil {
|
||||
return []string{muted(" Select a vault or scope to browse its secrets.")}
|
||||
@@ -211,30 +222,27 @@ func (d Detail) lines(st styles.Styles) []string {
|
||||
if containerLabel == "" {
|
||||
containerLabel = "vault"
|
||||
}
|
||||
source := d.Icons.Prefix(c.Source.Kind) + cmp.Or(c.Source.ProviderLabel, string(c.Source.Kind)) + " / " + c.Source.Name
|
||||
|
||||
if d.secret == nil {
|
||||
field(containerLabel, c.Name)
|
||||
if d.note != "" {
|
||||
field("note", st.Favourite.Render(d.note))
|
||||
}
|
||||
note()
|
||||
if c.Detail != "" {
|
||||
field("", muted(c.Detail))
|
||||
}
|
||||
field("source", d.Icons.Prefix(c.Source.Kind)+cmp.Or(c.Source.ProviderLabel, string(c.Source.Kind))+" / "+c.Source.Name)
|
||||
field("source", source)
|
||||
out = append(out, "", muted(" Select a secret to see its details."))
|
||||
return out
|
||||
}
|
||||
|
||||
s := *d.secret
|
||||
field("name", s.Name)
|
||||
if d.note != "" {
|
||||
field("note", st.Favourite.Render(d.note))
|
||||
}
|
||||
note()
|
||||
field(containerLabel, c.Name)
|
||||
if c.Source.Kind != provider.KindAzure && c.Detail != "" {
|
||||
field("", muted(c.Detail))
|
||||
}
|
||||
field("source", d.Icons.Prefix(c.Source.Kind)+cmp.Or(c.Source.ProviderLabel, string(c.Source.Kind))+" / "+c.Source.Name)
|
||||
field("source", source)
|
||||
if s.Version != "" {
|
||||
field("version", s.Version)
|
||||
}
|
||||
@@ -298,14 +306,12 @@ func (d Detail) lines(st styles.Styles) []string {
|
||||
case provider.TypeCertificate:
|
||||
label, hidden, reveal = "cert", "", "show the certificate"
|
||||
}
|
||||
indent := strings.Repeat(" ", 12)
|
||||
|
||||
out = append(out, "")
|
||||
switch d.state {
|
||||
case ValueHidden:
|
||||
if hidden != "" {
|
||||
field(label, hidden)
|
||||
out = append(out, indent+hints(reveal))
|
||||
out = append(out, valueIndent+hints(reveal))
|
||||
} else {
|
||||
field(label, hints(reveal))
|
||||
}
|
||||
@@ -322,9 +328,9 @@ func (d Detail) lines(st styles.Styles) []string {
|
||||
for j, w := range strings.Split(ansi.Wrap(text, max(1, inner-11-len(lead)), ""), "\n") {
|
||||
w = lead + w
|
||||
if i == 0 && j == 0 {
|
||||
out = append(out, " "+st.Label.Render(fmt.Sprintf("%-10s", label))+" "+st.Error.Render(w))
|
||||
out = append(out, fieldLabel(st, label)+st.Error.Render(w))
|
||||
} else {
|
||||
out = append(out, strings.Repeat(" ", 12)+st.Error.Render(w))
|
||||
out = append(out, valueIndent+st.Error.Render(w))
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -335,10 +341,10 @@ func (d Detail) lines(st styles.Styles) []string {
|
||||
for _, line := range lines {
|
||||
for _, w := range strings.Split(ansi.Hardwrap(line, max(1, inner-11), true), "\n") {
|
||||
if first {
|
||||
out = append(out, " "+st.Label.Render(fmt.Sprintf("%-10s", label))+" "+st.Value.Render(w))
|
||||
out = append(out, fieldLabel(st, label)+st.Value.Render(w))
|
||||
first = false
|
||||
} else {
|
||||
out = append(out, indent+st.Value.Render(w))
|
||||
out = append(out, valueIndent+st.Value.Render(w))
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -352,7 +358,7 @@ func (d Detail) lines(st styles.Styles) []string {
|
||||
if d.hidesIn != "" {
|
||||
more = append(more, "hides in "+d.hidesIn)
|
||||
}
|
||||
out = append(out, indent+hints("hide", more...))
|
||||
out = append(out, valueIndent+hints("hide", more...))
|
||||
}
|
||||
return append(out, d.versionLines(st)...)
|
||||
}
|
||||
@@ -373,7 +379,7 @@ func (d Detail) versionLines(st styles.Styles) []string {
|
||||
head += muted(" · " + d.VersionsKey + " to browse")
|
||||
}
|
||||
}
|
||||
out := []string{"", " " + st.Label.Render(fmt.Sprintf("%-10s", "versions")) + " " + head}
|
||||
out := []string{"", fieldLabel(st, "versions") + head}
|
||||
current := d.versions[0].Version
|
||||
for i, v := range d.versions {
|
||||
if i == maxVersionLines {
|
||||
|
||||
@@ -329,17 +329,7 @@ func (l List[T]) View(st styles.Styles, focused bool, spin string) string {
|
||||
ts := TitleStyle(st, focused)
|
||||
title := ts.Render(l.Title)
|
||||
if len(l.Tabs) > 1 {
|
||||
for i, tab := range l.Tabs {
|
||||
sep := " - "
|
||||
if i == 0 {
|
||||
sep = " "
|
||||
}
|
||||
if i == l.Tab {
|
||||
title += ts.Render(sep) + ts.Underline(true).Render(tab)
|
||||
} else {
|
||||
title += ts.Render(sep) + st.Muted.Render(tab)
|
||||
}
|
||||
}
|
||||
title += ts.Render(" ") + Tabs(st, ts, l.Tabs, l.Tab)
|
||||
}
|
||||
if q := l.input.Value(); q != "" && !l.filtering {
|
||||
title += ts.Render(" /" + q)
|
||||
@@ -370,26 +360,13 @@ func (l List[T]) View(st styles.Styles, focused bool, spin string) string {
|
||||
default:
|
||||
for i := l.offset; i < len(l.visible) && i < l.offset+rows; i++ {
|
||||
line := l.item.Render(st, l.items[l.visible[i]], inner-1)
|
||||
plain := ansi.Strip(line)
|
||||
hits := l.highlight(i, plain)
|
||||
line = " " + MarkMatches(line, l.highlight(i, ansi.Strip(line)), st.Match)
|
||||
if i == l.cursor {
|
||||
base := st.SelectedBlurred
|
||||
if focused {
|
||||
base = st.Selected
|
||||
}
|
||||
text := " " + line
|
||||
if len(hits) > 0 {
|
||||
for j := range hits {
|
||||
hits[j]++ // leading space
|
||||
}
|
||||
text = lipgloss.StyleRanges(text, matchRanges(" "+plain, hits, st.Match)...)
|
||||
}
|
||||
line = Highlight(ansi.Truncate(text, inner, "…"), base, inner)
|
||||
} else if len(hits) > 0 {
|
||||
// Style just the matches, keeping the row's own colours.
|
||||
line = " " + lipgloss.StyleRanges(line, matchRanges(plain, hits, st.Match)...)
|
||||
} else {
|
||||
line = " " + line
|
||||
line = Highlight(ansi.Truncate(line, inner, "…"), base, inner)
|
||||
}
|
||||
body = append(body, line)
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user