feat: watch together

This commit is contained in:
edde746
2025-12-18 08:42:18 +01:00
parent 79ac2793e3
commit 63ba2bb3de
38 changed files with 3909 additions and 183 deletions
+4 -2
View File
@@ -1,8 +1,9 @@
import '../mpv/mpv.dart';
/// Seeks by the given offset (can be positive or negative) while clamping
/// the result between 0 and the video duration
void seekWithClamping(Player player, Duration offset) {
/// the result between 0 and the video duration.
/// Returns the clamped position that was seeked to.
Duration seekWithClamping(Player player, Duration offset) {
final currentPosition = player.state.position;
final duration = player.state.duration;
final newPosition = currentPosition + offset;
@@ -11,4 +12,5 @@ void seekWithClamping(Player player, Duration offset) {
final clampedPosition = newPosition.isNegative ? Duration.zero : (newPosition > duration ? duration : newPosition);
player.seek(clampedPosition);
return clampedPosition;
}
+14
View File
@@ -6,6 +6,8 @@ import '../screens/video_player_screen.dart';
import '../services/settings_service.dart';
import 'app_logger.dart';
const String kVideoPlayerRouteName = '/video_player';
/// Navigates to the VideoPlayerScreen with instant transitions to prevent white flash.
///
/// This utility function provides a consistent way to navigate to the video player
@@ -54,7 +56,19 @@ Future<bool?> navigateToVideoPlayer(
}
}
// Prevent stacking an identical video player when already active
if (!usePushReplacement &&
metadata.ratingKey != null &&
VideoPlayerScreenState.activeRatingKey == metadata.ratingKey &&
VideoPlayerScreenState.activeMediaIndex == mediaIndex) {
appLogger.d(
'Video player already active for ${metadata.ratingKey} (mediaIndex=$mediaIndex), skipping duplicate navigation',
);
return null;
}
final route = PageRouteBuilder<bool>(
settings: const RouteSettings(name: kVideoPlayerRouteName),
pageBuilder: (context, animation, secondaryAnimation) => VideoPlayerScreen(
metadata: metadata,
preferredAudioTrack: preferredAudioTrack,