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 }