1package git
  2
  3import (
  4	tea "github.com/charmbracelet/bubbletea"
  5	"github.com/charmbracelet/lipgloss"
  6	"github.com/charmbracelet/soft-serve/internal/tui/bubbles/git/about"
  7	"github.com/charmbracelet/soft-serve/internal/tui/bubbles/git/log"
  8	"github.com/charmbracelet/soft-serve/internal/tui/bubbles/git/refs"
  9	"github.com/charmbracelet/soft-serve/internal/tui/bubbles/git/tree"
 10	"github.com/charmbracelet/soft-serve/internal/tui/bubbles/git/types"
 11	"github.com/charmbracelet/soft-serve/internal/tui/style"
 12	"github.com/go-git/go-git/v5/plumbing"
 13)
 14
 15const (
 16	repoNameMaxWidth = 32
 17)
 18
 19type pageState int
 20
 21const (
 22	aboutPage pageState = iota
 23	refsPage
 24	logPage
 25	treePage
 26)
 27
 28type Bubble struct {
 29	state        pageState
 30	repo         types.Repo
 31	height       int
 32	heightMargin int
 33	width        int
 34	widthMargin  int
 35	style        *style.Styles
 36	boxes        []tea.Model
 37}
 38
 39func NewBubble(repo types.Repo, styles *style.Styles, width, wm, height, hm int) *Bubble {
 40	b := &Bubble{
 41		repo:         repo,
 42		state:        aboutPage,
 43		width:        width,
 44		widthMargin:  wm,
 45		height:       height,
 46		heightMargin: hm,
 47		style:        styles,
 48		boxes:        make([]tea.Model, 4),
 49	}
 50	heightMargin := hm + lipgloss.Height(b.headerView())
 51	b.boxes[aboutPage] = about.NewBubble(repo, b.style, b.width, wm, b.height, heightMargin)
 52	b.boxes[refsPage] = refs.NewBubble(repo, b.style, b.width, wm, b.height, heightMargin)
 53	b.boxes[logPage] = log.NewBubble(repo, b.style, width, wm, height, heightMargin)
 54	b.boxes[treePage] = tree.NewBubble(repo, b.style, width, wm, height, heightMargin)
 55	return b
 56}
 57
 58func (b *Bubble) Init() tea.Cmd {
 59	return b.setupCmd
 60}
 61
 62func (b *Bubble) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
 63	cmds := make([]tea.Cmd, 0)
 64	switch msg := msg.(type) {
 65	case tea.KeyMsg:
 66		switch msg.String() {
 67		case "A":
 68			b.state = aboutPage
 69		case "R":
 70			b.state = refsPage
 71		case "L":
 72			b.state = logPage
 73		case "T":
 74			b.state = treePage
 75		}
 76	case tea.WindowSizeMsg:
 77		b.width = msg.Width
 78		b.height = msg.Height
 79		for i, bx := range b.boxes {
 80			m, cmd := bx.Update(msg)
 81			b.boxes[i] = m
 82			if cmd != nil {
 83				cmds = append(cmds, cmd)
 84			}
 85		}
 86	}
 87	m, cmd := b.boxes[b.state].Update(msg)
 88	b.boxes[b.state] = m
 89	if cmd != nil {
 90		cmds = append(cmds, cmd)
 91	}
 92
 93	switch msg := msg.(type) {
 94	case tea.KeyMsg:
 95		switch msg.String() {
 96		case "enter":
 97			if b.state == refsPage {
 98				b.state = treePage
 99				cmds = append(cmds, b.boxes[b.state].Init())
100			}
101		}
102	}
103	return b, tea.Batch(cmds...)
104}
105
106func (b *Bubble) Help() []types.HelpEntry {
107	h := []types.HelpEntry{}
108	if b.state != treePage {
109		h = append(h, types.HelpEntry{"↑/↓", "navigate"})
110	}
111	h = append(h, b.boxes[b.state].(types.HelpableBubble).Help()...)
112	if b.state != aboutPage {
113		h = append(h, types.HelpEntry{"A", "about"})
114	}
115	if b.state != refsPage {
116		h = append(h, types.HelpEntry{"R", "refs"})
117	}
118	if b.state != logPage {
119		h = append(h, types.HelpEntry{"L", "log"})
120	}
121	if b.state != treePage {
122		h = append(h, types.HelpEntry{"T", "tree"})
123	}
124	return h
125}
126
127func (b *Bubble) Reference() plumbing.ReferenceName {
128	return b.repo.GetReference().Name()
129}
130
131func (b *Bubble) headerView() string {
132	// TODO better header, tabs?
133	return ""
134}
135
136func (b *Bubble) View() string {
137	header := b.headerView()
138	return header + b.boxes[b.state].View()
139}
140
141func (b *Bubble) setupCmd() tea.Msg {
142	cmds := make([]tea.Cmd, 0)
143	for _, bx := range b.boxes {
144		if bx != nil {
145			initCmd := bx.Init()
146			if initCmd != nil {
147				msg := initCmd()
148				switch msg := msg.(type) {
149				case types.ErrMsg:
150					return msg
151				}
152			}
153			cmds = append(cmds, initCmd)
154		}
155	}
156	return tea.Batch(cmds...)
157}