fix(tv): reach app bar actions via up from tabs

close #1202
This commit is contained in:
edde746
2026-06-06 08:51:08 +02:00
parent d90cc61541
commit 32421e4c84
5 changed files with 21 additions and 44 deletions
+8 -2
View File
@@ -88,12 +88,17 @@ mixin TabNavigationMixin<T extends StatefulWidget> on State<T>, TickerProviderSt
}
/// Shared tab chip builder — eliminates duplication between screens.
///
/// [onNavigateToActions] moves focus into the app bar's right-aligned
/// [FocusableActionBar]. It fires both on RIGHT from the last tab and on UP
/// from any tab, so every screen with that layout gets a consistent remote
/// path to its app bar actions.
Widget buildTabChip(
String label,
int index, {
required VoidCallback onSelectWhenActive,
required VoidCallback onNavigateDown,
VoidCallback? onNavigateRightFromLast,
VoidCallback? onNavigateToActions,
}) {
final isSelected = tabController.index == index;
return FocusableTabChip(
@@ -128,8 +133,9 @@ mixin TabNavigationMixin<T extends StatefulWidget> on State<T>, TickerProviderSt
});
getTabChipFocusNode(newIndex).requestFocus();
}
: onNavigateRightFromLast,
: onNavigateToActions,
onNavigateDown: onNavigateDown,
onNavigateUp: onNavigateToActions,
onBack: onTabBarBack,
);
}
+5 -39
View File
@@ -14,7 +14,6 @@ import '../../mixins/refreshable.dart';
import '../../utils/grid_size_calculator.dart';
import '../../utils/platform_detector.dart';
import '../../widgets/desktop_app_bar.dart';
import '../../widgets/focusable_tab_chip.dart';
import '../../widgets/focusable_media_card.dart';
import '../../widgets/media_grid_delegate.dart';
import '../../widgets/download_tree_view.dart';
@@ -87,45 +86,12 @@ class DownloadsScreenState extends State<DownloadsScreen>
}
Widget _buildTabChip(String label, int index) {
final isSelected = tabController.index == index;
return FocusableTabChip(
label: label,
isSelected: isSelected,
focusNode: getTabChipFocusNode(index),
onSelect: () {
if (isSelected) {
// Already selected - navigate to tab content
_focusCurrentTab();
} else {
// Switch to this tab
setState(() {
tabController.index = index;
});
}
},
onNavigateLeft: index > 0
? () {
final newIndex = index - 1;
setState(() {
suppressAutoFocus = true;
tabController.index = newIndex;
});
getTabChipFocusNode(newIndex).requestFocus();
}
: onTabBarBack,
onNavigateRight: index < tabCount - 1
? () {
final newIndex = index + 1;
setState(() {
suppressAutoFocus = true;
tabController.index = newIndex;
});
getTabChipFocusNode(newIndex).requestFocus();
}
: () => _actionBarKey.currentState?.requestFocusOnFirst(),
return buildTabChip(
label,
index,
onSelectWhenActive: _focusCurrentTab,
onNavigateDown: _focusCurrentTab,
onBack: onTabBarBack,
onNavigateToActions: () => _actionBarKey.currentState?.requestFocusOnFirst(),
);
}
+2 -2
View File
@@ -923,7 +923,7 @@ class _LibrariesScreenState extends State<LibrariesScreen>
i,
onSelectWhenActive: _focusCurrentTab,
onNavigateDown: _focusCurrentTabFromTabBar,
onNavigateRightFromLast: () => _actionBarKey.currentState?.requestFocusOnFirst(),
onNavigateToActions: () => _actionBarKey.currentState?.requestFocusOnFirst(),
),
],
],
@@ -1181,7 +1181,7 @@ class _LibrariesScreenState extends State<LibrariesScreen>
i,
onSelectWhenActive: _focusCurrentTab,
onNavigateDown: _focusCurrentTabFromTabBar,
onNavigateRightFromLast: () => _actionBarKey.currentState?.requestFocusOnFirst(),
onNavigateToActions: () => _actionBarKey.currentState?.requestFocusOnFirst(),
),
],
],
+1 -1
View File
@@ -535,7 +535,7 @@ class _LiveTvScreenState extends State<LiveTvScreen>
i,
onSelectWhenActive: _focusCurrentTab,
onNavigateDown: _focusCurrentTab,
onNavigateRightFromLast: () => _actionBarKey.currentState?.requestFocusOnFirst(),
onNavigateToActions: () => _actionBarKey.currentState?.requestFocusOnFirst(),
),
],
];
+5
View File
@@ -31,6 +31,9 @@ class FocusableTabChip extends StatefulWidget {
/// Called when the user presses DOWN from this chip.
final VoidCallback? onNavigateDown;
/// Called when the user presses UP from this chip.
final VoidCallback? onNavigateUp;
/// Called when the user presses BACK from this chip.
final VoidCallback? onBack;
@@ -50,6 +53,7 @@ class FocusableTabChip extends StatefulWidget {
this.onNavigateLeft,
this.onNavigateRight,
this.onNavigateDown,
this.onNavigateUp,
this.onBack,
this.onLongPress,
this.topImage,
@@ -94,6 +98,7 @@ class _FocusableTabChipState extends State<FocusableTabChip> with FocusableChipS
onNavigateLeft: widget.onNavigateLeft,
onNavigateRight: widget.onNavigateRight,
onNavigateDown: widget.onNavigateDown,
onNavigateUp: widget.onNavigateUp,
onBack: widget.onBack,
),
);