gostations/internal/ui/ui.go

70 lines
1.6 KiB
Go
Raw Normal View History

package ui
import (
"fmt"
tea "github.com/charmbracelet/bubbletea"
"github.com/charmbracelet/lipgloss"
"github.com/gmgauthier/gostations/internal/radio"
)
// App is the root Bubble Tea model for the two-stage UI (selection then playback).
type App struct {
stations []radio.Station
// current view state etc.
width, height int
quitting bool
}
func NewApp(initial []radio.Station) *App {
return &App{stations: initial}
}
func (a *App) Init() tea.Cmd {
return nil
}
func (a *App) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
switch msg := msg.(type) {
case tea.KeyMsg:
switch msg.String() {
case "q", "ctrl+c":
a.quitting = true
return a, tea.Quit
case "enter":
// TODO Phase2: switch to playback view, start player etc.
return a, nil
}
case tea.WindowSizeMsg:
a.width = msg.Width
a.height = msg.Height
}
return a, nil
}
var (
titleStyle = lipgloss.NewStyle().Bold(true).Foreground(lipgloss.Color("63"))
)
func (a *App) View() string {
if a.quitting {
return "Thanks for using GoStations!\n"
}
s := titleStyle.Render("GoStations - Radio Browser") + "\n\n"
s += "Selection view (placeholder). Press enter for playback stub, q to quit.\n"
if len(a.stations) > 0 {
s += fmt.Sprintf("%d stations available (favorites would be pinned here).\n", len(a.stations))
s += "First: " + a.stations[0].Name + "\n"
}
s += "\n(Full two-stage TUI with bubbles/list + playback controls coming in Phase 2.)\n"
return s
}
// Run starts the TUI program (alt screen).
func Run(initial []radio.Station) error {
p := tea.NewProgram(NewApp(initial), tea.WithAltScreen())
_, err := p.Run()
return err
}