1package modes
2
3import (
4 "fmt"
5 "strings"
6
7 "github.com/mattn/go-runewidth"
8
9 "github.com/patriceckhart/zot/internal/tui"
10)
11
12type extPanelDialog struct {
13 active bool
14 ext string
15 id string
16 title string
17 lines []string
18 footer string
19}
20
21func newExtPanelDialog() *extPanelDialog { return &extPanelDialog{} }
22
23func (d *extPanelDialog) Active() bool { return d != nil && d.active }
24
25func (d *extPanelDialog) Open(ext, id, title string, lines []string, footer string) {
26 d.active = true
27 d.ext = ext
28 d.id = id
29 d.title = title
30 d.lines = append([]string(nil), lines...)
31 d.footer = footer
32}
33
34func (d *extPanelDialog) Update(title string, lines []string, footer string) {
35 if !d.active {
36 return
37 }
38 if title != "" {
39 d.title = title
40 }
41 d.lines = append(d.lines[:0], lines...)
42 d.footer = footer
43}
44
45func (d *extPanelDialog) Close() {
46 d.active = false
47 d.ext = ""
48 d.id = ""
49 d.title = ""
50 d.lines = nil
51 d.footer = ""
52}
53
54func (d *extPanelDialog) Render(th tui.Theme, width int) []string {
55 if !d.Active() {
56 return nil
57 }
58 title := d.title
59 if title == "" {
60 title = d.ext
61 }
62 out := []string{frameHeaderColor(th, title, width, th.Accent)}
63 for _, l := range d.lines {
64 plain := stripANSIBytes(l)
65 trimmed := strings.TrimLeft(plain, " ")
66 selected := strings.HasPrefix(trimmed, "▸ ") || strings.HasPrefix(trimmed, "● ")
67 out = append(out, styleExtPanelLine(th, l, plain, width, selected))
68 }
69 if strings.TrimSpace(d.footer) != "" {
70 out = append(out, "")
71 out = append(out, th.FG256(th.Muted, d.footer))
72 }
73 out = append(out, frameRuleColor(th, width, th.Accent))
74 return out
75}
76
77func styleExtPanelLine(th tui.Theme, raw string, plain string, width int, selected bool) string {
78 if selected {
79 if visible := runewidth.StringWidth(plain); visible < width {
80 plain += strings.Repeat(" ", width-visible)
81 }
82 base := fmt.Sprintf("\x1b[38;5;%dm\x1b[48;5;%dm", th.SelectionFG, th.SelectionBG)
83 green := fmt.Sprintf("\x1b[38;5;%dm\x1b[48;5;%dm", th.Tool, th.SelectionBG)
84 return base + strings.ReplaceAll(plain, "✓", green+"✓"+base) + "\x1b[0m"
85 }
86 if raw != plain {
87 return raw + "\x1b[0m"
88 }
89 styled := th.FG256(th.Muted, plain)
90 styled = strings.ReplaceAll(styled, "✓", th.FG256(th.Tool, "✓"))
91 return styled
92}