feat: Add natural D-pad navigation for hub sections
- Add left navigation from hubs to sidebar when at leftmost item - Add up navigation from first hub to tab bar (Libraries) or hero section (Discover) - Enhance HubSection with onNavigateLeft and onNavigateUp callbacks - Update _handleVerticalNavigation to return false at top boundary for proper UP handling - Implement _navigateToSidebar() in Library Recommended tab and Discover screen - Update all HubSection instances with proper navigation callbacks
This commit is contained in:
@@ -39,6 +39,14 @@ class HubSection extends StatefulWidget {
|
||||
/// Used to navigate focus back to the tab bar.
|
||||
final VoidCallback? onBack;
|
||||
|
||||
/// Called when the user presses LEFT while at the leftmost item.
|
||||
/// Used to navigate focus to the side navigation rail.
|
||||
final VoidCallback? onNavigateLeft;
|
||||
|
||||
/// Called when the user presses UP while at the topmost item (first hub).
|
||||
/// Used to navigate focus to the tab bar.
|
||||
final VoidCallback? onNavigateUp;
|
||||
|
||||
const HubSection({
|
||||
super.key,
|
||||
required this.hub,
|
||||
@@ -49,6 +57,8 @@ class HubSection extends StatefulWidget {
|
||||
this.showServerName = false,
|
||||
this.onVerticalNavigation,
|
||||
this.onBack,
|
||||
this.onNavigateLeft,
|
||||
this.onNavigateUp,
|
||||
});
|
||||
|
||||
@override
|
||||
@@ -172,6 +182,9 @@ class HubSectionState extends State<HubSection> {
|
||||
HubFocusMemory.setForHub(widget.hub.hubKey, _focusedIndex);
|
||||
_scrollToIndex(_focusedIndex);
|
||||
setState(() {});
|
||||
} else if (widget.onNavigateLeft != null) {
|
||||
// At leftmost item - navigate to sidebar
|
||||
widget.onNavigateLeft!();
|
||||
}
|
||||
return KeyEventResult.handled;
|
||||
}
|
||||
@@ -189,7 +202,11 @@ class HubSectionState extends State<HubSection> {
|
||||
|
||||
// Up/Down: delegate to parent for vertical hub navigation, ALWAYS consume
|
||||
if (key.isUpKey) {
|
||||
widget.onVerticalNavigation?.call(true);
|
||||
final handled = widget.onVerticalNavigation?.call(true) ?? false;
|
||||
// If not handled (at top boundary) and we have onNavigateUp, call it
|
||||
if (!handled && widget.onNavigateUp != null) {
|
||||
widget.onNavigateUp!();
|
||||
}
|
||||
return KeyEventResult.handled;
|
||||
}
|
||||
if (key.isDownKey) {
|
||||
|
||||
Reference in New Issue
Block a user