fixed texteditingcontroller issues
This commit is contained in:
@@ -696,13 +696,13 @@ class MessageInputState extends State<MessageInput> {
|
|||||||
_buildAttachments(),
|
_buildAttachments(),
|
||||||
LimitedBox(
|
LimitedBox(
|
||||||
maxHeight: widget.maxHeight,
|
maxHeight: widget.maxHeight,
|
||||||
child: TextField(
|
child: StreamMessageTextField(
|
||||||
key: const Key('messageInputText'),
|
key: const Key('messageInputText'),
|
||||||
enabled: _inputEnabled,
|
enabled: _inputEnabled,
|
||||||
maxLines: null,
|
maxLines: null,
|
||||||
onSubmitted: (_) => sendMessage(),
|
onSubmitted: (_) => sendMessage(),
|
||||||
keyboardType: widget.keyboardType,
|
keyboardType: widget.keyboardType,
|
||||||
controller: messageInputController.textEditingController,
|
controller: messageInputController,
|
||||||
focusNode: _focusNode,
|
focusNode: _focusNode,
|
||||||
style: _messageInputTheme.inputTextStyle,
|
style: _messageInputTheme.inputTextStyle,
|
||||||
autofocus: widget.autofocus,
|
autofocus: widget.autofocus,
|
||||||
@@ -876,7 +876,7 @@ class MessageInputState extends State<MessageInput> {
|
|||||||
.contains(':')) {
|
.contains(':')) {
|
||||||
final textToSelection = messageInputController.text.substring(
|
final textToSelection = messageInputController.text.substring(
|
||||||
0,
|
0,
|
||||||
messageInputController.textEditingController.value.selection.start,
|
messageInputController.selectionStart,
|
||||||
);
|
);
|
||||||
final splits = textToSelection.split(':');
|
final splits = textToSelection.split(':');
|
||||||
final query = splits[splits.length - 2].toLowerCase();
|
final query = splits[splits.length - 2].toLowerCase();
|
||||||
@@ -1179,15 +1179,14 @@ class MessageInputState extends State<MessageInput> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Widget _buildMentionsOverlayEntry() {
|
Widget _buildMentionsOverlayEntry() {
|
||||||
if (messageInputController.textEditingController.value.selection.start <
|
if (messageInputController.selectionStart < 0) {
|
||||||
0) {
|
|
||||||
return const Offstage();
|
return const Offstage();
|
||||||
}
|
}
|
||||||
|
|
||||||
final splits = messageInputController.text
|
final splits = messageInputController.text
|
||||||
.substring(
|
.substring(
|
||||||
0,
|
0,
|
||||||
messageInputController.textEditingController.value.selection.start,
|
messageInputController.selectionStart,
|
||||||
)
|
)
|
||||||
.split('@');
|
.split('@');
|
||||||
final query = splits.last.toLowerCase();
|
final query = splits.last.toLowerCase();
|
||||||
@@ -1223,8 +1222,7 @@ class MessageInputState extends State<MessageInput> {
|
|||||||
messageInputController.textEditingController.value = TextEditingValue(
|
messageInputController.textEditingController.value = TextEditingValue(
|
||||||
text: rejoin +
|
text: rejoin +
|
||||||
messageInputController.text.substring(
|
messageInputController.text.substring(
|
||||||
messageInputController
|
messageInputController.selectionStart,
|
||||||
.textEditingController.value.selection.start,
|
|
||||||
),
|
),
|
||||||
selection: TextSelection.collapsed(
|
selection: TextSelection.collapsed(
|
||||||
offset: rejoin.length,
|
offset: rejoin.length,
|
||||||
@@ -1267,7 +1265,7 @@ class MessageInputState extends State<MessageInput> {
|
|||||||
messageInputController.textEditingController.value = TextEditingValue(
|
messageInputController.textEditingController.value = TextEditingValue(
|
||||||
text: rejoin +
|
text: rejoin +
|
||||||
messageInputController.text.substring(
|
messageInputController.text.substring(
|
||||||
messageInputController.textEditingController.selection.start,
|
messageInputController.selectionStart,
|
||||||
),
|
),
|
||||||
selection: TextSelection.collapsed(
|
selection: TextSelection.collapsed(
|
||||||
offset: rejoin.length,
|
offset: rejoin.length,
|
||||||
@@ -1794,8 +1792,9 @@ class MessageInputState extends State<MessageInput> {
|
|||||||
text = '${'/${_chosenCommand!.name} '}$text';
|
text = '${'/${_chosenCommand!.name} '}$text';
|
||||||
}
|
}
|
||||||
|
|
||||||
messageInputController.text = '';
|
messageInputController
|
||||||
messageInputController.clearAttachments();
|
..text = ''
|
||||||
|
..clearAttachments();
|
||||||
widget.onQuotedMessageCleared?.call();
|
widget.onQuotedMessageCleared?.call();
|
||||||
|
|
||||||
setState(() {
|
setState(() {
|
||||||
|
|||||||
@@ -710,17 +710,13 @@ class _StreamMessageTextFieldState extends State<StreamMessageTextField>
|
|||||||
registerForRestoration(_controller!, 'controller');
|
registerForRestoration(_controller!, 'controller');
|
||||||
}
|
}
|
||||||
|
|
||||||
late final _onChangedDebounced = debounce(
|
|
||||||
(String newText) => _effectiveController.text = newText,
|
|
||||||
const Duration(milliseconds: 350),
|
|
||||||
leading: true,
|
|
||||||
);
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) => TextField(
|
Widget build(BuildContext context) => TextField(
|
||||||
key: widget.key,
|
key: widget.key,
|
||||||
controller: _effectiveController.textEditingController,
|
controller: _effectiveController.textEditingController,
|
||||||
onChanged: (newText) => _onChangedDebounced([newText]),
|
onChanged: (newText) {
|
||||||
|
_effectiveController.text = newText;
|
||||||
|
},
|
||||||
focusNode: widget.focusNode,
|
focusNode: widget.focusNode,
|
||||||
decoration: widget.decoration,
|
decoration: widget.decoration,
|
||||||
keyboardType: widget.keyboardType,
|
keyboardType: widget.keyboardType,
|
||||||
@@ -775,7 +771,6 @@ class _StreamMessageTextFieldState extends State<StreamMessageTextField>
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
void dispose() {
|
void dispose() {
|
||||||
_onChangedDebounced.cancel();
|
|
||||||
_controller?.dispose();
|
_controller?.dispose();
|
||||||
super.dispose();
|
super.dispose();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,6 +28,7 @@ export 'src/message_search_item.dart';
|
|||||||
export 'src/message_search_list_view.dart';
|
export 'src/message_search_list_view.dart';
|
||||||
export 'src/message_text.dart';
|
export 'src/message_text.dart';
|
||||||
export 'src/message_widget.dart';
|
export 'src/message_widget.dart';
|
||||||
|
export 'src/mip/stream_message_text_field.dart';
|
||||||
export 'src/option_list_tile.dart';
|
export 'src/option_list_tile.dart';
|
||||||
export 'src/reaction_icon.dart';
|
export 'src/reaction_icon.dart';
|
||||||
export 'src/reaction_picker.dart';
|
export 'src/reaction_picker.dart';
|
||||||
|
|||||||
@@ -32,16 +32,20 @@ class MessageInputController extends ValueNotifier<Message> {
|
|||||||
final TextEditingController _textEditingController;
|
final TextEditingController _textEditingController;
|
||||||
|
|
||||||
///
|
///
|
||||||
String get text => value.text ?? '';
|
String get text => _textEditingController.text;
|
||||||
|
|
||||||
///
|
///
|
||||||
set message(Message message) {
|
set message(Message message) {
|
||||||
value = message;
|
value = message;
|
||||||
}
|
}
|
||||||
|
|
||||||
set text(String? newText) {
|
set text(String newText) {
|
||||||
value = value.copyWith(text: newText);
|
value = value.copyWith(text: newText);
|
||||||
_textEditingController.text = newText ?? '';
|
_textEditingController
|
||||||
|
..text = newText
|
||||||
|
..selection = TextSelection.fromPosition(
|
||||||
|
TextPosition(offset: _textEditingController.text.length),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
@@ -55,6 +59,11 @@ class MessageInputController extends ValueNotifier<Message> {
|
|||||||
return textEditingController.selection.baseOffset;
|
return textEditingController.selection.baseOffset;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
get selectionStart {
|
||||||
|
return textEditingController.selection.start;
|
||||||
|
}
|
||||||
|
|
||||||
set showInChannel(bool newValue) {
|
set showInChannel(bool newValue) {
|
||||||
value = value.copyWith(showInChannel: newValue);
|
value = value.copyWith(showInChannel: newValue);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user