From b0b2277c53f00bbf30a9073100dbc63360458dc5 Mon Sep 17 00:00:00 2001 From: Amir Panahandeh Date: Fri, 23 Feb 2024 21:14:51 +0330 Subject: [PATCH 1/2] Scroll to selection after keyboard opened Fixes #280. --- packages/fleather/lib/src/widgets/editor.dart | 40 ++++++++++++++++--- 1 file changed, 34 insertions(+), 6 deletions(-) diff --git a/packages/fleather/lib/src/widgets/editor.dart b/packages/fleather/lib/src/widgets/editor.dart index 666bd210..4d412024 100644 --- a/packages/fleather/lib/src/widgets/editor.dart +++ b/packages/fleather/lib/src/widgets/editor.dart @@ -1474,6 +1474,7 @@ class RawEditorState extends EditorState if (_hasFocus) { // Listen for changing viewInsets, which indicates keyboard showing up. WidgetsBinding.instance.addObserver(this); + _lastBottomViewInset = View.of(context).viewInsets.bottom; _showCaretOnScreen(); // _lastBottomViewInset = WidgetsBinding.instance.window.viewInsets.bottom; // if (!_value.selection.isValid) { @@ -1514,7 +1515,7 @@ class RawEditorState extends EditorState bool _showCaretOnScreenScheduled = false; - void _showCaretOnScreen() { + void _showCaretOnScreen([bool withAnimation = true]) { if (!widget.showCursor || _showCaretOnScreenScheduled) { return; } @@ -1539,11 +1540,16 @@ class RawEditorState extends EditorState ); if (offset != null) { - _scrollController.animateTo( - math.min(offset, _scrollController.position.maxScrollExtent), - duration: _caretAnimationDuration, - curve: _caretAnimationCurve, - ); + if (withAnimation) { + _scrollController.animateTo( + math.min(offset, _scrollController.position.maxScrollExtent), + duration: _caretAnimationDuration, + curve: _caretAnimationCurve, + ); + } else { + _scrollController.jumpTo( + math.min(offset, _scrollController.position.maxScrollExtent)); + } } }); } @@ -1569,6 +1575,28 @@ class RawEditorState extends EditorState } } + late double _lastBottomViewInset; + + @override + void didChangeMetrics() { + super.didChangeMetrics(); + if (!mounted) { + return; + } + final bottomBiewInset = View.of(context).viewInsets.bottom; + if (_lastBottomViewInset != bottomBiewInset) { + SchedulerBinding.instance.addPostFrameCallback((_) { + _selectionOverlay?.updateForScroll(); + }); + if (_lastBottomViewInset < bottomBiewInset) { + // Because the metrics change signal from engine will come here every frame + // (on both iOS and Android). So we don't need to show caret with animation. + _showCaretOnScreen(false); + } + } + _lastBottomViewInset = bottomBiewInset; + } + // On MacOS some actions are sent as selectors. We need to manually find the right Action and invoke it. // Ref: https://github.com/flutter/flutter/blob/3.7.0/packages/flutter/lib/src/widgets/editable_text.dart#L3731 @override From b149fb7e7a2501ad57c5242d5cdb00cce48b1037 Mon Sep 17 00:00:00 2001 From: Amir Panahandeh Date: Wed, 27 Mar 2024 10:15:22 +0330 Subject: [PATCH 2/2] Fix typo --- packages/fleather/lib/src/widgets/editor.dart | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/fleather/lib/src/widgets/editor.dart b/packages/fleather/lib/src/widgets/editor.dart index 4d412024..d1e6ee57 100644 --- a/packages/fleather/lib/src/widgets/editor.dart +++ b/packages/fleather/lib/src/widgets/editor.dart @@ -1583,18 +1583,18 @@ class RawEditorState extends EditorState if (!mounted) { return; } - final bottomBiewInset = View.of(context).viewInsets.bottom; - if (_lastBottomViewInset != bottomBiewInset) { + final bottomViewInset = View.of(context).viewInsets.bottom; + if (_lastBottomViewInset != bottomViewInset) { SchedulerBinding.instance.addPostFrameCallback((_) { _selectionOverlay?.updateForScroll(); }); - if (_lastBottomViewInset < bottomBiewInset) { + if (_lastBottomViewInset < bottomViewInset) { // Because the metrics change signal from engine will come here every frame // (on both iOS and Android). So we don't need to show caret with animation. _showCaretOnScreen(false); } } - _lastBottomViewInset = bottomBiewInset; + _lastBottomViewInset = bottomViewInset; } // On MacOS some actions are sent as selectors. We need to manually find the right Action and invoke it.