diff --git a/lib/common/widgets/text_field/editable_text.dart b/lib/common/widgets/text_field/editable_text.dart index be89d694..65f8f6b1 100644 --- a/lib/common/widgets/text_field/editable_text.dart +++ b/lib/common/widgets/text_field/editable_text.dart @@ -3251,7 +3251,7 @@ class EditableTextState extends State // to make sure the user can see the changes they just made. Programmatic // changes to `textEditingValue` do not trigger the behavior even if the // text field is focused. - _scheduleShowCaretOnScreen(withAnimation: true); + scheduleShowCaretOnScreen(withAnimation: true); } bool _checkNeedsAdjustAffinity(TextEditingValue value) { @@ -4119,7 +4119,7 @@ class EditableTextState extends State bool _showCaretOnScreenScheduled = false; - void _scheduleShowCaretOnScreen({required bool withAnimation}) { + void scheduleShowCaretOnScreen({required bool withAnimation}) { if (_showCaretOnScreenScheduled) { return; } @@ -4217,7 +4217,7 @@ class EditableTextState extends State if (_lastBottomViewInset < view.viewInsets.bottom) { // 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. - _scheduleShowCaretOnScreen(withAnimation: false); + scheduleShowCaretOnScreen(withAnimation: false); } } _lastBottomViewInset = view.viewInsets.bottom; @@ -4518,7 +4518,7 @@ class EditableTextState extends State WidgetsBinding.instance.addObserver(this); _lastBottomViewInset = View.of(context).viewInsets.bottom; if (!widget.readOnly) { - _scheduleShowCaretOnScreen(withAnimation: true); + scheduleShowCaretOnScreen(withAnimation: true); } final TextSelection? updatedSelection = _adjustedSelectionWhenFocused(); if (updatedSelection != null) { @@ -4747,7 +4747,7 @@ class EditableTextState extends State final bool shouldShowCaret = widget.readOnly ? _value.selection != value.selection : _value != value; if (shouldShowCaret) { - _scheduleShowCaretOnScreen(withAnimation: true); + scheduleShowCaretOnScreen(withAnimation: true); } // Even if the value doesn't change, it may be necessary to focus and build diff --git a/lib/common/widgets/text_field/text_field.dart b/lib/common/widgets/text_field/text_field.dart index 26c3811f..bc96dfe4 100644 --- a/lib/common/widgets/text_field/text_field.dart +++ b/lib/common/widgets/text_field/text_field.dart @@ -82,12 +82,11 @@ typedef InputCounterWidgetBuilder = Widget? Function( class _TextFieldSelectionGestureDetectorBuilder extends TextSelectionGestureDetectorBuilder { - _TextFieldSelectionGestureDetectorBuilder( - {required _RichTextFieldState state}) + _TextFieldSelectionGestureDetectorBuilder({required RichTextFieldState state}) : _state = state, super(delegate: state); - final _RichTextFieldState _state; + final RichTextFieldState _state; @override bool get onUserTapAlwaysCalled => _state.widget.onTapAlwaysCalled; @@ -961,7 +960,7 @@ class RichTextField extends StatefulWidget { } @override - State createState() => _RichTextFieldState(); + State createState() => RichTextFieldState(); @override void debugFillProperties(DiagnosticPropertiesBuilder properties) { @@ -1150,7 +1149,7 @@ class RichTextField extends StatefulWidget { } } -class _RichTextFieldState extends State +class RichTextFieldState extends State with RestorationMixin implements TextSelectionGestureDetectorBuilderDelegate, AutofillClient { // RestorableRichTextEditingController? _controller; @@ -1912,6 +1911,10 @@ class _RichTextFieldState extends State ), ); } + + void scheduleShowCaretOnScreen({required bool withAnimation}) { + _editableText?.scheduleShowCaretOnScreen(withAnimation: withAnimation); + } } TextStyle? _m2StateInputStyle(BuildContext context) => diff --git a/lib/pages/common/publish/common_rich_text_pub_page.dart b/lib/pages/common/publish/common_rich_text_pub_page.dart index c8366a2c..22496fb8 100644 --- a/lib/pages/common/publish/common_rich_text_pub_page.dart +++ b/lib/pages/common/publish/common_rich_text_pub_page.dart @@ -2,6 +2,7 @@ import 'dart:io'; import 'package:PiliPlus/common/widgets/button/icon_button.dart'; import 'package:PiliPlus/common/widgets/text_field/controller.dart'; +import 'package:PiliPlus/common/widgets/text_field/text_field.dart'; import 'package:PiliPlus/models/common/image_preview_type.dart'; import 'package:PiliPlus/models_new/dynamic/dyn_mention/item.dart'; import 'package:PiliPlus/models_new/emote/emote.dart' as e; @@ -31,6 +32,8 @@ abstract class CommonRichTextPubPage abstract class CommonRichTextPubPageState extends CommonPublishPageState { + final key = GlobalKey(); + @override late final RichTextEditingController editController = RichTextEditingController( @@ -329,10 +332,6 @@ abstract class CommonRichTextPubPageState ..syncRichText(delta) ..value = newValue; } else { - editController.value = TextEditingValue( - text: text, - selection: TextSelection.collapsed(offset: text.length), - ); editController.items ..clear() ..add( @@ -348,7 +347,13 @@ abstract class CommonRichTextPubPageState id: id, ), ); + editController.value = TextEditingValue( + text: text, + selection: TextSelection.collapsed(offset: text.length), + ); } + + key.currentState?.scheduleShowCaretOnScreen(withAnimation: true); } @override diff --git a/lib/pages/dynamics_create/view.dart b/lib/pages/dynamics_create/view.dart index d8d605ba..37cf87f9 100644 --- a/lib/pages/dynamics_create/view.dart +++ b/lib/pages/dynamics_create/view.dart @@ -621,6 +621,7 @@ class _CreateDynPanelState extends CommonRichTextPubPageState { }, child: Obx( () => RichTextField( + key: key, controller: editController, minLines: 4, maxLines: null, diff --git a/lib/pages/dynamics_repost/view.dart b/lib/pages/dynamics_repost/view.dart index 6c644b07..2be8fedf 100644 --- a/lib/pages/dynamics_repost/view.dart +++ b/lib/pages/dynamics_repost/view.dart @@ -225,6 +225,7 @@ class _RepostPanelState extends CommonRichTextPubPageState { }, child: Obx( () => RichTextField( + key: key, controller: editController, minLines: 4, maxLines: null, diff --git a/lib/pages/live_room/send_danmaku/view.dart b/lib/pages/live_room/send_danmaku/view.dart index 62471d8e..9ba5ccae 100644 --- a/lib/pages/live_room/send_danmaku/view.dart +++ b/lib/pages/live_room/send_danmaku/view.dart @@ -102,6 +102,7 @@ class _ReplyPageState extends CommonRichTextPubPageState { }, child: Obx( () => RichTextField( + key: key, controller: editController, minLines: 1, maxLines: 2, diff --git a/lib/pages/video/reply_new/view.dart b/lib/pages/video/reply_new/view.dart index 091fce23..12d0b5ba 100644 --- a/lib/pages/video/reply_new/view.dart +++ b/lib/pages/video/reply_new/view.dart @@ -139,6 +139,7 @@ class _ReplyPageState extends CommonRichTextPubPageState { }, child: Obx( () => RichTextField( + key: key, controller: editController, minLines: 4, maxLines: 8, diff --git a/lib/pages/whisper_detail/view.dart b/lib/pages/whisper_detail/view.dart index 9590aa79..2b42ba03 100644 --- a/lib/pages/whisper_detail/view.dart +++ b/lib/pages/whisper_detail/view.dart @@ -240,6 +240,7 @@ class _WhisperDetailPageState }, child: Obx( () => RichTextField( + key: key, readOnly: readOnly.value, focusNode: focusNode, controller: editController,