From 4d9a554f0de9cff5e7433370d791ec94afb180d8 Mon Sep 17 00:00:00 2001 From: jdysya <1912377458@qq.com> Date: Tue, 10 Jun 2025 16:17:27 +0800 Subject: [PATCH] =?UTF-8?q?feat(widgets):=20=E4=BC=98=E5=8C=96=20LeetCode?= =?UTF-8?q?=20=E5=8D=A1=E7=89=87=E6=A0=B7=E5=BC=8F=E5=92=8C=E5=8A=9F?= =?UTF-8?q?=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 添加图表图标和用户击败图标 - 优化难度显示,添加颜色区分 - 调整布局和样式,提升可读性 - 添加圆形头像和对勾图标 - 优化错误和空状态显示 --- lib/widgets/leetcode_card.dart | 181 +++++++++++++++++++++++++-------- 1 file changed, 140 insertions(+), 41 deletions(-) diff --git a/lib/widgets/leetcode_card.dart b/lib/widgets/leetcode_card.dart index 6d52580..1764e16 100644 --- a/lib/widgets/leetcode_card.dart +++ b/lib/widgets/leetcode_card.dart @@ -135,33 +135,81 @@ class _LeetCodeCardState extends State _progress!['totalQuestionBeatsPercentage'] as double; return Card( + elevation: 3, + shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12)), + margin: const EdgeInsets.symmetric(vertical: 8), child: Padding( padding: const EdgeInsets.all(16.0), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - const Text( - '解题进度', - style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold), + Row( + children: [ + const Icon(Icons.bar_chart, color: Colors.green), + const SizedBox(width: 8), + const Text( + '解题进度', + style: TextStyle( + fontSize: 18, + fontWeight: FontWeight.bold, + ), + ), + ], ), - const SizedBox(height: 8), + const SizedBox(height: 12), ...acceptedQuestions.map((q) { final difficulty = q['difficulty'] as String; final count = q['count'] as int; + Color difficultyColor = Colors.grey; + if (difficulty == 'Easy') + difficultyColor = Colors.green; + else if (difficulty == 'Medium') + difficultyColor = Colors.orange; + else if (difficulty == 'Hard') difficultyColor = Colors.red; + return Padding( - padding: const EdgeInsets.symmetric(vertical: 4.0), + padding: const EdgeInsets.symmetric(vertical: 6.0), child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [Text(difficulty), Text('$count 题')], + children: [ + Row( + children: [ + Container( + width: 12, + height: 12, + decoration: BoxDecoration( + color: difficultyColor, + shape: BoxShape.circle, + ), + ), + const SizedBox(width: 8), + Text( + difficulty == 'EASY' + ? '简单' + : difficulty == 'MEDIUM' + ? '中等' + : '困难', + style: const TextStyle(fontWeight: FontWeight.w500), + ), + ], + ), + Text('$count 题', style: const TextStyle(fontSize: 14)), + ], ), ); - }), + }).toList(), const Divider(), Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - const Text('击败用户', - style: TextStyle(fontWeight: FontWeight.bold)), + const Row( + children: [ + Icon(Icons.workspace_premium, + size: 18, color: Colors.green), + SizedBox(width: 6), + Text('击败用户', style: TextStyle(fontWeight: FontWeight.bold)), + ], + ), Text('${totalBeatsPercentage.toStringAsFixed(1)}%', style: const TextStyle( fontWeight: FontWeight.bold, @@ -178,6 +226,9 @@ class _LeetCodeCardState extends State @override Widget build(BuildContext context) { return Card( + shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(16)), + elevation: 4, + margin: const EdgeInsets.all(16), child: Padding( padding: const EdgeInsets.all(16.0), child: Column( @@ -188,18 +239,30 @@ class _LeetCodeCardState extends State children: [ const Text( 'LeetCode 最近提交', - style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold), + style: TextStyle( + fontSize: 20, + fontWeight: FontWeight.bold, + color: Colors.green, + ), ), - RotationTransition( - turns: _refreshController, - child: IconButton( - icon: const Icon(Icons.refresh, size: 28), - onPressed: _isLoading - ? null - : () async { - _refreshController.forward(from: 0.0); - await _fetchData(); - }, + Container( + decoration: BoxDecoration( + color: Colors.green.shade100, + borderRadius: BorderRadius.circular(20), + ), + padding: const EdgeInsets.all(8), + child: RotationTransition( + turns: _refreshController, + child: IconButton( + icon: const Icon(Icons.refresh, + size: 24, color: Colors.green), + onPressed: _isLoading + ? null + : () async { + _refreshController.forward(from: 0.0); + await _fetchData(); + }, + ), ), ), ], @@ -207,24 +270,37 @@ class _LeetCodeCardState extends State if (_isLoading) Center( child: Padding( - padding: const EdgeInsets.all(16.0), + padding: const EdgeInsets.all(24.0), child: AnimatedBuilder( animation: _refreshController, builder: (_, child) => Transform.rotate( angle: _refreshController.value * 2 * 3.14, child: child, ), - child: const CircularProgressIndicator(), + child: const CircularProgressIndicator( + color: Colors.green, + strokeWidth: 2, + ), ), ), ) else if (_error != null) Center( child: Padding( - padding: const EdgeInsets.all(16.0), - child: Text( - _error!, - style: const TextStyle(color: Colors.red), + padding: const EdgeInsets.all(24.0), + child: Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + const Icon(Icons.error_outline, color: Colors.red), + const SizedBox(width: 8), + Expanded( + child: Text( + _error!, + style: const TextStyle(color: Colors.red), + textAlign: TextAlign.center, + ), + ), + ], ), ), ) @@ -239,8 +315,11 @@ class _LeetCodeCardState extends State const Center( child: Padding( padding: EdgeInsets.all(16.0), - child: - Text('暂无提交记录', style: TextStyle(fontSize: 16)), + child: Text( + '暂无提交记录', + style: + TextStyle(fontSize: 16, color: Colors.grey), + ), ), ) else @@ -252,20 +331,40 @@ class _LeetCodeCardState extends State final submission = _submissions[index]; final question = submission['question']; - return ListTile( - title: Text( - question['translatedTitle'] ?? - question['title'], - style: const TextStyle(fontSize: 16), + return Card( + elevation: 2, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(12), ), - subtitle: Text( - '提交时间: ${timeago.format(DateTime.fromMillisecondsSinceEpoch(submission['submitTime'] * 1000), locale: 'zh_CN')}', - style: const TextStyle(fontSize: 14), - ), - trailing: Text( - '#${question['questionFrontendId']}', - style: const TextStyle( - fontSize: 14, fontWeight: FontWeight.bold), + margin: const EdgeInsets.symmetric(vertical: 6), + child: ListTile( + leading: CircleAvatar( + backgroundColor: Colors.green, + radius: 16, + child: Text( + question['questionFrontendId'].toString(), + style: const TextStyle( + color: Colors.white, + fontSize: 12, + ), + ), + ), + title: Text( + question['translatedTitle'] ?? + question['title'], + style: const TextStyle( + fontSize: 16, + fontWeight: FontWeight.bold, + ), + ), + subtitle: Text( + '提交时间: ${timeago.format(DateTime.fromMillisecondsSinceEpoch(submission['submitTime'] * 1000), locale: 'zh_CN')}', + style: const TextStyle(fontSize: 14), + ), + trailing: const Icon( + Icons.check_circle, + color: Colors.green, + ), ), ); },