import 'dart:async'; import 'package:ainoval/blocs/editor/editor_bloc.dart'; import 'package:ainoval/screens/editor/controllers/editor_screen_controller.dart'; import 'package:ainoval/components/editable_title.dart'; import 'package:ainoval/utils/debouncer.dart' as debouncer; import 'package:ainoval/utils/logger.dart'; import 'package:ainoval/screens/editor/widgets/custom_dropdown.dart'; import 'package:ainoval/screens/editor/widgets/menu_builder.dart'; import 'package:ainoval/utils/web_theme.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:provider/provider.dart'; class ChapterSection extends StatefulWidget { const ChapterSection({ super.key, // Will be replaced by chapterKey if passed required this.title, required this.scenes, required this.actId, required this.chapterId, required this.editorBloc, this.chapterIndex, // 添加章节序号参数 this.chapterKey, // New GlobalKey parameter }); final String title; final List scenes; final String actId; final String chapterId; final EditorBloc editorBloc; final int? chapterIndex; // 章节在卷中的序号,从1开始 final GlobalKey? chapterKey; // New GlobalKey parameter @override State createState() => _ChapterSectionState(); } class _ChapterSectionState extends State { late TextEditingController _chapterTitleController; late debouncer.Debouncer _debouncer; // 为章节创建一个ValueKey,确保唯一性 - This will be overridden by widget.chapterKey if provided // late final Key _chapterKey = // ValueKey('chapter_${widget.actId}_${widget.chapterId}'); @override void initState() { super.initState(); _chapterTitleController = TextEditingController(text: widget.title); _debouncer = debouncer.Debouncer(); } @override void didUpdateWidget(ChapterSection oldWidget) { super.didUpdateWidget(oldWidget); // 更新标题控制器 if (oldWidget.title != widget.title) { _chapterTitleController.text = widget.title; } } @override void dispose() { _debouncer.dispose(); _chapterTitleController.dispose(); super.dispose(); } // 获取章节序号文本 String _getChapterIndexText() { if (widget.chapterIndex == null) return ''; // 使用中文数字表示章节序号 final List chineseNumbers = ['零', '一', '二', '三', '四', '五', '六', '七', '八', '九', '十']; if (widget.chapterIndex! <= 10) { return '第${chineseNumbers[widget.chapterIndex!]}章 · '; } else if (widget.chapterIndex! < 20) { return '第十${chineseNumbers[widget.chapterIndex! - 10]}章 · '; } else { // 对于更大的数字,直接使用阿拉伯数字 return '第${widget.chapterIndex}章 · '; } } // 手动触发加载场景的方法 void _loadScenes() { AppLogger.i('ChapterSection', '手动触发加载章节场景: ${widget.actId} - ${widget.chapterId}'); try { final controller = Provider.of(context, listen: false); controller.loadScenesForChapter(widget.actId, widget.chapterId); } catch (e) { // 如果无法获取控制器,直接使用EditorBloc widget.editorBloc.add(LoadMoreScenes( fromChapterId: widget.chapterId, direction: 'center', actId: widget.actId, chaptersLimit: 2, preventFocusChange: true, )); } } @override Widget build(BuildContext context) { final theme = Theme.of(context); return Container( key: widget.chapterKey, // Use the passed GlobalKey here color: WebTheme.getBackgroundColor(context), // 使用动态背景色 child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ // Chapter标题 Padding( // 调整间距 padding: const EdgeInsets.fromLTRB(0, 8, 0, 24), // 调整上下间距 child: Row( crossAxisAlignment: CrossAxisAlignment.center, // 垂直居中对齐 children: [ // 添加章节序号前缀 if (widget.chapterIndex != null) Text( _getChapterIndexText(), style: WebTheme.getAlignedTextStyle( baseStyle: theme.textTheme.headlineMedium?.copyWith( fontWeight: FontWeight.w600, color: WebTheme.getTextColor(context), ) ?? const TextStyle(), ), ), // 可编辑的文本字段 Expanded( child: EditableTitle( // 保持 EditableTitle initialText: widget.title, style: WebTheme.getAlignedTextStyle( baseStyle: theme.textTheme.headlineMedium?.copyWith( fontWeight: FontWeight.w600, color: WebTheme.getTextColor(context), ) ?? const TextStyle(), ), onChanged: (value) { // 使用防抖更新 _debouncer.run(() { if (mounted) { widget.editorBloc.add(UpdateChapterTitle( actId: widget.actId, chapterId: widget.chapterId, title: value, )); } }); }, ), ), const SizedBox(width: 8), // 增加间距 // 替换为MenuBuilder MenuBuilder.buildChapterMenu( context: context, editorBloc: widget.editorBloc, actId: widget.actId, chapterId: widget.chapterId, onRenamePressed: () { // 聚焦到标题编辑框 // 通过setState强制刷新使标题进入编辑状态 setState(() {}); }, ), ], ), ), // 场景列表 if (widget.scenes.isEmpty) // 显示空章节的UI,提供手动加载按钮 Padding( padding: const EdgeInsets.symmetric(vertical: 20.0, horizontal: 16.0), child: Center( child: Column( children: [ Icon(Icons.article_outlined, size: 48, color: WebTheme.getSecondaryTextColor(context)), const SizedBox(height: 16), Text( '章节 "${widget.title}" 暂无场景内容', style: TextStyle(color: WebTheme.getSecondaryTextColor(context)), ), const SizedBox(height: 8), Text( '请手动加载或等待自动加载', style: TextStyle(color: WebTheme.getSecondaryTextColor(context), fontSize: 14), ), const SizedBox(height: 24), // 加载场景按钮 OutlinedButton.icon( onPressed: _loadScenes, icon: Icon(Icons.download, size: 18, color: WebTheme.getTextColor(context)), label: Text('加载场景', style: TextStyle(color: WebTheme.getTextColor(context))), style: OutlinedButton.styleFrom( foregroundColor: WebTheme.getTextColor(context), side: BorderSide.none, // 去掉边框 padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 12), elevation: 0, // 去掉阴影 ), ), ], ), ), ) else Column(children: widget.scenes), // 移除添加新场景按钮 - 现在由EditorMainArea统一管理 ], ), ); } }