// 分享 BottomSheet — 编辑器完成后选择分享到班级或仅自己可见 // // 设计要点: // - 温暖友好的文案(面向小学生) // - 分享到班级(有班级时显示)/ 仅自己可见 // - 无班级时提示加入班级后可分享 // - 分享前自动进行内容安全检查(敏感词过滤) import 'package:flutter/material.dart'; import '../../../data/services/content_filter_service.dart'; /// 编辑器完成后的分享选择面板 class ShareBottomSheet extends StatelessWidget { final String? classId; final String className; final void Function(bool shareToClass) onDecision; /// 用于内容安全检查的文本内容(标题 + 文本元素) final String contentText; const ShareBottomSheet({ super.key, required this.classId, required this.className, required this.onDecision, this.contentText = '', }); @override Widget build(BuildContext context) { final hasClass = classId != null && classId!.isNotEmpty; final theme = Theme.of(context); return Container( padding: const EdgeInsets.all(20), decoration: BoxDecoration( color: theme.colorScheme.surface, borderRadius: const BorderRadius.vertical(top: Radius.circular(22)), ), child: Column( mainAxisSize: MainAxisSize.min, children: [ // 拖拽条 Center( child: Container( margin: const EdgeInsets.only(bottom: 16), width: 40, height: 4, decoration: BoxDecoration( color: Colors.grey.shade300, borderRadius: BorderRadius.circular(2), ), ), ), Text( '日记写好了!', style: theme.textTheme.titleMedium, ), const SizedBox(height: 8), Text( '要分享给老师和同学们看看吗?', style: theme.textTheme.bodyMedium?.copyWith( color: Colors.grey.shade600, ), ), const SizedBox(height: 24), // 分享到班级 if (hasClass) ...[ SizedBox( width: double.infinity, height: 52, child: FilledButton.icon( onPressed: () => _handleShare(context, shareToClass: true), icon: const Icon(Icons.group), label: Text('分享到 $className'), style: FilledButton.styleFrom( shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(12), ), ), ), ), const SizedBox(height: 12), ], // 仅自己可见 SizedBox( width: double.infinity, height: 52, child: OutlinedButton.icon( onPressed: () => _handleShare(context, shareToClass: false), icon: const Icon(Icons.lock_outline), label: const Text('仅自己可见'), style: OutlinedButton.styleFrom( shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(12), ), ), ), ), // 无班级时的提示 if (!hasClass) ...[ const SizedBox(height: 12), Text( '加入班级后可以分享给老师和同学哦', style: theme.textTheme.bodySmall?.copyWith( color: Colors.grey.shade500, ), ), ], const SizedBox(height: 8), ], ), ); } /// 处理分享/保存决定 void _handleShare(BuildContext context, {required bool shareToClass}) { // 仅在分享到班级时进行内容安全检查 if (shareToClass && contentText.isNotEmpty) { final matches = ContentFilterService.checkText(contentText); if (matches.isNotEmpty) { _showContentWarning(context, matches); return; } } // 安全或仅自己可见 → 直接执行 onDecision(shareToClass); Navigator.pop(context); } /// 显示内容安全警告对话框 void _showContentWarning( BuildContext context, List matches, ) { final categories = ContentFilterService.getMatchedCategories(matches); final words = matches.map((m) => ' "${m.word}"').toSet().toList(); final wordList = words.take(5).join('、'); final categoryList = categories.join('、'); showDialog( context: context, builder: (dialogContext) => AlertDialog( shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(16)), title: const Row( children: [ Icon(Icons.warning_amber_rounded, color: Colors.orange), SizedBox(width: 8), Text('内容提醒'), ], ), content: Column( mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.start, children: [ const Text('日记中可能包含不太合适分享的内容:'), const SizedBox(height: 8), Text( wordList, style: const TextStyle(fontWeight: FontWeight.w600), ), const SizedBox(height: 4), Text( '涉及:$categoryList', style: TextStyle(fontSize: 13, color: Colors.grey.shade600), ), const SizedBox(height: 12), const Text( '建议修改后再分享,或者先保存为仅自己可见。', style: TextStyle(fontSize: 13), ), ], ), actions: [ TextButton( onPressed: () => Navigator.pop(dialogContext), child: const Text('返回修改'), ), TextButton( onPressed: () { Navigator.pop(dialogContext); // 关闭对话框 onDecision(true); // 仍然分享 Navigator.pop(context); // 关闭 BottomSheet }, child: const Text('仍然分享'), ), ], ), ); } }