Commit Graph
197 Commits
Author SHA1 Message Date
edde746 2ebc1e250d fix(providers): stop loads after disposal 2026-07-12 08:42:22 +02:00
edde746 1b9ef3b3b6 fix(discover): avoid progress refresh fanout 2026-07-12 08:42:21 +02:00
edde746 ac9c236b6b refactor(providers): harden server listener state 2026-07-12 08:42:20 +02:00
edde746 b925705173 fix(downloads): discard stale profile refreshes 2026-07-12 08:42:19 +02:00
edde746 bc55aea701 refactor: remove superseded code paths 2026-07-12 08:42:19 +02:00
edde746 dca51a752a refactor(downloads): centralize metadata merging 2026-07-12 08:42:19 +02:00
edde746 04daf89a20 feat(explore): Explore tab with catalog detail, search, and Seerr requests 2026-07-10 07:10:15 +02:00
edde746 b4943f8c50 feat(seerr): Seerr API, account provider, and Explore catalog source 2026-07-10 07:08:42 +02:00
edde746 2aa084287d feat(explore): MyAnimeList catalog source 2026-07-10 07:07:54 +02:00
edde746 4e6ea5b4c5 feat(trakt): catalog API and shared catalog core (watchlist, discover, recommendations) 2026-07-10 07:06:21 +02:00
edde746 e2ad28ca32 fix(downloads): retain offline media after logout 2026-07-09 23:22:27 +02:00
edde746 5867809560 fix: resolve Jellyfin, logout, playback, and Android regressions 2026-07-09 17:14:45 +02:00
edde746 4a3295b7fd fix(player): handle Plex multi-episode files in up-next and watch state
close #1500
2026-07-06 18:39:45 +02:00
edde746 ef75887504 style: apply analyzer lint fixes across lib
Initializing formals, unawaited() on fire-and-forget futures, unused
import removal, wildcard params, and mounted vs context.mounted.
2026-07-06 15:56:56 +02:00
edde746 764345f021 feat(music): audio downloads and music home rows
Album/artist downloads expand to tracks with pinned parent metadata,
aggregate progress, container deletes with reference-counted album
covers, and a Music tab on the downloads screen with fully offline
album playback. Home rows include music libraries (fixes plex hub
items being filtered to video types) and audio playlists join
download/sync rules.
2026-07-05 21:51:37 +02:00
edde746 05a631415e feat(music): music browsing UI — square cards, library groupings, artist/album screens
Un-gates music libraries; adds CardShape.square plumbing (circular
artists), artists/albums/tracks browse groupings with per-grouping
sorts, audio playlists tab, artist + album detail screens with dpad
track rows, music context-menu actions, and a stub MusicPlaybackService
seam for the upcoming engine.
2026-07-05 17:20:28 +02:00
edde746 c4184c6148 fix(ci): restore sanity checks 2026-07-05 08:34:55 +02:00
edde746 6e83aeda88 fix(hubs): drop deleted items from recommended and home continue watching
The library Recommended tab never subscribed to deletion events, so
"Delete from server" left the episode sitting in Continue Watching
until a full reload. Make the tab DeletionAware (remove in place across
all hubs, then resync) and give DiscoverProvider the same subscription
so the home row and hubs drop deleted items too.

close #1486
2026-07-05 05:58:52 +02:00
edde746 d80a1ed15a feat: report real device identity to media servers
Resolve platform, hardware model, and friendly device name once via a
shared DeviceIdentityService and send them to both backends: Plex gets
a real X-Plex-Platform plus X-Plex-Device/X-Plex-Device-Name (shown as
Player in dashboards/Tautulli), Jellyfin gets the device name in the
MediaBrowser auth header. Transcode and live-TV decision requests keep
their pinned platform names, which Plex validates server-side.

close #1270
2026-07-05 01:22:20 +02:00
edde746 87aea49ab6 fix(servers): stop rebinds from flashing an empty home screen after sign-in
Signing in triggered two back-to-back profile rebinds; the second re-added
the same Jellyfin connection, which tore down the live client and aborted
the home screen's in-flight fetches. The aborted pass was committed as
loaded-empty, flashing 'no content available' until the follow-up load
landed. Fix at the root instead of patching the sign-in window:

- addJellyfinConnection now reuses the live client when the connection is
  unchanged (token, deviceId, URL set), matching the existing Plex
  refreshTokensForProfile behavior; material changes still recreate it.
- Cancelled requests are classified end-to-end: the client's
  treat-as-empty helpers rethrow cancellations, and the aggregation
  fan-outs report cancelledServerIds alongside succeededServerIds.
- A fetch pass in which zero servers succeeded is never authoritative:
  it keeps existing content instead of wiping it (also fixes the
  pre-existing blanking of home/sidebar on a totally failed refresh),
  stays in loading while disrupted (cancellation or binding in flight),
  and only commits loaded-empty on a settled failure.
2026-07-04 23:44:38 +02:00
edde746 536e8e3d2a fix(playback): keep the Jellyfin shuffle queue across episodes
close #1466
2026-07-03 10:20:13 +02:00
edde746 fd4291aafb fix(playback): play the downloaded version when offline close #1440
Plain Play requests the default media version (index 0 or the saved
preference), but the offline resolvers rejected the single downloaded
row when a non-default version was downloaded, then threw "No video
URL available" with no client to fall back to.

Three-part fix sharing one matcher (downloadedVersionMatches):
- getPlaybackData falls back to the downloaded version when there is no
  client to stream from; the result now carries the effective
  mediaIndex/mediaSourceId so cached media info and the committed
  session describe the file actually played.
- navigateToVideoPlayer seeds the selection from the download record
  for isOffline plays with no explicit version, covering the external
  player branch and offline-library plays with a reachable server.
- PlaybackSession.fromContext prefers the result source id over the
  requested one, keeping in-player state in sync after a fallback.

Online pinning is untouched: with a live client an explicitly requested
non-downloaded version still streams from the server.
2026-07-03 10:19:55 +02:00
edde746 d193633a5d fix(remote): live auth-context refresh + lifecycle races
Keep a running companion-remote host's crypto identity in sync with the
active profile: subscribe to PlexHome/connection/join streams and rebuild
auth contexts (restarting the broadcast when they change) so a removed
home user or revoked borrowed connection stops controlling the host.

Serialize host start/stop/crypto-rebuild through a lifecycle lock, clean
up peer subscriptions before re-listening, and guard the replaced-client
onDone against clobbering the new client's session. Drop the context.mounted
guards that aborted an app-level host start, fix the DiscoveryView
init-flash/stuck-on-throw, and delete the dead initialize*Crypto helpers.
2026-07-02 11:41:25 +02:00
edde746 2b7142bdcd fix(downloads): profile-scoped ownership and watch-sync integrity 2026-07-02 11:41:25 +02:00
edde746 f9123eb40f fix(profiles): binder settle, active-id, and rebind correctness 2026-07-02 11:41:25 +02:00
edde746 79b75483bd style: fix CI formatting 2026-06-27 10:36:21 +02:00
edde746 78090d8bd6 refactor(trackers): unify session and account store across services
Replace the per-tracker json_serializable session classes and account stores with a shared TrackerSession (service-aware persisted validation), a single TrackerAccountStore, a shared TrackerHttpClient, and an AnimeListTrackerBase mixin for MAL/AniList. Scope the per-service rebind guard so a disconnect can't abort a racing profile load. Add migration-safety, MAL refresh, episode-count cache, and content-type tests.
2026-06-27 10:05:03 +02:00
edde746 f04691d321 feat: add "Include Specials" toggle to the show download dialog
The aired-order rework can sweep correctly-placed Specials into "download
next N"; this toggle lets users opt out. Shown only for whole shows
(reusing FocusableSwitchListTile via an optional toggle on the shared
option-picker dialog), remembered across opens via a BoolPref
(default on = unchanged behavior). Filters Specials at the single
collect choke point (_collectPlayable), with a guard so explicitly
downloading the Specials season still queues its episodes.
2026-06-25 23:41:31 +02:00
edde746 791433bceb fix: download and queue episodes in watch order, Specials last
close #1414
2026-06-25 10:47:13 +02:00
edde746 cd1978ee1c fix: scope hidden libraries to profiles
close #1388
2026-06-23 00:21:01 +02:00
edde746 f602925896 fix(trakt): persist refreshed auth sessions
close #1347
2026-06-15 14:42:24 +02:00
edde746 edd0618e64 fix: harden playback and discover state 2026-06-14 09:44:04 +02:00
edde746 979db254d1 perf(providers): delta-fetch newly-online servers instead of full refetch
Discover and libraries now fetch only the servers that came online since
the last pass and merge the results; already-loaded servers are not
refetched. Both providers also own their online-servers listener
(registered in the constructor, removed in dispose), so profile switches
no longer leak listeners that kept disposed providers refetching.
2026-06-12 17:12:18 +02:00
edde746 b2cb874b73 fix(discover): refresh content when a server comes online mid-session 2026-06-12 15:56:09 +02:00
edde746 f671f367ea refactor(discover): DiscoverProvider owns hubs and continue-watching 2026-06-12 15:53:26 +02:00
edde746 acdae74587 refactor(offline): single connectivity subscription in OfflineModeProvider 2026-06-12 14:18:49 +02:00
edde746 5e4449247b fix(downloads): inject visibility-aware client resolver 2026-06-12 14:16:24 +02:00
edde746 97ba02f45e fix: flashbang 2026-06-12 02:40:42 +02:00
edde746 9b48f26463 refactor(watch): shared point-of-use resolution across consumers
Adds context.withFreshWatchState/readFreshWatchState and sweeps the
remaining session-critical readers: context menu actions, folder tree
rows, discover hero, and TV spotlight minutes-left.
2026-06-10 05:38:33 +02:00
edde746 516925cf50 refactor(watch): promote overlay to hierarchy-aware WatchStateStore
Resolution now considers parentChain ancestors (newest event wins) and
watched patches set container leaf counts, so container marks reach
descendant cards and vice versa.
2026-06-10 05:18:02 +02:00
edde746 38868e0078 fix: use device name for companion remote
close #1256
2026-06-07 12:58:13 +02:00
edde746 4c4b18e2cd fix(i18n): localize hardcoded UI strings
close #1257
2026-06-06 11:45:34 +02:00
edde746 0fd0506551 feat(media): lazily page detail episodes
close #1245
2026-06-05 19:26:02 +02:00
edde746 145881318e fix: harden server-scoped state 2026-06-04 13:47:06 +02:00
edde746 74b8dc4561 refactor: type server identifiers 2026-06-01 11:06:03 +02:00
edde746 4ffa3d30f6 fix(player): preserve shader toggle preset
close #1208
2026-05-31 21:25:46 +02:00
edde746 d5c8778074 fix: harden reconnect and playback regressions 2026-05-31 20:33:38 +02:00
edde746 6111c381af fix(libraries): reload when a server connects after initial load 2026-05-30 14:01:01 +02:00
edde746 00fce3a997 fix(downloads): cap aggregate progress below 100% until all episodes complete
Rounding the smoothed per-episode progress could fill the ring to 100% while a download was still finishing; only report 100% once every queued episode is complete. Also drop the stale episode-count diagnostic log that read leafCount/_totalEpisodeCounts solely for logging after the denominator change.
2026-05-30 08:48:44 +02:00
Darkmadda 4148c1c8ff fix(downloads): scope show progress to queued episodes; manage completed downloads (#1195)
Progress ring now measures completion against the episodes actually queued (episodes.length) instead of the show's full leafCount, and advances smoothly using per-episode progress. The completed show/season download button reopens the download-options dialog (with a Delete row) so users can fetch more episodes or switch to sync instead of only deleting.
2026-05-30 08:40:17 +02:00