1package repo
2
3import (
4 "fmt"
5 "io"
6 "strings"
7
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/styles"
12 "github.com/muesli/reflow/truncate"
13)
14
15type LogItem struct {
16 *git.Commit
17}
18
19func (i LogItem) ID() string {
20 return i.Commit.ID.String()
21}
22
23func (i LogItem) Title() string {
24 if i.Commit != nil {
25 return strings.Split(i.Commit.Message, "\n")[0]
26 }
27 return ""
28}
29
30func (i LogItem) Description() string { return "" }
31
32func (i LogItem) FilterValue() string { return i.Title() }
33
34type LogItemDelegate struct {
35 style *styles.Styles
36}
37
38func (d LogItemDelegate) Height() int { return 1 }
39func (d LogItemDelegate) Spacing() int { return 0 }
40func (d LogItemDelegate) Update(msg tea.Msg, m *list.Model) tea.Cmd { return nil }
41func (d LogItemDelegate) Render(w io.Writer, m list.Model, index int, listItem list.Item) {
42 i, ok := listItem.(LogItem)
43 if !ok {
44 return
45 }
46 if i.Commit == nil {
47 return
48 }
49
50 hash := i.Commit.ID.String()
51 leftMargin := d.style.LogItemSelector.GetMarginLeft() +
52 d.style.LogItemSelector.GetWidth() +
53 d.style.LogItemHash.GetMarginLeft() +
54 d.style.LogItemHash.GetWidth() +
55 d.style.LogItemInactive.GetMarginLeft()
56 title := truncateString(i.Title(), m.Width()-leftMargin, "…")
57 if index == m.Index() {
58 fmt.Fprint(w, d.style.LogItemSelector.Render(">")+
59 d.style.LogItemHash.Bold(true).Render(hash[:7])+
60 d.style.LogItemActive.Render(title))
61 } else {
62 fmt.Fprint(w, d.style.LogItemSelector.Render(" ")+
63 d.style.LogItemHash.Render(hash[:7])+
64 d.style.LogItemInactive.Render(title))
65 }
66}
67
68func truncateString(s string, max int, tail string) string {
69 if max < 0 {
70 max = 0
71 }
72 return truncate.StringWithTail(s, uint(max), tail)
73}