1package repo
2
3import (
4 "fmt"
5 "io"
6
7 "github.com/charmbracelet/bubbles/key"
8 "github.com/charmbracelet/bubbles/list"
9 tea "github.com/charmbracelet/bubbletea"
10 "github.com/charmbracelet/soft-serve/git"
11 "github.com/charmbracelet/soft-serve/ui/common"
12)
13
14// RefItem is a git reference item.
15type RefItem struct {
16 *git.Reference
17}
18
19// ID implements selector.IdentifiableItem.
20func (i RefItem) ID() string {
21 return i.Reference.Name().String()
22}
23
24// Title implements list.DefaultItem.
25func (i RefItem) Title() string {
26 return i.Reference.Name().Short()
27}
28
29// Description implements list.DefaultItem.
30func (i RefItem) Description() string {
31 return ""
32}
33
34// Short returns the short name of the reference.
35func (i RefItem) Short() string {
36 return i.Reference.Name().Short()
37}
38
39// FilterValue implements list.Item.
40func (i RefItem) FilterValue() string { return i.Short() }
41
42// RefItems is a list of git references.
43type RefItems []RefItem
44
45// Len implements sort.Interface.
46func (cl RefItems) Len() int { return len(cl) }
47
48// Swap implements sort.Interface.
49func (cl RefItems) Swap(i, j int) { cl[i], cl[j] = cl[j], cl[i] }
50
51// Less implements sort.Interface.
52func (cl RefItems) Less(i, j int) bool {
53 return cl[i].Short() < cl[j].Short()
54}
55
56// RefItemDelegate is the delegate for the ref item.
57type RefItemDelegate struct {
58 common *common.Common
59}
60
61// Height implements list.ItemDelegate.
62func (d RefItemDelegate) Height() int { return 1 }
63
64// Spacing implements list.ItemDelegate.
65func (d RefItemDelegate) Spacing() int { return 0 }
66
67// Update implements list.ItemDelegate.
68func (d RefItemDelegate) Update(msg tea.Msg, m *list.Model) tea.Cmd {
69 idx := m.Index()
70 item, ok := m.SelectedItem().(RefItem)
71 if !ok {
72 return nil
73 }
74 switch msg := msg.(type) {
75 case tea.KeyMsg:
76 switch {
77 case key.Matches(msg, d.common.KeyMap.Copy):
78 d.common.Copy.Copy(item.Title())
79 return m.SetItem(idx, item)
80 }
81 }
82 return nil
83}
84
85// Render implements list.ItemDelegate.
86func (d RefItemDelegate) Render(w io.Writer, m list.Model, index int, listItem list.Item) {
87 s := d.common.Styles
88 i, ok := listItem.(RefItem)
89 if !ok {
90 return
91 }
92
93 ref := i.Short()
94 if i.Reference.IsTag() {
95 ref = s.RefItemTag.Render(ref)
96 }
97 ref = s.RefItemBranch.Render(ref)
98 refMaxWidth := m.Width() -
99 s.RefItemSelector.GetMarginLeft() -
100 s.RefItemSelector.GetWidth() -
101 s.RefItemInactive.GetMarginLeft()
102 ref = truncateString(ref, refMaxWidth, "…")
103 if index == m.Index() {
104 fmt.Fprint(w, s.RefItemSelector.Render(">")+
105 s.RefItemActive.Render(ref))
106 } else {
107 fmt.Fprint(w, s.RefItemSelector.Render(" ")+
108 s.RefItemInactive.Render(ref))
109 }
110}