You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Add a persistent 1-2 line "now playing" status bar at the bottom of every buffer, showing the current episode, playback state, position, and volume — regardless of which buffer is active.
The NowPlaying buffer (#140) shows playback info, but only when the user switches to it. While browsing podcasts, episodes, or playlists, there's no indication of what's currently playing. Users must switch buffers (F6) just to check playback state.
Popular terminal music players (cmus, ncmpcpp) solve this with a persistent status bar.
Proposed Solution
1. Layout Change
Reserve 1-2 lines at the bottom of the terminal for the mini-player, above the minibuffer/status line:
┌─ Podcasts ─────────────────────────────────────────────┐
│ > My Podcast │
│ Another Podcast │
│ ... │
│ │
├─────────────────────────────────────────────────────────┤
│ ▶ Episode Title - Podcast Name 12:34/45:00 Vol: 80% │
├─────────────────────────────────────────────────────────┤
│ :command [Podcasts] │
└─────────────────────────────────────────────────────────┘
2. Implementation
In the main render function (src/ui/app.rs, render() method):
fnrender(&self,frame:&mutFrame){let chunks = Layout::default().direction(Direction::Vertical).constraints([Constraint::Min(1),// Main buffer areaConstraint::Length(1),// Mini-player bar (NEW)Constraint::Length(1),// Status/minibuffer line]).split(frame.area());// Render active bufferself.render_buffer(frame, chunks[0]);// Render mini-player (always visible when playing)self.render_mini_player(frame, chunks[1]);// Render status line / minibufferself.render_status(frame, chunks[2]);}
3. Mini-Player Widget
fnrender_mini_player(&self,frame:&mutFrame,area:Rect){ifletSome(ref rx) = self.playback_status_rx{let status = rx.borrow();match status.state{PlaybackState::Playing | PlaybackState::Paused => {let icon = if status.state == PlaybackState::Playing{"▶"}else{"⏸"};let pos = format_duration(status.position);let dur = format_duration(status.duration);let vol = format!("Vol: {}%",(status.volume *100.0)asu32);let text = format!("{icon} {title} {pos}/{dur} {vol}");// Render with theme styles}PlaybackState::Stopped => {// Hide mini-player or show empty line}}}}
4. Adaptive Layout
When nothing is playing: hide the mini-player line (give space back to buffer)
When playing: show the 1-line bar
Truncate episode title if terminal is narrow
Right-align position and volume
Files to Modify
File
Change
src/ui/app.rs
Modify render layout to include mini-player row
src/ui/components/mini_player.rs
New — Mini-player widget component
src/ui/themes.rs
Add mini-player styles (background, text colors)
Acceptance Criteria
Mini-player bar visible at bottom when audio is playing
Shows: state icon, episode title, position/duration, volume
Hidden when nothing is playing (no wasted space)
Works in every buffer (podcast list, episode list, detail, help, etc.)
Adapts to terminal width (truncates title if needed)
Uses Theme styles (no hardcoded colors)
Does not interfere with minibuffer/status line
Implementation Notes
This changes the global render layout — needs careful testing with all buffers
The mini-player is NOT a buffer (not managed by BufferManager) — it's a persistent UI component rendered by UIApp::render() directly
Consider making it optional via config: config.ui.show_mini_player: bool
Summary
Add a persistent 1-2 line "now playing" status bar at the bottom of every buffer, showing the current episode, playback state, position, and volume — regardless of which buffer is active.
Related: #131 (Meta-Epic: Cross-Platform Audio Playback)
Problem / Background
The NowPlaying buffer (#140) shows playback info, but only when the user switches to it. While browsing podcasts, episodes, or playlists, there's no indication of what's currently playing. Users must switch buffers (F6) just to check playback state.
Popular terminal music players (cmus, ncmpcpp) solve this with a persistent status bar.
Proposed Solution
1. Layout Change
Reserve 1-2 lines at the bottom of the terminal for the mini-player, above the minibuffer/status line:
2. Implementation
In the main render function (
src/ui/app.rs,render()method):3. Mini-Player Widget
4. Adaptive Layout
Files to Modify
src/ui/app.rssrc/ui/components/mini_player.rssrc/ui/themes.rsAcceptance Criteria
Implementation Notes
UIApp::render()directlyconfig.ui.show_mini_player: bool