Documentation
¶
Overview ¶
Package pocket is pixeltui's hardware-player front-end: it renders a now-playing screen and maps physical buttons onto playback, driving the headless session.Controller. The actual panel and GPIO live behind the Display/Buttons interfaces — a Raspberry Pi + Pirate Audio (ST7789 + buttons) backend for the device, and a laptop dev backend (PNG out + keyboard) so it runs anywhere.
Index ¶
Constants ¶
const Size = 240
Size is the square panel edge (the Pirate Audio ST7789 is 240×240).
Variables ¶
var Debug bool
Debug, when set (via POCKET_DEBUG in cmdPocket), logs each button press so tap-vs-hold detection can be verified on-device over SSH / journalctl.
Functions ¶
Types ¶
type App ¶
type App struct {
// contains filtered or unexported fields
}
App is the on-device player: a navigation stack of screens (menus, lists, now playing, volume) driven by the four buttons, rendered to the panel.
func (*App) Run ¶
Run renders and reacts until ctx is cancelled. The caller starts the Controller's own poll loop (session.Controller.Run) so progress events flow.
func (*App) SetHost ¶
func (a *App) SetHost(fn func())
SetHost injects the party-hosting action invoked by the "Host Party" menu item.
func (*App) SetOffline ¶
SetOffline updates the connectivity badge (driven by a connectivity.Monitor). Safe to call from another goroutine — it routes through the render loop.
func (*App) SetParty ¶
SetParty enters or leaves party mode. In a party the ROOM is the source of truth: the local player follows the room (applyRoom), so the pocket stays in sync with phones; the shared queue lives in the room; and the pocket's own controls drive the room. Pass nil to leave. Call from a goroutine OTHER than the one running Run — it hands the change to the render loop and waits for it (so it must not be called from a button handler, which runs on the Run loop).
type Button ¶
type Button int
Button is a physical button. On the Pirate Audio the four sit at the screen corners — A top-left, B bottom-left, X top-right, Y bottom-right — and what each does is context-sensitive to the current screen (see handle).
type Buttons ¶
Buttons delivers physical button presses until closed.
func NewDevButtons ¶
func NewDevButtons() Buttons
NewDevButtons returns a Buttons driven by stdin keypresses.
func NewPiButtons ¶
NewPiButtons wires the four tactile buttons as active-low inputs with pull-ups. Each button gets a watcher goroutine that samples its level to time taps vs. holds.
type Controller ¶
type Controller interface {
Current() engine.Candidate
Queue() []engine.Candidate
Playing() bool
TogglePause()
Next()
Prev()
Play(engine.Candidate) error
PlayAll([]engine.Candidate, int)
Enqueue(...engine.Candidate)
Shuffle()
SetRepeat(session.RepeatMode)
SetAutoplay(bool)
SetVolume(int)
Seek(float64)
Stop()
Events() <-chan session.Event
}
Controller is the slice of session.Controller the pocket UI drives (an interface so the app loop is testable with a fake).
type Display ¶
Display renders a frame to the panel and is closed on shutdown.
func NewDevDisplay ¶
NewDevDisplay returns a Display that writes frames to a PNG at path.
func NewPiDisplay ¶
NewPiDisplay opens the ST7789 panel on the Pirate Audio board.
type Sources ¶
type Sources struct {
Registry *source.Registry // optional: drives charts and source-aware downloads
Liked func() []engine.Candidate // liked tracks
Playlists func() []string // playlist names
Playlist func(name string) []engine.Candidate // a playlist's tracks
History func() []engine.Candidate // recently played
Charts func() []engine.Candidate // top charts (sourced from the registry)
Downloaded func() []engine.Candidate // on-device files (downloads + local) — play offline
// Per-track actions (the hold-Y menu); any may be nil.
Like func(engine.Candidate)
Unlike func(engine.Candidate)
IsLiked func(engine.Candidate) bool
Download func(engine.Candidate) error
}
Sources supplies the browsable library/catalog the menus list. Any field may be nil (its menu just shows empty). cmdPocket wires these to the library + the central source registry.
type View ¶
type View struct {
Mode string // "standalone" | "serve" | "party"
Track engine.Candidate
Pos float64
Dur float64
Paused bool
Status string // shown when there's no track (e.g. "queue empty", a party code)
Cover image.Image // optional album art (decoded); nil → no art
Frame int // animation frame (drives marquee scrolling of long names)
}
View is the state the now-playing screen draws.