Fix arrow keys for production web builds.
Handle all arrows in Focus.onKeyEvent with a HardwareKeyboard fallback, and remove invalid CallbackShortcuts repeat parameter. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
parent
b840db0cff
commit
60b14fb49e
@ -111,13 +111,15 @@ class _SwipeQuestionTileState extends State<SwipeQuestionTile>
|
|||||||
AnimationController(vsync: this, duration: _holdEdgeDuration)
|
AnimationController(vsync: this, duration: _holdEdgeDuration)
|
||||||
..addListener(_syncHoldDeferDrag)
|
..addListener(_syncHoldDeferDrag)
|
||||||
..addStatusListener(_onHoldDeferStatus);
|
..addStatusListener(_onHoldDeferStatus);
|
||||||
|
HardwareKeyboard.instance.addHandler(_handleHardwareKey);
|
||||||
WidgetsBinding.instance.addPostFrameCallback((_) => _requestTileFocus());
|
WidgetsBinding.instance.addPostFrameCallback((_) => _requestTileFocus());
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void didUpdateWidget(SwipeQuestionTile oldWidget) {
|
void didUpdateWidget(SwipeQuestionTile oldWidget) {
|
||||||
super.didUpdateWidget(oldWidget);
|
super.didUpdateWidget(oldWidget);
|
||||||
if (oldWidget.questionId != widget.questionId) {
|
if (oldWidget.questionId != widget.questionId ||
|
||||||
|
(oldWidget.busy && !widget.busy)) {
|
||||||
WidgetsBinding.instance.addPostFrameCallback((_) => _requestTileFocus());
|
WidgetsBinding.instance.addPostFrameCallback((_) => _requestTileFocus());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -131,6 +133,7 @@ class _SwipeQuestionTileState extends State<SwipeQuestionTile>
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
void dispose() {
|
void dispose() {
|
||||||
|
HardwareKeyboard.instance.removeHandler(_handleHardwareKey);
|
||||||
_focusNode.dispose();
|
_focusNode.dispose();
|
||||||
_snapController.dispose();
|
_snapController.dispose();
|
||||||
_holdSaveController.dispose();
|
_holdSaveController.dispose();
|
||||||
@ -484,7 +487,15 @@ class _SwipeQuestionTileState extends State<SwipeQuestionTile>
|
|||||||
_stepSliderBy(scrollDy > 0 ? -1 : 1);
|
_stepSliderBy(scrollDy > 0 ? -1 : 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Arrow left/right (held): defer / save swipe. Up/down use [CallbackShortcuts].
|
/// Web/production fallback when [Focus.onKeyEvent] does not receive arrows.
|
||||||
|
bool _handleHardwareKey(KeyEvent event) {
|
||||||
|
if (!_focusNode.hasFocus) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return _onKeyEvent(_focusNode, event) == KeyEventResult.handled;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Arrow up/down step value; hold left/right to defer / save (edge buttons).
|
||||||
KeyEventResult _onKeyEvent(FocusNode node, KeyEvent event) {
|
KeyEventResult _onKeyEvent(FocusNode node, KeyEvent event) {
|
||||||
if (widget.busy || _acting) {
|
if (widget.busy || _acting) {
|
||||||
return KeyEventResult.ignored;
|
return KeyEventResult.ignored;
|
||||||
@ -493,6 +504,18 @@ class _SwipeQuestionTileState extends State<SwipeQuestionTile>
|
|||||||
final LogicalKeyboardKey key = event.logicalKey;
|
final LogicalKeyboardKey key = event.logicalKey;
|
||||||
const _HoldInputSource kb = _HoldInputSource.keyboard;
|
const _HoldInputSource kb = _HoldInputSource.keyboard;
|
||||||
|
|
||||||
|
if (key == LogicalKeyboardKey.arrowUp ||
|
||||||
|
key == LogicalKeyboardKey.arrowDown) {
|
||||||
|
if (event is KeyUpEvent) {
|
||||||
|
return KeyEventResult.handled;
|
||||||
|
}
|
||||||
|
if (event is KeyDownEvent || event is KeyRepeatEvent) {
|
||||||
|
_stepSliderBy(key == LogicalKeyboardKey.arrowUp ? 1 : -1);
|
||||||
|
return KeyEventResult.handled;
|
||||||
|
}
|
||||||
|
return KeyEventResult.ignored;
|
||||||
|
}
|
||||||
|
|
||||||
if (key == LogicalKeyboardKey.arrowRight) {
|
if (key == LogicalKeyboardKey.arrowRight) {
|
||||||
if (event is KeyDownEvent) {
|
if (event is KeyDownEvent) {
|
||||||
_beginHoldSave(kb);
|
_beginHoldSave(kb);
|
||||||
@ -608,13 +631,6 @@ class _SwipeQuestionTileState extends State<SwipeQuestionTile>
|
|||||||
autofocus: true,
|
autofocus: true,
|
||||||
descendantsAreFocusable: false,
|
descendantsAreFocusable: false,
|
||||||
onKeyEvent: _onKeyEvent,
|
onKeyEvent: _onKeyEvent,
|
||||||
child: CallbackShortcuts(
|
|
||||||
bindings: <ShortcutActivator, VoidCallback>{
|
|
||||||
const SingleActivator(LogicalKeyboardKey.arrowUp, repeat: true):
|
|
||||||
() => _stepSliderBy(1),
|
|
||||||
const SingleActivator(LogicalKeyboardKey.arrowDown, repeat: true):
|
|
||||||
() => _stepSliderBy(-1),
|
|
||||||
},
|
|
||||||
child: Stack(
|
child: Stack(
|
||||||
alignment: Alignment.center,
|
alignment: Alignment.center,
|
||||||
clipBehavior: Clip.none,
|
clipBehavior: Clip.none,
|
||||||
@ -770,7 +786,6 @@ class _SwipeQuestionTileState extends State<SwipeQuestionTile>
|
|||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user