/** * 添加新卷按钮组件 * * 用于显示一个可点击的"添加新卷"按钮,用户点击后会触发创建新卷的逻辑。 * 包含加载状态反馈和防抖功能,避免短时间内重复点击触发多次创建操作。 */ import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; import 'package:ainoval/utils/logger.dart'; import 'package:ainoval/widgets/common/top_toast.dart'; import 'package:ainoval/screens/editor/controllers/editor_screen_controller.dart'; import 'package:ainoval/utils/web_theme.dart'; /// 添加新卷按钮组件 /// /// 在编辑器中用于添加新卷时使用的按钮组件,包含点击反馈和加载态。 /// 使用Provider模式调用EditorScreenController中的创建方法。 class AddActButton extends StatefulWidget { /// 创建一个添加新卷按钮 const AddActButton({Key? key}) : super(key: key); @override State createState() => _AddActButtonState(); } class _AddActButtonState extends State { /// 标记是否正在添加中,用于显示加载状态 bool _isAdding = false; /// 记录上次点击时间,用于防抖 DateTime? _lastAddTime; /// 防抖时间间隔(2秒) static const Duration _debounceInterval = Duration(seconds: 2); /// 添加新卷的处理方法 /// /// 包含防抖和错误处理逻辑,避免短时间内多次触发 void _addNewAct() { // 防止频繁点击导致重复添加 final now = DateTime.now(); if (_isAdding || (_lastAddTime != null && now.difference(_lastAddTime!) < _debounceInterval)) { // 如果正在添加中或最后添加时间在2秒内,忽略此次点击 AppLogger.i('AddActButton', '忽略重复点击: 正在添加=${_isAdding}, 距上次点击=${_lastAddTime != null ? now.difference(_lastAddTime!).inMilliseconds : "首次点击"}ms'); // 显示提示(仅在UI上) TopToast.warning(context, '操作正在处理中,请稍候...'); return; } // 记录当前时间并标记为添加中 _lastAddTime = now; setState(() { _isAdding = true; }); AppLogger.i('AddActButton', '触发EditorScreenController的createNewAct方法'); // 使用EditorScreenController创建新卷及章节 Provider.of(context, listen: false).createNewAct().then((_) { if (mounted) { setState(() { _isAdding = false; }); } }).catchError((error) { AppLogger.e('AddActButton', '调用createNewAct失败', error); if (mounted) { setState(() { _isAdding = false; }); TopToast.error(context, '创建失败: ${error.toString()}'); } }); } @override Widget build(BuildContext context) { return Center( child: Padding( padding: const EdgeInsets.symmetric(vertical: 16.0), child: OutlinedButton.icon( onPressed: _isAdding ? null : _addNewAct, // 如果正在添加中,禁用按钮 icon: _isAdding // 添加中状态显示加载指示器 ? SizedBox( width: 18, height: 18, child: CircularProgressIndicator( strokeWidth: 2, valueColor: AlwaysStoppedAnimation(WebTheme.getPrimaryColor(context)), ), ) // 常规状态显示加号图标 : const Icon(Icons.add, size: 18), label: Text(_isAdding ? '添加中...' : '添加新卷'), style: OutlinedButton.styleFrom( foregroundColor: WebTheme.getPrimaryColor(context), backgroundColor: WebTheme.getSurfaceColor(context), side: BorderSide(color: WebTheme.getPrimaryColor(context), width: 1.5), padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 12), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(8), ), elevation: 1, ).copyWith( overlayColor: MaterialStateProperty.resolveWith( (Set states) { if (states.contains(MaterialState.hovered)) { return WebTheme.getPrimaryColor(context).withOpacity(0.1); } return null; }, ), ), ), ), ); } }