Files
trufflehog/pkg/tui/pages/wizard_intro/item.go
Amaan Ullah 0fa069c12f Enable errcheck and staticcheck for golangci-lint v2 and resolve all issues (#4924)
* enable errcheck and staticcheck for golangci-lint v2 and resolve all issues

* skip lint on intentional reference of deprecated DetectorType values
2026-05-15 17:07:14 +05:00

138 lines
3.6 KiB
Go

package wizard_intro
import (
"fmt"
"io"
"strings"
"github.com/charmbracelet/bubbles/key"
"github.com/charmbracelet/bubbles/list"
tea "github.com/charmbracelet/bubbletea"
"github.com/charmbracelet/lipgloss"
"github.com/trufflesecurity/trufflehog/v3/pkg/tui/common"
)
// Item represents a single item in the selector.
type Item int
// ID implements selector.IdentifiableItem.
func (i Item) ID() string {
return i.String()
}
// Title returns the item title. Implements list.DefaultItem.
func (i Item) Title() string { return i.String() }
// Description returns the item description. Implements list.DefaultItem.
func (i Item) Description() string { return "" }
// FilterValue implements list.Item.
func (i Item) FilterValue() string { return i.Title() }
// Command returns the item Command view.
func (i Item) Command() string {
return i.Title()
}
// ItemDelegate is the delegate for the item.
type ItemDelegate struct {
common *common.Common
}
// Width returns the item width.
func (d ItemDelegate) Width() int {
width := d.common.Styles.MenuItem.GetHorizontalFrameSize() + d.common.Styles.MenuItem.GetWidth()
return width
}
// Height returns the item height. Implements list.ItemDelegate.
func (d ItemDelegate) Height() int {
height := d.common.Styles.MenuItem.GetVerticalFrameSize() + d.common.Styles.MenuItem.GetHeight()
return height
}
// Spacing returns the spacing between items. Implements list.ItemDelegate.
func (d ItemDelegate) Spacing() int { return 1 }
// Update implements list.ItemDelegate.
func (d ItemDelegate) Update(msg tea.Msg, m *list.Model) tea.Cmd {
idx := m.Index()
item, ok := m.SelectedItem().(Item)
if !ok {
return nil
}
switch msg := msg.(type) {
case tea.KeyMsg:
switch {
case key.Matches(msg, d.common.KeyMap.Copy):
d.common.Copy.Copy(item.Command())
return m.SetItem(idx, item)
}
}
return nil
}
// Render implements list.ItemDelegate.
func (d ItemDelegate) Render(w io.Writer, m list.Model, index int, listItem list.Item) {
i := listItem.(Item)
s := strings.Builder{}
var matchedRunes []int
// Conditions
var (
isSelected = index == m.Index()
isFiltered = m.FilterState() == list.Filtering || m.FilterState() == list.FilterApplied
)
styles := d.common.Styles.RepoSelector.Normal
if isSelected {
styles = d.common.Styles.RepoSelector.Active
}
title := i.Title()
title = common.TruncateString(title, m.Width()-styles.Base.GetHorizontalFrameSize())
// if i.repo.IsPrivate() {
// title += " 🔒"
// }
if isSelected {
title += " "
}
updatedStr := " Updated"
if m.Width()-styles.Base.GetHorizontalFrameSize()-lipgloss.Width(updatedStr)-lipgloss.Width(title) <= 0 {
updatedStr = ""
}
updatedStyle := styles.Updated.
Align(lipgloss.Right).
Width(m.Width() - styles.Base.GetHorizontalFrameSize() - lipgloss.Width(title))
updated := updatedStyle.Render(updatedStr)
if isFiltered && index < len(m.VisibleItems()) {
// Get indices of matched characters
matchedRunes = m.MatchesForItem(index)
}
if isFiltered {
unmatched := styles.Title.Inline(true)
matched := unmatched.Underline(true)
title = lipgloss.StyleRunes(title, matchedRunes, matched, unmatched)
}
title = styles.Title.Render(title)
desc := i.Description()
desc = common.TruncateString(desc, m.Width()-styles.Base.GetHorizontalFrameSize())
desc = styles.Desc.Render(desc)
s.WriteString(lipgloss.JoinHorizontal(lipgloss.Bottom, title, updated))
s.WriteRune('\n')
s.WriteString(desc)
s.WriteRune('\n')
cmd := common.TruncateString(i.Command(), m.Width()-styles.Base.GetHorizontalFrameSize())
cmd = styles.Command.Render(cmd)
s.WriteString(cmd)
_, _ = fmt.Fprint(w,
d.common.Zone.Mark(i.ID(),
styles.Base.Render(s.String()),
),
)
}