From cad2bc4f057c419b82e6237d6f80ba305e205ac6 Mon Sep 17 00:00:00 2001 From: lxm <1274844347@qq.com> Date: Tue, 20 May 2025 11:40:26 +0800 Subject: [PATCH] =?UTF-8?q?feat(message=5Fbubble):=20=E4=BD=BF=E7=94=A8Mar?= =?UTF-8?q?kdown=E6=B8=B2=E6=9F=93AI=E6=B6=88=E6=81=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 为AI消息添加Markdown渲染支持,提升消息内容的可读性和格式化效果。用户消息仍保持普通文本显示。 --- lib/modules/agent/views/message_bubble.dart | 189 ++++++++++++++------ 1 file changed, 133 insertions(+), 56 deletions(-) diff --git a/lib/modules/agent/views/message_bubble.dart b/lib/modules/agent/views/message_bubble.dart index 589b18b4a..7c8df4796 100644 --- a/lib/modules/agent/views/message_bubble.dart +++ b/lib/modules/agent/views/message_bubble.dart @@ -1,10 +1,12 @@ import 'package:common_utils/common_utils.dart'; import 'package:deep_voice/modules/agent/views/message_bubble_navigation.dart'; +import 'weather_card.dart'; import 'package:flutter/material.dart'; import 'package:get/get.dart'; import 'package:intl/intl.dart'; import 'package:get_storage/get_storage.dart'; import 'dart:io'; +import 'package:flutter_markdown/flutter_markdown.dart'; import '../controllers/agent_controller.dart'; @@ -120,63 +122,63 @@ class MessageBubble extends GetView { } /// 构建头像 - Widget _buildAvatar(bool isUser, BuildContext context) { - if (isUser) { - final storage = GetStorage(); - final localAvatarPath = storage.read('local_avatar') ?? ''; + // Widget _buildAvatar(bool isUser, BuildContext context) { + // if (isUser) { + // final storage = GetStorage(); + // final localAvatarPath = storage.read('local_avatar') ?? ''; - return Container( - width: 36, - height: 36, - decoration: BoxDecoration( - color: localAvatarPath.isEmpty ? Colors.grey[300] : null, - borderRadius: BorderRadius.circular(18), - boxShadow: [ - BoxShadow( - color: Colors.black.withOpacity(0.05), - blurRadius: 2, - offset: const Offset(0, 1), - ), - ], - ), - child: localAvatarPath.isNotEmpty - ? ClipRRect( - borderRadius: BorderRadius.circular(18), - child: Image.file( - File(localAvatarPath), - fit: BoxFit.cover, - ), - ) - : Icon( - Icons.person, - color: Colors.grey[700], - size: 20, - ), - ); - } else { - // AI头像保持不变 - return Container( - width: 36, - height: 36, - decoration: BoxDecoration( - color: Theme.of(context).primaryColor, - borderRadius: BorderRadius.circular(18), - boxShadow: [ - BoxShadow( - color: Colors.black.withOpacity(0.05), - blurRadius: 2, - offset: const Offset(0, 1), - ), - ], - ), - child: Icon( - Icons.smart_toy_outlined, - color: Colors.white, - size: 20, - ), - ); - } - } + // return Container( + // width: 36, + // height: 36, + // decoration: BoxDecoration( + // color: localAvatarPath.isEmpty ? Colors.grey[300] : null, + // borderRadius: BorderRadius.circular(18), + // boxShadow: [ + // BoxShadow( + // color: Colors.black.withOpacity(0.05), + // blurRadius: 2, + // offset: const Offset(0, 1), + // ), + // ], + // ), + // child: localAvatarPath.isNotEmpty + // ? ClipRRect( + // borderRadius: BorderRadius.circular(18), + // child: Image.file( + // File(localAvatarPath), + // fit: BoxFit.cover, + // ), + // ) + // : Icon( + // Icons.person, + // color: Colors.grey[700], + // size: 20, + // ), + // ); + // } else { + // // AI头像保持不变 + // return Container( + // width: 36, + // height: 36, + // decoration: BoxDecoration( + // color: Theme.of(context).primaryColor, + // borderRadius: BorderRadius.circular(18), + // boxShadow: [ + // BoxShadow( + // color: Colors.black.withOpacity(0.05), + // blurRadius: 2, + // offset: const Offset(0, 1), + // ), + // ], + // ), + // child: Icon( + // Icons.smart_toy_outlined, + // color: Colors.white, + // size: 20, + // ), + // ); + // } + // } /// 构建消息内容 Widget _buildMessageContent(BuildContext context) { @@ -300,6 +302,81 @@ class MessageBubble extends GetView { // } } + // 使用Markdown渲染AI消息,用户消息仍然使用普通文本 + if (!isUser) { + return MarkdownBody( + data: message, + styleSheet: MarkdownStyleSheet( + p: TextStyle( + color: Theme.of(context).brightness == Brightness.dark + ? Colors.white.withOpacity(0.9) + : Colors.black87, + fontSize: 14, + height: 1.4, + fontWeight: FontWeight.w400, + ), + h1: TextStyle( + color: Theme.of(context).brightness == Brightness.dark + ? Colors.white + : Colors.black, + fontSize: 18, + fontWeight: FontWeight.bold, + ), + h2: TextStyle( + color: Theme.of(context).brightness == Brightness.dark + ? Colors.white + : Colors.black, + fontSize: 16, + fontWeight: FontWeight.bold, + ), + h3: TextStyle( + color: Theme.of(context).brightness == Brightness.dark + ? Colors.white + : Colors.black, + fontSize: 15, + fontWeight: FontWeight.bold, + ), + code: TextStyle( + backgroundColor: Theme.of(context).brightness == Brightness.dark + ? Colors.grey[800] + : Colors.grey[200], + fontFamily: 'monospace', + fontSize: 13, + ), + codeblockDecoration: BoxDecoration( + color: Theme.of(context).brightness == Brightness.dark + ? Colors.grey[800] + : Colors.grey[200], + borderRadius: BorderRadius.circular(4), + ), + blockquote: TextStyle( + color: Theme.of(context).brightness == Brightness.dark + ? Colors.grey[400] + : Colors.grey[700], + fontSize: 14, + fontStyle: FontStyle.italic, + ), + blockquoteDecoration: BoxDecoration( + border: Border( + left: BorderSide( + color: Theme.of(context).brightness == Brightness.dark + ? Colors.grey[600]! + : Colors.grey[400]!, + width: 4, + ), + ), + ), + listBullet: TextStyle( + color: Theme.of(context).brightness == Brightness.dark + ? Colors.white.withOpacity(0.9) + : Colors.black87, + fontSize: 14, + ), + ), + selectable: true, + ); + } + // 用户消息仍然使用普通文本 return Text( message, style: TextStyle(