From 1fb32f16188a45f85feb1d4b01cfec2b806355a3 Mon Sep 17 00:00:00 2001 From: edde746 <86283021+edde746@users.noreply.github.com> Date: Mon, 9 Feb 2026 06:37:59 +0100 Subject: [PATCH] fix: debounce alpha jump bar keyboard navigation --- .../libraries/tabs/library_browse_tab.dart | 11 +++++++- lib/widgets/alpha_jump_bar.dart | 25 +++++++++++++++++-- 2 files changed, 33 insertions(+), 3 deletions(-) diff --git a/lib/screens/libraries/tabs/library_browse_tab.dart b/lib/screens/libraries/tabs/library_browse_tab.dart index 18662e21..8adc3aef 100644 --- a/lib/screens/libraries/tabs/library_browse_tab.dart +++ b/lib/screens/libraries/tabs/library_browse_tab.dart @@ -794,9 +794,18 @@ class _LibraryBrowseTabState extends BaseLibraryTabState { /// Whether this bar currently has focus (for D-pad mode). bool _hasFocus = false; + /// Debounce timer for keyboard-driven jumps. + Timer? _debounce; + @override void initState() { super.initState(); @@ -54,6 +59,12 @@ class _AlphaJumpBarState extends State { } } + @override + void dispose() { + _debounce?.cancel(); + super.dispose(); + } + void _jumpToLetter(String letter) { final index = _helper.indexForLetter(letter); if (index != null) { @@ -61,6 +72,16 @@ class _AlphaJumpBarState extends State { } } + /// Schedule a debounced jump to the currently highlighted letter. + /// The highlight updates immediately for visual feedback, but the + /// actual scroll only fires after keyboard input settles. + void _debouncedJump() { + _debounce?.cancel(); + _debounce = Timer(const Duration(milliseconds: 150), () { + _jumpToLetter(AlphaJumpHelper.allLetters[_highlightedIndex]); + }); + } + /// Resolves a vertical drag position to a letter index. int _letterIndexFromDy(double dy, double totalHeight) { final index = (dy / totalHeight * AlphaJumpHelper.allLetters.length).floor(); @@ -75,14 +96,14 @@ class _AlphaJumpBarState extends State { if (event.logicalKey == LogicalKeyboardKey.arrowUp) { if (_highlightedIndex > 0) { setState(() => _highlightedIndex--); - _jumpToLetter(AlphaJumpHelper.allLetters[_highlightedIndex]); + _debouncedJump(); } return KeyEventResult.handled; } if (event.logicalKey == LogicalKeyboardKey.arrowDown) { if (_highlightedIndex < AlphaJumpHelper.allLetters.length - 1) { setState(() => _highlightedIndex++); - _jumpToLetter(AlphaJumpHelper.allLetters[_highlightedIndex]); + _debouncedJump(); } return KeyEventResult.handled; }