import 'package:flutter/material.dart'; import 'package:flutter_markdown/flutter_markdown.dart'; import '../core/app_colors.dart'; import '../core/app_design_tokens.dart'; class AiContent { AiContent._(); static String clean(String text) { var t = text; t = t.replaceAll(RegExp(r'\$\d+'), ''); t = t.replaceAll(RegExp(r'<[^>]+>'), ''); t = t.replaceAllMapped(RegExp(r'^#{4,}\s', multiLine: true), (_) => '### '); t = t.replaceAll(RegExp(r'\n{3,}'), '\n\n'); return t.trim(); } static String plain(String text) { final cleaned = clean(text); return cleaned .replaceAll(RegExp(r'\*\*(.*?)\*\*'), r'$1') .replaceAll(RegExp(r'__(.*?)__'), r'$1') .replaceAll(RegExp(r'`([^`]+)`'), r'$1') .replaceAll(RegExp(r'^\s*[-*]\s+', multiLine: true), '• ') .trim(); } } class AiMarkdownView extends StatelessWidget { final String data; final bool selectable; final void Function(String text, String? href, String title)? onTapLink; const AiMarkdownView({ super.key, required this.data, this.selectable = true, this.onTapLink, }); @override Widget build(BuildContext context) { return MarkdownBody( data: AiContent.clean(data), selectable: selectable, onTapLink: onTapLink, styleSheet: MarkdownStyleSheet( p: AppTextStyles.chatBody, a: AppTextStyles.chatBody.copyWith( color: AppColors.primary, fontWeight: FontWeight.w600, decoration: TextDecoration.underline, decorationColor: AppColors.primary, ), strong: AppTextStyles.chatBody.copyWith(fontWeight: FontWeight.w600), h1: AppTextStyles.chatTitle.copyWith(fontSize: 20), h2: AppTextStyles.chatTitle.copyWith(fontSize: 20), h3: AppTextStyles.chatTitle.copyWith(fontSize: 19), listBullet: AppTextStyles.chatBody.copyWith( fontSize: 21, fontWeight: FontWeight.w700, ), listBulletPadding: const EdgeInsets.only(right: 8), blockquote: AppTextStyles.chatBody.copyWith( color: AppColors.textSecondary, ), ), ); } } class AiGeneratedNote extends StatelessWidget { const AiGeneratedNote({super.key}); @override Widget build(BuildContext context) => const Padding( padding: EdgeInsets.only(top: 10), child: Text('内容由 AI 生成', style: AppTextStyles.aiNote), ); }