Files
Turbine/pkg/launchpad/interactive/dev_mode.go

127 lines
2.4 KiB
Go

package interactive
import (
"fmt"
"strings"
"git.solsynth.dev/goatworks/turbine/pkg/launchpad/config"
tea "github.com/charmbracelet/bubbletea"
"github.com/charmbracelet/lipgloss"
)
var (
titleStyle = lipgloss.NewStyle().
Background(lipgloss.Color("62")).
Foreground(lipgloss.Color("230")).
Padding(0, 1)
helpStyle = lipgloss.NewStyle().Foreground(lipgloss.Color("241"))
)
type model struct {
services []config.Service
cursor int
selected map[int]struct{}
startServices bool
}
func initialModel(services []config.Service) model {
selected := make(map[int]struct{})
for i := range services {
selected[i] = struct{}{}
}
return model{
services: services,
selected: selected,
}
}
func (m model) Init() tea.Cmd {
return nil
}
func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
switch msg := msg.(type) {
case tea.KeyMsg:
switch msg.String() {
case "ctrl+c", "q":
return m, tea.Quit
case "up", "k":
if m.cursor > 0 {
m.cursor--
}
case "down", "j":
if m.cursor < len(m.services)-1 {
m.cursor++
}
case " ":
if _, ok := m.selected[m.cursor]; ok {
delete(m.selected, m.cursor)
} else {
m.selected[m.cursor] = struct{}{}
}
case "enter":
m.startServices = true
return m, tea.Quit
}
}
return m, nil
}
func (m model) View() string {
var b strings.Builder
b.WriteString(titleStyle.Render("Select services to start"))
b.WriteString("\n\n")
for i, service := range m.services {
cursor := " "
if m.cursor == i {
cursor = ">"
}
checked := " "
if _, ok := m.selected[i]; ok {
checked = "x"
}
b.WriteString(fmt.Sprintf("%s [%s] %s\n", cursor, checked, service.Name))
}
b.WriteString("\n")
b.WriteString(helpStyle.Render("Use up/down to navigate, space to select, enter to start, q to quit."))
return b.String()
}
func (m model) SelectedServices() []config.Service {
var selectedServices []config.Service
for i := range m.selected {
selectedServices = append(selectedServices, m.services[i])
}
return selectedServices
}
func SelectServices(services []config.Service) ([]config.Service, error) {
if len(services) == 0 {
return nil, fmt.Errorf("no services defined in launchpad.toml")
}
m := initialModel(services)
p := tea.NewProgram(m)
finalModel, err := p.Run()
if err != nil {
return nil, err
}
fm := finalModel.(model)
if fm.startServices {
return fm.SelectedServices(), nil
}
return nil, nil // User quit
}