aboutsummaryrefslogtreecommitdiff
path: root/frontend/lib/views/chat/agent_message_tile.dart
diff options
context:
space:
mode:
Diffstat (limited to 'frontend/lib/views/chat/agent_message_tile.dart')
-rw-r--r--frontend/lib/views/chat/agent_message_tile.dart175
1 files changed, 175 insertions, 0 deletions
diff --git a/frontend/lib/views/chat/agent_message_tile.dart b/frontend/lib/views/chat/agent_message_tile.dart
new file mode 100644
index 000000000..029f487c0
--- /dev/null
+++ b/frontend/lib/views/chat/agent_message_tile.dart
@@ -0,0 +1,175 @@
+import 'dart:convert';
+
+import 'package:auto_gpt_flutter_client/models/chat.dart';
+import 'package:auto_gpt_flutter_client/views/chat/json_code_snippet_view.dart';
+import 'package:flutter/material.dart';
+import 'package:flutter_markdown/flutter_markdown.dart';
+
+class AgentMessageTile extends StatefulWidget {
+ final Chat chat;
+ final VoidCallback onArtifactsButtonPressed;
+
+ const AgentMessageTile({
+ Key? key,
+ required this.chat,
+ required this.onArtifactsButtonPressed,
+ }) : super(key: key);
+
+ @override
+ _AgentMessageTileState createState() => _AgentMessageTileState();
+}
+
+class _AgentMessageTileState extends State<AgentMessageTile> {
+ bool isExpanded = false;
+
+ @override
+ Widget build(BuildContext context) {
+ String jsonString = jsonEncode(widget.chat.jsonResponse);
+ int artifactsCount = widget.chat.artifacts.length;
+
+ bool containsMarkdown(String text) {
+ // Regular expression to detect Markdown patterns like headers, bold, links, etc.
+ final RegExp markdownPattern = RegExp(
+ r'(?:\*\*|__).*?(?:\*\*|__)|' + // Bold
+ r'(?:\*|_).*?(?:\*|_)|' + // Italic
+ r'\[.*?\]\(.*?\)|' + // Links
+ r'!\[.*?\]\(.*?\)|' + // Images
+ r'#{1,6}.*|' + // Headers
+ r'```.*?```', // Fenced code blocks
+ dotAll: true, // To match across multiple lines
+ caseSensitive: false,
+ );
+
+ return markdownPattern.hasMatch(text);
+ }
+
+ bool hasMarkdown = containsMarkdown(widget.chat.message);
+
+ return LayoutBuilder(
+ builder: (context, constraints) {
+ double chatViewWidth = constraints.maxWidth;
+ double tileWidth = (chatViewWidth >= 1000) ? 900 : chatViewWidth - 40;
+
+ return Align(
+ alignment: Alignment.center,
+ child: Container(
+ width: tileWidth,
+ margin: const EdgeInsets.symmetric(vertical: 8),
+ padding: const EdgeInsets.symmetric(horizontal: 20),
+ decoration: BoxDecoration(
+ color: Colors.white,
+ border: Border.all(color: Colors.black, width: 0.5),
+ borderRadius: BorderRadius.circular(4),
+ ),
+ child: Column(
+ mainAxisAlignment: MainAxisAlignment.start,
+ children: [
+ Container(
+ constraints: const BoxConstraints(minHeight: 50),
+ child: Row(
+ crossAxisAlignment: CrossAxisAlignment.center,
+ children: [
+ const Text(
+ "Agent",
+ style: TextStyle(
+ color: Colors.black,
+ fontSize: 16,
+ fontWeight: FontWeight.bold,
+ ),
+ ),
+ const SizedBox(width: 20),
+ Expanded(
+ child: Container(
+ padding: const EdgeInsets.fromLTRB(0, 10, 20, 10),
+ child: SingleChildScrollView(
+ child: hasMarkdown
+ ? Markdown(
+ data: widget.chat.message,
+ shrinkWrap: true,
+ styleSheet: MarkdownStyleSheet.fromTheme(
+ Theme.of(context))
+ .copyWith(
+ blockquoteDecoration: BoxDecoration(
+ color: Colors
+ .black, // Background color for blockquotes
+ border: Border(
+ left: BorderSide(
+ color: Colors.grey,
+ width: 4.0,
+ ),
+ ),
+ ),
+ blockquoteAlign: WrapAlignment.start,
+ blockquotePadding: const EdgeInsets.all(
+ 10.0), // Padding for blockquotes
+ codeblockDecoration: BoxDecoration(
+ color: Colors.grey[
+ 200], // Background color for code blocks
+ borderRadius:
+ BorderRadius.circular(4.0),
+ ),
+ codeblockPadding: const EdgeInsets.all(
+ 10.0), // Padding for code blocks
+ code: TextStyle(
+ backgroundColor: Colors.grey[
+ 200], // Background color for inline code
+ fontFamily: 'monospace',
+ ),
+ ),
+ )
+ : SelectableText(widget.chat.message,
+ maxLines: null),
+ ),
+ ),
+ ),
+ ElevatedButton(
+ onPressed: widget.onArtifactsButtonPressed,
+ style: ElevatedButton.styleFrom(
+ backgroundColor: Colors.white,
+ foregroundColor: Colors.black,
+ side: const BorderSide(color: Colors.black),
+ shape: RoundedRectangleBorder(
+ borderRadius: BorderRadius.circular(8),
+ ),
+ ),
+ child: Text('$artifactsCount Artifacts'),
+ ),
+ const SizedBox(width: 20),
+ // Expand/Collapse button
+ IconButton(
+ splashRadius: 0.1,
+ icon: Icon(isExpanded
+ ? Icons.keyboard_arrow_up
+ : Icons.keyboard_arrow_down),
+ onPressed: () {
+ setState(() {
+ isExpanded = !isExpanded;
+ });
+ },
+ ),
+ ],
+ ),
+ ),
+ // Expanded view with JSON code snippet and copy button
+ if (isExpanded) ...[
+ const Divider(),
+ ClipRect(
+ child: SizedBox(
+ height: 200,
+ child: Padding(
+ padding: const EdgeInsets.only(right: 20),
+ child: JsonCodeSnippetView(
+ jsonString: jsonString,
+ ),
+ ),
+ ),
+ ),
+ ],
+ ],
+ ),
+ ),
+ );
+ },
+ );
+ }
+}