You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
127 lines
3.4 KiB
127 lines
3.4 KiB
import 'package:flutter/material.dart';
|
|
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
|
import '../../config/emoji_config.dart';
|
|
|
|
/// 表情文本组件 - 用于在消息中显示文本和表情的混合内容
|
|
class EmojiTextWidget extends StatelessWidget {
|
|
final String text;
|
|
final TextStyle? textStyle;
|
|
final double? emojiSize;
|
|
|
|
const EmojiTextWidget({
|
|
super.key,
|
|
required this.text,
|
|
this.textStyle,
|
|
this.emojiSize,
|
|
});
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return Wrap(
|
|
crossAxisAlignment: WrapCrossAlignment.center,
|
|
children: _parseMessageContent(),
|
|
);
|
|
}
|
|
|
|
/// 解析消息内容,将文本和表情混合显示
|
|
List<Widget> _parseMessageContent() {
|
|
final List<Widget> widgets = [];
|
|
final RegExp emojiRegex = RegExp(r'\[emoji:(\d+)\]');
|
|
|
|
int lastMatchEnd = 0;
|
|
final matches = emojiRegex.allMatches(text);
|
|
|
|
for (final match in matches) {
|
|
// 添加表情之前的文本
|
|
if (match.start > lastMatchEnd) {
|
|
final textPart = text.substring(lastMatchEnd, match.start);
|
|
widgets.add(
|
|
Text(
|
|
textPart,
|
|
style: textStyle,
|
|
),
|
|
);
|
|
}
|
|
|
|
// 添加表情图片
|
|
final emojiId = match.group(1);
|
|
if (emojiId != null) {
|
|
final emoji = EmojiConfig.getEmojiById(emojiId);
|
|
if (emoji != null) {
|
|
widgets.add(
|
|
Padding(
|
|
padding: EdgeInsets.symmetric(horizontal: 2.w),
|
|
child: Image.asset(
|
|
emoji.path,
|
|
width: emojiSize ?? 24.w,
|
|
height: emojiSize ?? 24.w,
|
|
fit: BoxFit.contain,
|
|
),
|
|
),
|
|
);
|
|
} else {
|
|
// 如果表情不存在,显示原始文本
|
|
widgets.add(
|
|
Text(
|
|
match.group(0)!,
|
|
style: textStyle,
|
|
),
|
|
);
|
|
}
|
|
}
|
|
|
|
lastMatchEnd = match.end;
|
|
}
|
|
|
|
// 添加剩余的文本
|
|
if (lastMatchEnd < text.length) {
|
|
final textPart = text.substring(lastMatchEnd);
|
|
widgets.add(
|
|
Text(
|
|
textPart,
|
|
style: textStyle,
|
|
),
|
|
);
|
|
}
|
|
|
|
return widgets;
|
|
}
|
|
}
|
|
|
|
/// 表情文本工具类
|
|
class EmojiTextHelper {
|
|
/// 检查消息是否包含表情
|
|
static bool containsEmoji(String text) {
|
|
return RegExp(r'\[emoji:\d+\]').hasMatch(text);
|
|
}
|
|
|
|
/// 获取消息中的所有表情ID
|
|
static List<String> getEmojiIds(String text) {
|
|
final RegExp emojiRegex = RegExp(r'\[emoji:(\d+)\]');
|
|
final matches = emojiRegex.allMatches(text);
|
|
return matches.map((match) => match.group(1)!).toList();
|
|
}
|
|
|
|
/// 将表情替换为表情名称(用于预览或搜索)
|
|
static String replaceEmojiWithName(String text) {
|
|
final RegExp emojiRegex = RegExp(r'\[emoji:(\d+)\]');
|
|
return text.replaceAllMapped(emojiRegex, (match) {
|
|
final emojiId = match.group(1);
|
|
if (emojiId != null) {
|
|
final emoji = EmojiConfig.getEmojiById(emojiId);
|
|
if (emoji != null) {
|
|
return '[${emoji.name}]';
|
|
}
|
|
}
|
|
return match.group(0)!;
|
|
});
|
|
}
|
|
|
|
/// 检查是否为纯表情消息(只包含一个表情,没有其他文字)
|
|
static bool isPureEmoji(String text) {
|
|
final trimmed = text.trim();
|
|
final RegExp pureEmojiRegex = RegExp(r'^\[emoji:\d+\]$');
|
|
return pureEmojiRegex.hasMatch(trimmed);
|
|
}
|
|
}
|
|
|