Files
beefy-player/somafm_tui/widgets/help.py
T
beefcarver 2570d9b854 docs(readme): document macOS support, Now Playing and loopback capture
Split the install instructions per platform, add the macOS microphone
permission and BlackHole/Multi-Output recipe for a synced spectrum,
describe the Now Playing integration and its limits, and note that config
and cache stay in the XDG locations. The in-app help text is now
platform-aware too, and the package metadata lists macOS.
2026-10-30 18:43:26 -04:00

94 lines
3.0 KiB
Python

"""Full-screen keyboard help."""
from __future__ import annotations
import sys
import textwrap
from rich.console import Group
from rich.table import Table
from rich.text import Text
from textual.app import ComposeResult
from textual.screen import ModalScreen
from textual.widgets import Static
from .common import SPECTRUM_STOPS, gradient
HELP_ROWS: tuple[tuple[str, str], ...] = (
("↑ / ↓ j / k", "move through the station list"),
("enter", "tune in to the selected station"),
("space", "play / pause the current station"),
("s", "stop playback"),
("] / [", "next / previous station (tunes immediately)"),
("+ / -", "volume up / down"),
("m", "mute / unmute"),
("f", "favourite — favourites float to the top"),
("/", "filter stations by title, genre or description"),
("esc", "clear the filter / close overlays"),
("v", "cycle visualiser: mirrored bars → bars → wave"),
("r", "refresh station list and song history"),
("g / G", "jump to the top / bottom of the list"),
("? ", "this help"),
("q", "quit"),
)
ABOUT_COMMON = (
(
"Stations and song history come from somafm.com "
"(channels.json + songs/<station>.json)."
),
)
ABOUT_LINUX = (
(
"The spectrum captures your actual PulseAudio/PipeWire output with "
"parec (SYNC); otherwise it falls back to a muted ffmpeg stream tap "
"(FFT, can drift) or a synthesized display (SIM)."
),
(
"The desktop picks us up over MPRIS as a "
"somafmtui media player — try `playerctl -l` / `playerctl metadata`."
),
)
ABOUT_MACOS = (
(
"The spectrum follows your audio output (SYNC) when a loopback device "
"such as BlackHole is available for ffmpeg/avfoundation; otherwise it "
"falls back to a muted ffmpeg stream tap (FFT, can drift) or a "
"synthesized display (SIM)."
),
(
"mpv publishes what is playing to the macOS Now Playing session, so "
"Control Center and the keyboard media keys control this app."
),
)
ABOUT = ABOUT_COMMON + (ABOUT_MACOS if sys.platform == "darwin" else ABOUT_LINUX)
class HelpScreen(ModalScreen[None]):
def compose(self) -> ComposeResult:
table = Table.grid(padding=(0, 2), expand=False)
table.add_column(style="bold cyan", no_wrap=True, justify="right")
table.add_column(style="")
for key, description in HELP_ROWS:
table.add_row(key, description)
header = Text()
header.append("◤ ", style=f"bold {gradient(SPECTRUM_STOPS, 0.9)}")
header.append("SOMAFM TUI", style=f"bold {gradient(SPECTRUM_STOPS, 0.55)}")
header.append(" keyboard & credits", style="dim")
footer = Text()
for paragraph in ABOUT:
for line in textwrap.wrap(paragraph, width=70):
footer.append(line + "\n", style="dim")
body = Group(header, Text(""), table, Text(""), footer)
yield Static(body, id="help")
def on_key(self, event) -> None:
event.stop()
self.dismiss(None)