1package selector
 2
 3import (
 4	"fmt"
 5	"io"
 6	"strings"
 7	"time"
 8
 9	"github.com/charmbracelet/bubbles/list"
10	tea "github.com/charmbracelet/bubbletea"
11	"github.com/charmbracelet/soft-serve/ui/components/yankable"
12	"github.com/charmbracelet/soft-serve/ui/styles"
13	"github.com/dustin/go-humanize"
14)
15
16type Item struct {
17	Title       string
18	Name        string
19	Description string
20	LastUpdate  time.Time
21	URL         *yankable.Yankable
22}
23
24func (i *Item) Init() tea.Cmd {
25	return nil
26}
27
28func (i *Item) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
29	return i, nil
30}
31
32func (i *Item) View() string {
33	return ""
34}
35
36func (i Item) FilterValue() string { return i.Title }
37
38type ItemDelegate struct {
39	styles *styles.Styles
40}
41
42func (d ItemDelegate) Width() int {
43	width := d.styles.MenuItem.GetHorizontalFrameSize() + d.styles.MenuItem.GetWidth()
44	return width
45}
46func (d ItemDelegate) Height() int {
47	height := d.styles.MenuItem.GetVerticalFrameSize() + d.styles.MenuItem.GetHeight()
48	return height
49}
50func (d ItemDelegate) Spacing() int { return 1 }
51func (d ItemDelegate) Update(msg tea.Msg, m *list.Model) tea.Cmd {
52	cmds := make([]tea.Cmd, 0)
53	for i, item := range m.VisibleItems() {
54		itm, ok := item.(Item)
55		if !ok {
56			continue
57		}
58		// FIXME check if X & Y are within the item box
59		switch msg := msg.(type) {
60		case tea.MouseMsg:
61			x := msg.X
62			y := msg.Y
63			minX := (i * d.Width())
64			maxX := minX + d.Width()
65			minY := (i * d.Height())
66			maxY := minY + d.Height()
67			// log.Printf("i: %d, x: %d, y: %d", i, x, y)
68			if y < minY || y > maxY || x < minX || x > maxX {
69				continue
70			}
71		}
72		y, cmd := itm.URL.Update(msg)
73		itm.URL = y.(*yankable.Yankable)
74		if cmd != nil {
75			cmds = append(cmds, cmd)
76		}
77	}
78	return tea.Batch(cmds...)
79}
80func (d ItemDelegate) Render(w io.Writer, m list.Model, index int, listItem list.Item) {
81	i := listItem.(Item)
82	s := strings.Builder{}
83	style := d.styles.MenuItem
84	if index == m.Index() {
85		style = d.styles.SelectedMenuItem
86	}
87	updated := d.styles.MenuLastUpdate.Render(fmt.Sprintf("Updated %s", humanize.Time(i.LastUpdate)))
88
89	s.WriteString(fmt.Sprintf("%s %s", i.Title, updated))
90	s.WriteString("\n")
91	s.WriteString(i.Description)
92	s.WriteString("\n\n")
93	s.WriteString(i.URL.View())
94	w.Write([]byte(style.Render(s.String())))
95}