Repository navigation
Description
Summary
A user who already has completed local downloads can be locked out of them when Labstream cold-launches or relaunches without a reachable network/server session.
The credentials are generally preserved on transient transport failure, and the offline index/files are already loaded, but the top-level UI gate requires a live browse session before it mounts the only navigation surface that contains Offline. The result is a reconnect/sign-in surface with no route to playable local content.
This affects the download-capable visionOS, iOS/iPadOS, and macOS products. tvOS intentionally has no downloads capability.
Current behavior found in code
ContentViewrunsAuthManager.restoreSession()and then chooses betweenRootViewandLoginViewthroughBrowseUIGate.- On a cold launch, a transient restore failure leaves
appModel.isBrowseReady == false; once restoration finishes,BrowseUIGateresolves to.login. - Plex preserves the saved account token and shows
PlexRestoreFailureView, but clears resolved server state, so the browse root is still unavailable. - Jellyfin and Emby preserve their Keychain snapshots on transport/unreachable failure but clear their runtime lanes, which also leaves the browse root unavailable.
DownloadManageris constructed before authentication, loadsDownloadStore.records, and buildsofflineLibrarySnapshotimmediately.OfflineLibraryViewplays completed media throughCustomPlayerView(localFile:...); local playback itself does not require a live backend session.- Offline navigation exists only inside the platform root shells, which are mounted by
RootViewafter the live browse gate succeeds.
If connectivity disappears after RootView is already mounted, Offline generally remains reachable. The principal gap is cold launch/relaunch and a failed restore/switch that removes the root UI.
Expected behavior
A transient inability to reach the internet or configured server must not prevent access to valid completed local downloads.
Labstream should clearly distinguish:
- no saved credentials / explicit sign-out;
- confirmed invalid or revoked credentials;
- saved credentials with a transient network, DNS, TLS, timeout, discovery, or server-unreachable failure.
For case 3, users with playable local content should have an obvious Open Offline path while retaining retry/reconnect and sign-in controls.
Suggested direction
- Add a typed selected-session restore outcome rather than deriving product behavior from a Boolean plus user-facing error text, e.g.
restored,missingCredential,invalidCredential, andtemporarilyUnavailable. - Extend the top-level launch gate with an offline-capable state when:
- downloads are supported;
- restore failed transiently; and
- at least one completed record still has its local media file.
- Prefer a deliberately restricted offline launch surface over mounting the complete online browse hierarchy with a fabricated authenticated session.
- The offline surface should provide:
- completed-download list and local playback;
- cached poster, subtitle, chapter, and trick-play assets when present;
- local resume-position updates and delete controls;
- reconnect/retry and Settings/sign-in access;
- honest presentation for incomplete/active rows that cannot progress while unreachable.
- On successful reconnect, transition back to the normal root without destroying local playback state unnecessarily.
- Do not weaken credential validation, fabricate
BackendSession, or treat transient failure as authenticated online browse readiness.
Product decisions to make explicitly
- Whether local downloads remain accessible after a deliberate sign-out or confirmed credential revocation. This issue at minimum covers saved credentials plus transient unreachability.
- Whether the offline entry should appear when durable rows exist but no completed local file survives.
- Whether Plex should separately cache enough selected-server connection metadata to reach a LAN PMS when plex.tv resource discovery is unavailable. That is related but not required to solve local-file access.
Acceptance criteria
- Cold-launch each download-capable platform with a saved session, at least one completed local download, and network/server reachability disabled.
- The app does not require re-authentication merely to open and play the completed local file.
- Plex, Jellyfin, and Emby transient restore failures preserve credentials and expose the same offline-access contract.
- A real unauthorized response remains distinct and does not silently create online browse authority.
- The offline-only surface does not issue browse/playback metadata requests for local playback.
- Cached offline posters, subtitles, chapters, trick-play data, and local playback position continue to work where present.
- Reconnect/retry upgrades to normal browse UI without losing the offline library.
- Behavior is covered by pure gate/restore-outcome tests plus platform integration tests for visionOS, iOS/iPadOS, and macOS.
- Manual airplane-mode/unreachable-server validation is recorded for at least one physical mobile device and Vision Pro; macOS network-unavailable launch is also checked.
Related context
- Audit long-lived auth/session handling for Plex, Jellyfin, and Emby #229 hardened credential preservation for transient network failures, but did not add an offline-content route around the live browse gate.
- Support simultaneous downloads across multiple backends #84 made persisted downloads backend-independent and hydrates inactive lanes, which means the local data plane is already largely separated from the selected browse session.
Activity
jlipworth commentedon Aug 22, 2026
Implementation is now up as draft PR #267.
The patch adds a restricted cold-launch Offline surface when the selected saved session is preserved after a transient reachability failure and at least one completed local media file still exists. Invalid/missing credentials still go to sign-in, and tvOS remains excluded.
Automated unit/policy tests, all affected platform builds, docs hygiene, visionOS passive smoke, and macOS host launch passed. The PR intentionally leaves the real completed-download/disconnected-launch matrix and credential-expiry/reconnect scenarios as explicit manual acceptance gates before this issue is closed.
jlipworth commentedon Aug 22, 2026
PR #267 landed on
origin/mainat5c0e2015.Validated before merge: 1,662 PMSKit tests, repository/docs hygiene, all affected Apple-platform builds, visionOS passive smoke, and macOS host build/launch. The Woodpecker checks remain red across both this PR and recent
maincommits; the equivalent local hygiene and PMSKit lanes pass, so this appears to be an existing CI-service failure rather than a feature-specific regression.This issue remains open because its acceptance contract still requires real disconnected-launch/local-playback checks on physical mobile hardware and Vision Pro, plus macOS and all three saved-session backends. No simulator is left booted and the staged macOS development app was removed.
jlipworth commentedon Sep 15, 2026
Release-scope clarification: the user explicitly deferred this ticket during pre-release triage. It remains open; no disconnected cold-launch or physical-platform acceptance is newly claimed. #92 now separates this deferred work from the active release queue.
docs: consolidate screenshot provenance and release gates (#330)
Tell a refused account apart from a wrong password at sign-in (#259)
Gate offline launch on a typed session-restore outcome (#259) (#355)
Sweep dead code, redundant tests and superseded docs (#365)
jlipworth commentedon Oct 18, 2026
Status update. The typed restore-outcome gate (#355) is on
main. The downloads overhaul (downloads/overhaul, shipping as 1.8.0 TestFlight internal) adds generation-tagged offline availability: blocked-but-readable rows stay playable, and a late index load publishes even after startup times out or a background wake expires. Close this once the 1.8.0 device acceptance passes; that check is in the overhaul landing issue.Downloads overhaul, iPhone Duo and player rework (1.8.0) (#425)