refactor(github_card): 重构 GitHub 卡片组件
- 优化了 GitHub 事件加载和显示逻辑 - 添加了事件类型文本转换功能 - 改进了错误处理和加载状态显示 - 调整了卡片样式和布局
This commit is contained in:
parent
bfedef58f4
commit
f7d2fc10a4
20
README.md
20
README.md
@ -1,16 +1,10 @@
|
|||||||
# dashboard
|
## dashboard
|
||||||
|
|
||||||
A new Flutter project.
|
个人项目信息面板
|
||||||
|
|
||||||
## Getting Started
|
## 配置获取
|
||||||
|
|
||||||
This project is a starting point for a Flutter application.
|
- leetcode:浏览器获取随便找一个xhr请求,从Header中获取cookie,user-slug在个人页面url中
|
||||||
|
- gitea: 用户设置 >> 应用 >> 生成令牌(授予全部权限)
|
||||||
A few resources to get you started if this is your first Flutter project:
|
- kodbox: 参考官方文档[获取accesstoken](https://doc.kodcloud.com/v2/#/user/user?id=%e8%8e%b7%e5%8f%96accesstoken)的方式
|
||||||
|
- github: Settings >> Developer Settings >> Personal access tokens (classic)
|
||||||
- [Lab: Write your first Flutter app](https://docs.flutter.dev/get-started/codelab)
|
|
||||||
- [Cookbook: Useful Flutter samples](https://docs.flutter.dev/cookbook)
|
|
||||||
|
|
||||||
For help getting started with Flutter development, view the
|
|
||||||
[online documentation](https://docs.flutter.dev/), which offers tutorials,
|
|
||||||
samples, guidance on mobile development, and a full API reference.
|
|
||||||
@ -14,101 +14,200 @@ class GithubCard extends StatefulWidget {
|
|||||||
|
|
||||||
class _GithubCardState extends State<GithubCard> {
|
class _GithubCardState extends State<GithubCard> {
|
||||||
final GithubService _githubService = GithubService();
|
final GithubService _githubService = GithubService();
|
||||||
late Future<List<GithubEvent>> _eventsFuture;
|
List<GithubEvent> _events = [];
|
||||||
|
bool _isLoading = false;
|
||||||
|
String? _error;
|
||||||
|
|
||||||
@override
|
String _getEventTypeText(String type) {
|
||||||
void initState() {
|
switch (type) {
|
||||||
super.initState();
|
case 'PushEvent':
|
||||||
_loadEvents();
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void _loadEvents() {
|
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 authService = Provider.of<AuthService>(context, listen: false);
|
||||||
final username = authService.credentials['github_username'];
|
final username = authService.credentials['github_username'];
|
||||||
final token = authService.credentials['github_token'];
|
final token = authService.credentials['github_token'];
|
||||||
|
|
||||||
if (username != null && token != null) {
|
if (username == null || token == null) {
|
||||||
_eventsFuture = _githubService.getUserEvents(username, token);
|
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
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final authService = Provider.of<AuthService>(context);
|
|
||||||
final username = authService.credentials['github_username'];
|
|
||||||
final token = authService.credentials['github_token'];
|
|
||||||
|
|
||||||
if (username == null || token == null) {
|
|
||||||
return const Center(child: Text('请在设置中配置 GitHub 用户名和 Token'));
|
|
||||||
}
|
|
||||||
|
|
||||||
return FutureBuilder<List<GithubEvent>>(
|
|
||||||
future: _eventsFuture,
|
|
||||||
builder: (context, snapshot) {
|
|
||||||
if (snapshot.connectionState == ConnectionState.waiting) {
|
|
||||||
return const Center(child: CircularProgressIndicator());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (snapshot.hasError) {
|
|
||||||
return Center(child: Text('加载失败: ${snapshot.error}'));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!snapshot.hasData || snapshot.data!.isEmpty) {
|
|
||||||
return const Center(child: Text('暂无活动数据'));
|
|
||||||
}
|
|
||||||
|
|
||||||
return ListView.builder(
|
|
||||||
itemCount: snapshot.data!.length,
|
|
||||||
itemBuilder: (context, index) {
|
|
||||||
final event = snapshot.data![index];
|
|
||||||
return Card(
|
return Card(
|
||||||
margin: const EdgeInsets.symmetric(horizontal: 16, vertical: 8),
|
child: Padding(
|
||||||
child: ListTile(
|
padding: const EdgeInsets.all(16.0),
|
||||||
leading: CircleAvatar(
|
child: Column(
|
||||||
backgroundImage: NetworkImage(event.actor.avatarUrl),
|
|
||||||
),
|
|
||||||
title: Text(
|
|
||||||
_getEventTitle(event),
|
|
||||||
style: const TextStyle(fontWeight: FontWeight.bold),
|
|
||||||
),
|
|
||||||
subtitle: Column(
|
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
Text('仓库: ${event.repo.name}'),
|
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(
|
Text(
|
||||||
'时间: ${timeago.format(event.createdAt, locale: "zh_CN")}',
|
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' &&
|
if (event.type == 'PushEvent' &&
|
||||||
event.payload.commits != null)
|
event.payload.commits != null)
|
||||||
...event.payload.commits!.map(
|
Padding(
|
||||||
(commit) => Text(
|
padding: const EdgeInsets.only(top: 8.0),
|
||||||
'提交: ${commit.message}',
|
child: _buildCommitContent(
|
||||||
style: const TextStyle(fontSize: 12),
|
event.payload.commits!,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(height: 8),
|
||||||
|
Text(
|
||||||
|
'时间: ${timeago.format(event.createdAt, locale: 'zh_CN')}',
|
||||||
|
style: const TextStyle(
|
||||||
|
fontSize: 12,
|
||||||
|
color: Colors.grey,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
isThreeLine: true,
|
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
);
|
);
|
||||||
},
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
String _getEventTitle(GithubEvent event) {
|
|
||||||
switch (event.type) {
|
|
||||||
case 'WatchEvent':
|
|
||||||
return '${event.actor.login} 关注了 ${event.repo.name}';
|
|
||||||
case 'PushEvent':
|
|
||||||
return '${event.actor.login} 推送了代码到 ${event.repo.name}';
|
|
||||||
case 'CreateEvent':
|
|
||||||
return '${event.actor.login} 创建了 ${event.repo.name}';
|
|
||||||
case 'ForkEvent':
|
|
||||||
return '${event.actor.login} Fork 了 ${event.repo.name}';
|
|
||||||
default:
|
|
||||||
return '${event.actor.login} 在 ${event.repo.name} 进行了 ${event.type} 操作';
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user