From 3366b83a89b16c28725b3c4921ce2d9291890486 Mon Sep 17 00:00:00 2001 From: edde746 <86283021+edde746@users.noreply.github.com> Date: Sun, 12 Apr 2026 11:12:28 +0200 Subject: [PATCH] fix: hide spoilers in watch next thumbnails close #849 --- lib/screens/discover_screen.dart | 6 +++++- lib/services/watch_next_service.dart | 19 +++++++++++++------ lib/utils/content_utils.dart | 3 +++ 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/lib/screens/discover_screen.dart b/lib/screens/discover_screen.dart index acfa752d..22786261 100644 --- a/lib/screens/discover_screen.dart +++ b/lib/screens/discover_screen.dart @@ -638,7 +638,11 @@ class _DiscoverScreenState extends State /// Sync On Deck items to Android TV Watch Next row Future _syncWatchNext(List onDeck) async { try { - await WatchNextService().syncFromOnDeck(onDeck, (serverId) => context.getClientForServer(serverId)); + await WatchNextService().syncFromOnDeck( + onDeck, + (serverId) => context.getClientForServer(serverId), + hideSpoilers: context.read().hideSpoilers, + ); } catch (e) { appLogger.w('Failed to sync Watch Next', error: e); } diff --git a/lib/services/watch_next_service.dart b/lib/services/watch_next_service.dart index e9957bd4..d0410d7d 100644 --- a/lib/services/watch_next_service.dart +++ b/lib/services/watch_next_service.dart @@ -4,6 +4,7 @@ import 'package:flutter/services.dart'; import '../models/plex_metadata.dart'; import '../utils/app_logger.dart'; +import '../utils/content_utils.dart'; import 'plex_client.dart'; import 'settings_service.dart' show EpisodePosterMode; @@ -54,8 +55,9 @@ class WatchNextService { /// Sync On Deck items to Watch Next row. Future syncFromOnDeck( List onDeckItems, - PlexClient Function(String serverId) getClientForServerId, - ) async { + PlexClient Function(String serverId) getClientForServerId, { + bool hideSpoilers = false, + }) async { if (!Platform.isAndroid) return false; try { @@ -63,7 +65,7 @@ class WatchNextService { if (!supported) return false; final items = onDeckItems.map((item) { - return _convertToWatchNextItem(item, getClientForServerId); + return _convertToWatchNextItem(item, getClientForServerId, hideSpoilers: hideSpoilers); }).toList(); return await _channel.invokeMethod('sync', {'items': items}) ?? false; @@ -111,15 +113,20 @@ class WatchNextService { Map _convertToWatchNextItem( PlexMetadata item, - PlexClient Function(String serverId) getClientForServerId, - ) { + PlexClient Function(String serverId) getClientForServerId, { + bool hideSpoilers = false, + }) { final contentId = _buildContentId(item.serverId, item.ratingKey); String? posterUri; try { if (item.serverId != null) { final client = getClientForServerId(item.serverId!); - final thumbPath = item.posterThumb(mode: EpisodePosterMode.episodeThumbnail, mixedHubContext: true); + String? thumbPath; + if (hideSpoilers && item.shouldHideSpoiler) { + thumbPath = item.spoilerSafeArt; + } + thumbPath ??= item.posterThumb(mode: EpisodePosterMode.episodeThumbnail, mixedHubContext: true); if (thumbPath != null) { posterUri = client.getThumbnailUrl(thumbPath); } diff --git a/lib/utils/content_utils.dart b/lib/utils/content_utils.dart index 54b0195d..88193b6b 100644 --- a/lib/utils/content_utils.dart +++ b/lib/utils/content_utils.dart @@ -108,4 +108,7 @@ extension PlexMetadataType on PlexMetadata { } return true; } + + /// Non-spoiler art path for episodes (show/season background). + String? get spoilerSafeArt => grandparentArt ?? art; }