Files
beefy-player/somafm_tui/widgets/help.py
T

75 lines
2.5 KiB
Python

"""Full-screen keyboard help."""
from __future__ import annotations
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 = (
(
"Stations and song history come from somafm.com "
"(channels.json + songs/<station>.json)."
),
(
"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`."
),
)
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)