Files
-rpi-sendspin/third_party/sendspin-go/internal/ui/tui.go

66 lines
1.7 KiB
Go

// ABOUTME: TUI initialization and control
// ABOUTME: Wraps bubbletea program for player UI
package ui
import (
tea "github.com/charmbracelet/bubbletea"
)
type VolumeControl struct {
Changes chan VolumeChangeMsg
Quit chan QuitMsg
}
func NewVolumeControl() *VolumeControl {
return &VolumeControl{
Changes: make(chan VolumeChangeMsg, 10),
Quit: make(chan QuitMsg, 1),
}
}
type TransportMsg struct {
Command string // "play", "pause", "toggle", "next", "previous", "reconnect"
}
type TransportControl struct {
Commands chan TransportMsg
}
func NewTransportControl() *TransportControl {
return &TransportControl{
Commands: make(chan TransportMsg, 10),
}
}
// Config bundles everything the TUI needs from main.go at construction.
// Extending by adding fields is intentionally cheap — the alternative was
// growing the Run() / NewModel() positional argument list every time a new
// TUI feature needs a dependency.
type Config struct {
VolumeCtrl *VolumeControl
TransportCtrl *TransportControl
// ConfigPath is where WriteStringKey persists settings like audio_device.
// Empty disables the Save action in modals that would write to disk.
ConfigPath string
// AudioDevice is the device currently driving playback, shown in the
// status line and used to seed the picker's highlighted row.
AudioDevice string
}
func NewModel(cfg Config) Model {
return Model{
volume: 100,
state: "idle",
playbackState: "idle",
volumeCtrl: cfg.VolumeCtrl,
transportCtrl: cfg.TransportCtrl,
configPath: cfg.ConfigPath,
audioDevice: cfg.AudioDevice,
}
}
func Run(cfg Config) (*tea.Program, error) {
p := tea.NewProgram(NewModel(cfg), tea.WithAltScreen())
return p, nil
}