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)
|
||||
..addListener(_syncHoldDeferDrag)
|
||||
..addStatusListener(_onHoldDeferStatus);
|
||||
HardwareKeyboard.instance.addHandler(_handleHardwareKey);
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) => _requestTileFocus());
|
||||
}
|
||||
|
||||
@override
|
||||
void didUpdateWidget(SwipeQuestionTile oldWidget) {
|
||||
super.didUpdateWidget(oldWidget);
|
||||
if (oldWidget.questionId != widget.questionId) {
|
||||
if (oldWidget.questionId != widget.questionId ||
|
||||
(oldWidget.busy && !widget.busy)) {
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) => _requestTileFocus());
|
||||
}
|
||||
}
|
||||
@ -131,6 +133,7 @@ class _SwipeQuestionTileState extends State<SwipeQuestionTile>
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
HardwareKeyboard.instance.removeHandler(_handleHardwareKey);
|
||||
_focusNode.dispose();
|
||||
_snapController.dispose();
|
||||
_holdSaveController.dispose();
|
||||
@ -484,7 +487,15 @@ class _SwipeQuestionTileState extends State<SwipeQuestionTile>
|
||||
_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) {
|
||||
if (widget.busy || _acting) {
|
||||
return KeyEventResult.ignored;
|
||||
@ -493,6 +504,18 @@ class _SwipeQuestionTileState extends State<SwipeQuestionTile>
|
||||
final LogicalKeyboardKey key = event.logicalKey;
|
||||
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 (event is KeyDownEvent) {
|
||||
_beginHoldSave(kb);
|
||||
@ -608,14 +631,7 @@ class _SwipeQuestionTileState extends State<SwipeQuestionTile>
|
||||
autofocus: true,
|
||||
descendantsAreFocusable: false,
|
||||
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,
|
||||
clipBehavior: Clip.none,
|
||||
children: <Widget>[
|
||||
@ -769,7 +785,6 @@ class _SwipeQuestionTileState extends State<SwipeQuestionTile>
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user