diff --git a/lib/utils/media_navigation_helper.dart b/lib/utils/media_navigation_helper.dart index 469e3453..31618a12 100644 --- a/lib/utils/media_navigation_helper.dart +++ b/lib/utils/media_navigation_helper.dart @@ -22,10 +22,12 @@ enum MediaNavigationResult { /// Navigates to the appropriate screen based on the item type. /// /// For episodes, starts playback directly via video player. +/// For movies, starts playback directly if [playDirectly] is true, otherwise +/// navigates to media detail screen. /// For seasons, navigates to season detail screen. /// For playlists, navigates to playlist detail screen. /// For collections, navigates to collection detail screen. -/// For other types (shows, movies), navigates to media detail screen. +/// For other types (shows), navigates to media detail screen. /// For music types (artist, album, track), returns [MediaNavigationResult.unsupported]. /// /// The [onRefresh] callback is invoked with the item's ratingKey after @@ -33,6 +35,8 @@ enum MediaNavigationResult { /// /// Set [isOffline] to true for downloaded content without server access. /// +/// Set [playDirectly] to true to play movies immediately (e.g., from continue watching). +/// /// Returns a [MediaNavigationResult] indicating what action was taken: /// - [MediaNavigationResult.navigated]: Navigation completed, item refresh handled /// - [MediaNavigationResult.listRefreshNeeded]: Caller should refresh entire list @@ -42,6 +46,7 @@ Future navigateToMediaItem( dynamic item, { void Function(String)? onRefresh, bool isOffline = false, + bool playDirectly = false, }) async { // Handle playlists if (item is PlexPlaylist) { @@ -77,11 +82,24 @@ Future navigateToMediaItem( } return MediaNavigationResult.navigated; + case PlexMediaType.movie: + if (playDirectly) { + // For movies in continue watching, start playback directly + final result = await navigateToVideoPlayer(context, metadata: metadata, isOffline: isOffline); + if (result == true) { + onRefresh?.call(metadata.ratingKey); + } + return MediaNavigationResult.navigated; + } + // Fall through to default case for detail screen + continue defaultCase; + case PlexMediaType.season: await Navigator.push(context, MaterialPageRoute(builder: (context) => SeasonDetailScreen(season: metadata))); onRefresh?.call(metadata.ratingKey); return MediaNavigationResult.navigated; + defaultCase: default: // For all other types (shows, movies), show detail screen final result = await Navigator.push( diff --git a/lib/widgets/hub_section.dart b/lib/widgets/hub_section.dart index 6b60e391..2e9b7519 100644 --- a/lib/widgets/hub_section.dart +++ b/lib/widgets/hub_section.dart @@ -231,7 +231,12 @@ class HubSectionState extends State { } Future _navigateToItem(dynamic item) async { - await navigateToMediaItem(context, item, onRefresh: widget.onRefresh); + await navigateToMediaItem( + context, + item, + onRefresh: widget.onRefresh, + playDirectly: widget.isInContinueWatching, + ); } void _navigateToHubDetail(BuildContext context) { diff --git a/lib/widgets/media_card.dart b/lib/widgets/media_card.dart index c6e2ea22..0089426f 100644 --- a/lib/widgets/media_card.dart +++ b/lib/widgets/media_card.dart @@ -119,6 +119,7 @@ class MediaCardState extends State { widget.item, onRefresh: widget.onRefresh, isOffline: widget.isOffline, + playDirectly: widget.isInContinueWatching, ); if (!context.mounted) return;