1package model
2
3import (
4 "fmt"
5 "log/slog"
6 "strings"
7
8 "charm.land/bubbles/v2/key"
9 tea "charm.land/bubbletea/v2"
10 "charm.land/lipgloss/v2"
11 "github.com/charmbracelet/crush/internal/config"
12 "github.com/charmbracelet/crush/internal/home"
13 "github.com/charmbracelet/crush/internal/ui/common"
14)
15
16func (m *UI) markProjectInitialized() tea.Msg {
17 // TODO: handle error so we show it in the tui footer
18 err := config.MarkProjectInitialized()
19 if err != nil {
20 slog.Error(err.Error())
21 }
22 return nil
23}
24
25func (m *UI) updateInitializeView(msg tea.KeyPressMsg) (cmds []tea.Cmd) {
26 switch {
27 case key.Matches(msg, m.keyMap.Initialize.Enter):
28 if m.onboarding.yesInitializeSelected {
29 cmds = append(cmds, m.initializeProject())
30 } else {
31 cmds = append(cmds, m.skipInitializeProject())
32 }
33 case key.Matches(msg, m.keyMap.Initialize.Switch):
34 m.onboarding.yesInitializeSelected = !m.onboarding.yesInitializeSelected
35 case key.Matches(msg, m.keyMap.Initialize.Yes):
36 cmds = append(cmds, m.initializeProject())
37 case key.Matches(msg, m.keyMap.Initialize.No):
38 cmds = append(cmds, m.skipInitializeProject())
39 }
40 return cmds
41}
42
43func (m *UI) initializeProject() tea.Cmd {
44 // TODO: initialize the project
45 // for now we just go to the landing page
46 m.state = uiLanding
47 m.focus = uiFocusEditor
48 // TODO: actually send a message to the agent
49 return m.markProjectInitialized
50}
51
52func (m *UI) skipInitializeProject() tea.Cmd {
53 // TODO: initialize the project
54 m.state = uiLanding
55 m.focus = uiFocusEditor
56 // mark the project as initialized
57 return m.markProjectInitialized
58}
59
60func (m *UI) initializeView() string {
61 cfg := m.com.Config()
62 s := m.com.Styles.Initialize
63 cwd := home.Short(cfg.WorkingDir())
64 initFile := cfg.Options.InitializeAs
65
66 header := s.Header.Render("Would you like to initialize this project?")
67 path := s.Accent.PaddingLeft(2).Render(cwd)
68 desc := s.Content.Render(fmt.Sprintf("When I initialize your codebase I examine the project and put the result into an %s file which serves as general context.", initFile))
69 hint := s.Content.Render("You can also initialize anytime via ") + s.Accent.Render("ctrl+p") + s.Content.Render(".")
70 prompt := s.Content.Render("Would you like to initialize now?")
71
72 buttons := common.ButtonGroup(m.com.Styles, []common.ButtonOpts{
73 {Text: "Yep!", Selected: m.onboarding.yesInitializeSelected},
74 {Text: "Nope", Selected: !m.onboarding.yesInitializeSelected},
75 }, " ")
76
77 // max width 60 so the text is compact
78 width := min(m.layout.main.Dx(), 60)
79
80 return lipgloss.NewStyle().
81 Width(width).
82 Height(m.layout.main.Dy()).
83 PaddingBottom(1).
84 AlignVertical(lipgloss.Bottom).
85 Render(strings.Join(
86 []string{
87 header,
88 path,
89 desc,
90 hint,
91 prompt,
92 buttons,
93 },
94 "\n\n",
95 ))
96}