Four things people hit while using the panel:
- The bot could be sent into a channel the requester was not in, and
playback could be started from nowhere. Playback now follows the
listener (REQUIRE_LISTENER, on by default), and the voice row shows
where you and the bot are instead of offering a free channel picker.
- Voice presence only refreshed on reload, because the SDK updates
channel participants without emitting an event. The socket now watches
that view and pushes changes.
- The bot left the channel whenever the queue ran dry. It now leaves only
after the last person does, EMPTY_TIMEOUT_SECONDS later (120 by
default), and stays put while anyone is still listening.
- A search that yielded nothing said nothing: yt-dlp can exit 0 with an
empty result, so that case now reports the reason (or "nothing found"),
and searches are logged with their result count.
The queue moved under the player so search owns the left column, and
elapsed time no longer renders as "LIVE" — formatDuration treated 0 as a
live stream, which also affected the chat's progress bar.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>