Skip to content

v5.5.1

Choose a tag to compare

@sahara101 sahara101 released this 01 Aug 20:11
· 3 commits to main since this release

Improvements

  • Trakt Device Code authorization - the previous flow opened https://trakt.tv/oauth/authorize with redirect_uri=urn:ietf:wg:oauth:2.0:oob. Trakt retired out-of-band redirects, so approving the request sent the browser to a urn: address it cannot resolve; instead of showing a code, the browser offered to hand the address to an external application and the connection could never be completed. Settings now shows a short activation code next to a link to https://trakt.tv/activate, the server polls /oauth/device/token until you approve, and watched history synchronizes immediately afterwards
  • Trakt application credentials no longer lock the integration UI - TRAKT_CLIENT_ID and TRAKT_CLIENT_SECRET identify the application rather than a user session, so they no longer mark Trakt as environment controlled; only TRAKT_ENABLED, TRAKT_ACCESS_TOKEN, and TRAKT_REFRESH_TOKEN do. The built-in Trakt application needs no configuration, while self-hosters using their own application must set the client ID and its secret, since Trakt requires a secret for both the device and refresh grants
  • Tracking provider selector redesign - the None / Trakt / Simkl control now reports each provider's own state (Active, Signed in, Not connected, Needs Client Secret / Needs Client ID) beside provider logos, with hover, keyboard focus, disabled, and in-progress styling and a HeroUI variant matching the rest of the settings page. Both providers can hold a connection at once while only the selected one contributes watched status, so the labels now distinguish the active provider from a retained connection

Bug Fixes

  • Trakt sessions dropped after the first token rotation - refresh requests omitted the client secret Trakt requires, and a rotated refresh token was not always persisted, so a single-use token could be spent without being replaced. Refreshes now send the secret, store the rotated pair, serialize concurrent refreshes, and skip the exchange when another request already renewed the session. A refresh rejected with invalid_grant clears the stored tokens and resets the provider so the UI asks for a reconnect instead of retrying a dead session
  • Periodic Trakt sync skipped regular users - the background loop iterated get_users(), which returns a projection carrying only account metadata, so trakt_enabled and trakt_access_token were never present and no regular user was selected for a sync. Managed users were unaffected
  • Poster stuck on a finished movie instead of returning to the screensaver - the screensaver loop was never stopped when playback began, which killed the browser polling that reported PLAYING back to the server; the poster manager then stayed latched on STOPPED, the 5-minute transition timer never armed, and current_movie.json was never cleared. Playback state is now driven server-side by PlaybackMonitor, and stored playback state past the movie's end time (plus a grace period) is discarded
  • Default-poster transition timer could only fire once - the expired threading.Timer handle was left assigned, and a new timer refuses to arm while one is present, so any later stop that was not preceded by a cancel never scheduled a transition

Full Changelog: v5.5.0...v5.5.1