适配深色模式

This commit is contained in:
DelLevin-Home
2026-05-26 05:10:21 +08:00
parent b36f50827f
commit 73f3795e65
53 changed files with 3846 additions and 3211 deletions

View File

@@ -19,8 +19,9 @@ class _StatisticsPageState extends State<StatisticsPage> {
@override
Widget build(BuildContext context) {
final colors = Theme.of(context).colorScheme;
return Scaffold(
backgroundColor: Colors.white,
backgroundColor: colors.surface,
appBar: AppBar(title: const Text('数据统计')),
body: Consumer<AppProvider>(
builder: (context, provider, child) {
@@ -63,6 +64,7 @@ class _StatisticsPageState extends State<StatisticsPage> {
// ─── 总览卡片 ────────────────────────────────────────────────────────
Widget _buildTotalCards(List<Movie> movies, List<Book> books, List<Note> notes) {
final colors = Theme.of(context).colorScheme;
final items = <_CardData>[];
if (_showMovies) items.add(_CardData('影视', movies.length, Icons.movie_outlined, const Color(0xFF4A90D9)));
if (_showBooks) items.add(_CardData('书籍', books.length, Icons.menu_book_outlined, const Color(0xFF7E57C2)));
@@ -83,7 +85,7 @@ class _StatisticsPageState extends State<StatisticsPage> {
const SizedBox(height: 10),
Text('${d.count}', style: TextStyle(fontSize: 26, fontWeight: FontWeight.w700, color: d.color)),
const SizedBox(height: 2),
Text(d.label, style: const TextStyle(fontSize: 12, color: Color(0xFF888888))),
Text(d.label, style: TextStyle(fontSize: 12, color: colors.onSurface.withValues(alpha: 0.5))),
],
),
),
@@ -94,6 +96,7 @@ class _StatisticsPageState extends State<StatisticsPage> {
// ─── 状态分布 ────────────────────────────────────────────────────────
Widget _buildStatusSection(String title, List items, String Function(dynamic) getStatus, Map<String, String> labels) {
final colors = Theme.of(context).colorScheme;
final active = items.where((i) => !(i is Movie) || !i.isDeleted).toList();
final total = active.length;
@@ -110,11 +113,11 @@ class _StatisticsPageState extends State<StatisticsPage> {
children: [
Row(
children: [
Text(e.key, style: const TextStyle(fontSize: 13, color: Color(0xFF666666))),
Text(e.key, style: TextStyle(fontSize: 13, color: colors.onSurface.withValues(alpha: 0.6))),
const Spacer(),
Text('$count', style: const TextStyle(fontSize: 14, fontWeight: FontWeight.w600, color: Color(0xFF1A1A1A))),
Text('$count', style: TextStyle(fontSize: 14, fontWeight: FontWeight.w600, color: colors.onSurface)),
const SizedBox(width: 4),
Text('${(pct * 100).toStringAsFixed(0)}%', style: const TextStyle(fontSize: 12, color: Color(0xFFBBBBBB))),
Text('${(pct * 100).toStringAsFixed(0)}%', style: TextStyle(fontSize: 12, color: colors.onSurface.withValues(alpha: 0.3))),
],
),
const SizedBox(height: 6),
@@ -122,8 +125,8 @@ class _StatisticsPageState extends State<StatisticsPage> {
borderRadius: BorderRadius.circular(3),
child: LinearProgressIndicator(
value: pct,
backgroundColor: const Color(0xFFF0F0F0),
color: const Color(0xFF1A1A1A),
backgroundColor: colors.outlineVariant,
color: colors.primary,
minHeight: 6,
),
),
@@ -138,6 +141,7 @@ class _StatisticsPageState extends State<StatisticsPage> {
// ─── 类型/标签分布 ───────────────────────────────────────────────────
Widget _buildGenreDistribution(String title, List items) {
final colors = Theme.of(context).colorScheme;
final genreCounts = <String, int>{};
for (final item in items) {
for (final genre in (item.genres as List<String>)) {
@@ -161,17 +165,17 @@ class _StatisticsPageState extends State<StatisticsPage> {
children: [
SizedBox(
width: 60,
child: Text(e.key, style: const TextStyle(fontSize: 12, color: Color(0xFF666666)), overflow: TextOverflow.ellipsis),
child: Text(e.key, style: TextStyle(fontSize: 12, color: colors.onSurface.withValues(alpha: 0.6)), overflow: TextOverflow.ellipsis),
),
const SizedBox(width: 10),
Expanded(
child: ClipRRect(
borderRadius: BorderRadius.circular(2),
child: LinearProgressIndicator(value: pct, backgroundColor: const Color(0xFFF0F0F0), color: const Color(0xFF1A1A1A), minHeight: 4),
child: LinearProgressIndicator(value: pct, backgroundColor: colors.outlineVariant, color: colors.primary, minHeight: 4),
),
),
const SizedBox(width: 8),
Text('${e.value}', style: const TextStyle(fontSize: 12, fontWeight: FontWeight.w600, color: Color(0xFF1A1A1A))),
Text('${e.value}', style: TextStyle(fontSize: 12, fontWeight: FontWeight.w600, color: colors.onSurface)),
],
),
);
@@ -181,6 +185,7 @@ class _StatisticsPageState extends State<StatisticsPage> {
}
Widget _buildNoteTagDistribution(String title, List<Note> notes) {
final colors = Theme.of(context).colorScheme;
final tagCounts = <String, int>{};
for (final note in notes) {
for (final tag in note.tags) {
@@ -204,17 +209,17 @@ class _StatisticsPageState extends State<StatisticsPage> {
children: [
SizedBox(
width: 60,
child: Text(e.key, style: const TextStyle(fontSize: 12, color: Color(0xFF666666)), overflow: TextOverflow.ellipsis),
child: Text(e.key, style: TextStyle(fontSize: 12, color: colors.onSurface.withValues(alpha: 0.6)), overflow: TextOverflow.ellipsis),
),
const SizedBox(width: 10),
Expanded(
child: ClipRRect(
borderRadius: BorderRadius.circular(2),
child: LinearProgressIndicator(value: pct, backgroundColor: const Color(0xFFF0F0F0), color: const Color(0xFF1A1A1A), minHeight: 4),
child: LinearProgressIndicator(value: pct, backgroundColor: colors.outlineVariant, color: colors.primary, minHeight: 4),
),
),
const SizedBox(width: 8),
Text('${e.value}', style: const TextStyle(fontSize: 12, fontWeight: FontWeight.w600, color: Color(0xFF1A1A1A))),
Text('${e.value}', style: TextStyle(fontSize: 12, fontWeight: FontWeight.w600, color: colors.onSurface)),
],
),
);
@@ -226,6 +231,7 @@ class _StatisticsPageState extends State<StatisticsPage> {
// ─── 评分分布 ────────────────────────────────────────────────────────
Widget _buildRatingDistribution(String title, List<Movie> movies, List<Book> books) {
final colors = Theme.of(context).colorScheme;
final allRatings = <double>[];
for (final m in movies) {
if (m.rating != null) allRatings.add(m.rating!);
@@ -255,10 +261,10 @@ class _StatisticsPageState extends State<StatisticsPage> {
children: [
Row(
children: [
const Text('平均评分', style: TextStyle(fontSize: 13, color: Color(0xFF666666))),
Text('平均评分', style: TextStyle(fontSize: 13, color: colors.onSurface.withValues(alpha: 0.6))),
const Spacer(),
Text(avg.toStringAsFixed(1), style: const TextStyle(fontSize: 22, fontWeight: FontWeight.w700, color: Color(0xFF1A1A1A))),
const Text(' / 10', style: TextStyle(fontSize: 13, color: Color(0xFFBBBBBB))),
Text(avg.toStringAsFixed(1), style: TextStyle(fontSize: 22, fontWeight: FontWeight.w700, color: colors.onSurface)),
Text(' / 10', style: TextStyle(fontSize: 13, color: colors.onSurface.withValues(alpha: 0.3))),
],
),
const SizedBox(height: 16),
@@ -268,7 +274,7 @@ class _StatisticsPageState extends State<StatisticsPage> {
children: [
SizedBox(
width: 28,
child: Text(ranges[i], style: const TextStyle(fontSize: 11, color: Color(0xFF999999))),
child: Text(ranges[i], style: TextStyle(fontSize: 11, color: colors.onSurface.withValues(alpha: 0.4))),
),
const SizedBox(width: 8),
Expanded(
@@ -276,14 +282,14 @@ class _StatisticsPageState extends State<StatisticsPage> {
borderRadius: BorderRadius.circular(2),
child: LinearProgressIndicator(
value: maxCount > 0 ? counts[i] / maxCount : 0.0,
backgroundColor: const Color(0xFFF0F0F0),
color: const Color(0xFF1A1A1A),
backgroundColor: colors.outlineVariant,
color: colors.primary,
minHeight: 6,
),
),
),
const SizedBox(width: 8),
Text('${counts[i]}', style: const TextStyle(fontSize: 12, fontWeight: FontWeight.w600, color: Color(0xFF1A1A1A))),
Text('${counts[i]}', style: TextStyle(fontSize: 12, fontWeight: FontWeight.w600, color: colors.onSurface)),
],
),
)),
@@ -295,6 +301,7 @@ class _StatisticsPageState extends State<StatisticsPage> {
// ─── 月度趋势 ────────────────────────────────────────────────────────
Widget _buildMonthlyTrend(List<Movie> movies, List<Book> books, List<Note> notes) {
final colors = Theme.of(context).colorScheme;
final now = DateTime.now();
final months = List.generate(6, (i) {
final d = DateTime(now.year, now.month - (5 - i), 1);
@@ -323,7 +330,7 @@ class _StatisticsPageState extends State<StatisticsPage> {
final maxVal = allValues.isEmpty ? 1 : allValues.reduce((a, b) => a > b ? a : b);
final safeMax = maxVal == 0 ? 1 : maxVal;
final colors = { '影视': const Color(0xFF4A90D9), '书籍': const Color(0xFF7E57C2), '笔记': const Color(0xFF66BB6A) };
final brandColors = { '影视': const Color(0xFF4A90D9), '书籍': const Color(0xFF7E57C2), '笔记': const Color(0xFF66BB6A) };
return _buildCard(
title: '近6月趋势',
@@ -345,7 +352,7 @@ class _StatisticsPageState extends State<StatisticsPage> {
height: h < 2 && e.value[i] > 0 ? 2 : h,
margin: const EdgeInsets.only(top: 1),
decoration: BoxDecoration(
color: colors[e.key]!.withValues(alpha: 0.7),
color: brandColors[e.key]!.withValues(alpha: 0.7),
borderRadius: BorderRadius.circular(2),
),
);
@@ -357,12 +364,12 @@ class _StatisticsPageState extends State<StatisticsPage> {
),
),
const SizedBox(height: 8),
const Divider(height: 1, color: Color(0xFFF0F0F0)),
Divider(height: 1, color: colors.outlineVariant),
const SizedBox(height: 8),
// 月份标签
Row(
children: months.map((m) => Expanded(
child: Text(m, textAlign: TextAlign.center, style: const TextStyle(fontSize: 11, color: Color(0xFFBBBBBB))),
child: Text(m, textAlign: TextAlign.center, style: TextStyle(fontSize: 11, color: colors.onSurface.withValues(alpha: 0.3))),
)).toList(),
),
const SizedBox(height: 12),
@@ -374,9 +381,9 @@ class _StatisticsPageState extends State<StatisticsPage> {
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
Container(width: 8, height: 8, decoration: BoxDecoration(color: colors[k], borderRadius: BorderRadius.circular(2))),
Container(width: 8, height: 8, decoration: BoxDecoration(color: brandColors[k], borderRadius: BorderRadius.circular(2))),
const SizedBox(width: 4),
Text(k, style: const TextStyle(fontSize: 12, color: Color(0xFF888888))),
Text(k, style: TextStyle(fontSize: 12, color: colors.onSurface.withValues(alpha: 0.5))),
],
),
)).toList(),
@@ -394,10 +401,11 @@ class _StatisticsPageState extends State<StatisticsPage> {
// ─── 通用卡片 ────────────────────────────────────────────────────────
Widget _buildCard({required String title, required Widget child}) {
final colors = Theme.of(context).colorScheme;
return Container(
padding: const EdgeInsets.all(18),
decoration: BoxDecoration(
color: const Color(0xFFFAFAFA),
color: colors.surfaceContainerHigh,
borderRadius: BorderRadius.circular(14),
),
child: Column(
@@ -405,9 +413,9 @@ class _StatisticsPageState extends State<StatisticsPage> {
children: [
Row(
children: [
Container(width: 3, height: 14, decoration: BoxDecoration(color: const Color(0xFF1A1A1A), borderRadius: BorderRadius.circular(2))),
Container(width: 3, height: 14, decoration: BoxDecoration(color: colors.primary, borderRadius: BorderRadius.circular(2))),
const SizedBox(width: 8),
Text(title, style: const TextStyle(fontSize: 14, fontWeight: FontWeight.w600, color: Color(0xFF1A1A1A))),
Text(title, style: TextStyle(fontSize: 14, fontWeight: FontWeight.w600, color: colors.onSurface)),
],
),
const SizedBox(height: 16),