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 = common.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}