diff --git a/lib/common/widgets/text_field/editable_text.dart b/lib/common/widgets/text_field/editable_text.dart index cfdf8eb6f..777e362a9 100644 --- a/lib/common/widgets/text_field/editable_text.dart +++ b/lib/common/widgets/text_field/editable_text.dart @@ -3287,6 +3287,7 @@ class EditableTextState extends State composing: e.composing, ).apply(value); widget.onChanged?.call(_value.text); + widget.onDelAtUser?.call(match.group(0)!.trim()); return; } } diff --git a/lib/pages/common/common_publish_page.dart b/lib/pages/common/common_publish_page.dart index 49e274520..9180e1d8a 100644 --- a/lib/pages/common/common_publish_page.dart +++ b/lib/pages/common/common_publish_page.dart @@ -14,7 +14,6 @@ import 'package:PiliPlus/pages/dynamics_mention/view.dart'; import 'package:PiliPlus/utils/extension.dart'; import 'package:PiliPlus/utils/feed_back.dart'; import 'package:chat_bottom_container/chat_bottom_container.dart'; -import 'package:collection/collection.dart'; import 'package:dio/dio.dart'; import 'package:easy_debounce/easy_throttle.dart'; import 'package:flutter/material.dart'; @@ -34,9 +33,9 @@ abstract class CommonPublishPage extends StatefulWidget { }); final String? initialValue; - final Set? mentions; + final List? mentions; final int? imageLengthLimit; - final ValueChanged<({String text, Set? mentions})>? onSave; + final ValueChanged<({String text, List? mentions})>? onSave; final bool autofocus; } @@ -54,7 +53,7 @@ abstract class CommonPublishPageState late final RxList pathList = [].obs; int get limit => widget.imageLengthLimit ?? 9; - Set? mentions; + List? mentions; @override void initState() { @@ -409,8 +408,8 @@ abstract class CommonPublishPageState }); } - final pattern = - RegExp(mentions!.map((e) => RegExp.escape('@${e.name!}')).join('|')); + final pattern = RegExp( + mentions!.toSet().map((e) => RegExp.escape('@${e.name!}')).join('|')); editController.text.splitMapJoin( pattern, @@ -448,7 +447,7 @@ abstract class CommonPublishPageState if (res != null) { enablePublish.value = true; - (mentions ??= {}).add(res); + (mentions ??= []).add(res); String atName = '${fromClick ? '@' : ''}${res.name} '; final int cursorPosition = editController.selection.baseOffset; @@ -464,4 +463,18 @@ abstract class CommonPublishPageState } }); } + + void onDelAtUser(String name) { + mentions!.removeFirstWhere((e) => e.name == name); + } + + void onChanged(String value) { + bool isEmpty = value.trim().isEmpty; + if (!isEmpty && !enablePublish.value) { + enablePublish.value = true; + } else if (isEmpty && enablePublish.value) { + enablePublish.value = false; + } + widget.onSave?.call((text: value, mentions: mentions)); + } } diff --git a/lib/pages/common/reply_controller.dart b/lib/pages/common/reply_controller.dart index 8ab251b95..78727b7c9 100644 --- a/lib/pages/common/reply_controller.dart +++ b/lib/pages/common/reply_controller.dart @@ -26,7 +26,7 @@ abstract class ReplyController extends CommonListController { late Rx mode; late final savedReplies = - ? mentions})?>{}; + ? mentions})?>{}; AccountService accountService = Get.find(); diff --git a/lib/pages/dynamics_create/view.dart b/lib/pages/dynamics_create/view.dart index d43e08f1a..3914fec7e 100644 --- a/lib/pages/dynamics_create/view.dart +++ b/lib/pages/dynamics_create/view.dart @@ -569,16 +569,8 @@ class _CreateDynPanelState extends CommonPublishPageState { maxLines: null, focusNode: focusNode, readOnly: readOnly.value, - onDelAtUser: (name) => - mentions?.removeWhere((e) => e.name == name), - onChanged: (value) { - bool isEmpty = value.trim().isEmpty && pathList.isEmpty; - if (!isEmpty && !enablePublish.value) { - enablePublish.value = true; - } else if (isEmpty && enablePublish.value) { - enablePublish.value = false; - } - }, + onDelAtUser: onDelAtUser, + onChanged: onChanged, decoration: InputDecoration( hintText: '说点什么吧', hintStyle: TextStyle(color: theme.colorScheme.outline), diff --git a/lib/pages/dynamics_repost/view.dart b/lib/pages/dynamics_repost/view.dart index f127fa3d3..66c981126 100644 --- a/lib/pages/dynamics_repost/view.dart +++ b/lib/pages/dynamics_repost/view.dart @@ -242,6 +242,7 @@ class _RepostPanelState extends CommonPublishPageState { ), inputFormatters: [LengthLimitingTextInputFormatter(1000)], onMention: onMention, + onDelAtUser: onDelAtUser, ), ), ), diff --git a/lib/pages/live_room/send_danmaku/view.dart b/lib/pages/live_room/send_danmaku/view.dart index 7ac9a6d84..3177a1425 100644 --- a/lib/pages/live_room/send_danmaku/view.dart +++ b/lib/pages/live_room/send_danmaku/view.dart @@ -107,15 +107,7 @@ class _ReplyPageState extends CommonPublishPageState { maxLines: 2, autofocus: false, readOnly: readOnly.value, - onChanged: (value) { - bool isEmpty = value.trim().isEmpty; - if (!isEmpty && !enablePublish.value) { - enablePublish.value = true; - } else if (isEmpty && enablePublish.value) { - enablePublish.value = false; - } - liveRoomController.savedDanmaku = value; - }, + onChanged: onChanged, focusNode: focusNode, decoration: const InputDecoration( hintText: "输入弹幕内容", diff --git a/lib/pages/video/reply_new/view.dart b/lib/pages/video/reply_new/view.dart index 893a2839a..98ab04e70 100644 --- a/lib/pages/video/reply_new/view.dart +++ b/lib/pages/video/reply_new/view.dart @@ -143,15 +143,7 @@ class _ReplyPageState extends CommonPublishPageState { maxLines: 8, autofocus: false, readOnly: readOnly.value, - onChanged: (value) { - bool isEmpty = value.trim().isEmpty; - if (!isEmpty && !enablePublish.value) { - enablePublish.value = true; - } else if (isEmpty && enablePublish.value) { - enablePublish.value = false; - } - widget.onSave?.call((text: value, mentions: mentions)); - }, + onChanged: onChanged, focusNode: focusNode, decoration: InputDecoration( hintText: widget.hint ?? "输入回复内容", @@ -160,6 +152,7 @@ class _ReplyPageState extends CommonPublishPageState { ), style: themeData.textTheme.bodyLarge, onMention: onMention, + onDelAtUser: onDelAtUser, ), ), ), diff --git a/lib/pages/video/send_danmaku/view.dart b/lib/pages/video/send_danmaku/view.dart index 6f885b9e0..80de58712 100644 --- a/lib/pages/video/send_danmaku/view.dart +++ b/lib/pages/video/send_danmaku/view.dart @@ -370,15 +370,7 @@ class _SendDanmakuPanelState extends CommonPublishPageState { inputFormatters: [ LengthLimitingTextInputFormatter(100), ], - onChanged: (value) { - bool isEmpty = value.trim().isEmpty; - if (!isEmpty && !enablePublish.value) { - enablePublish.value = true; - } else if (isEmpty && enablePublish.value) { - enablePublish.value = false; - } - widget.onSave?.call((text: value, mentions: null)); - }, + onChanged: onChanged, textInputAction: TextInputAction.send, onSubmitted: (value) { if (value.trim().isNotEmpty) { diff --git a/lib/pages/whisper_detail/view.dart b/lib/pages/whisper_detail/view.dart index 2d509d501..89f56205a 100644 --- a/lib/pages/whisper_detail/view.dart +++ b/lib/pages/whisper_detail/view.dart @@ -245,14 +245,7 @@ class _WhisperDetailPageState controller: editController, minLines: 1, maxLines: 4, - onChanged: (value) { - bool isNotEmpty = value.trim().isNotEmpty; - if (isNotEmpty && !enablePublish.value) { - enablePublish.value = true; - } else if (!isNotEmpty && enablePublish.value) { - enablePublish.value = false; - } - }, + onChanged: onChanged, textInputAction: TextInputAction.newline, decoration: InputDecoration( filled: true, diff --git a/lib/utils/extension.dart b/lib/utils/extension.dart index 081f5bf83..c9fbbb8d1 100644 --- a/lib/utils/extension.dart +++ b/lib/utils/extension.dart @@ -58,6 +58,16 @@ extension ListExt on List? { T getOrElse(int index, {required T Function() orElse}) { return getOrNull(index) ?? orElse(); } + + bool removeFirstWhere(bool Function(T) test) { + if (this == null) return false; + final index = this!.indexWhere(test); + if (index != -1) { + this!.removeAt(index); + return true; + } + return false; + } } final _regExp = RegExp("^(http:)?//", caseSensitive: false);