1
0
mirror of https://github.com/git-touch/git-touch synced 2025-02-20 13:30:38 +01:00

feat(gitee): repo screen

This commit is contained in:
Rongjian Zhang 2020-10-17 19:06:11 +08:00
parent a5d64fdb86
commit 66ab665f31
6 changed files with 171 additions and 5 deletions

View File

@ -34,6 +34,7 @@ class GiteeListUser {
@JsonSerializable(fieldRename: FieldRename.snake)
class GiteeRepo {
GiteeRepoNamespace namespace;
GiteeRepoOwner owner;
String path;
String description;
@ -45,6 +46,10 @@ class GiteeRepo {
int stargazersCount;
int watchersCount;
DateTime updatedAt;
String license;
String homepage;
int openIssuesCount;
bool pullRequestsEnabled;
GiteeRepo();
factory GiteeRepo.fromJson(Map<String, dynamic> json) =>
_$GiteeRepoFromJson(json);
@ -58,3 +63,11 @@ class GiteeRepoOwner {
factory GiteeRepoOwner.fromJson(Map<String, dynamic> json) =>
_$GiteeRepoOwnerFromJson(json);
}
@JsonSerializable(fieldRename: FieldRename.snake)
class GiteeRepoNamespace {
String path;
GiteeRepoNamespace();
factory GiteeRepoNamespace.fromJson(Map<String, dynamic> json) =>
_$GiteeRepoNamespaceFromJson(json);
}

View File

@ -57,6 +57,9 @@ Map<String, dynamic> _$GiteeListUserToJson(GiteeListUser instance) =>
GiteeRepo _$GiteeRepoFromJson(Map<String, dynamic> json) {
return GiteeRepo()
..namespace = json['namespace'] == null
? null
: GiteeRepoNamespace.fromJson(json['namespace'] as Map<String, dynamic>)
..owner = json['owner'] == null
? null
: GiteeRepoOwner.fromJson(json['owner'] as Map<String, dynamic>)
@ -71,10 +74,15 @@ GiteeRepo _$GiteeRepoFromJson(Map<String, dynamic> json) {
..watchersCount = json['watchers_count'] as int
..updatedAt = json['updated_at'] == null
? null
: DateTime.parse(json['updated_at'] as String);
: DateTime.parse(json['updated_at'] as String)
..license = json['license'] as String
..homepage = json['homepage'] as String
..openIssuesCount = json['open_issues_count'] as int
..pullRequestsEnabled = json['pull_requests_enabled'] as bool;
}
Map<String, dynamic> _$GiteeRepoToJson(GiteeRepo instance) => <String, dynamic>{
'namespace': instance.namespace,
'owner': instance.owner,
'path': instance.path,
'description': instance.description,
@ -86,6 +94,10 @@ Map<String, dynamic> _$GiteeRepoToJson(GiteeRepo instance) => <String, dynamic>{
'stargazers_count': instance.stargazersCount,
'watchers_count': instance.watchersCount,
'updated_at': instance.updatedAt?.toIso8601String(),
'license': instance.license,
'homepage': instance.homepage,
'open_issues_count': instance.openIssuesCount,
'pull_requests_enabled': instance.pullRequestsEnabled,
};
GiteeRepoOwner _$GiteeRepoOwnerFromJson(Map<String, dynamic> json) {
@ -99,3 +111,12 @@ Map<String, dynamic> _$GiteeRepoOwnerToJson(GiteeRepoOwner instance) =>
'login': instance.login,
'avatar_url': instance.avatarUrl,
};
GiteeRepoNamespace _$GiteeRepoNamespaceFromJson(Map<String, dynamic> json) {
return GiteeRepoNamespace()..path = json['path'] as String;
}
Map<String, dynamic> _$GiteeRepoNamespaceToJson(GiteeRepoNamespace instance) =>
<String, dynamic>{
'path': instance.path,
};

View File

@ -6,6 +6,7 @@ import 'package:git_touch/screens/bb_issues.dart';
import 'package:git_touch/screens/bb_pulls.dart';
import 'package:git_touch/screens/bb_user.dart';
import 'package:git_touch/screens/code_theme.dart';
import 'package:git_touch/screens/ge_repo.dart';
import 'package:git_touch/screens/ge_repos.dart';
import 'package:git_touch/screens/ge_user.dart';
import 'package:git_touch/screens/ge_users.dart';
@ -379,6 +380,10 @@ class GiteeRouter {
static const prefix = '/gitee';
static final routes = [
GiteeRouter.user,
GiteeRouter.repo,
GiteeRouter.stargazers,
GiteeRouter.watchers,
GiteeRouter.forks,
];
static final user = RouterScreen('/:login', (context, p) {
final login = p['login'].first;
@ -397,4 +402,18 @@ class GiteeRouter {
return GeUserScreen(login);
}
});
static final repo = RouterScreen(
'/:owner/:name',
(context, params) =>
GeRepoScreen(params['owner'].first, params['name'].first),
);
static final stargazers = RouterScreen('/:owner/:name/stargazers', (_, p) {
return GeUsersScreen.stargazers(p['owner'].first, p['name'].first);
});
static final watchers = RouterScreen('/:owner/:name/watchers', (_, p) {
return GeUsersScreen.watchers(p['owner'].first, p['name'].first);
});
static final forks = RouterScreen('/:owner/:name/forks', (_, p) {
return GeReposScreen.forks(p['owner'].first, p['name'].first);
});
}

110
lib/screens/ge_repo.dart Normal file
View File

@ -0,0 +1,110 @@
import 'package:flutter/material.dart';
import 'package:git_touch/models/auth.dart';
import 'package:git_touch/models/gitee.dart';
import 'package:git_touch/models/theme.dart';
import 'package:git_touch/scaffolds/refresh_stateful.dart';
import 'package:git_touch/utils/utils.dart';
import 'package:git_touch/widgets/app_bar_title.dart';
import 'package:git_touch/widgets/entry_item.dart';
import 'package:git_touch/widgets/markdown_view.dart';
import 'package:git_touch/widgets/repo_header.dart';
import 'package:git_touch/widgets/table_view.dart';
import 'package:provider/provider.dart';
import 'package:tuple/tuple.dart';
class GeRepoScreen extends StatelessWidget {
final String owner;
final String name;
GeRepoScreen(this.owner, this.name);
@override
Widget build(BuildContext context) {
return RefreshStatefulScaffold<Tuple2<GiteeRepo, String>>(
title: AppBarTitle('Repository'),
fetch: () async {
final auth = context.read<AuthModel>();
final res = await Future.wait([
auth.fetchGitee('/repos/$owner/$name'),
auth.fetchGitee('/repos/$owner/$name/readme'),
]);
return Tuple2(
GiteeRepo.fromJson(res[0]),
(res[1]['content'] as String)?.base64ToUtf8,
);
},
bodyBuilder: (t, setState) {
final theme = Provider.of<ThemeModel>(context);
final p = t.item1;
return Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
RepoHeader(
avatarUrl: p.owner.avatarUrl,
avatarLink: '/gitee/${p.namespace.path}',
owner: p.namespace.path,
name: p.path,
description: p.description,
homepageUrl: p.homepage,
),
CommonStyle.border,
Row(
children: <Widget>[
EntryItem(
text: 'Watchers',
url: '/gitee/$owner/$name/watchers',
),
EntryItem(
count: p.stargazersCount,
text: 'Stars',
url: '/gitee/$owner/$name/stargazers',
),
EntryItem(
count: p.forksCount,
text: 'Forks',
url: '/gitee/$owner/$name/forks',
),
],
),
CommonStyle.border,
TableView(
hasIcon: true,
items: [
TableViewItem(
leftIconData: Octicons.code,
text: Text('Code'),
rightWidget: Text(p.license ?? ''),
url: '/gitee/$owner/$name/blob',
),
TableViewItem(
leftIconData: Octicons.issue_opened,
text: Text('Issues'),
rightWidget: Text(numberFormat.format(p.openIssuesCount)),
url: 'https://gitee.com/$owner/$name/issues', // TODO:
),
if (p.pullRequestsEnabled)
TableViewItem(
leftIconData: Octicons.git_pull_request,
text: Text('Pull requests'),
url: 'https://gitee.com/$owner/$name/pulls', // TODO:
),
TableViewItem(
leftIconData: Octicons.history,
text: Text('Commits'),
url: '/gitee/$owner/$name/commits',
),
],
),
CommonStyle.verticalGap,
if (t.item2 != null)
Container(
padding: CommonStyle.padding,
color: theme.palette.background,
child: MarkdownView(t.item2),
),
CommonStyle.verticalGap,
],
);
},
);
}
}

View File

@ -17,6 +17,9 @@ class GeReposScreen extends StatelessWidget {
GeReposScreen.star(String owner)
: api = '/users/$owner/starred',
title = 'Stars';
GeReposScreen.forks(String owner, String name)
: api = '/repos/$owner/$name/forks',
title = 'Forks';
@override
Widget build(BuildContext context) {

View File

@ -92,7 +92,7 @@ class GeUserScreen extends StatelessWidget {
// TableViewItem(
// leftIconData: Octicons.home,
// text: Text('Organizations'),
// url: '/gitea/$login?tab=organizations',
// url: '/gitee/$login?tab=organizations',
// ),
// ],
// ),
@ -101,15 +101,15 @@ class GeUserScreen extends StatelessWidget {
children: <Widget>[
for (var v in repos)
RepositoryItem(
owner: v.owner.login,
owner: v.namespace.path,
avatarUrl: v.owner.avatarUrl,
name: v.path,
description: v.description,
starCount: v.stargazersCount,
forkCount: v.forksCount,
note: 'Updated ${timeago.format(v.updatedAt)}',
url: '/gitea/${v.owner.login}/${v.path}',
avatarLink: '/gitea/${v.owner.login}',
url: '/gitee/${v.namespace.path}/${v.path}',
avatarLink: '/gitee/${v.namespace.path}',
// iconData: , TODO:
)
],