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

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);
}
}