import 'package:flutter_openim_sdk/flutter_openim_sdk.dart'; /// 时间与消息预览的格式化工具,全部用户可见文案集中在这里,避免出现英文残留。 class FormatUtils { FormatUtils._(); static const List _weekdays = ['星期一', '星期二', '星期三', '星期四', '星期五', '星期六', '星期日']; static String _two(int v) => v.toString().padLeft(2, '0'); /// 消息列表右侧时间:当天 HH:mm、昨天、一周内星期X、更早显示日期 static String conversationTime(int? millis) { if (millis == null || millis <= 0) return ''; final t = DateTime.fromMillisecondsSinceEpoch(millis); final now = DateTime.now(); final today = DateTime(now.year, now.month, now.day); final day = DateTime(t.year, t.month, t.day); final diff = today.difference(day).inDays; if (diff <= 0) { return '${t.hour}:${_two(t.minute)}'; } else if (diff == 1) { return '昨天'; } else if (diff < 7) { return _weekdays[t.weekday - 1]; } else if (t.year == now.year) { return '${t.month}月${t.day}日'; } return '${t.year}年${t.month}月${t.day}日'; } /// 聊天页时间分隔条:当天「上午 9:30」,非当天带日期 static String chatDividerTime(int millis) { final t = DateTime.fromMillisecondsSinceEpoch(millis); final now = DateTime.now(); final isToday = t.year == now.year && t.month == now.month && t.day == now.day; final period = t.hour < 6 ? '凌晨' : t.hour < 12 ? '上午' : t.hour < 13 ? '中午' : t.hour < 18 ? '下午' : '晚上'; final hour12 = t.hour % 12 == 0 ? 12 : t.hour % 12; final clock = '$period $hour12:${_two(t.minute)}'; if (isToday) return clock; if (t.year == now.year) return '${t.month}月${t.day}日 $clock'; return '${t.year}年${t.month}月${t.day}日 $clock'; } /// 通话时长:mm:ss static String callDuration(int seconds) { final m = seconds ~/ 60; final s = seconds % 60; return '${_two(m)}:${_two(s)}'; } /// 文件大小:不足 1 KB 显示 B,不足 1 MB 显示 KB,否则 MB static String fileSize(int? bytes) { if (bytes == null || bytes < 0) return ''; if (bytes < 1024) return '$bytes B'; if (bytes < 1024 * 1024) return '${(bytes / 1024).toStringAsFixed(0)} KB'; return '${(bytes / 1024 / 1024).toStringAsFixed(1)} MB'; } /// 会话预览文本:群消息带「发送人: 」前缀,语音/文件等按效果图规则 static String messagePreview(Message? msg, {required bool isGroup}) { if (msg == null) return ''; String body; switch (msg.contentType) { case MessageType.text: case MessageType.atText: case MessageType.quote: body = msg.textElem?.content ?? ''; break; case MessageType.voice: body = '[语音]'; break; case MessageType.picture: body = '[图片]'; break; case MessageType.video: body = '[视频]'; break; case MessageType.file: final name = msg.fileElem?.fileName ?? ''; body = name.isEmpty ? '[文件]' : '[文件] $name'; break; case MessageType.custom: body = _customPreview(msg); break; default: if ((msg.contentType ?? 0) >= MessageType.notificationBegin) { body = '[群通知]'; } else { body = '[其他消息]'; } } // 群聊里别人发的消息,预览加「发送人: 」前缀 if (isGroup && msg.sendID != OpenIM.iMManager.userID && body.isNotEmpty) { final sender = msg.senderNickname ?? ''; if (sender.isNotEmpty) return '$sender: $body'; } return body; } static String _customPreview(Message msg) { try { final data = msg.customElem?.data; if (data == null || data.isEmpty) return '[其他消息]'; // 通话相关的自定义消息(信令 200-204、通话记录 901)在会话里统一显示 [语音通话] if (data.contains('calling') || data.contains('"customType":901')) { return '[语音通话]'; } } catch (_) { // 解析失败按未知消息处理 } return '[其他消息]'; } }