From c604fcc72d7eb9d3a5aa233bac0a8277ab55909e Mon Sep 17 00:00:00 2001 From: Jolie <412895109@qq.com> Date: Tue, 6 Jan 2026 15:40:08 +0800 Subject: [PATCH] =?UTF-8?q?fix(chat):=20=E4=BF=AE=E5=A4=8D=E8=A1=A8?= =?UTF-8?q?=E6=83=85=E5=88=A0=E9=99=A4=E6=97=B6=E5=85=89=E6=A0=87=E5=AE=9A?= =?UTF-8?q?=E4=BD=8D=E9=97=AE=E9=A2=98=E5=B9=B6=E6=B7=BB=E5=8A=A0=E5=B9=B4?= =?UTF-8?q?=E9=BE=84=E8=AE=A1=E7=AE=97=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 修复了删除表情标记时光标位置计算错误的问题 - 优化了表情标记删除逻辑,正确处理光标在表情开始位置的情况 - 添加了根据出生年份计算年龄的工具方法 - 更新了聊天页面中年龄显示逻辑,使用动态计算的年龄值 --- lib/pages/message/chat_page.dart | 21 +++++++++++++++- lib/widget/message/chat_input_bar.dart | 33 ++++++++++++++++++++++---- 2 files changed, 49 insertions(+), 5 deletions(-) diff --git a/lib/pages/message/chat_page.dart b/lib/pages/message/chat_page.dart index cfca2aa..fd0906f 100644 --- a/lib/pages/message/chat_page.dart +++ b/lib/pages/message/chat_page.dart @@ -35,6 +35,25 @@ class ChatPage extends StatefulWidget { } class _ChatPageState extends State { + /// 根据出生年份计算年龄 + String _calculateAgeFromBirthYear(String birthYear) { + if (birthYear.isEmpty) { + return '0'; + } + + try { + final year = int.tryParse(birthYear); + if (year == null) { + return '0'; + } + + final currentYear = DateTime.now().year; + final age = currentYear - year; + return age > 0 ? age.toString() : '0'; + } catch (e) { + return '0'; + } + } final ScrollController _scrollController = ScrollController(); bool _isLoadingMore = false; late ChatController _controller; @@ -515,7 +534,7 @@ class _ChatPageState extends State { ), SizedBox(width: 4.w), Text( - '${marriageData.age}', + _calculateAgeFromBirthYear(marriageData.birthYear), style: TextStyle( fontSize: 12.sp, color: Colors.grey[700], diff --git a/lib/widget/message/chat_input_bar.dart b/lib/widget/message/chat_input_bar.dart index 945ddab..d26ce19 100644 --- a/lib/widget/message/chat_input_bar.dart +++ b/lib/widget/message/chat_input_bar.dart @@ -82,6 +82,7 @@ class EmojiTextInputFormatter extends TextInputFormatter { if (newValue.text.length < oldValue.text.length) { final oldSelection = oldValue.selection; final cursorOffset = oldSelection.baseOffset; + final deletedLength = oldValue.text.length - newValue.text.length; // 在整个文本中查找所有表情标记 final emojiRegex = RegExp(r'\[emoji:\d+\]'); @@ -92,21 +93,45 @@ class EmojiTextInputFormatter extends TextInputFormatter { final emojiStart = match.start; final emojiEnd = match.end; - // 如果光标在表情标记内部(包括开始和结束位置) - if (cursorOffset >= emojiStart && cursorOffset <= emojiEnd) { + // 如果光标在表情标记内部(不包括开始位置,包括结束位置) + if (cursorOffset > emojiStart && cursorOffset <= emojiEnd) { // 删除整个表情标记 final beforeEmoji = oldValue.text.substring(0, emojiStart); final afterEmoji = oldValue.text.substring(emojiEnd); final newText = beforeEmoji + afterEmoji; - // 光标位置设置为表情标记的开始位置 - final newCursorOffset = emojiStart; + // 删除表情后,光标保持在删除操作发生的位置 + // 跟删除普通文本一样:删除后光标停留在删除位置 + // 光标位置 = 删除位置 - 表情长度 + final emojiLength = emojiEnd - emojiStart; + int newCursorOffset = (cursorOffset - emojiLength).clamp(0, newText.length); return TextEditingValue( text: newText, selection: TextSelection.collapsed(offset: newCursorOffset), ); } + + // 如果光标刚好在表情标记的开始位置,且删除的是表情标记内部的字符 + if (cursorOffset == emojiStart) { + // 检查删除的字符是否在表情标记范围内 + if (cursorOffset + deletedLength <= emojiEnd) { + // 删除整个表情标记 + final beforeEmoji = oldValue.text.substring(0, emojiStart); + final afterEmoji = oldValue.text.substring(emojiEnd); + final newText = beforeEmoji + afterEmoji; + + // 删除表情后,光标保持在删除位置 + // 光标位置 = 删除位置 - 表情长度 + final emojiLength = emojiEnd - emojiStart; + int newCursorOffset = (cursorOffset - emojiLength).clamp(0, newText.length); + + return TextEditingValue( + text: newText, + selection: TextSelection.collapsed(offset: newCursorOffset), + ); + } + } } }