flutter_dashboard/lib/widgets/github_card.dart
jdysya 6b64d1a0cd refactor(widgets): 重构卡片组件的样式
- 统一了卡片的阴影、边框和圆角样式
- 调整了卡片的外边距
- 优化了部分卡片的内边距
- 统一了难度等级的命名方式
2025-06-10 16:33:54 +08:00

221 lines
7.2 KiB
Dart

import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import '../services/auth_service.dart';
import '../services/github_service.dart';
import '../models/github_event.dart';
import 'package:timeago/timeago.dart' as timeago;
class GithubCard extends StatefulWidget {
const GithubCard({super.key});
@override
State<GithubCard> createState() => _GithubCardState();
}
class _GithubCardState extends State<GithubCard> {
final GithubService _githubService = GithubService();
List<GithubEvent> _events = [];
bool _isLoading = false;
String? _error;
String _getEventTypeText(String type) {
switch (type) {
case 'PushEvent':
return '推送代码';
case 'CreateEvent':
return '创建仓库';
case 'IssuesEvent':
return 'Issue 操作';
case 'PullRequestEvent':
return 'Pull Request 操作';
case 'ForkEvent':
return 'Fork 仓库';
case 'WatchEvent':
return '关注仓库';
case 'StarEvent':
return 'Star 仓库';
default:
return type;
}
}
Widget _buildCommitContent(List<Commit> commits) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children:
commits.map((commit) {
return Padding(
padding: const EdgeInsets.symmetric(vertical: 4.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
commit.message,
style: const TextStyle(fontWeight: FontWeight.bold),
),
Text(
'作者: ${commit.author.name} <${commit.author.email}>',
style: const TextStyle(fontSize: 12, color: Colors.grey),
),
],
),
);
}).toList(),
);
}
Future<void> _fetchEvents() async {
setState(() {
_isLoading = true;
_error = null;
});
try {
final authService = Provider.of<AuthService>(context, listen: false);
final username = authService.credentials['github_username'];
final token = authService.credentials['github_token'];
if (username == null || token == null) {
throw Exception('请在设置中配置 GitHub 用户名和 Token');
}
final events = await _githubService.getUserEvents(username, token);
setState(() {
_events = events;
_isLoading = false;
});
} catch (e) {
setState(() {
_error = e.toString();
_isLoading = false;
});
}
}
@override
void initState() {
super.initState();
_fetchEvents();
}
@override
Widget build(BuildContext context) {
return Card(
elevation: 4,
shadowColor: Colors.deepPurple.withOpacity(0.3),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(16),
side: BorderSide(color: Colors.deepPurple.withOpacity(0.1)),
),
margin: const EdgeInsets.symmetric(vertical: 8.0),
child: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
const Text(
'GitHub 最近活动',
style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold),
),
IconButton(
icon: const Icon(Icons.refresh),
onPressed: _isLoading ? null : _fetchEvents,
),
],
),
if (_isLoading)
const Center(
child: Padding(
padding: EdgeInsets.all(16.0),
child: CircularProgressIndicator(),
),
)
else if (_error != null)
Center(
child: Padding(
padding: const EdgeInsets.all(16.0),
child: Text(
_error!,
style: const TextStyle(color: Colors.red),
),
),
)
else if (_events.isEmpty)
const Center(
child: Padding(
padding: EdgeInsets.all(16.0),
child: Text('暂无活动记录'),
),
)
else
Expanded(
child: ListView.builder(
itemCount: _events.length,
itemBuilder: (context, index) {
final event = _events[index];
return Card(
margin: const EdgeInsets.symmetric(vertical: 4.0),
child: Padding(
padding: const EdgeInsets.all(12.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: [
CircleAvatar(
backgroundImage: NetworkImage(
event.actor.avatarUrl,
),
),
const SizedBox(width: 8),
Text(
event.actor.login,
style: const TextStyle(
fontWeight: FontWeight.bold,
),
),
const SizedBox(width: 8),
Text(_getEventTypeText(event.type)),
],
),
const SizedBox(height: 8),
Text(
event.repo.name,
style: const TextStyle(
color: Colors.blue,
fontWeight: FontWeight.bold,
),
),
if (event.type == 'PushEvent' &&
event.payload.commits != null)
Padding(
padding: const EdgeInsets.only(top: 8.0),
child: _buildCommitContent(
event.payload.commits!,
),
),
const SizedBox(height: 8),
Text(
'时间: ${timeago.format(event.createdAt, locale: 'zh_CN')}',
style: const TextStyle(
fontSize: 12,
color: Colors.grey,
),
),
],
),
),
);
},
),
),
],
),
),
);
}
}