import "package:flutter/src/material/theme_data.dart"; import "package:flutter_markdown/flutter_markdown.dart"; import "package:shadcn_flutter/shadcn_flutter.dart"; import "../../src/session/session_types.dart"; class MessageBubble extends StatelessWidget { const MessageBubble({required this.message}); final Message message; @override Widget build(BuildContext context) { final isUser = message.role == "user"; final isTool = message.role == "tool"; final isAssistant = message.role == "assistant"; final theme = Theme.of(context); if (isUser) { return Row( children: [ Spacer(), OutlinedContainer( padding: EdgeInsets.symmetric( horizontal: 12, vertical: 8, ), backgroundColor: theme.colorScheme.border, child: MarkdownBody( data: message.content, selectable: true, shrinkWrap: true, styleSheet: _toolMarkdownStyleSheet(context), ), ), ], ); } else if (isAssistant) { return MarkdownBody( data: message.content, selectable: true, shrinkWrap: true, styleSheet: _toolMarkdownStyleSheet(context), ); } else if (isTool) { final lines = message.content.split("\n"); final title = lines.first.trim(); return Row( children: [ Container( height: 10, width: 10, decoration: BoxDecoration( color: Colors.green, shape: BoxShape.circle ), ), Gap(8), Text( title, style: theme.typography.p.copyWith( fontSize: 13 ), ), ], ); } return Align( alignment: isUser ? Alignment.centerRight : Alignment.centerLeft, child: Container( child: Padding( padding: const EdgeInsets.all(12), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( message.role, style: TextStyle( fontSize: 12, fontWeight: FontWeight.w600, ), ), const SizedBox(height: 4), if (isAssistant || isTool) MarkdownBody( data: isTool ? _buildToolMarkdown(message.content) : message.content, selectable: true, shrinkWrap: true, styleSheet: isTool ? _toolMarkdownStyleSheet(context) : null, ) else Text(message.content), ], ), ), ), ); } String _buildToolMarkdown(String content) { final lines = content.split("\n"); if (lines.isEmpty) { return "```text\n\n```"; } final title = lines.first.trim(); final body = lines.skip(1).join("\n").trimRight(); if (body.isEmpty) { return title; } return "$title\n\n```text\n$body\n```"; } MarkdownStyleSheet _toolMarkdownStyleSheet(BuildContext context) { final theme = Theme.of(context); return MarkdownStyleSheet( p: theme.typography.p.copyWith( fontSize: 13 ), ); } }