opt insert rich text

Signed-off-by: bggRGjQaUbCoE <githubaccount56556@proton.me>
This commit is contained in:
bggRGjQaUbCoE
2025-07-05 13:12:39 +08:00
parent 0f1665bf08
commit b496ea4da4
8 changed files with 27 additions and 14 deletions

View File

@@ -3251,7 +3251,7 @@ class EditableTextState extends State<EditableText>
// to make sure the user can see the changes they just made. Programmatic // to make sure the user can see the changes they just made. Programmatic
// changes to `textEditingValue` do not trigger the behavior even if the // changes to `textEditingValue` do not trigger the behavior even if the
// text field is focused. // text field is focused.
_scheduleShowCaretOnScreen(withAnimation: true); scheduleShowCaretOnScreen(withAnimation: true);
} }
bool _checkNeedsAdjustAffinity(TextEditingValue value) { bool _checkNeedsAdjustAffinity(TextEditingValue value) {
@@ -4119,7 +4119,7 @@ class EditableTextState extends State<EditableText>
bool _showCaretOnScreenScheduled = false; bool _showCaretOnScreenScheduled = false;
void _scheduleShowCaretOnScreen({required bool withAnimation}) { void scheduleShowCaretOnScreen({required bool withAnimation}) {
if (_showCaretOnScreenScheduled) { if (_showCaretOnScreenScheduled) {
return; return;
} }
@@ -4217,7 +4217,7 @@ class EditableTextState extends State<EditableText>
if (_lastBottomViewInset < view.viewInsets.bottom) { if (_lastBottomViewInset < view.viewInsets.bottom) {
// Because the metrics change signal from engine will come here every frame // 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. // (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; _lastBottomViewInset = view.viewInsets.bottom;
@@ -4518,7 +4518,7 @@ class EditableTextState extends State<EditableText>
WidgetsBinding.instance.addObserver(this); WidgetsBinding.instance.addObserver(this);
_lastBottomViewInset = View.of(context).viewInsets.bottom; _lastBottomViewInset = View.of(context).viewInsets.bottom;
if (!widget.readOnly) { if (!widget.readOnly) {
_scheduleShowCaretOnScreen(withAnimation: true); scheduleShowCaretOnScreen(withAnimation: true);
} }
final TextSelection? updatedSelection = _adjustedSelectionWhenFocused(); final TextSelection? updatedSelection = _adjustedSelectionWhenFocused();
if (updatedSelection != null) { if (updatedSelection != null) {
@@ -4747,7 +4747,7 @@ class EditableTextState extends State<EditableText>
final bool shouldShowCaret = final bool shouldShowCaret =
widget.readOnly ? _value.selection != value.selection : _value != value; widget.readOnly ? _value.selection != value.selection : _value != value;
if (shouldShowCaret) { if (shouldShowCaret) {
_scheduleShowCaretOnScreen(withAnimation: true); scheduleShowCaretOnScreen(withAnimation: true);
} }
// Even if the value doesn't change, it may be necessary to focus and build // Even if the value doesn't change, it may be necessary to focus and build

View File

@@ -82,12 +82,11 @@ typedef InputCounterWidgetBuilder = Widget? Function(
class _TextFieldSelectionGestureDetectorBuilder class _TextFieldSelectionGestureDetectorBuilder
extends TextSelectionGestureDetectorBuilder { extends TextSelectionGestureDetectorBuilder {
_TextFieldSelectionGestureDetectorBuilder( _TextFieldSelectionGestureDetectorBuilder({required RichTextFieldState state})
{required _RichTextFieldState state})
: _state = state, : _state = state,
super(delegate: state); super(delegate: state);
final _RichTextFieldState _state; final RichTextFieldState _state;
@override @override
bool get onUserTapAlwaysCalled => _state.widget.onTapAlwaysCalled; bool get onUserTapAlwaysCalled => _state.widget.onTapAlwaysCalled;
@@ -961,7 +960,7 @@ class RichTextField extends StatefulWidget {
} }
@override @override
State<RichTextField> createState() => _RichTextFieldState(); State<RichTextField> createState() => RichTextFieldState();
@override @override
void debugFillProperties(DiagnosticPropertiesBuilder properties) { void debugFillProperties(DiagnosticPropertiesBuilder properties) {
@@ -1150,7 +1149,7 @@ class RichTextField extends StatefulWidget {
} }
} }
class _RichTextFieldState extends State<RichTextField> class RichTextFieldState extends State<RichTextField>
with RestorationMixin with RestorationMixin
implements TextSelectionGestureDetectorBuilderDelegate, AutofillClient { implements TextSelectionGestureDetectorBuilderDelegate, AutofillClient {
// RestorableRichTextEditingController? _controller; // RestorableRichTextEditingController? _controller;
@@ -1912,6 +1911,10 @@ class _RichTextFieldState extends State<RichTextField>
), ),
); );
} }
void scheduleShowCaretOnScreen({required bool withAnimation}) {
_editableText?.scheduleShowCaretOnScreen(withAnimation: withAnimation);
}
} }
TextStyle? _m2StateInputStyle(BuildContext context) => TextStyle? _m2StateInputStyle(BuildContext context) =>

View File

@@ -2,6 +2,7 @@ import 'dart:io';
import 'package:PiliPlus/common/widgets/button/icon_button.dart'; 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/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/common/image_preview_type.dart';
import 'package:PiliPlus/models_new/dynamic/dyn_mention/item.dart'; import 'package:PiliPlus/models_new/dynamic/dyn_mention/item.dart';
import 'package:PiliPlus/models_new/emote/emote.dart' as e; import 'package:PiliPlus/models_new/emote/emote.dart' as e;
@@ -31,6 +32,8 @@ abstract class CommonRichTextPubPage
abstract class CommonRichTextPubPageState<T extends CommonRichTextPubPage> abstract class CommonRichTextPubPageState<T extends CommonRichTextPubPage>
extends CommonPublishPageState<T> { extends CommonPublishPageState<T> {
final key = GlobalKey<RichTextFieldState>();
@override @override
late final RichTextEditingController editController = late final RichTextEditingController editController =
RichTextEditingController( RichTextEditingController(
@@ -329,10 +332,6 @@ abstract class CommonRichTextPubPageState<T extends CommonRichTextPubPage>
..syncRichText(delta) ..syncRichText(delta)
..value = newValue; ..value = newValue;
} else { } else {
editController.value = TextEditingValue(
text: text,
selection: TextSelection.collapsed(offset: text.length),
);
editController.items editController.items
..clear() ..clear()
..add( ..add(
@@ -348,7 +347,13 @@ abstract class CommonRichTextPubPageState<T extends CommonRichTextPubPage>
id: id, id: id,
), ),
); );
editController.value = TextEditingValue(
text: text,
selection: TextSelection.collapsed(offset: text.length),
);
} }
key.currentState?.scheduleShowCaretOnScreen(withAnimation: true);
} }
@override @override

View File

@@ -621,6 +621,7 @@ class _CreateDynPanelState extends CommonRichTextPubPageState<CreateDynPanel> {
}, },
child: Obx( child: Obx(
() => RichTextField( () => RichTextField(
key: key,
controller: editController, controller: editController,
minLines: 4, minLines: 4,
maxLines: null, maxLines: null,

View File

@@ -225,6 +225,7 @@ class _RepostPanelState extends CommonRichTextPubPageState<RepostPanel> {
}, },
child: Obx( child: Obx(
() => RichTextField( () => RichTextField(
key: key,
controller: editController, controller: editController,
minLines: 4, minLines: 4,
maxLines: null, maxLines: null,

View File

@@ -102,6 +102,7 @@ class _ReplyPageState extends CommonRichTextPubPageState<LiveSendDmPanel> {
}, },
child: Obx( child: Obx(
() => RichTextField( () => RichTextField(
key: key,
controller: editController, controller: editController,
minLines: 1, minLines: 1,
maxLines: 2, maxLines: 2,

View File

@@ -139,6 +139,7 @@ class _ReplyPageState extends CommonRichTextPubPageState<ReplyPage> {
}, },
child: Obx( child: Obx(
() => RichTextField( () => RichTextField(
key: key,
controller: editController, controller: editController,
minLines: 4, minLines: 4,
maxLines: 8, maxLines: 8,

View File

@@ -240,6 +240,7 @@ class _WhisperDetailPageState
}, },
child: Obx( child: Obx(
() => RichTextField( () => RichTextField(
key: key,
readOnly: readOnly.value, readOnly: readOnly.value,
focusNode: focusNode, focusNode: focusNode,
controller: editController, controller: editController,