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:
1 parent
773a04369e
commit
ae4edc29e8
33 files changed
+3541
-175
No files matched your search
@@ -7,7 +7,7 @@ import 'package:sync_relay_core/core.dart';
|
||||
import 'package:watch_together/src/jellyfin/accounts.dart';
|
||||
import 'package:watch_together/src/jellyfin/format.dart';
|
||||
import 'package:watch_together/src/jellyfin/sign_in.dart';
|
||||
import 'package:watch_together/src/screens/home/host_tab.dart' show interimJellyfinLink, mediaSummary;
|
||||
import 'package:watch_together/src/screens/home/host_tab.dart' show mediaSummary;
|
||||
import 'package:watch_together/src/screens/home/media_picker.dart';
|
||||
|
||||
/// Captured Jellyfin 10.11 answers shared with packages/core's client tests.
|
||||
@@ -342,22 +342,6 @@ void main() {
|
||||
expect(m.subtitle, 'Black Summoner · S1E6');
|
||||
expect(m.runtime, isNotNull);
|
||||
});
|
||||
|
||||
test('INTERIM: the host plays a Jellyfin pick as its authorised stream link', () async {
|
||||
final (accounts, _) = await linkedAccounts();
|
||||
const m = JellyfinMedia(
|
||||
serverId: fixtureServerId, baseUrl: 'https://example.invalid', itemId: 'abc', title: 't');
|
||||
final url = Uri.parse(interimJellyfinLink(accounts, m));
|
||||
expect(url.path, '/Videos/abc/stream');
|
||||
expect(url.queryParameters['static'], 'true');
|
||||
expect(url.queryParameters['api_key'], 'TEST_ACCESS_TOKEN');
|
||||
expect(
|
||||
() => interimJellyfinLink(
|
||||
accounts, const JellyfinMedia(serverId: 'gone', baseUrl: 'x', itemId: 'i', title: 't')),
|
||||
throwsFormatException);
|
||||
accounts.markExpired(fixtureServerId);
|
||||
expect(() => interimJellyfinLink(accounts, m), throwsFormatException);
|
||||
});
|
||||
});
|
||||
|
||||
group('format', () {
|
||||
|
||||
Reference in new issue
Block a user