package cli import ( "fmt" tea "github.com/charmbracelet/bubbletea" "github.com/charmbracelet/lipgloss" "github.com/hachem-wtf/benson/internal/config" "github.com/hachem-wtf/benson/internal/server" ) func runStart(m *model) tea.Cmd { pid, err := server.Start(m.cfg) if err != nil { return tea.Println(errorStyle.Render(err.Error())) } return tea.Println(successStyle.Render("Server started ") + mutedStyle.Render(fmt.Sprintf("(pid %d) · logs: %s", pid, server.LogPath(m.cfg)))) } func runStop(m *model) tea.Cmd { return m.runServerJob(func(cfg *config.Config, emit func(string)) tea.Msg { if err := server.Stop(cfg, emit); err != nil { return streamDoneMsg{errorStyle.Render(err.Error())} } return streamDoneMsg{successStyle.Render("Server stopped.")} }) } func runRestart(m *model) tea.Cmd { return m.runServerJob(func(cfg *config.Config, emit func(string)) tea.Msg { if err := server.Restart(cfg, emit); err != nil { return streamDoneMsg{errorStyle.Render(err.Error())} } return streamDoneMsg{successStyle.Render("Server restarted.")} }) } func runStatus(m *model) tea.Cmd { m.busy = true cfg := m.cfg return tea.Batch(m.spin.Tick, func() tea.Msg { return outputMsg{text: renderStatus(server.GetStatus(cfg))} }) } func (m *model) runServerJob(job func(cfg *config.Config, emit func(string)) tea.Msg) tea.Cmd { m.busy = true ch := make(chan tea.Msg, 64) m.events = ch cfg := m.cfg go func() { emit := func(line string) { ch <- streamMsg{" " + mutedStyle.Render(line)} } ch <- job(cfg, emit) }() return tea.Batch(m.spin.Tick, waitForEvent(ch)) } func renderStatus(s server.Status) string { rows := []string{headingStyle.Render("Server status"), ""} if s.Running { rows = append(rows, " "+successStyle.Render("● running")+mutedStyle.Render(fmt.Sprintf(" (pid %d)", s.PID))) } else { rows = append(rows, " "+errorStyle.Render("● stopped")) } rows = append(rows, " "+mutedStyle.Render("address ")+s.Address) if s.Reachable { rows = append(rows, " "+mutedStyle.Render("version ")+s.Version, " "+mutedStyle.Render("players ")+fmt.Sprintf("%d / %d", s.Players, s.MaxPlayers), ) if s.MOTD != "" { rows = append(rows, " "+mutedStyle.Render("motd ")+s.MOTD) } } else if s.Running { rows = append(rows, " "+warnStyle.Render("not yet accepting connections (still loading?)")) } return lipgloss.JoinVertical(lipgloss.Left, rows...) }