dependabot/github_actions/actions/setup-java-6.0.0
6
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
5a666fd10f |
feat(discover): refresh home and library content from server library push events
New media added server-side was invisible while the app was open - the client had no channel for library-change notifications, so the home screen and library tabs sat stale until an app restart. Each online server now runs a reconnecting websocket push channel (Plex `/:/websockets/notifications`; Jellyfin/Emby `/socket` with the dialect deltas, including Emby's capabilities registration), owned per server by a LibraryEventService supervisor that follows server online/offline/replaced-client transitions and app lifecycle. Channels emit one coalesced LibraryChangeEvent per burst on a leading-edge throttle modeled on Plex Web's repopulate pacing: the first settled change surfaces immediately and a library scan's flood merges behind it. Connection failure degrades silently to the stale-refresh paths - bounded reconnect backoff, re-armed on every status sync. Consumers pace their reaction through one shared RefreshPacer: burst debounce, blocked retry while video playback or an active scroll owns the surface, a cooldown bounding pass frequency during bulk imports, and credit for committed pull passes so a push landing right after a fresh load defers to the cooldown's trailing edge. - Discover runs a debounced full pass and swaps the result in place; the hero carousel resets only when a pass lands first content, so a push never yanks a screen the user is reading. Pushed removals drop from every visible list immediately via the deletion bus, scoped to the emitting server. - The visible library tab swaps its data in place: transaction tabs reload without clearing, and the browse and paginated card grids refetch their loaded span (Plex Web's repopulateRange) with the scroll offset anchored on the first visible item and the span clamped after alpha jumps. Hidden tabs - and tabs behind another main tab - mark per-library staleness epochs instead and reload when next shown; epochs are snapshotted at load start so a push racing an in-flight fetch stays stale. - The stale-resume and tab-shown paths refetch home hubs (previously Continue Watching only), covering setups where the socket cannot connect. close #1646 |
||
|
|
ae555ed5d7 |
feat(settings): account preferences, stored on the server instead of the device (#2112)
Preferences that belong to the media-server account had nowhere to live in Plezy. Jellyfin keeps a user's audio/subtitle language, subtitle mode and several library options in `UserConfiguration`; plex.tv keeps the same language choices plus watched indicators and review visibility on the account. Plezy read four of those fields for auto-track selection and could never show or change any of them.
Adds an Account preferences section under Connections. One account edits in place; several show a picker first, scoped to the active profile's own connections so a managed Plex Home user never edits the owner's record. Every row is gated on what the backend can actually store.
It also moves "rewatching in Next Up" onto the account. There is no `UserConfiguration` field for it, but the per-user `DisplayPreferences` store is keyed `(userId, displayPreferencesId, client)` with no device component, so the switch goes there and follows the account.
`AccountRef` keys by account, not `clientScopeId`: MediaBrowser is `{machineId}/{userId}`, Plex is (account, Home user). Writes are patch-shaped because both backends replace whole objects — Jellyfin's `POST /Users/{id}/Configuration` and its `DisplayPreferences` row both reset omitted fields, so each write re-reads, merges only the patched keys, and posts back. Plex takes its changes as query parameters with an empty body, and its `experience` blob and the PMS `/accounts/1` mirror are deliberately untouched.
`AccountPreferencesController` owns a single repository above the profile session, so changing a language in settings reaches the next playback without a restart. Emby is gated out of rewatching through `MediaBrowserDialect.supportsNextUpRewatching`.
close #1910
|
||
|
|
0f3d06668f |
fix(jellyfin): read Emby playback shelves from the hide-aware resume route
Removing an item from Continue Watching on Emby posts HideFromResume,
which only the dedicated /Users/{uid}/Items/Resume route honors: the
IsResumable /Items query and the per-series /Shows/NextUp lookups kept
returning hidden rows, so removed items blipped back on every refresh.
Emby's dedicated route conflates both shelves (in-progress items plus
one zero-position next episode per started series), so every playback
surface now reads one hide-aware window from it and splits the rows by
PlaybackPositionTicks: positive rows feed Continue Watching, zero-
position episode rows feed Next Up. The 1+N per-series Next Up
reconstruction is deleted; one recency scan still supplies the play
dates and the NextUpDateCutoff window. Jellyfin request strings are
unchanged.
close #2003
|
||
|
|
8033a308ce |
refactor(connection): drop dead status/kind enums, share the Plex account build pipeline
Connection.status was write-only health state (only the Jellyfin refresh wrote it, nothing read it — MultiServerManager owns real server status), ConnectionKind duplicated MediaBackend line for line, the token-to-PlexAccountConnection pipeline existed three times (sign-in, dev-token seed, legacy migration) with drifting label/dedup policy, and JellyfinConnectionAuthService.validate/refresh/signOut had no production callers. Connection.kind is now MediaBackend (persisted 'plex'/'jellyfin'/'emby' strings are identical, no migration); buildPlexAccountConnection in plex_account_setup.dart owns identity resolution with the three callers keeping only their genuine deltas; the test-only auth trio and its jellyfinSignOut timeout constant are gone. |
||
|
|
8f9ffc76eb |
fix(emby): show scrub previews from the /Videos/{id}/index.bif transport
Scrubbing an Emby video showed no preview thumbnails on the timeline
while Plex and Jellyfin both worked: Emby's scrubThumbnails capability
was off, so the player never attempted a load. It was off because the
4.9.5 test server answered the preview endpoints with empty payloads —
its extraction task had not run.
Emby's preview transport is a Roku-format BIF at
/Videos/{id}/index.bif?Width=320, the same wire format Plex serves, so
the existing BIF parser handles it unchanged. Enable the capability and
route Emby previews through the shared BifThumbnailService, whose load
now takes a bytes callback instead of a Plex-typed client. MediaBrowser
sources also carry videoAspectRatio from the video stream so the
tooltip sizes itself to the stream. A server without extracted frames
still answers a header-only BIF, which parses to zero frames and keeps
the tooltip suppressed.
close #1930
|
||
|
|
05fd622968 |
feat(emby): add Emby as a MediaBrowser backend alongside Jellyfin
Emby is Jellyfin's upstream ancestor and speaks a near-identical MediaBrowser
API, so the existing Jellyfin stack is parameterised by a `MediaBrowserDialect`
rather than forked. `JellyfinClient`, its auth service, endpoint discovery, LAN
discovery, and the add/edit connection screens all take the dialect and keep one
implementation; `MediaBackend.emby` and `ConnectionKind.emby` carry it through
the neutral models, the Drift `kind` discriminator, downloads, and caches.
Every divergence below was measured against a live Emby 4.9.5 server, not
inferred from documentation, and each is documented at its capability getter.
Jellyfin's request strings stay byte-identical so nothing about its behaviour
changes.
Routes and auth
- Emby only accepts the pre-10.9 user-scoped item routes (`/Users/{id}/Items/…`,
`/Users/{id}/PlayedItems/…`, `/Users/{id}/FavoriteItems/…`); the unprefixed
forms Jellyfin 10.11 added return 404.
- The API is also served under a legacy `/emby` prefix, and both dialects accept
the token as `X-Emby-Token` or `api_key=`.
- Emby answers only its own LAN discovery datagram ("who is EmbyServer?") and
ignores Jellyfin's; its default HTTPS port is 8920.
- No `/QuickConnect` route exists, so Quick Connect stays Jellyfin-only.
Row fields Emby withholds
- `ProductionYear`, `OfficialRating`, `PremiereDate` and `DateCreated` are absent
from list rows unless named in `Fields`, which would otherwise strip the year
and age-rating badge from every card in the app.
- `UserData.LastPlayedDate` never appears on a list row under `Fields=UserData`,
`EnableUserData=true` or the user-scoped `Ids=` form — only on the single-item
detail route, or when the Emby-specific `UserDataLastPlayedDate` token is
requested. Without it every recency-ordered surface silently degrades to
library-add time, and `JellyfinApiCache.applyWatchState` stamps
`DateTime.now()` on watched rows, so an offline watch-state pull would rewrite
the cached play time of everything it walked.
Continue Watching and Next Up
- Emby computes Next Up per series only: the library-wide `/Shows/NextUp` query
returns nothing under every parameter combination tried. The shelf is
therefore reconstructed from a played-episode recency scan plus one
`/Shows/NextUp?SeriesId=` per distinct series, bounded by a shared wall clock
that covers the scan as well — per-request timeouts cannot bound the pass
because `MediaServerHttpClient` times the connect and receive phases
independently. Rows are stamped with their series' newest play from the same
response that ordered them, so no per-series enrichment request is needed.
- `/Shows/NextUp` ignores `NextUpDateCutoff`, and no server-side played-date
filter exists to delegate to (`MinDatePlayed` and `MinDateLastPlayed` are
ignored; `MinDateLastSaved`, `MinDateCreated` and `MinPremiereDate` filter
unrelated dates), so the 365-day window is applied to the scanned dates.
- The resume route returns items with no saved position, including plain next
episodes, so the Emby resume leg reads from `/Items?Filters=IsResumable`.
- Emby is ahead of Jellyfin in one place: `/Users/{id}/Items/{id}/HideFromResume`
makes Continue Watching removal a real capability.
Everything else
- `/Sessions/Playing` and `/Sessions/Playing/Progress` reject a body with no
`PlaySessionId` (HTTP 400), so playback reporting always sends one.
- Passing any `MediaTypes` value to the playlist query returns an empty list.
- There is no aggregate `/Items/Filters` route; the four filter facets are
reassembled from `/Genres`, `/OfficialRatings`, `/Studios` and `/Tags`.
- Metadata writes take name-pair lists (`Genres: [{'Name': 'Action'}]`); the
plain string array is accepted and then silently discarded.
- Custom artwork uploads must be base64 text, not raw bytes — which was broken
for Jellyfin too and is fixed for both.
- Trickplay, media segments and lyrics 404 on Emby, so scrub previews are absent
and intro/credit markers fall back to chapter names.
Verified against a local Emby 4.9.5 and a Jellyfin 10.11.11 control server:
onboarding, browse, detail, playable stream URLs serving real bytes, subtitle
sidecars, watch-state write and restore, hubs, cross-server aggregation and
search across both backends simultaneously.
|