马良AI写作初始化仓库

This commit is contained in:
邓滨杰
2025-09-10 00:07:52 +08:00
parent 3c06bb1a03
commit 39c0f8840f
1309 changed files with 318528 additions and 0 deletions

View File

@@ -0,0 +1,210 @@
import 'package:flutter/material.dart';
// import 'package:ainoval/utils/web_theme.dart';
/// 上下文数据
class ContextData {
/// 构造函数
const ContextData({
required this.title,
this.subtitle,
this.icon,
this.id,
});
/// 标题
final String title;
/// 副标题(可选)
final String? subtitle;
/// 图标(可选,如果不提供会根据内容自动判断)
final IconData? icon;
/// 唯一标识(可选)
final String? id;
@override
bool operator ==(Object other) {
if (identical(this, other)) return true;
return other is ContextData &&
other.title == title &&
other.subtitle == subtitle &&
other.icon == icon &&
other.id == id;
}
@override
int get hashCode {
return title.hashCode ^
subtitle.hashCode ^
icon.hashCode ^
id.hashCode;
}
}
/// 上下文标签组件
/// 显示上下文信息,支持删除操作,风格简洁现代
class ContextBadge extends StatelessWidget {
/// 构造函数
const ContextBadge({
super.key,
required this.data,
this.onDelete,
this.maxWidth = 200,
this.showDeleteButton = true,
this.globalKey,
});
/// 上下文数据
final ContextData data;
/// 删除回调
final VoidCallback? onDelete;
/// 最大宽度
final double maxWidth;
/// 是否显示删除按钮
final bool showDeleteButton;
/// 全局Key用于定位
final GlobalKey? globalKey;
@override
Widget build(BuildContext context) {
// final isDark = WebTheme.isDarkMode(context);
return Container(
key: globalKey,
constraints: BoxConstraints(maxWidth: maxWidth),
height: 36, // h-9 equivalent
decoration: BoxDecoration(
color: _getBackgroundColor(context),
borderRadius: BorderRadius.circular(8),
),
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
// 图标
Padding(
padding: const EdgeInsets.only(left: 8, right: 8),
child: Icon(
_getIcon(),
size: 16, // size-4 equivalent
color: _getIconColor(context),
),
),
// 内容
Expanded(
child: Padding(
padding: const EdgeInsets.only(right: 4),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
// 标题
Text(
data.title,
style: TextStyle(
fontSize: 12,
fontWeight: FontWeight.w600, // font-semibold
color: _getTextColor(context),
height: 1.2, // leading-tight
),
maxLines: 1,
overflow: TextOverflow.ellipsis,
),
// 副标题
if (data.subtitle != null && data.subtitle!.isNotEmpty) ...[
const SizedBox(height: 1),
Text(
data.subtitle!,
style: TextStyle(
fontSize: 10, // text-xs
color: _getSubtitleColor(context),
height: 1.2, // leading-tight
),
maxLines: 1,
overflow: TextOverflow.ellipsis,
),
],
],
),
),
),
// 删除按钮
if (showDeleteButton)
Material(
type: MaterialType.transparency,
child: InkWell(
onTap: onDelete,
borderRadius: BorderRadius.circular(4),
child: Container(
width: 20, // h-5 w-5
height: 20,
margin: const EdgeInsets.only(right: 6),
child: Icon(
Icons.close,
size: 14, // h-3.5 w-3.5
color: _getDeleteButtonColor(context),
),
),
),
),
],
),
);
}
/// 获取图标
IconData _getIcon() {
// 如果提供了自定义图标,直接使用
if (data.icon != null) {
return data.icon!;
}
// 根据标题内容自动判断图标
final title = data.title.toLowerCase();
if (title.contains('act') || title.contains('chapter') || title.contains('scene')) {
return Icons.menu_book_outlined; // block-quote equivalent
} else if (title.contains('novel') || title.contains('book') || title.contains('text')) {
return Icons.menu_book; // book-open equivalent
} else if (title.contains('folder') || title.contains('directory')) {
return Icons.folder_outlined; // folder-closed equivalent
} else {
return Icons.description_outlined; // 默认文档图标
}
}
/// 获取背景颜色
Color _getBackgroundColor(BuildContext context) {
final scheme = Theme.of(context).colorScheme;
final title = data.title.toLowerCase();
final bool isContent = title.contains('novel') || title.contains('book') || title.contains('text');
return isContent ? scheme.surfaceContainerHigh : scheme.surfaceContainer;
}
/// 获取图标颜色
Color _getIconColor(BuildContext context) {
return Theme.of(context).colorScheme.onSurfaceVariant;
}
/// 获取文字颜色
Color _getTextColor(BuildContext context) {
return Theme.of(context).colorScheme.onSurface;
}
/// 获取副标题颜色
Color _getSubtitleColor(BuildContext context) {
return Theme.of(context).colorScheme.onSurfaceVariant;
}
/// 获取删除按钮颜色
Color _getDeleteButtonColor(BuildContext context) {
return Theme.of(context).colorScheme.onSurfaceVariant;
}
}