From 51af830160dbb88b2384f2ea7a3e8072dce42892 Mon Sep 17 00:00:00 2001 From: foxyz Date: Fri, 16 Oct 2026 07:53:37 +0300 Subject: [PATCH] Joining another server no longer opens an empty player connect() kept the last server's state while dialling the next; the shell saw its media on arrival and opened the player (full, on a friend's server) over the new, empty one. Co-Authored-By: Claude Opus 5.5 --- .../lib/src/session/session_coordinator.dart | 3 ++ apps/desktop/pubspec.lock | 4 +-- apps/desktop/test/coord_presence_test.dart | 34 +++++++++++++++++++ 3 files changed, 39 insertions(+), 2 deletions(-) diff --git a/apps/desktop/lib/src/session/session_coordinator.dart b/apps/desktop/lib/src/session/session_coordinator.dart index 8747bc0..8a073f8 100644 --- a/apps/desktop/lib/src/session/session_coordinator.dart +++ b/apps/desktop/lib/src/session/session_coordinator.dart @@ -517,6 +517,9 @@ class SessionCoordinator { final epoch = connection.invalidate(); await _teardown(silent: true); if (!connection.isCurrent(epoch)) throw const ConnectCancelled(); + // The last server's state is not this one's: kept, its media opened the + // player (full, on a friend's server) over an empty new server. + serverState.value = null; connection.begin(params); _wsHost = params.host; _wsPort = params.port; diff --git a/apps/desktop/pubspec.lock b/apps/desktop/pubspec.lock index 6cc91a6..bca9f2a 100644 --- a/apps/desktop/pubspec.lock +++ b/apps/desktop/pubspec.lock @@ -865,14 +865,14 @@ packages: path: "../../packages/core" relative: true source: path - version: "1.2.0" + version: "1.3.0" sync_relay_server: dependency: "direct main" description: path: "../../packages/server" relative: true source: path - version: "1.2.0" + version: "1.3.0" synchronized: dependency: transitive description: diff --git a/apps/desktop/test/coord_presence_test.dart b/apps/desktop/test/coord_presence_test.dart index 30b7a41..124d69f 100644 --- a/apps/desktop/test/coord_presence_test.dart +++ b/apps/desktop/test/coord_presence_test.dart @@ -6,6 +6,7 @@ import 'dart:io'; import 'package:flutter_test/flutter_test.dart'; import 'package:hive_ce/hive.dart'; import 'package:media_kit/media_kit.dart'; +import 'package:signals/signals.dart' show effect; import 'package:sync_relay_core/core.dart'; import 'package:sync_relay_core/testing.dart'; import 'package:sync_relay_server/server.dart'; @@ -443,6 +444,39 @@ void main() { } }); + test('moving to another server never shows the last one\'s media', timeout: const Timeout(Duration(minutes: 1)), + () async { + final home = SyncServer(const AppConfig(port: 0, secret: 'pw', name: 'home')); + final empty = SyncServer(const AppConfig(port: 0, secret: 'pw', name: 'empty')); + await home.start(); + await empty.start(); + final origin = await _origin(await _media()); + try { + final alice = await member(home.boundPort, 'alice'); + expect(await alice.swapPicked(LinkMedia('http://127.0.0.1:${origin.port}/ep.mkv', anyway: true)), isNull); + await _poll(() => alice.serverState.peek()?.media != null, 'media up at home'); + // The shell opens the player on any state with media as soon as the + // app is in a server again: nothing from the last one may be left + // while the new one is dialled. + final seen = []; + final stop = effect(() { + if (alice.connection.state.value is ConnConnecting) { + seen.add(alice.serverState.peek()?.media?['name'] as String? ?? ''); + } + }); + await alice.connect(ConnectParams(host: '127.0.0.1', port: empty.boundPort, secret: 'pw', name: 'alice')); + await _poll(() => alice.serverState.peek() != null, 'the new server\'s state'); + stop(); + expect(seen, isNotEmpty); + expect(seen.where((n) => n.isNotEmpty), isEmpty, reason: 'no media from the last server'); + expect(alice.serverState.peek()?.media, isNull); + } finally { + await home.stop(); + await empty.stop(); + await origin.close(force: true); + } + }); + test('cancel during connect setup aborts without joining', timeout: const Timeout(Duration(minutes: 1)), () async { final server = SyncServer(const AppConfig(port: 0, secret: '', name: 'cancel')); await server.start();