From 63e807dd582bba74223b5980b9b08edbaa70f0d7 Mon Sep 17 00:00:00 2001 From: edde746 <86283021+edde746@users.noreply.github.com> Date: Wed, 20 May 2026 03:54:30 +0200 Subject: [PATCH] fix(tv): focus flattened episode rows close #1081 --- lib/screens/media_detail_screen.dart | 9 ++++-- test/widgets/tv_browse_rail_test.dart | 42 +++++++++++++++++++++++++++ 2 files changed, 49 insertions(+), 2 deletions(-) diff --git a/lib/screens/media_detail_screen.dart b/lib/screens/media_detail_screen.dart index e1d78a21..186ae651 100644 --- a/lib/screens/media_detail_screen.dart +++ b/lib/screens/media_detail_screen.dart @@ -3211,8 +3211,13 @@ class _MediaDetailScreenState extends State } String? _tvDetailInitialHubId(MediaItem metadata) { - if (!metadata.isShow || _showEpisodesDirectly || _seasons.isEmpty) return null; - return '$_tvDetailSeasonHubIdPrefix$_selectedSeasonIndex'; + if (metadata.isShow && !_showEpisodesDirectly && _seasons.isNotEmpty) { + return '$_tvDetailSeasonHubIdPrefix$_selectedSeasonIndex'; + } + if ((metadata.isShow && _showEpisodesDirectly) || metadata.isSeason) { + return 'detail_episodes'; + } + return null; } String? _tvDetailInitialItemId(MediaItem metadata) { diff --git a/test/widgets/tv_browse_rail_test.dart b/test/widgets/tv_browse_rail_test.dart index dd938619..b20b1fac 100644 --- a/test/widgets/tv_browse_rail_test.dart +++ b/test/widgets/tv_browse_rail_test.dart @@ -201,6 +201,48 @@ void main() { expect(activeHubIds.last, 'detail_season_1'); }); + testWidgets('selects preferred hub after an earlier update could not find it', (tester) async { + final activeHubIds = []; + + Widget buildRail(List hubs, {String? initialHubId}) { + final serverManager = MultiServerManager(); + return ChangeNotifierProvider( + create: (_) => MultiServerProvider(serverManager, DataAggregationService(serverManager)), + child: MaterialApp( + theme: monoTheme(dark: true), + home: Scaffold( + body: SizedBox( + width: 1280, + height: 720, + child: TvBrowseRail( + key: const ValueKey('rail'), + hubs: hubs, + initialHubId: initialHubId, + iconForHub: (_, _) => Icons.tv_rounded, + onActiveHubChanged: (hub, _) => activeHubIds.add(hub.id), + ), + ), + ), + ), + ); + } + + const castHub = MediaHub(id: 'detail_actors', title: 'Cast', type: 'person', items: []); + const episodesHub = MediaHub(id: 'detail_episodes', title: 'Episodes', type: 'episode', items: []); + + await tester.pumpWidget(buildRail(const [castHub])); + await tester.pump(); + + await tester.pumpWidget(buildRail(const [castHub], initialHubId: episodesHub.id)); + await tester.pump(); + + await tester.pumpWidget(buildRail(const [episodesHub, castHub], initialHubId: episodesHub.id)); + await tester.pump(); + + expect(activeHubIds, containsAllInOrder(['detail_actors', 'detail_episodes'])); + expect(activeHubIds.last, 'detail_episodes'); + }); + testWidgets('selects preferred item when active hub items are populated asynchronously', (tester) async { final focusedItemIds = [];