Skip to content

fix(radio): What's Playing copy and review always answer you (#1282) - #1286

Merged
accesswatch merged 1 commit into
mainfrom
fix/whats-playing-commands
Aug 2, 2026
Merged

fix(radio): What's Playing copy and review always answer you (#1282)#1286
accesswatch merged 1 commit into
mainfrom
fix/whats-playing-commands

Conversation

@accesswatch

Copy link
Copy Markdown
Contributor

Closes #1282.

Howard reported that with a station playing, Copy What's Playing and What's Playing - Review and Copy... "do nothing except return to the main window" — while with nothing playing, both speak a sensible message. That inversion is the tell: the code was answering correctly only on the path where it never got as far as the real work.

Three faults

  1. A missing title was treated as "nothing is playing." Both commands read a cached track title and gave up when it was empty — which is the normal state for the first seconds of a station, for a stream whose ICY tap is refused, and for every station when track announcements are off. The review window never opened in that case at all.
  2. The fallback was asynchronous and could end in silence. It called the speak-only What's Playing command, which starts a background fetch and returns — so the palette closed with nothing on screen — and its on_failure=lambda *_a: None swallowed any error, so nothing was ever spoken either. With nothing playing, the same path answers immediately ("Nothing is playing."), which is exactly why the bug looked backwards.
  3. A successful copy reported failure in the standalone apps. AppShellFrame._copy_to_clipboard returned None where MainFrame._copy_to_clipboard returns a bool, and the shared radio mixin branches on that value — so in Quill Radio (Howard's app) a copy that actually worked announced "Could not copy to the clipboard."

The fix

With a station on, both commands now resolve the title first — announcing "Checking what's playing..." so the command never looks dead — and then finish the job. _radio_fetch_track_title gained an on_resolved callback that fires on the UI thread for success and failure, so a waiting command always gets its turn; the two swallow-everything on_failure lambdas are gone. A stream that carries no titles says so, and the review window still opens naming the station — someone who asked to review what is playing should get a window to arrow through, not a one-shot announcement. The copy confirmation now names what it copied. Both hosts' clipboard helpers return bool.

Tests

9 new tests against the extracted, wx-free command helpers: cached title copies; a missing title is fetched and then copied rather than claiming nothing is playing; a title-less stream says so; a clipboard failure is reported; nothing playing says so; and the review window opens with the track, opens after fetching a missing title, opens naming the station when the stream has no titles, and stays closed with nothing playing. Two existing wiring tests were updated to the new wording (with the reason recorded inline).

pytest tests/unit/ui -k radio → 153 passed. Ruff, mypy, and GATE-11 green.

Docs

CHANGELOG, release notes 1.0.0, user guide (a new "Copying and reviewing what's playing" paragraph), and the PRD radio section, with HTML/EPUB regenerated.

🤖 Generated with Claude Code

Reported by Howard Goldstein: with a station playing, "Copy What's Playing"
and "What's Playing - Review and Copy..." return to the main window having
done nothing -- no window, no copy, nothing spoken -- while with nothing
playing both speak a sensible message. Three faults behind that:

1. A *missing* track title was treated as "nothing is playing". That is the
   normal state for the first seconds of a station, for a stream whose ICY
   tap is refused, and for every station when track announcements are off.
   The review window never opened in that case; it degraded to the
   speak-only command.
2. That fallback is asynchronous. It starts a background fetch and returns,
   so the palette closes with nothing on screen -- and its on_failure
   swallowed the error, so nothing was spoken either. Silence, exactly as
   reported. With nothing playing the same path answers immediately
   ("Nothing is playing."), which is why the bug looked inverted.
3. AppShellFrame._copy_to_clipboard returned None where
   MainFrame._copy_to_clipboard returns a bool, and the shared radio mixin
   branches on that value -- so in Quill Radio a copy that actually worked
   announced "Could not copy to the clipboard."

Now: with a station on, both commands resolve the title first (announcing
"Checking what's playing...") and then finish the job. A stream that carries
no titles says so and the review window still opens naming the station -- a
listener who asked to review what is playing gets a window to arrow through,
not silence. A failed fetch is reported instead of swallowed. The copy
confirmation names what it copied. Both hosts' clipboard helpers return bool.

The command bodies live in the new ui/radio/now_playing_commands.py; the
on_resolved plumbing stays with the fetch it instruments (GATE-11 residue
rebaselined with the reasoning recorded).

Docs: CHANGELOG, release notes 1.0.0, user guide (What's playing), and the
PRD radio section, with HTML/EPUB regenerated.

Closes #1282

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@accesswatch
accesswatch requested a review from kellylford as a code owner August 2, 2026 17:55
Copilot AI review requested due to automatic review settings August 2, 2026 17:55

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Not ready to approve

copy_whats_playing can announce the “no titles” message when playback stops mid-fetch because it doesn’t re-check station state on the empty-title completion path.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

This review doesn't count toward merge requirements. Sign up for the private preview to control whether Copilot approvals count.

Pull request overview

This PR fixes a user-reported regression in the Radio “What’s Playing” copy/review commands by ensuring they resolve track titles (including via async fetch) before acting, and by aligning clipboard helper return contracts across hosts so copy success/failure is reported correctly.

Changes:

  • Adds wx-free “now playing” command helpers that fetch-on-demand and always produce a user-facing outcome (copy confirmation, dialog, or spoken message).
  • Threads an on_resolved UI-thread callback through the async title-fetch plumbing so waiting commands reliably continue on both success and failure paths.
  • Updates/extends unit tests and user-facing docs/release notes/changelog to reflect the new behavior and wording.
File summaries
File Description
tests/unit/ui/test_radio_whats_playing_commands.py New unit tests covering copy/review behavior across cached, fetched, no-title, and nothing-playing scenarios.
tests/unit/ui/test_radio_now_playing_wiring.py Updates expected copy confirmation and “nothing playing” wording for wiring-level tests.
quill/ui/radio/now_playing_commands.py New wx-free helper functions for resolving/copying/showing now-playing details with consistent user feedback.
quill/ui/main_frame_radio.py Adds on_resolved callback plumbing to async title fetch + replaces silent failure lambdas.
quill/ui/app_shell.py Makes _copy_to_clipboard return bool to match MainFrame contract and avoid false failure announcements.
quill/tools/module_size_budgets.json Rebaselines size budget entries to account for the required wiring/plumbing growth.
docs/user guide/userguide.md Documents the improved “Copying and reviewing what’s playing” behavior and messaging.
docs/user guide/userguide.html Regenerated HTML user guide reflecting the new paragraph.
docs/release notes/release1.0.0.md Adds a release-note bullet describing the fix and user-visible outcomes.
docs/release notes/release1.0.0.html Regenerated HTML release notes reflecting the new bullet.
docs/Product Requirement Documents and Specifications/QUILL-PRD.md Updates PRD radio section to codify the fixed behavior and contracts.
docs/Product Requirement Documents and Specifications/QUILL-PRD.html Regenerated HTML PRD reflecting the new section.
CHANGELOG.md Adds a changelog entry describing the bug and the behavioral fixes.
Review details
  • Files reviewed: 13/16 changed files
  • Comments generated: 1
  • Review effort level: Lite

We're testing this review assessment. Please use 👍 or 👎 to tell us if it's correct.

Comment on lines +70 to +73
def _copy(text: str) -> None:
if not text:
host._announce(NO_TITLE_MESSAGE)
return
@accesswatch
accesswatch merged commit 338a7b8 into main Aug 2, 2026
17 checks passed
@accesswatch
accesswatch deleted the fix/whats-playing-commands branch August 6, 2026 01:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Quill] bug report: "copy What's Playing" and "What's Playing - Review & Copy" commands do nothing

2 participants