feat(gitee): branches, labels, contributors, refactor(RouterScreen) (#153)
* feat: labels, contributors, fix: bio in search * feat: branch, cancel/confirm to showPicker * refactor(router): RouterScreen fallback params
This commit is contained in:
parent
85a393dd2e
commit
f723eef83a
|
@ -124,6 +124,15 @@ class GiteeBlob {
|
|||
_$GiteeBlobFromJson(json);
|
||||
}
|
||||
|
||||
@JsonSerializable(fieldRename: FieldRename.snake)
|
||||
class GiteeLabel {
|
||||
String color;
|
||||
String name;
|
||||
GiteeLabel();
|
||||
factory GiteeLabel.fromJson(Map<String, dynamic> json) =>
|
||||
_$GiteeLabelFromJson(json);
|
||||
}
|
||||
|
||||
@JsonSerializable(fieldRename: FieldRename.snake)
|
||||
class GiteeIssue {
|
||||
int comments;
|
||||
|
@ -138,6 +147,7 @@ class GiteeIssue {
|
|||
GiteeRepo repository;
|
||||
GiteeRepoOwner user;
|
||||
String number;
|
||||
List<GiteeLabel> labels;
|
||||
int id;
|
||||
GiteeIssue();
|
||||
factory GiteeIssue.fromJson(Map<String, dynamic> json) =>
|
||||
|
@ -155,6 +165,7 @@ class GiteePull {
|
|||
String title;
|
||||
String state;
|
||||
GiteeRepoOwner user;
|
||||
List<GiteeLabel> labels;
|
||||
int number;
|
||||
int id;
|
||||
GiteePull();
|
||||
|
@ -211,3 +222,20 @@ class GiteeCommitFile {
|
|||
factory GiteeCommitFile.fromJson(Map<String, dynamic> json) =>
|
||||
_$GiteeCommitFileFromJson(json);
|
||||
}
|
||||
|
||||
@JsonSerializable(fieldRename: FieldRename.snake)
|
||||
class GiteeContributor {
|
||||
String name;
|
||||
int contributions;
|
||||
GiteeContributor();
|
||||
factory GiteeContributor.fromJson(Map<String, dynamic> json) =>
|
||||
_$GiteeContributorFromJson(json);
|
||||
}
|
||||
|
||||
@JsonSerializable(fieldRename: FieldRename.snake)
|
||||
class GiteeBranch {
|
||||
String name;
|
||||
GiteeBranch();
|
||||
factory GiteeBranch.fromJson(Map<String, dynamic> json) =>
|
||||
_$GiteeBranchFromJson(json);
|
||||
}
|
||||
|
|
|
@ -206,6 +206,18 @@ Map<String, dynamic> _$GiteeBlobToJson(GiteeBlob instance) => <String, dynamic>{
|
|||
'content': instance.content,
|
||||
};
|
||||
|
||||
GiteeLabel _$GiteeLabelFromJson(Map<String, dynamic> json) {
|
||||
return GiteeLabel()
|
||||
..color = json['color'] as String
|
||||
..name = json['name'] as String;
|
||||
}
|
||||
|
||||
Map<String, dynamic> _$GiteeLabelToJson(GiteeLabel instance) =>
|
||||
<String, dynamic>{
|
||||
'color': instance.color,
|
||||
'name': instance.name,
|
||||
};
|
||||
|
||||
GiteeIssue _$GiteeIssueFromJson(Map<String, dynamic> json) {
|
||||
return GiteeIssue()
|
||||
..comments = json['comments'] as int
|
||||
|
@ -224,6 +236,10 @@ GiteeIssue _$GiteeIssueFromJson(Map<String, dynamic> json) {
|
|||
? null
|
||||
: GiteeRepoOwner.fromJson(json['user'] as Map<String, dynamic>)
|
||||
..number = json['number'] as String
|
||||
..labels = (json['labels'] as List)
|
||||
?.map((e) =>
|
||||
e == null ? null : GiteeLabel.fromJson(e as Map<String, dynamic>))
|
||||
?.toList()
|
||||
..id = json['id'] as int;
|
||||
}
|
||||
|
||||
|
@ -241,6 +257,7 @@ Map<String, dynamic> _$GiteeIssueToJson(GiteeIssue instance) =>
|
|||
'repository': instance.repository,
|
||||
'user': instance.user,
|
||||
'number': instance.number,
|
||||
'labels': instance.labels,
|
||||
'id': instance.id,
|
||||
};
|
||||
|
||||
|
@ -257,6 +274,10 @@ GiteePull _$GiteePullFromJson(Map<String, dynamic> json) {
|
|||
..user = json['user'] == null
|
||||
? null
|
||||
: GiteeRepoOwner.fromJson(json['user'] as Map<String, dynamic>)
|
||||
..labels = (json['labels'] as List)
|
||||
?.map((e) =>
|
||||
e == null ? null : GiteeLabel.fromJson(e as Map<String, dynamic>))
|
||||
?.toList()
|
||||
..number = json['number'] as int
|
||||
..id = json['id'] as int;
|
||||
}
|
||||
|
@ -271,6 +292,7 @@ Map<String, dynamic> _$GiteePullToJson(GiteePull instance) => <String, dynamic>{
|
|||
'title': instance.title,
|
||||
'state': instance.state,
|
||||
'user': instance.user,
|
||||
'labels': instance.labels,
|
||||
'number': instance.number,
|
||||
'id': instance.id,
|
||||
};
|
||||
|
@ -349,3 +371,24 @@ Map<String, dynamic> _$GiteeCommitFileToJson(GiteeCommitFile instance) =>
|
|||
'status': instance.status,
|
||||
'patch': instance.patch,
|
||||
};
|
||||
|
||||
GiteeContributor _$GiteeContributorFromJson(Map<String, dynamic> json) {
|
||||
return GiteeContributor()
|
||||
..name = json['name'] as String
|
||||
..contributions = json['contributions'] as int;
|
||||
}
|
||||
|
||||
Map<String, dynamic> _$GiteeContributorToJson(GiteeContributor instance) =>
|
||||
<String, dynamic>{
|
||||
'name': instance.name,
|
||||
'contributions': instance.contributions,
|
||||
};
|
||||
|
||||
GiteeBranch _$GiteeBranchFromJson(Map<String, dynamic> json) {
|
||||
return GiteeBranch()..name = json['name'] as String;
|
||||
}
|
||||
|
||||
Map<String, dynamic> _$GiteeBranchToJson(GiteeBranch instance) =>
|
||||
<String, dynamic>{
|
||||
'name': instance.name,
|
||||
};
|
||||
|
|
|
@ -317,39 +317,80 @@ class ThemeModel with ChangeNotifier {
|
|||
await showCupertinoModalPopup(
|
||||
context: context,
|
||||
builder: (context) {
|
||||
return Container(
|
||||
height: 216,
|
||||
child: CupertinoPicker(
|
||||
backgroundColor: palette.background,
|
||||
children: <Widget>[
|
||||
for (var v in groupItem.items)
|
||||
Text(v.text, style: TextStyle(color: palette.text)),
|
||||
],
|
||||
itemExtent: 40,
|
||||
scrollController: FixedExtentScrollController(
|
||||
initialItem: groupItem.items
|
||||
.toList()
|
||||
.indexWhere((v) => v.value == groupItem.value)),
|
||||
onSelectedItemChanged: (index) {
|
||||
_selectedItem = groupItem.items[index].value;
|
||||
return Column(
|
||||
mainAxisAlignment: MainAxisAlignment.end,
|
||||
children: [
|
||||
Container(
|
||||
alignment: Alignment.bottomCenter,
|
||||
decoration: BoxDecoration(
|
||||
color: palette.background,
|
||||
border: Border(
|
||||
bottom: BorderSide(
|
||||
color: palette.grayBackground,
|
||||
width: 0.0,
|
||||
),
|
||||
),
|
||||
),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: <Widget>[
|
||||
CupertinoButton(
|
||||
child: Text('Cancel'),
|
||||
onPressed: () {
|
||||
Navigator.pop(context);
|
||||
_selectedItem = groupItem.value;
|
||||
},
|
||||
padding: const EdgeInsets.symmetric(
|
||||
horizontal: 16.0,
|
||||
vertical: 5.0,
|
||||
),
|
||||
),
|
||||
CupertinoButton(
|
||||
child: Text('Confirm'),
|
||||
onPressed: () {
|
||||
Navigator.pop(context);
|
||||
groupItem.onClose(_selectedItem);
|
||||
},
|
||||
padding: const EdgeInsets.symmetric(
|
||||
horizontal: 16.0,
|
||||
vertical: 5.0,
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
Container(
|
||||
height: 216,
|
||||
child: CupertinoPicker(
|
||||
backgroundColor: palette.background,
|
||||
children: <Widget>[
|
||||
for (var v in groupItem.items)
|
||||
Text(v.text, style: TextStyle(color: palette.text)),
|
||||
],
|
||||
itemExtent: 40,
|
||||
scrollController: FixedExtentScrollController(
|
||||
initialItem: groupItem.items
|
||||
.toList()
|
||||
.indexWhere((v) => v.value == groupItem.value)),
|
||||
onSelectedItemChanged: (index) {
|
||||
_selectedItem = groupItem.items[index].value;
|
||||
|
||||
if (groupItem.onChange != null) {
|
||||
if (_debounce?.isActive ?? false) {
|
||||
_debounce.cancel();
|
||||
}
|
||||
if (groupItem.onChange != null) {
|
||||
if (_debounce?.isActive ?? false) {
|
||||
_debounce.cancel();
|
||||
}
|
||||
|
||||
_debounce = Timer(const Duration(milliseconds: 500), () {
|
||||
groupItem.onChange(_selectedItem);
|
||||
});
|
||||
}
|
||||
},
|
||||
),
|
||||
_debounce = Timer(const Duration(milliseconds: 500), () {
|
||||
groupItem.onChange(_selectedItem);
|
||||
});
|
||||
}
|
||||
},
|
||||
),
|
||||
)
|
||||
],
|
||||
);
|
||||
},
|
||||
);
|
||||
if (groupItem.onClose != null) {
|
||||
groupItem.onClose(_selectedItem);
|
||||
}
|
||||
}
|
||||
|
||||
showActions(BuildContext context, List<ActionItem> actionItems) async {
|
||||
|
|
328
lib/router.dart
328
lib/router.dart
|
@ -12,6 +12,7 @@ import 'package:git_touch/screens/code_theme.dart';
|
|||
import 'package:git_touch/screens/ge_blob.dart';
|
||||
import 'package:git_touch/screens/ge_commit.dart';
|
||||
import 'package:git_touch/screens/ge_commits.dart';
|
||||
import 'package:git_touch/screens/ge_contributors.dart';
|
||||
import 'package:git_touch/screens/ge_files.dart';
|
||||
import 'package:git_touch/screens/ge_issue.dart';
|
||||
import 'package:git_touch/screens/ge_issue_comment.dart';
|
||||
|
@ -81,10 +82,12 @@ class CommonRouter {
|
|||
CommonRouter.login,
|
||||
CommonRouter.settings
|
||||
];
|
||||
static final codeTheme = RouterScreen('/choose-code-theme', (context, p) {
|
||||
static final codeTheme =
|
||||
RouterScreen('/choose-code-theme', (context, parameters) {
|
||||
return CodeThemeScreen();
|
||||
});
|
||||
static final login = RouterScreen('/login', (context, p) => LoginScreen());
|
||||
static final login =
|
||||
RouterScreen('/login', (context, parameters) => LoginScreen());
|
||||
static final settings =
|
||||
RouterScreen('/settings', (context, parameters) => SettingsScreen());
|
||||
}
|
||||
|
@ -109,9 +112,9 @@ class GithubRouter {
|
|||
GithubRouter.gistObject,
|
||||
GithubRouter.compare,
|
||||
];
|
||||
static final user = RouterScreen('/:login', (_, p) {
|
||||
final login = p['login'].first;
|
||||
final tab = p['tab']?.first;
|
||||
static final user = RouterScreen('/:login', (context, parameters) {
|
||||
final login = parameters['login'].first;
|
||||
final tab = parameters['tab']?.first;
|
||||
switch (tab) {
|
||||
case 'followers':
|
||||
return GhUsersScreen(login, UsersScreenType.follower);
|
||||
|
@ -135,75 +138,93 @@ class GithubRouter {
|
|||
return GhUserScreen(login);
|
||||
}
|
||||
});
|
||||
static final repo = RouterScreen('/:owner/:name', (_, p) {
|
||||
if (p['ref'] == null) {
|
||||
return GhRepoScreen(p['owner'].first, p['name'].first);
|
||||
static final repo = RouterScreen('/:owner/:name', (context, parameters) {
|
||||
if (parameters['ref'] == null) {
|
||||
return GhRepoScreen(parameters['owner'].first, parameters['name'].first);
|
||||
} else {
|
||||
return GhRepoScreen(p['owner'].first, p['name'].first,
|
||||
branch: p['ref'].first);
|
||||
return GhRepoScreen(parameters['owner'].first, parameters['name'].first,
|
||||
branch: parameters['ref'].first);
|
||||
}
|
||||
});
|
||||
static final gistObject = RouterScreen('/:login/gists/:id/:file', (_, p) {
|
||||
static final gistObject =
|
||||
RouterScreen('/:login/gists/:id/:file', (context, parameters) {
|
||||
return GistObjectScreen(
|
||||
p['login'].first,
|
||||
p['id'].first,
|
||||
p['file'].first,
|
||||
raw: p['raw']?.first,
|
||||
content: p['content'].first,
|
||||
parameters['login'].first,
|
||||
parameters['id'].first,
|
||||
parameters['file'].first,
|
||||
raw: parameters['raw']?.first,
|
||||
content: parameters['content'].first,
|
||||
);
|
||||
});
|
||||
static final gistFiles = RouterScreen('/:login/gists/:id', (_, p) {
|
||||
return GhGistsFilesScreen(p['login'].first, p['id'].first);
|
||||
static final gistFiles =
|
||||
RouterScreen('/:login/gists/:id', (context, parameters) {
|
||||
return GhGistsFilesScreen(
|
||||
parameters['login'].first, parameters['id'].first);
|
||||
});
|
||||
static final issueAdd = RouterScreen('/:owner/:name/issues/new', (_, p) {
|
||||
return GhIssueFormScreen(p['owner'].first, p['name'].first);
|
||||
static final issueAdd =
|
||||
RouterScreen('/:owner/:name/issues/new', (context, parameters) {
|
||||
return GhIssueFormScreen(
|
||||
parameters['owner'].first, parameters['name'].first);
|
||||
});
|
||||
static final issues = RouterScreen('/:owner/:name/issues',
|
||||
(context, p) => GhIssuesScreen(p['owner'].first, p['name'].first));
|
||||
static final pulls = RouterScreen('/:owner/:name/pulls',
|
||||
(context, p) => GhPullsScreen(p['owner'].first, p['name'].first));
|
||||
static final issues = RouterScreen(
|
||||
'/:owner/:name/issues',
|
||||
(context, parameters) =>
|
||||
GhIssuesScreen(parameters['owner'].first, parameters['name'].first));
|
||||
static final pulls = RouterScreen(
|
||||
'/:owner/:name/pulls',
|
||||
(context, parameters) =>
|
||||
GhPullsScreen(parameters['owner'].first, parameters['name'].first));
|
||||
static final issue = RouterScreen(
|
||||
'/:owner/:name/issues/:number',
|
||||
(context, p) => GhIssueScreen(
|
||||
p['owner'].first, p['name'].first, int.parse(p['number'].first)));
|
||||
(context, parameters) => GhIssueScreen(parameters['owner'].first,
|
||||
parameters['name'].first, int.parse(parameters['number'].first)));
|
||||
static final pull = RouterScreen(
|
||||
'/:owner/:name/pull/:number',
|
||||
(context, p) => GhIssueScreen(
|
||||
p['owner'].first, p['name'].first, int.parse(p['number'].first),
|
||||
(context, parameters) => GhIssueScreen(parameters['owner'].first,
|
||||
parameters['name'].first, int.parse(parameters['number'].first),
|
||||
isPullRequest: true));
|
||||
static final files = RouterScreen(
|
||||
'/:owner/:name/pull/:number/files',
|
||||
(context, p) => GhFilesScreen(
|
||||
p['owner'].first,
|
||||
p['name'].first,
|
||||
int.parse(p['number'].first),
|
||||
(context, parameters) => GhFilesScreen(
|
||||
parameters['owner'].first,
|
||||
parameters['name'].first,
|
||||
int.parse(parameters['number'].first),
|
||||
));
|
||||
static final compare = RouterScreen(
|
||||
'/:owner/:name/compare/:before/:head',
|
||||
(context, p) => GhComparisonScreen(p['owner'].first, p['name'].first,
|
||||
p['before'].first, p['head'].first));
|
||||
static final commits = RouterScreen('/:owner/:name/commits',
|
||||
(context, p) => GhCommitsScreen(p['owner'].first, p['name'].first));
|
||||
static final object = RouterScreen('/:owner/:name/blob/:ref', (_, p) {
|
||||
(context, parameters) => GhComparisonScreen(
|
||||
parameters['owner'].first,
|
||||
parameters['name'].first,
|
||||
parameters['before'].first,
|
||||
parameters['head'].first));
|
||||
static final commits = RouterScreen(
|
||||
'/:owner/:name/commits',
|
||||
(context, parameters) =>
|
||||
GhCommitsScreen(parameters['owner'].first, parameters['name'].first));
|
||||
static final object =
|
||||
RouterScreen('/:owner/:name/blob/:ref', (context, parameters) {
|
||||
return GhObjectScreen(
|
||||
p['owner'].first,
|
||||
p['name'].first,
|
||||
p['ref'].first,
|
||||
path: p['path']?.first,
|
||||
raw: p['raw']?.first,
|
||||
parameters['owner'].first,
|
||||
parameters['name'].first,
|
||||
parameters['ref'].first,
|
||||
path: parameters['path']?.first,
|
||||
raw: parameters['raw']?.first,
|
||||
);
|
||||
});
|
||||
static final stargazers = RouterScreen('/:owner/:name/stargazers', (_, p) {
|
||||
return GhUsersScreen(p['owner'].first, UsersScreenType.star,
|
||||
repoName: p['name'].first);
|
||||
static final stargazers =
|
||||
RouterScreen('/:owner/:name/stargazers', (context, parameters) {
|
||||
return GhUsersScreen(parameters['owner'].first, UsersScreenType.star,
|
||||
repoName: parameters['name'].first);
|
||||
});
|
||||
static final watchers = RouterScreen('/:owner/:name/watchers', (_, p) {
|
||||
return GhUsersScreen(p['owner'].first, UsersScreenType.watch,
|
||||
repoName: p['name'].first);
|
||||
static final watchers =
|
||||
RouterScreen('/:owner/:name/watchers', (context, parameters) {
|
||||
return GhUsersScreen(parameters['owner'].first, UsersScreenType.watch,
|
||||
repoName: parameters['name'].first);
|
||||
});
|
||||
static final contributors =
|
||||
RouterScreen('/:owner/:name/contributors', (_, p) {
|
||||
return GhContributorsScreen(p['owner'].first, p['name'].first);
|
||||
RouterScreen('/:owner/:name/contributors', (context, parameters) {
|
||||
return GhContributorsScreen(
|
||||
parameters['owner'].first, parameters['name'].first);
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -224,44 +245,50 @@ class GitlabRouter {
|
|||
GitlabRouter.groupMembers,
|
||||
GitlabRouter.issue,
|
||||
];
|
||||
static final user = RouterScreen(
|
||||
'/user/:id', (context, p) => GlUserScreen(int.parse(p['id'].first)));
|
||||
static final user = RouterScreen('/user/:id',
|
||||
(context, parameters) => GlUserScreen(int.parse(parameters['id'].first)));
|
||||
static final group = RouterScreen(
|
||||
'/group/:id', (context, p) => GlGroupScreen(int.parse(p['id'].first)));
|
||||
'/group/:id',
|
||||
(context, parameters) =>
|
||||
GlGroupScreen(int.parse(parameters['id'].first)));
|
||||
static final blob = RouterScreen(
|
||||
'/projects/:id/blob/:ref',
|
||||
(context, params) => GlBlobScreen(
|
||||
int.parse(params['id'].first), params['ref'].first,
|
||||
path: params['path']?.first));
|
||||
(context, parameters) => GlBlobScreen(
|
||||
int.parse(parameters['id'].first), parameters['ref'].first,
|
||||
path: parameters['path']?.first));
|
||||
static final tree = RouterScreen(
|
||||
'/projects/:id/tree/:ref',
|
||||
(context, params) => GlTreeScreen(
|
||||
int.parse(params['id'].first), params['ref'].first,
|
||||
path: params['path']?.first));
|
||||
static final project = RouterScreen('/projects/:id',
|
||||
(context, params) => GlProjectScreen(int.parse(params['id'].first)));
|
||||
static final starrers = RouterScreen('/projects/:id/starrers',
|
||||
(context, params) => GlStarrersScreen(int.parse(params['id'].first)));
|
||||
(context, parameters) => GlTreeScreen(
|
||||
int.parse(parameters['id'].first), parameters['ref'].first,
|
||||
path: parameters['path']?.first));
|
||||
static final project = RouterScreen(
|
||||
'/projects/:id',
|
||||
(context, parameters) =>
|
||||
GlProjectScreen(int.parse(parameters['id'].first)));
|
||||
static final starrers = RouterScreen(
|
||||
'/projects/:id/starrers',
|
||||
(context, parameters) =>
|
||||
GlStarrersScreen(int.parse(parameters['id'].first)));
|
||||
static final issues = RouterScreen(
|
||||
'/projects/:id/issues',
|
||||
(context, params) => GlIssuesScreen(
|
||||
params['id'].first,
|
||||
prefix: params['prefix'].first,
|
||||
(context, parameters) => GlIssuesScreen(
|
||||
parameters['id'].first,
|
||||
prefix: parameters['prefix'].first,
|
||||
));
|
||||
static final mergeRequests = RouterScreen(
|
||||
'/projects/:id/merge_requests',
|
||||
(context, params) => GlMergeRequestsScreen(
|
||||
params['id'].first,
|
||||
prefix: params['prefix'].first,
|
||||
(context, parameters) => GlMergeRequestsScreen(
|
||||
parameters['id'].first,
|
||||
prefix: parameters['prefix'].first,
|
||||
));
|
||||
static final commits = RouterScreen(
|
||||
'/projects/:id/commits',
|
||||
(context, params) =>
|
||||
GlCommitsScreen(params['id'].first, prefix: params['prefix'].first));
|
||||
(context, parameters) => GlCommitsScreen(parameters['id'].first,
|
||||
prefix: parameters['prefix'].first));
|
||||
static final commit = RouterScreen(
|
||||
'/projects/:id/commit/:sha',
|
||||
(context, params) =>
|
||||
GlCommitScreen(params['id'].first, sha: params['sha'].first));
|
||||
(context, parameters) =>
|
||||
GlCommitScreen(parameters['id'].first, sha: parameters['sha'].first));
|
||||
static final projectMembers = RouterScreen(
|
||||
'/projects/:id/members',
|
||||
(context, parameters) =>
|
||||
|
@ -272,10 +299,10 @@ class GitlabRouter {
|
|||
GlMembersScreen(int.parse(parameters['id'].first), 'groups'));
|
||||
static final issue = RouterScreen(
|
||||
'/gitlab/projects/:id/issues/:iid',
|
||||
(context, params) {
|
||||
(context, parameters) {
|
||||
return GlIssueScreen(
|
||||
int.parse(params['id'].first),
|
||||
int.parse(params['iid'].first),
|
||||
int.parse(parameters['id'].first),
|
||||
int.parse(parameters['iid'].first),
|
||||
);
|
||||
},
|
||||
);
|
||||
|
@ -297,9 +324,9 @@ class GiteaRouter {
|
|||
];
|
||||
static final status =
|
||||
RouterScreen('/status', (context, parameters) => GtStatusScreen());
|
||||
static final user = RouterScreen('/:login', (context, p) {
|
||||
final login = p['login'].first;
|
||||
final tab = p['tab']?.first;
|
||||
static final user = RouterScreen('/:login', (context, parameters) {
|
||||
final login = parameters['login'].first;
|
||||
final tab = parameters['tab']?.first;
|
||||
switch (tab) {
|
||||
case 'followers':
|
||||
return GtUsersScreen.followers(login);
|
||||
|
@ -321,32 +348,45 @@ class GiteaRouter {
|
|||
});
|
||||
static final repo = RouterScreen(
|
||||
'/:owner/:name',
|
||||
(context, params) =>
|
||||
GtRepoScreen(params['owner'].first, params['name'].first),
|
||||
(context, parameters) =>
|
||||
GtRepoScreen(parameters['owner'].first, parameters['name'].first),
|
||||
);
|
||||
static final object = RouterScreen(
|
||||
'/:owner/:name/blob',
|
||||
(context, params) => GtObjectScreen(
|
||||
params['owner'].first,
|
||||
params['name'].first,
|
||||
path: params['path']?.first,
|
||||
(context, parameters) => GtObjectScreen(
|
||||
parameters['owner'].first,
|
||||
parameters['name'].first,
|
||||
path: parameters['path']?.first,
|
||||
),
|
||||
);
|
||||
static final stargazers = RouterScreen('/:owner/:name/stargazers', (_, p) {
|
||||
return GtUsersScreen.stargazers(p['owner'].first, p['name'].first);
|
||||
static final stargazers =
|
||||
RouterScreen('/:owner/:name/stargazers', (context, parameters) {
|
||||
return GtUsersScreen.stargazers(
|
||||
parameters['owner'].first, parameters['name'].first);
|
||||
});
|
||||
static final watchers = RouterScreen('/:owner/:name/watchers', (_, p) {
|
||||
return GtUsersScreen.watchers(p['owner'].first, p['name'].first);
|
||||
static final watchers =
|
||||
RouterScreen('/:owner/:name/watchers', (context, parameters) {
|
||||
return GtUsersScreen.watchers(
|
||||
parameters['owner'].first, parameters['name'].first);
|
||||
});
|
||||
static final forks = RouterScreen('/:owner/:name/forks', (_, p) {
|
||||
return GtReposScreen.forks(p['owner'].first, p['name'].first);
|
||||
static final forks =
|
||||
RouterScreen('/:owner/:name/forks', (context, parameters) {
|
||||
return GtReposScreen.forks(
|
||||
parameters['owner'].first, parameters['name'].first);
|
||||
});
|
||||
static final commits = RouterScreen('/:owner/:name/commits',
|
||||
(_, p) => GtCommitsScreen(p['owner'].first, p['name'].first));
|
||||
static final issues = RouterScreen('/:owner/:name/issues',
|
||||
(_, p) => GtIssuesScreen(p['owner'].first, p['name'].first));
|
||||
static final pulls = RouterScreen('/:owner/:name/pulls',
|
||||
(_, p) => GtIssuesScreen(p['owner'].first, p['name'].first, isPr: true));
|
||||
static final commits = RouterScreen(
|
||||
'/:owner/:name/commits',
|
||||
(context, parameters) =>
|
||||
GtCommitsScreen(parameters['owner'].first, parameters['name'].first));
|
||||
static final issues = RouterScreen(
|
||||
'/:owner/:name/issues',
|
||||
(context, parameters) =>
|
||||
GtIssuesScreen(parameters['owner'].first, parameters['name'].first));
|
||||
static final pulls = RouterScreen(
|
||||
'/:owner/:name/pulls',
|
||||
(context, parameters) => GtIssuesScreen(
|
||||
parameters['owner'].first, parameters['name'].first,
|
||||
isPr: true));
|
||||
}
|
||||
|
||||
class BitbucketRouter {
|
||||
|
@ -364,40 +404,46 @@ class BitbucketRouter {
|
|||
];
|
||||
static final user = RouterScreen(
|
||||
'/:login',
|
||||
(context, params) => BbUserScreen(params['login'].first,
|
||||
isTeam: params['team'].first == '1'));
|
||||
(context, parameters) => BbUserScreen(parameters['login'].first,
|
||||
isTeam: parameters['team'].first == '1'));
|
||||
static final repo = RouterScreen(
|
||||
'/:owner/:name',
|
||||
(context, params) =>
|
||||
BbRepoScreen(params['owner'].first, params['name'].first),
|
||||
(context, parameters) =>
|
||||
BbRepoScreen(parameters['owner'].first, parameters['name'].first),
|
||||
);
|
||||
static final object = RouterScreen(
|
||||
'/:owner/:name/src/:ref',
|
||||
(context, params) => BbObjectScreen(
|
||||
params['owner'].first,
|
||||
params['name'].first,
|
||||
params['ref'].first,
|
||||
path: params['path']?.first,
|
||||
(context, parameters) => BbObjectScreen(
|
||||
parameters['owner'].first,
|
||||
parameters['name'].first,
|
||||
parameters['ref'].first,
|
||||
path: parameters['path']?.first,
|
||||
),
|
||||
);
|
||||
static final issues = RouterScreen('/:owner/:name/issues',
|
||||
(_, p) => BbIssuesScreen(p['owner'].first, p['name'].first));
|
||||
static final issues = RouterScreen(
|
||||
'/:owner/:name/issues',
|
||||
(context, parameters) =>
|
||||
BbIssuesScreen(parameters['owner'].first, parameters['name'].first));
|
||||
static final commits = RouterScreen(
|
||||
'/:owner/:name/commits/:ref',
|
||||
(_, p) =>
|
||||
BbCommitsScreen(p['owner'].first, p['name'].first, p['ref'].first));
|
||||
static final pulls = RouterScreen('/:owner/:name/pulls',
|
||||
(_, p) => BbPullsScreen(p['owner'].first, p['name'].first));
|
||||
static final issueAdd = RouterScreen('/:owner/:name/issues/new',
|
||||
(_, p) => BbIssueFormScreen(p['owner'].first, p['name'].first));
|
||||
(context, parameters) => BbCommitsScreen(parameters['owner'].first,
|
||||
parameters['name'].first, parameters['ref'].first));
|
||||
static final pulls = RouterScreen(
|
||||
'/:owner/:name/pulls',
|
||||
(context, parameters) =>
|
||||
BbPullsScreen(parameters['owner'].first, parameters['name'].first));
|
||||
static final issueAdd = RouterScreen(
|
||||
'/:owner/:name/issues/new',
|
||||
(context, parameters) => BbIssueFormScreen(
|
||||
parameters['owner'].first, parameters['name'].first));
|
||||
static final issue = RouterScreen(
|
||||
'/:owner/:name/issues/:number',
|
||||
(_, p) =>
|
||||
BbIssueScreen(p['owner'].first, p['name'].first, p['number'].first));
|
||||
(context, parameters) => BbIssueScreen(parameters['owner'].first,
|
||||
parameters['name'].first, parameters['number'].first));
|
||||
static final issueComment = RouterScreen(
|
||||
'/:owner/:name/issues/:number/comment',
|
||||
(_, p) => BbIssueCommentScreen(
|
||||
p['owner'].first, p['name'].first, p['number'].first));
|
||||
(context, parameters) => BbIssueCommentScreen(parameters['owner'].first,
|
||||
parameters['name'].first, parameters['number'].first));
|
||||
}
|
||||
|
||||
class GiteeRouter {
|
||||
|
@ -421,13 +467,14 @@ class GiteeRouter {
|
|||
GiteeRouter.pullComment,
|
||||
GiteeRouter.files,
|
||||
GiteeRouter.commit,
|
||||
GiteeRouter.contributors,
|
||||
];
|
||||
static final search = RouterScreen('/search', (context, parameters) {
|
||||
return GeSearchScreen();
|
||||
});
|
||||
static final user = RouterScreen('/:login', (context, p) {
|
||||
final login = p['login'].first;
|
||||
final tab = p['tab']?.first;
|
||||
static final user = RouterScreen('/:login', (context, parameters) {
|
||||
final login = parameters['login'].first;
|
||||
final tab = parameters['tab']?.first;
|
||||
switch (tab) {
|
||||
case 'followers':
|
||||
return GeUsersScreen.followers(login);
|
||||
|
@ -444,21 +491,37 @@ class GiteeRouter {
|
|||
});
|
||||
static final repo = RouterScreen(
|
||||
'/:owner/:name',
|
||||
(context, params) =>
|
||||
GeRepoScreen(params['owner'].first, params['name'].first),
|
||||
(context, parameters) {
|
||||
if (parameters['branch'] == null) {
|
||||
return GeRepoScreen(
|
||||
parameters['owner'].first, parameters['name'].first);
|
||||
} else {
|
||||
return GeRepoScreen(parameters['owner'].first, parameters['name'].first,
|
||||
branch: parameters['branch'].first);
|
||||
}
|
||||
},
|
||||
);
|
||||
static final stargazers = RouterScreen('/:owner/:name/stargazers', (_, p) {
|
||||
return GeUsersScreen.stargazers(p['owner'].first, p['name'].first);
|
||||
static final stargazers =
|
||||
RouterScreen('/:owner/:name/stargazers', (context, parameters) {
|
||||
return GeUsersScreen.stargazers(
|
||||
parameters['owner'].first, parameters['name'].first);
|
||||
});
|
||||
static final watchers = RouterScreen('/:owner/:name/watchers', (_, p) {
|
||||
return GeUsersScreen.watchers(p['owner'].first, p['name'].first);
|
||||
static final watchers =
|
||||
RouterScreen('/:owner/:name/watchers', (context, parameters) {
|
||||
return GeUsersScreen.watchers(
|
||||
parameters['owner'].first, parameters['name'].first);
|
||||
});
|
||||
static final forks = RouterScreen('/:owner/:name/forks', (_, p) {
|
||||
return GeReposScreen.forks(p['owner'].first, p['name'].first);
|
||||
static final forks =
|
||||
RouterScreen('/:owner/:name/forks', (context, parameters) {
|
||||
return GeReposScreen.forks(
|
||||
parameters['owner'].first, parameters['name'].first);
|
||||
});
|
||||
static final commits = RouterScreen(
|
||||
'/:owner/:name/commits',
|
||||
(_, p) => GeCommitsScreen(p['owner'].first, p['name'].first),
|
||||
(context, parameters) => GeCommitsScreen(
|
||||
parameters['owner'].first, parameters['name'].first,
|
||||
branch:
|
||||
parameters['branch'] != null ? parameters['branch'].first : null),
|
||||
);
|
||||
static final tree = RouterScreen(
|
||||
'/:owner/:name/tree/:sha',
|
||||
|
@ -543,4 +606,9 @@ class GiteeRouter {
|
|||
(context, parameters) => GeCommitScreen(parameters['owner'].first,
|
||||
parameters['name'].first, parameters['sha'].first),
|
||||
);
|
||||
static final contributors = RouterScreen(
|
||||
'/:owner/:name/contributors',
|
||||
(context, parameters) => GeContributorsScreen(
|
||||
parameters['owner'].first, parameters['name'].first),
|
||||
);
|
||||
}
|
||||
|
|
|
@ -10,17 +10,17 @@ import '../generated/l10n.dart';
|
|||
class GeCommitsScreen extends StatelessWidget {
|
||||
final String owner;
|
||||
final String name;
|
||||
// final String branch; // TODO:
|
||||
GeCommitsScreen(this.owner, this.name);
|
||||
final String branch;
|
||||
GeCommitsScreen(this.owner, this.name, {this.branch});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return ListStatefulScaffold<GiteeCommit, int>(
|
||||
title: AppBarTitle(S.of(context).commits),
|
||||
fetch: (page) async {
|
||||
final res = await context
|
||||
.read<AuthModel>()
|
||||
.fetchGiteeWithPage('/repos/$owner/$name/commits', page: page);
|
||||
final res = await context.read<AuthModel>().fetchGiteeWithPage(
|
||||
'/repos/$owner/$name/commits?sha=$branch',
|
||||
page: page);
|
||||
return ListPayload(
|
||||
cursor: res.cursor,
|
||||
hasMore: res.hasMore,
|
||||
|
|
|
@ -0,0 +1,80 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:git_touch/models/gitee.dart';
|
||||
import 'package:git_touch/models/theme.dart';
|
||||
import 'package:git_touch/scaffolds/list_stateful.dart';
|
||||
import 'package:git_touch/utils/utils.dart';
|
||||
import 'package:git_touch/widgets/app_bar_title.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:git_touch/models/auth.dart';
|
||||
import '../generated/l10n.dart';
|
||||
|
||||
class GeContributorsScreen extends StatelessWidget {
|
||||
final String owner;
|
||||
final String name;
|
||||
GeContributorsScreen(this.owner, this.name);
|
||||
|
||||
Widget build(BuildContext context) {
|
||||
return ListStatefulScaffold<GiteeContributor, int>(
|
||||
title: AppBarTitle(S.of(context).contributors),
|
||||
fetch: (page) async {
|
||||
page = page ?? 1;
|
||||
final res = await context
|
||||
.read<AuthModel>()
|
||||
.fetchGiteeWithPage('/repos/$owner/$name/contributors')
|
||||
.then((v) {
|
||||
return [
|
||||
for (var contributor in v.data)
|
||||
GiteeContributor.fromJson(contributor)
|
||||
];
|
||||
});
|
||||
return ListPayload(
|
||||
cursor: page + 1,
|
||||
items: res,
|
||||
hasMore: res.isNotEmpty,
|
||||
);
|
||||
},
|
||||
itemBuilder: (v) {
|
||||
final theme = context.read<ThemeModel>();
|
||||
return Container(
|
||||
padding: CommonStyle.padding,
|
||||
child: Row(
|
||||
children: <Widget>[
|
||||
SizedBox(width: 10),
|
||||
Expanded(
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: <Widget>[
|
||||
Row(
|
||||
children: <Widget>[
|
||||
Text(
|
||||
v.name,
|
||||
style: TextStyle(
|
||||
color: theme.palette.primary,
|
||||
fontSize: 18,
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
SizedBox(height: 6),
|
||||
if (v.contributions != null)
|
||||
DefaultTextStyle(
|
||||
style: TextStyle(
|
||||
color: theme.palette.secondaryText,
|
||||
fontSize: 16,
|
||||
),
|
||||
child: Text(
|
||||
"Contributions: " + v.contributions.toString()),
|
||||
),
|
||||
],
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
|
@ -6,6 +6,7 @@ import 'package:git_touch/utils/utils.dart';
|
|||
import 'package:git_touch/widgets/action_entry.dart';
|
||||
import 'package:git_touch/widgets/app_bar_title.dart';
|
||||
import 'package:git_touch/widgets/issue_item.dart';
|
||||
import 'package:git_touch/widgets/label.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
class GeIssuesScreen extends StatelessWidget {
|
||||
|
@ -40,6 +41,12 @@ class GeIssuesScreen extends StatelessWidget {
|
|||
title: p.title,
|
||||
updatedAt: DateTime.parse(p.updatedAt),
|
||||
url: '/gitee/$owner/$name/issues/${p.number}',
|
||||
labels: p.labels.isEmpty
|
||||
? null
|
||||
: Wrap(spacing: 4, runSpacing: 4, children: [
|
||||
for (var label in p.labels)
|
||||
MyLabel(name: label.name, cssColor: label.color)
|
||||
]),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@ import 'package:git_touch/models/gitee.dart';
|
|||
import 'package:git_touch/scaffolds/list_stateful.dart';
|
||||
import 'package:git_touch/widgets/app_bar_title.dart';
|
||||
import 'package:git_touch/widgets/issue_item.dart';
|
||||
import 'package:git_touch/widgets/label.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
class GePullsScreen extends StatelessWidget {
|
||||
|
@ -34,6 +35,12 @@ class GePullsScreen extends StatelessWidget {
|
|||
title: p.title,
|
||||
updatedAt: DateTime.parse(p.updatedAt),
|
||||
url: '/gitee/$owner/$name/pulls/${p.number}',
|
||||
labels: p.labels.isEmpty
|
||||
? null
|
||||
: Wrap(spacing: 4, runSpacing: 4, children: [
|
||||
for (var label in p.labels)
|
||||
MyLabel(name: label.name, cssColor: label.color)
|
||||
]),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
import 'dart:convert';
|
||||
|
||||
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';
|
||||
|
@ -18,11 +18,13 @@ import '../generated/l10n.dart';
|
|||
class GeRepoScreen extends StatelessWidget {
|
||||
final String owner;
|
||||
final String name;
|
||||
GeRepoScreen(this.owner, this.name);
|
||||
final String branch;
|
||||
GeRepoScreen(this.owner, this.name, {this.branch});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return RefreshStatefulScaffold<Tuple2<GiteeRepo, MarkdownViewData>>(
|
||||
return RefreshStatefulScaffold<
|
||||
Tuple3<GiteeRepo, MarkdownViewData, List<GiteeBranch>>>(
|
||||
title: AppBarTitle(S.of(context).repository),
|
||||
fetch: () async {
|
||||
final auth = context.read<AuthModel>();
|
||||
|
@ -43,11 +45,16 @@ class GeRepoScreen extends StatelessWidget {
|
|||
return utf8.decode(res.bodyBytes).normalizedHtml;
|
||||
});
|
||||
final readmeData = MarkdownViewData(context, md: md, html: html);
|
||||
|
||||
return Tuple2(repo, readmeData);
|
||||
final branches =
|
||||
await auth.fetchGitee('/repos/$owner/$name/branches').then((v) {
|
||||
return [for (var branch in v) GiteeBranch.fromJson(branch)];
|
||||
});
|
||||
return Tuple3(repo, readmeData, branches);
|
||||
},
|
||||
bodyBuilder: (t, setState) {
|
||||
final p = t.item1;
|
||||
final branches = t.item3;
|
||||
final theme = context.read<ThemeModel>();
|
||||
return Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||
children: <Widget>[
|
||||
|
@ -86,7 +93,8 @@ class GeRepoScreen extends StatelessWidget {
|
|||
leftIconData: Octicons.code,
|
||||
text: Text('Code'),
|
||||
rightWidget: Text(p.license ?? ''),
|
||||
url: '/gitee/$owner/$name/tree/${p.defaultBranch}',
|
||||
url:
|
||||
'/gitee/$owner/$name/tree/${branch == null ? p.defaultBranch : branch}',
|
||||
),
|
||||
TableViewItem(
|
||||
leftIconData: Octicons.issue_opened,
|
||||
|
@ -103,8 +111,42 @@ class GeRepoScreen extends StatelessWidget {
|
|||
TableViewItem(
|
||||
leftIconData: Octicons.history,
|
||||
text: Text('Commits'),
|
||||
url: '/gitee/$owner/$name/commits',
|
||||
url:
|
||||
'/gitee/$owner/$name/commits?branch=${branch == null ? p.defaultBranch : branch}',
|
||||
),
|
||||
if (branches != null)
|
||||
TableViewItem(
|
||||
leftIconData: Octicons.git_branch,
|
||||
text: Text(S.of(context).branches),
|
||||
rightWidget: Text(
|
||||
(branch == null ? p.defaultBranch : branch) +
|
||||
' • ' +
|
||||
branches.length.toString()),
|
||||
onTap: () async {
|
||||
if (branches.length < 2) return;
|
||||
|
||||
await theme.showPicker(
|
||||
context,
|
||||
PickerGroupItem(
|
||||
value: branch,
|
||||
items: branches
|
||||
.map((b) => PickerItem(b.name, text: b.name))
|
||||
.toList(),
|
||||
onClose: (ref) {
|
||||
if (ref != branch) {
|
||||
theme.push(
|
||||
context, '/gitee/$owner/$name?branch=$ref',
|
||||
replace: true);
|
||||
}
|
||||
},
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
TableViewItem(
|
||||
leftIconData: Octicons.organization,
|
||||
text: Text('Contributors'),
|
||||
url: '/gitee/$owner/$name/contributors'),
|
||||
],
|
||||
),
|
||||
CommonStyle.verticalGap,
|
||||
|
|
|
@ -131,7 +131,7 @@ class _GeSearchScreenState extends State<GeSearchScreen> {
|
|||
login: p.login,
|
||||
name: p.name,
|
||||
avatarUrl: p.avatarUrl,
|
||||
bio: Text(p.htmlUrl),
|
||||
bio: Text(p.bio != null ? p.bio : p.htmlUrl),
|
||||
);
|
||||
default:
|
||||
return IssueItem(
|
||||
|
|
Loading…
Reference in New Issue