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.
113 lines
3.2 KiB
113 lines
3.2 KiB
import 'package:flutter/material.dart';
|
|
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
|
import 'package:im_flutter_sdk/im_flutter_sdk.dart';
|
|
|
|
import 'text_item.dart';
|
|
import 'image_item.dart';
|
|
|
|
class MessageItem extends StatelessWidget {
|
|
final EMMessage message;
|
|
final bool isSentByMe;
|
|
final EMMessage? previousMessage;
|
|
|
|
const MessageItem({
|
|
required this.message,
|
|
required this.isSentByMe,
|
|
this.previousMessage,
|
|
super.key,
|
|
});
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
// 处理文本消息
|
|
if (message.body.type == MessageType.TXT) {
|
|
final textBody = message.body as EMTextMessageBody;
|
|
return TextItem(
|
|
textBody: textBody,
|
|
isSentByMe: isSentByMe,
|
|
showTime: shouldShowTime(),
|
|
formattedTime: formatMessageTime(message.serverTime),
|
|
);
|
|
}
|
|
// 处理图片消息
|
|
else if (message.body.type == MessageType.IMAGE) {
|
|
final imageBody = message.body as EMImageMessageBody;
|
|
return ImageItem(
|
|
imageBody: imageBody,
|
|
isSentByMe: isSentByMe,
|
|
showTime: shouldShowTime(),
|
|
formattedTime: formatMessageTime(message.serverTime),
|
|
);
|
|
}
|
|
|
|
// 非文本消息显示占位符
|
|
return Column(
|
|
children: [
|
|
if (shouldShowTime()) _buildTimeLabel(),
|
|
Container(
|
|
padding: EdgeInsets.symmetric(
|
|
horizontal: 16.w,
|
|
vertical: 8.h,
|
|
),
|
|
child: Text('不支持的消息类型'),
|
|
),
|
|
],
|
|
);
|
|
}
|
|
|
|
// 判断是否需要显示时间
|
|
bool shouldShowTime() {
|
|
if (previousMessage == null) {
|
|
return true; // 第一条消息显示时间
|
|
}
|
|
|
|
// 判断距离上一条消息是否超过20分钟(1200000毫秒)
|
|
return (message.serverTime - previousMessage!.serverTime) > 1200000;
|
|
}
|
|
|
|
// 构建时间标签
|
|
Widget _buildTimeLabel() {
|
|
final formattedTime = formatMessageTime(message.serverTime);
|
|
|
|
return Container(
|
|
alignment: Alignment.center,
|
|
padding: EdgeInsets.symmetric(
|
|
horizontal: 16.w,
|
|
),
|
|
child: Container(
|
|
padding: EdgeInsets.symmetric(
|
|
horizontal: 12.w,
|
|
),
|
|
child: Text(
|
|
formattedTime,
|
|
style: TextStyle(
|
|
fontSize: 12.sp,
|
|
color: Colors.grey,
|
|
),
|
|
),
|
|
),
|
|
);
|
|
}
|
|
|
|
// 格式化消息时间
|
|
String formatMessageTime(int timestamp) {
|
|
final date = DateTime.fromMillisecondsSinceEpoch(timestamp);
|
|
final now = DateTime.now();
|
|
final today = DateTime(now.year, now.month, now.day);
|
|
final yesterday = DateTime(now.year, now.month, now.day - 1);
|
|
final messageDate = DateTime(date.year, date.month, date.day);
|
|
|
|
if (messageDate.isAtSameMomentAs(today)) {
|
|
// 今天的消息显示时间
|
|
return '今天 ${date.hour.toString().padLeft(2, '0')}:${date.minute.toString().padLeft(2, '0')}';
|
|
} else if (messageDate.isAtSameMomentAs(yesterday)) {
|
|
// 昨天的消息
|
|
return '昨天 ${date.hour.toString().padLeft(2, '0')}:${date.minute.toString().padLeft(2, '0')}';
|
|
} else {
|
|
// 其他日期显示完整日期和时间
|
|
return '${date.month}月${date.day}日 ${date.hour.toString().padLeft(2, '0')}:${date.minute.toString().padLeft(2, '0')}';
|
|
}
|
|
}
|
|
|
|
|
|
}
|