1package dialog
2
3import (
4 "charm.land/lipgloss/v2"
5 "github.com/charmbracelet/catwalk/pkg/catwalk"
6 "github.com/charmbracelet/crush/internal/ui/common"
7 "github.com/charmbracelet/crush/internal/ui/styles"
8 "github.com/charmbracelet/x/ansi"
9 "github.com/sahilm/fuzzy"
10)
11
12// ModelGroup represents a group of model items.
13type ModelGroup struct {
14 Title string
15 Items []*ModelItem
16 configured bool
17 t *styles.Styles
18}
19
20// NewModelGroup creates a new ModelGroup.
21func NewModelGroup(t *styles.Styles, title string, configured bool, items ...*ModelItem) ModelGroup {
22 return ModelGroup{
23 Title: title,
24 Items: items,
25 configured: configured,
26 t: t,
27 }
28}
29
30// AppendItems appends [ModelItem]s to the group.
31func (m *ModelGroup) AppendItems(items ...*ModelItem) {
32 m.Items = append(m.Items, items...)
33}
34
35// Render implements [list.Item].
36func (m *ModelGroup) Render(width int) string {
37 var configured string
38 if m.configured {
39 configuredIcon := m.t.ToolCallSuccess.Render()
40 configuredText := m.t.Subtle.Render("Configured")
41 configured = configuredIcon + " " + configuredText
42 }
43
44 title := " " + m.Title + " "
45 title = ansi.Truncate(title, max(0, width-lipgloss.Width(configured)-1), "…")
46
47 return common.Section(m.t, title, width, configured)
48}
49
50// ModelItem represents a list item for a model type.
51type ModelItem struct {
52 prov catwalk.Provider
53 model catwalk.Model
54
55 cache map[int]string
56 t *styles.Styles
57 m fuzzy.Match
58 focused bool
59 showProvider bool
60}
61
62var _ ListItem = &ModelItem{}
63
64// NewModelItem creates a new ModelItem.
65func NewModelItem(t *styles.Styles, prov catwalk.Provider, model catwalk.Model, showProvider bool) *ModelItem {
66 return &ModelItem{
67 prov: prov,
68 model: model,
69 t: t,
70 cache: make(map[int]string),
71 showProvider: showProvider,
72 }
73}
74
75// Filter implements ListItem.
76func (m *ModelItem) Filter() string {
77 return m.model.Name
78}
79
80// ID implements ListItem.
81func (m *ModelItem) ID() string {
82 return modelKey(string(m.prov.ID), m.model.ID)
83}
84
85// Render implements ListItem.
86func (m *ModelItem) Render(width int) string {
87 var providerInfo string
88 if m.showProvider {
89 providerInfo = string(m.prov.Name)
90 }
91 return renderItem(m.t, m.model.Name, providerInfo, m.focused, width, m.cache, &m.m)
92}
93
94// SetFocused implements ListItem.
95func (m *ModelItem) SetFocused(focused bool) {
96 if m.focused != focused {
97 m.cache = nil
98 }
99 m.focused = focused
100}
101
102// SetMatch implements ListItem.
103func (m *ModelItem) SetMatch(fm fuzzy.Match) {
104 m.cache = nil
105 m.m = fm
106}