Skip to content

fix spotatui native device and selector behavior#293

Merged
LargeModGames merged 1 commit into
LargeModGames:mainfrom
shilicioo:fix/playback-device-selection-fix
Jun 10, 2026
Merged

fix spotatui native device and selector behavior#293
LargeModGames merged 1 commit into
LargeModGames:mainfrom
shilicioo:fix/playback-device-selection-fix

Conversation

@shilicioo

@shilicioo shilicioo commented Jun 9, 2026

Copy link
Copy Markdown
Contributor

Summary

Fixes #292

This change makes explicit playback use the connected native spotatui streaming player when there is no current Spotify playback context, instead of falling through to the Web API and failing with NO_ACTIVE_DEVICE.

It also fixes the device selector behavior:

  • Adds the live local spotatui device to the selector when Spotify's devices API omits it.
  • Clears stale device state on refresh.
  • Shows useful status messages for invalid/empty selection state.
  • Makes Enter dispatch device transfer and close the selector.
  • Makes Esc close the selector instead of trapping the user.

Testing

  • cargo fmt --all
    • Passed
  • cargo clippy --no-default-features --features telemetry -- -D warnings
    • Passed
  • cargo test --no-default-features --features telemetry
    • Passed: 235 tests
  • cargo check
    • Passed with default features, including native streaming

Additional notes

The original bug showed as a Spotify API 404 Not Found / NO_ACTIVE_DEVICE error when trying to play tracks, while the local spotatui playback device was missing from the device selector. The selector could also become stuck because Esc was swallowed by the global handler.

@LargeModGames LargeModGames self-requested a review June 9, 2026 14:38
@LargeModGames

LargeModGames commented Jun 9, 2026

Copy link
Copy Markdown
Owner

Nice fix, this addresses the root cause well. The native-activation gate (is_connected() plus no current_playback_context, matching the saved device by both id and name) is a sensible guard, and preserving selected_device_index across refresh plus surfacing the API error in get_devices are real improvements. Good to see tests for both the Esc and Enter paths.

Two small things:

  • The Key::Esc => app.pop_navigation_stack() arm in select_device.rs is now dead code. Esc is intercepted globally in handle_app then handle_escape, and never reaches the per-screen handler. The actual fix that makes Esc work is the new SelectDevice arm in handle_escape (which is also what escape_exits_device_selector exercises). Worth removing the unreachable branch or leaving a comment that global escape owns it.
  • Can you confirm the non-native transfer branch below the native one also persists the device id when persist_device_id is set? Just want the two branches symmetric.

Otherwise looks good to merge.

@shilicioo shilicioo force-pushed the fix/playback-device-selection-fix branch from 7828e31 to f704140 Compare June 9, 2026 15:10
@shilicioo

Copy link
Copy Markdown
Contributor Author

Thanks @LargeModGames, good catch. I removed the unreachable Key::Esc arm from select_device.rs

the non-native transfer branch is already symmetric: when the Web API transfer succeeds, it persists the selected device_id via client_config.set_device_id(device_id) whenever persist_device_id is true.

@shilicioo shilicioo force-pushed the fix/playback-device-selection-fix branch from f704140 to 782366c Compare June 9, 2026 15:14
@shilicioo shilicioo force-pushed the fix/playback-device-selection-fix branch from 782366c to 638211e Compare June 10, 2026 09:38
@shilicioo

Copy link
Copy Markdown
Contributor Author

Found one more related long-idle case and pushed a fix for it.

After leaving spotatui running for a long time, the native librespot/Connect session can become disconnected while App still holds the stale streaming_player. In that state playback falls through to the Spotify Web API and hits NO_ACTIVE_DEVICE, and the device selector cannot synthesize the local spotatui device because player.is_connected() is false.

The new change treats stored native players as active only when connected, clears stale native state when detected, and triggers the existing native streaming recovery flow from playback/device selection instead of falling through to Web API playback.

@LargeModGames LargeModGames merged commit 55c3dbb into LargeModGames:main Jun 10, 2026
5 checks passed
LargeModGames added a commit that referenced this pull request Jun 11, 2026
# Summary
Fixes a native streaming recovery edge case where spotatui could keep
treating a stale Spotify API `spotatui` device snapshot as the active
native player after librespot disconnected and recovered. This edge-case
became more plausible with the changes added in scope of
#293

This change makes name-only native device matches valid only when there
is fresh local native activity, native playback metadata, or a very
recent explicit activation. It also clears stale playback context on
native disconnect so old API state cannot keep re-poisoning playback
routing.

  # Testing
  - `cargo fmt --all -- --check`
    - Passed
- `cargo clippy --no-default-features --features telemetry -- -D
warnings`
    - Passed
  - `cargo test --no-default-features --features telemetry`
    - Passed: 235 tests
  - `cargo check`
    - Passed with default features, including native streaming code
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.

Native spotatui device missing from selector; playback fails with NO_ACTIVE_DEVICE and selector traps input

2 participants