1. 功能需求背景
在聊天界面中,多媒体消息(图片、视频、文件)的UI需要进行优化,以提升整体体验和视觉一致性。
1.1 动机
- 修复文件气泡卡片文件名文字颜色错误问题
- 移除图片卡片右下角的发送时间(容易造成误解)
- 视频卡片继续显示时间,但显示视频时长而非发送时间
- 点击气泡显示发送时间(统一交互方式)
- 输入框中的Markdown图标优化
- 会话信息时间精确到秒
- 日历今天日期边框优化
1.2 设计考量
- 视觉一致性:统一颜色主题应用
- 交互一致性:时间显示方式统一
- 功能清晰性:避免时间信息混淆
2. 技术方案设计
2.1 问题分析
- 文件名颜色问题:
FileMessageContent使用了错误的颜色逻辑 - 时间显示问题:
MediaMessageBubble在右下角显示发送时间 - 视频时长显示:需要在视频组件中显示时长
- Markdown图标:输入框中的图标需要优化
- 时间精度:会话信息时间需要精确到秒
2.2 解决方案
- 颜色修复:统一使用
theme.colorScheme.onSurface - 时间移除:从
MediaMessageBubble移除时间显示 - 时长显示:在
VideoMessageContent中保留时长显示 - 点击交互:使用之前实现的点击显示时间机制
- 图标优化:移除背景,使用主题颜色
3. 实现细节
3.1 文件名颜色修复
原代码:
final textColor = isSent ? theme.colorScheme.onPrimary : null;修改后:
final textColor = theme.colorScheme.onSurface;影响文件:client/lib/ui/widgets/chat_widgets.dart
3.2 移除MediaMessageBubble时间显示
原代码:
child: Stack(
children: [
child,
// 时间戳
Positioned(
right: 8,
bottom: 6,
child: Container(
// 时间显示逻辑
),
),
],
),修改后:
child: child, // 直接使用child,无Stack包装3.3 视频时长显示保留
VideoMessageContent 中的时长显示保持不变,位于视频缩略图右下角:
// 时长标签
if (duration != null)
Positioned(
right: 8,
bottom: 8,
child: Container(
padding: const EdgeInsets.symmetric(horizontal: 6, vertical: 2),
decoration: BoxDecoration(
color: Colors.black54,
borderRadius: BorderRadius.circular(4),
),
child: Text(
duration!,
style: const TextStyle(color: Colors.white, fontSize: 12),
),
),
),3.4 输入框Markdown图标优化
原代码:
child: Container(
padding: const EdgeInsets.all(4),
decoration: BoxDecoration(
color: isDark ? Colors.white : Colors.black,
borderRadius: BorderRadius.circular(4),
),
child: Icon(
TablerIcons.markdown,
color: isDark ? Colors.black : Colors.white,
size: 16,
),
),修改后:
child: Icon(
TablerIcons.markdown,
color: isDark ? Colors.white : Colors.black,
size: 20,
),3.5 会话信息时间精确到秒
原代码:
String _formatDate(DateTime date) {
return '${date.year}-${date.month.toString().padLeft(2, '0')}-${date.day.toString().padLeft(2, '0')}';
}修改后:
String _formatDate(DateTime date) {
return '${date.year}-${date.month.toString().padLeft(2, '0')}-${date.day.toString().padLeft(2, '0')} '
'${date.hour.toString().padLeft(2, '0')}:${date.minute.toString().padLeft(2, '0')}:${date.second.toString().padLeft(2, '0')}';
}3.6 日历今天边框优化
原代码:
border: isToday
? Border.all(
color: Theme.of(context).colorScheme.primary,
width: 2, // 2px 边框
)
: null,修改后:
border: isToday
? Border.all(
color: Theme.of(context).colorScheme.primary,
width: 1, // 1px 边框
)
: null,4. 数据库变更
4.1 扩展SendMessages表
添加了两个字段以支持新功能:
format:支持Markdown格式duration:支持语音时长
变更内容:
class SendMessages extends Table {
// ... 原有字段
TextColumn get format => text().nullable()(); // 'plain' | 'markdown' | null
IntColumn get duration => integer().nullable()(); // 语音时长(毫秒)
// ... 其他字段
}4.2 数据转换方法更新
更新了 recordToSendMessage 和 sendMessageToCompanion 方法以支持新字段。
5. 遇到的问题及解决方案
5.1 Drift代码生成问题
问题:修改数据库表后需要重新生成Drift代码
解决方案:运行 dart run build_runner build --delete-conflicting-outputs
5.2 组件状态管理问题
问题:多个组件需要支持点击显示时间功能 解决方案:将相关组件改为StatefulWidget,统一实现时间显示逻辑
5.3 颜色主题一致性问题
问题:不同组件使用不同的颜色逻辑
解决方案:统一使用 Theme.of(context).colorScheme 中的颜色
6. 代码变更
6.1 文件变更
client/lib/ui/widgets/chat_widgets.dart:修复颜色、移除时间、组件重构client/lib/ui/chat_page.dart:Markdown图标、时间格式化client/lib/core/database/database.dart:数据库表结构变更client/lib/ui/widgets/message_history_calendar.dart:日历边框优化
6.2 组件变更
FileMessageContent:修复文字颜色MediaMessageBubble:移除时间显示MessageBubble:支持点击显示时间MediaMessageBubble:支持点击显示时间- 数据库表:添加format和duration字段
7. 测试验证
7.1 功能测试
- 文件名颜色正确显示
- 图片卡片无时间显示
- 视频卡片显示时长
- 点击气泡显示发送时间
- 输入框Markdown图标显示正确
- 会话信息时间精确到秒
- 日历今天边框正常
7.2 性能测试
-
flutter analyze无错误 - 滚动性能正常
- 内存使用正常
- 数据库迁移正常
7.3 交互测试
- 点击交互响应正常
- 颜色主题切换正常
- 不同消息类型显示正常
8. 设计决策总结
8.1 颜色统一决策
- 原因:避免颜色不一致问题
- 方案:统一使用
onSurface颜色 - 效果:提升视觉一致性
8.2 时间显示决策
- 原因:避免时间信息混淆
- 方案:移除右下角时间,统一点击显示
- 效果:功能更清晰,交互更统一
8.3 组件重构决策
- 原因:需要状态管理支持
- 方案:StatelessWidget → StatefulWidget
- 效果:支持交互功能,保持组件独立性
9. 未来优化方向
9.1 功能扩展
- 支持更多多媒体格式
- 添加动画效果
- 优化加载状态显示
9.2 性能优化
- 使用更高效的布局组件
- 优化图片加载策略
- 改进数据库查询性能