Jellyfin end to end: per-viewer playback, progress, episodes, swap browser

- Host/swap send refs only; pasted Jellyfin links become refs; the host
  hands the relay its own app-obtained credential.
- Each viewer resolves with their own account (token in a header) or
  via the relay, else a clear blocked card with Link account.
- Per-account progress reporting (Playing/Progress/Stopped), 401 marks
  the account expired.
- Previous/next episode in the controls (< > / Shift+P/N), floating
  Next episode pill near the end, auto-advance countdown (one
  designated swapper), track carry-over per series.
- Swap panel uses the shared MediaPicker; browser location remembered
  per server and opens on the current series.
- Fix: states are applied one at a time (a stale pause could land
  after a newer play).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
foxyzandClaude Opus 5.5 committed 2026-10-07 02:38:24 +03:00
1 parent 773a04369e
commit ae4edc29e8
33 files changed
+3541 -175

No files matched your search

@@ -3,6 +3,7 @@ import 'package:flutter/material.dart';
import '../screens/home/picked_media.dart';
import '../screens/home/ui.dart';
import 'accounts.dart';
import 'browse_scope.dart';
import 'browser.dart';
import 'sign_in_panel.dart';
@@ -15,8 +16,10 @@ class JellyfinPickerSource extends StatefulWidget {
final VoidCallback? onOpenIntegrations;
final VoidCallback? onToggleExpanded;
final bool expanded;
final BrowseStart? start;
const JellyfinPickerSource({
super.key,
this.start,
required this.accounts,
required this.onPick,
this.selected,
@@ -54,6 +57,7 @@ class _JellyfinPickerSourceState extends State<JellyfinPickerSource> {
onOpenIntegrations: widget.onOpenIntegrations,
onToggleExpanded: widget.onToggleExpanded,
expanded: widget.expanded,
start: widget.start,
);
},
);