二次开发源码提交

This commit is contained in:
2026-05-15 08:52:48 +08:00
parent 4131f7321a
commit eb35a1d067
191 changed files with 34566 additions and 0 deletions
@@ -0,0 +1,136 @@
import 'dart:math';
import 'package:flutter/material.dart';
import 'package:lucide_icons/lucide_icons.dart';
import 'package:provider/provider.dart';
import 'package:cloudreve4_flutter/presentation/providers/user_setting_provider.dart';
class StorageUsageCard extends StatelessWidget {
const StorageUsageCard({super.key});
@override
Widget build(BuildContext context) {
final theme = Theme.of(context);
final colorScheme = theme.colorScheme;
return Consumer<UserSettingProvider>(
builder: (context, userSetting, _) {
final capacity = userSetting.capacity;
final used = capacity?.used ?? 0;
final total = capacity?.total ?? 0;
final percentage = capacity?.usagePercentage ?? 0;
return Card(
child: Padding(
padding: const EdgeInsets.all(20),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: [
Icon(LucideIcons.hardDrive, size: 20, color: colorScheme.primary),
const SizedBox(width: 8),
Text('存储空间', style: theme.textTheme.titleMedium?.copyWith(fontWeight: FontWeight.w600)),
],
),
const SizedBox(height: 24),
Center(
child: SizedBox(
width: 160,
height: 90,
child: CustomPaint(
painter: _SemiCircleProgressPainter(
progress: percentage / 100,
color: colorScheme.primary,
backgroundColor: colorScheme.primary.withValues(alpha: 0.12),
),
),
),
),
const SizedBox(height: 16),
Center(
child: Text(
'${_formatBytes(used)} / ${_formatBytes(total)}',
style: theme.textTheme.bodyMedium?.copyWith(
color: theme.hintColor,
),
),
),
const SizedBox(height: 4),
Center(
child: Text(
'已使用 ${percentage.toStringAsFixed(1)}%',
style: theme.textTheme.bodySmall?.copyWith(
color: theme.hintColor,
),
),
),
],
),
),
);
},
);
}
String _formatBytes(int bytes) {
if (bytes < 1024) return '$bytes B';
if (bytes < 1024 * 1024) return '${(bytes / 1024).toStringAsFixed(1)} KB';
if (bytes < 1024 * 1024 * 1024) return '${(bytes / (1024 * 1024)).toStringAsFixed(1)} MB';
return '${(bytes / (1024 * 1024 * 1024)).toStringAsFixed(1)} GB';
}
}
class _SemiCircleProgressPainter extends CustomPainter {
final double progress;
final Color color;
final Color backgroundColor;
_SemiCircleProgressPainter({
required this.progress,
required this.color,
required this.backgroundColor,
});
@override
void paint(Canvas canvas, Size size) {
final strokeWidth = 14.0;
final center = Offset(size.width / 2, size.height);
final radius = min(size.width / 2, size.height) - strokeWidth / 2;
final bgPaint = Paint()
..color = backgroundColor
..strokeWidth = strokeWidth
..strokeCap = StrokeCap.round
..style = PaintingStyle.stroke;
canvas.drawArc(
Rect.fromCircle(center: center, radius: radius),
pi,
pi,
false,
bgPaint,
);
final fgPaint = Paint()
..color = color
..strokeWidth = strokeWidth
..strokeCap = StrokeCap.round
..style = PaintingStyle.stroke;
final sweepAngle = pi * progress.clamp(0.0, 1.0);
if (sweepAngle > 0) {
canvas.drawArc(
Rect.fromCircle(center: center, radius: radius),
pi,
sweepAngle,
false,
fgPaint,
);
}
}
@override
bool shouldRepaint(covariant _SemiCircleProgressPainter oldDelegate) {
return oldDelegate.progress != progress || oldDelegate.color != color;
}
}