From ab915d02583105df53160efdf3173baa9eae0939 Mon Sep 17 00:00:00 2001 From: edde746 <86283021+edde746@users.noreply.github.com> Date: Thu, 18 Dec 2025 12:04:36 +0100 Subject: [PATCH] refactor: fix warnings --- lib/screens/media_detail_screen.dart | 1 - lib/screens/video_player_screen.dart | 5 +-- lib/utils/video_player_navigation.dart | 1 - .../providers/watch_together_provider.dart | 9 ------ .../services/watch_together_sync_manager.dart | 32 +++++++++++++++++-- .../widgets/join_session_dialog.dart | 9 ++---- .../video_controls/video_controls.dart | 2 -- 7 files changed, 35 insertions(+), 24 deletions(-) diff --git a/lib/screens/media_detail_screen.dart b/lib/screens/media_detail_screen.dart index d5984042..27d0eb43 100644 --- a/lib/screens/media_detail_screen.dart +++ b/lib/screens/media_detail_screen.dart @@ -28,7 +28,6 @@ import '../widgets/app_bar_back_button.dart'; import '../utils/desktop_window_padding.dart'; import '../widgets/horizontal_scroll_with_arrows.dart'; import '../widgets/focusable_media_card.dart'; -import '../widgets/media_card.dart'; import '../widgets/media_context_menu.dart'; import '../widgets/placeholder_container.dart'; import 'season_detail_screen.dart'; diff --git a/lib/screens/video_player_screen.dart b/lib/screens/video_player_screen.dart index 696186d7..e045fba0 100644 --- a/lib/screens/video_player_screen.dart +++ b/lib/screens/video_player_screen.dart @@ -791,9 +791,9 @@ class VideoPlayerScreenState extends State with WidgetsBindin final watchTogether = context.read(); if (watchTogether.isHost && watchTogether.isInSession) { watchTogether.setCurrentMedia( - ratingKey: targetMetadata.ratingKey!, + ratingKey: targetMetadata.ratingKey, serverId: targetMetadata.serverId!, - mediaTitle: targetMetadata.title!, + mediaTitle: targetMetadata.title, ); } } catch (e) { @@ -825,6 +825,7 @@ class VideoPlayerScreenState extends State with WidgetsBindin // Detach and dispose current player before switching to avoid sync calls on a disposed instance await disposePlayerForNavigation(); + if (!mounted) return; // Use same navigation as local episode change (pushReplacement from player context) _isReplacingWithVideo = true; diff --git a/lib/utils/video_player_navigation.dart b/lib/utils/video_player_navigation.dart index a4353312..082fadd4 100644 --- a/lib/utils/video_player_navigation.dart +++ b/lib/utils/video_player_navigation.dart @@ -58,7 +58,6 @@ Future navigateToVideoPlayer( // Prevent stacking an identical video player when already active if (!usePushReplacement && - metadata.ratingKey != null && VideoPlayerScreenState.activeRatingKey == metadata.ratingKey && VideoPlayerScreenState.activeMediaIndex == mediaIndex) { appLogger.d( diff --git a/lib/watch_together/providers/watch_together_provider.dart b/lib/watch_together/providers/watch_together_provider.dart index 140d8b6d..3c76bd71 100644 --- a/lib/watch_together/providers/watch_together_provider.dart +++ b/lib/watch_together/providers/watch_together_provider.dart @@ -300,15 +300,6 @@ class WatchTogetherProvider with ChangeNotifier { ); } - // If we're the host and this is a guest joining, send our join info back - // so they add us to their participants list - if (isHost && message.peerId != _peerService?.myPeerId && !(message.isHost ?? false)) { - _peerService?.sendTo( - message.peerId!, - SyncMessage.join(peerId: _peerService!.myPeerId!, displayName: _displayName, isHost: true), - ); - } - notifyListeners(); } break; diff --git a/lib/watch_together/services/watch_together_sync_manager.dart b/lib/watch_together/services/watch_together_sync_manager.dart index b7c3cf6a..aaed301a 100644 --- a/lib/watch_together/services/watch_together_sync_manager.dart +++ b/lib/watch_together/services/watch_together_sync_manager.dart @@ -30,7 +30,6 @@ class WatchTogetherSyncManager { // Stream subscriptions StreamSubscription? _playingSubscription; - StreamSubscription? _positionSubscription; StreamSubscription? _bufferingSubscription; StreamSubscription? _rateSubscription; StreamSubscription? _messageSubscription; @@ -156,14 +155,12 @@ class WatchTogetherSyncManager { _hasAnnouncedReady = false; _playingSubscription?.cancel(); - _positionSubscription?.cancel(); _bufferingSubscription?.cancel(); _rateSubscription?.cancel(); _messageSubscription?.cancel(); _positionSyncTimer?.cancel(); _playingSubscription = null; - _positionSubscription = null; _bufferingSubscription = null; _rateSubscription = null; _messageSubscription = null; @@ -259,6 +256,15 @@ class WatchTogetherSyncManager { return _session.isHost; } + /// Check if a remote control message should be applied based on control mode + bool _shouldApplyRemoteControl(SyncMessage message) { + if (_session.controlMode == ControlMode.anyone) { + return true; + } + // In hostOnly mode, only apply control messages from the host + return message.peerId == _session.hostPeerId; + } + /// Broadcast play/pause state void _broadcastPlayPause(bool isPlaying) { if (!_canControl()) { @@ -326,21 +332,37 @@ class WatchTogetherSyncManager { switch (message.type) { case SyncMessageType.play: + if (!_shouldApplyRemoteControl(message)) { + appLogger.d('WatchTogether: Ignoring play from non-host in hostOnly mode'); + break; + } await _applyRemotePlay(position: message.position); break; case SyncMessageType.pause: + if (!_shouldApplyRemoteControl(message)) { + appLogger.d('WatchTogether: Ignoring pause from non-host in hostOnly mode'); + break; + } _wasPlayingBeforeBuffering = false; // User intentionally paused, don't auto-resume await _applyRemotePause(); break; case SyncMessageType.seek: + if (!_shouldApplyRemoteControl(message)) { + appLogger.d('WatchTogether: Ignoring seek from non-host in hostOnly mode'); + break; + } if (message.position != null) { await _applyRemoteSeek(message.position!); } break; case SyncMessageType.buffering: + if (_player == null) { + appLogger.d('WatchTogether: Ignoring buffering message, player not attached'); + break; + } if (message.peerId != null && message.bufferingState != null) { _participantBuffering[message.peerId!] = message.bufferingState!; @@ -367,6 +389,10 @@ class WatchTogetherSyncManager { break; case SyncMessageType.rate: + if (!_shouldApplyRemoteControl(message)) { + appLogger.d('WatchTogether: Ignoring rate from non-host in hostOnly mode'); + break; + } if (message.rate != null) { await _applyRemoteRate(message.rate!); } diff --git a/lib/watch_together/widgets/join_session_dialog.dart b/lib/watch_together/widgets/join_session_dialog.dart index 7e4ce9a6..a22ad5b8 100644 --- a/lib/watch_together/widgets/join_session_dialog.dart +++ b/lib/watch_together/widgets/join_session_dialog.dart @@ -13,7 +13,6 @@ class JoinSessionDialog extends StatefulWidget { class _JoinSessionDialogState extends State { final _formKey = GlobalKey(); final _sessionIdController = TextEditingController(); - bool _isLoading = false; @override void dispose() { @@ -93,11 +92,9 @@ class _JoinSessionDialogState extends State { // Join button FilledButton.icon( - onPressed: _isLoading ? null : _join, - icon: _isLoading - ? const SizedBox(width: 20, height: 20, child: CircularProgressIndicator(strokeWidth: 2)) - : const Icon(Symbols.group_add), - label: Text(_isLoading ? 'Joining...' : 'Join Session'), + onPressed: _join, + icon: const Icon(Symbols.group_add), + label: const Text('Join Session'), ), ], ), diff --git a/lib/widgets/video_controls/video_controls.dart b/lib/widgets/video_controls/video_controls.dart index 5635ff28..31f4540a 100644 --- a/lib/widgets/video_controls/video_controls.dart +++ b/lib/widgets/video_controls/video_controls.dart @@ -4,7 +4,6 @@ import 'dart:io' show Platform; import 'package:flutter/material.dart'; import 'package:plezy/widgets/app_icon.dart'; import 'package:material_symbols_icons/symbols.dart'; -import 'package:provider/provider.dart'; import 'package:rate_limiter/rate_limiter.dart'; import 'package:flutter/services.dart' show @@ -39,7 +38,6 @@ import 'icons.dart'; import '../../utils/app_logger.dart'; import '../../i18n/strings.g.dart'; import '../../focus/input_mode_tracker.dart'; -import '../../watch_together/watch_together.dart'; import 'widgets/track_chapter_controls.dart'; import 'mobile_video_controls.dart'; import 'desktop_video_controls.dart';