mirror of
https://github.com/git-touch/git-touch
synced 2025-02-08 23:58:46 +01:00
feat(gitee): updates (#148)
* feat: gitee pull screen (with posting comment) * feat: GeFilesScreen, remove 'changes' prop * feat: commitScreen, commits in pullScreen * fix: commit text formatting
This commit is contained in:
parent
fde136b974
commit
92bcdaa4b0
@ -79,6 +79,7 @@ class GiteeCommit {
|
|||||||
GiteeCommitDetail commit;
|
GiteeCommitDetail commit;
|
||||||
String sha;
|
String sha;
|
||||||
String htmlUrl;
|
String htmlUrl;
|
||||||
|
List<GiteeCommitFile> files;
|
||||||
GiteeCommit();
|
GiteeCommit();
|
||||||
factory GiteeCommit.fromJson(Map<String, dynamic> json) =>
|
factory GiteeCommit.fromJson(Map<String, dynamic> json) =>
|
||||||
_$GiteeCommitFromJson(json);
|
_$GiteeCommitFromJson(json);
|
||||||
@ -152,6 +153,7 @@ class GiteePull {
|
|||||||
String body;
|
String body;
|
||||||
String bodyHtml;
|
String bodyHtml;
|
||||||
String title;
|
String title;
|
||||||
|
String state;
|
||||||
GiteeRepoOwner user;
|
GiteeRepoOwner user;
|
||||||
int number;
|
int number;
|
||||||
int id;
|
int id;
|
||||||
@ -169,3 +171,42 @@ class GiteeComment {
|
|||||||
factory GiteeComment.fromJson(Map<String, dynamic> json) =>
|
factory GiteeComment.fromJson(Map<String, dynamic> json) =>
|
||||||
_$GiteeCommentFromJson(json);
|
_$GiteeCommentFromJson(json);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@JsonSerializable(fieldRename: FieldRename.snake)
|
||||||
|
class GiteePatch {
|
||||||
|
String diff;
|
||||||
|
GiteePatch();
|
||||||
|
factory GiteePatch.fromJson(Map<String, dynamic> json) =>
|
||||||
|
_$GiteePatchFromJson(json);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Two different classes because of variable type mismatch
|
||||||
|
// for additions, deletions, patch
|
||||||
|
@JsonSerializable(fieldRename: FieldRename.snake)
|
||||||
|
class GiteePullFile {
|
||||||
|
String additions;
|
||||||
|
String deletions;
|
||||||
|
String blobUrl;
|
||||||
|
String filename;
|
||||||
|
String sha;
|
||||||
|
String status;
|
||||||
|
GiteePatch patch;
|
||||||
|
GiteePullFile();
|
||||||
|
factory GiteePullFile.fromJson(Map<String, dynamic> json) =>
|
||||||
|
_$GiteePullFileFromJson(json);
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsonSerializable(fieldRename: FieldRename.snake)
|
||||||
|
class GiteeCommitFile {
|
||||||
|
int additions;
|
||||||
|
int deletions;
|
||||||
|
int changes;
|
||||||
|
String blobUrl;
|
||||||
|
String filename;
|
||||||
|
String sha;
|
||||||
|
String status;
|
||||||
|
String patch;
|
||||||
|
GiteeCommitFile();
|
||||||
|
factory GiteeCommitFile.fromJson(Map<String, dynamic> json) =>
|
||||||
|
_$GiteeCommitFileFromJson(json);
|
||||||
|
}
|
||||||
|
@ -132,7 +132,12 @@ GiteeCommit _$GiteeCommitFromJson(Map<String, dynamic> json) {
|
|||||||
? null
|
? null
|
||||||
: GiteeCommitDetail.fromJson(json['commit'] as Map<String, dynamic>)
|
: GiteeCommitDetail.fromJson(json['commit'] as Map<String, dynamic>)
|
||||||
..sha = json['sha'] as String
|
..sha = json['sha'] as String
|
||||||
..htmlUrl = json['html_url'] as String;
|
..htmlUrl = json['html_url'] as String
|
||||||
|
..files = (json['files'] as List)
|
||||||
|
?.map((e) => e == null
|
||||||
|
? null
|
||||||
|
: GiteeCommitFile.fromJson(e as Map<String, dynamic>))
|
||||||
|
?.toList();
|
||||||
}
|
}
|
||||||
|
|
||||||
Map<String, dynamic> _$GiteeCommitToJson(GiteeCommit instance) =>
|
Map<String, dynamic> _$GiteeCommitToJson(GiteeCommit instance) =>
|
||||||
@ -141,6 +146,7 @@ Map<String, dynamic> _$GiteeCommitToJson(GiteeCommit instance) =>
|
|||||||
'commit': instance.commit,
|
'commit': instance.commit,
|
||||||
'sha': instance.sha,
|
'sha': instance.sha,
|
||||||
'html_url': instance.htmlUrl,
|
'html_url': instance.htmlUrl,
|
||||||
|
'files': instance.files,
|
||||||
};
|
};
|
||||||
|
|
||||||
GiteeCommitDetail _$GiteeCommitDetailFromJson(Map<String, dynamic> json) {
|
GiteeCommitDetail _$GiteeCommitDetailFromJson(Map<String, dynamic> json) {
|
||||||
@ -247,6 +253,7 @@ GiteePull _$GiteePullFromJson(Map<String, dynamic> json) {
|
|||||||
..body = json['body'] as String
|
..body = json['body'] as String
|
||||||
..bodyHtml = json['body_html'] as String
|
..bodyHtml = json['body_html'] as String
|
||||||
..title = json['title'] as String
|
..title = json['title'] as String
|
||||||
|
..state = json['state'] as String
|
||||||
..user = json['user'] == null
|
..user = json['user'] == null
|
||||||
? null
|
? null
|
||||||
: GiteeRepoOwner.fromJson(json['user'] as Map<String, dynamic>)
|
: GiteeRepoOwner.fromJson(json['user'] as Map<String, dynamic>)
|
||||||
@ -262,6 +269,7 @@ Map<String, dynamic> _$GiteePullToJson(GiteePull instance) => <String, dynamic>{
|
|||||||
'body': instance.body,
|
'body': instance.body,
|
||||||
'body_html': instance.bodyHtml,
|
'body_html': instance.bodyHtml,
|
||||||
'title': instance.title,
|
'title': instance.title,
|
||||||
|
'state': instance.state,
|
||||||
'user': instance.user,
|
'user': instance.user,
|
||||||
'number': instance.number,
|
'number': instance.number,
|
||||||
'id': instance.id,
|
'id': instance.id,
|
||||||
@ -282,3 +290,60 @@ Map<String, dynamic> _$GiteeCommentToJson(GiteeComment instance) =>
|
|||||||
'created_at': instance.createdAt,
|
'created_at': instance.createdAt,
|
||||||
'user': instance.user,
|
'user': instance.user,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
GiteePatch _$GiteePatchFromJson(Map<String, dynamic> json) {
|
||||||
|
return GiteePatch()..diff = json['diff'] as String;
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, dynamic> _$GiteePatchToJson(GiteePatch instance) =>
|
||||||
|
<String, dynamic>{
|
||||||
|
'diff': instance.diff,
|
||||||
|
};
|
||||||
|
|
||||||
|
GiteePullFile _$GiteePullFileFromJson(Map<String, dynamic> json) {
|
||||||
|
return GiteePullFile()
|
||||||
|
..additions = json['additions'] as String
|
||||||
|
..deletions = json['deletions'] as String
|
||||||
|
..blobUrl = json['blob_url'] as String
|
||||||
|
..filename = json['filename'] as String
|
||||||
|
..sha = json['sha'] as String
|
||||||
|
..status = json['status'] as String
|
||||||
|
..patch = json['patch'] == null
|
||||||
|
? null
|
||||||
|
: GiteePatch.fromJson(json['patch'] as Map<String, dynamic>);
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, dynamic> _$GiteePullFileToJson(GiteePullFile instance) =>
|
||||||
|
<String, dynamic>{
|
||||||
|
'additions': instance.additions,
|
||||||
|
'deletions': instance.deletions,
|
||||||
|
'blob_url': instance.blobUrl,
|
||||||
|
'filename': instance.filename,
|
||||||
|
'sha': instance.sha,
|
||||||
|
'status': instance.status,
|
||||||
|
'patch': instance.patch,
|
||||||
|
};
|
||||||
|
|
||||||
|
GiteeCommitFile _$GiteeCommitFileFromJson(Map<String, dynamic> json) {
|
||||||
|
return GiteeCommitFile()
|
||||||
|
..additions = json['additions'] as int
|
||||||
|
..deletions = json['deletions'] as int
|
||||||
|
..changes = json['changes'] as int
|
||||||
|
..blobUrl = json['blob_url'] as String
|
||||||
|
..filename = json['filename'] as String
|
||||||
|
..sha = json['sha'] as String
|
||||||
|
..status = json['status'] as String
|
||||||
|
..patch = json['patch'] as String;
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, dynamic> _$GiteeCommitFileToJson(GiteeCommitFile instance) =>
|
||||||
|
<String, dynamic>{
|
||||||
|
'additions': instance.additions,
|
||||||
|
'deletions': instance.deletions,
|
||||||
|
'changes': instance.changes,
|
||||||
|
'blob_url': instance.blobUrl,
|
||||||
|
'filename': instance.filename,
|
||||||
|
'sha': instance.sha,
|
||||||
|
'status': instance.status,
|
||||||
|
'patch': instance.patch,
|
||||||
|
};
|
||||||
|
@ -10,11 +10,14 @@ import 'package:git_touch/screens/bb_pulls.dart';
|
|||||||
import 'package:git_touch/screens/bb_user.dart';
|
import 'package:git_touch/screens/bb_user.dart';
|
||||||
import 'package:git_touch/screens/code_theme.dart';
|
import 'package:git_touch/screens/code_theme.dart';
|
||||||
import 'package:git_touch/screens/ge_blob.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_commits.dart';
|
||||||
|
import 'package:git_touch/screens/ge_files.dart';
|
||||||
import 'package:git_touch/screens/ge_issue.dart';
|
import 'package:git_touch/screens/ge_issue.dart';
|
||||||
import 'package:git_touch/screens/ge_issue_comment.dart';
|
import 'package:git_touch/screens/ge_issue_comment.dart';
|
||||||
import 'package:git_touch/screens/ge_issue_form.dart';
|
import 'package:git_touch/screens/ge_issue_form.dart';
|
||||||
import 'package:git_touch/screens/ge_issues.dart';
|
import 'package:git_touch/screens/ge_issues.dart';
|
||||||
|
import 'package:git_touch/screens/ge_pull.dart';
|
||||||
import 'package:git_touch/screens/ge_pulls.dart';
|
import 'package:git_touch/screens/ge_pulls.dart';
|
||||||
import 'package:git_touch/screens/ge_repo.dart';
|
import 'package:git_touch/screens/ge_repo.dart';
|
||||||
import 'package:git_touch/screens/ge_repos.dart';
|
import 'package:git_touch/screens/ge_repos.dart';
|
||||||
@ -414,6 +417,10 @@ class GiteeRouter {
|
|||||||
GiteeRouter.issueAdd, // issueAdd should be above issue
|
GiteeRouter.issueAdd, // issueAdd should be above issue
|
||||||
GiteeRouter.issue, // Due to similarity of uris
|
GiteeRouter.issue, // Due to similarity of uris
|
||||||
GiteeRouter.issueComment,
|
GiteeRouter.issueComment,
|
||||||
|
GiteeRouter.pull,
|
||||||
|
GiteeRouter.pullComment,
|
||||||
|
GiteeRouter.files,
|
||||||
|
GiteeRouter.commit,
|
||||||
];
|
];
|
||||||
static final search = RouterScreen('/search', (context, parameters) {
|
static final search = RouterScreen('/search', (context, parameters) {
|
||||||
return GeSearchScreen();
|
return GeSearchScreen();
|
||||||
@ -499,6 +506,31 @@ class GiteeRouter {
|
|||||||
static final issueComment = RouterScreen(
|
static final issueComment = RouterScreen(
|
||||||
'/:owner/:name/issues/:number/comment', (context, parameters) {
|
'/:owner/:name/issues/:number/comment', (context, parameters) {
|
||||||
return GeIssueCommentScreen(parameters['owner'].first,
|
return GeIssueCommentScreen(parameters['owner'].first,
|
||||||
parameters['name'].first, parameters['number'].first);
|
parameters['name'].first, parameters['number'].first,
|
||||||
|
isPr: false);
|
||||||
});
|
});
|
||||||
|
static final pull = RouterScreen(
|
||||||
|
'/:owner/:name/pulls/:number',
|
||||||
|
(context, parameters) {
|
||||||
|
return GePullScreen(parameters['owner'].first, parameters['name'].first,
|
||||||
|
parameters['number'].first,
|
||||||
|
isPr: true);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
static final pullComment = RouterScreen('/:owner/:name/pulls/:number/comment',
|
||||||
|
(context, parameters) {
|
||||||
|
return GeIssueCommentScreen(parameters['owner'].first,
|
||||||
|
parameters['name'].first, parameters['number'].first,
|
||||||
|
isPr: true);
|
||||||
|
});
|
||||||
|
static final files =
|
||||||
|
RouterScreen('/:owner/:name/pulls/:number/files', (context, parameters) {
|
||||||
|
return GeFilesScreen(parameters['owner'].first, parameters['name'].first,
|
||||||
|
parameters['number'].first);
|
||||||
|
});
|
||||||
|
static final commit = RouterScreen(
|
||||||
|
'/:owner/:name/commits/:sha',
|
||||||
|
(context, parameters) => GeCommitScreen(parameters['owner'].first,
|
||||||
|
parameters['name'].first, parameters['sha'].first),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
91
lib/screens/ge_commit.dart
Normal file
91
lib/screens/ge_commit.dart
Normal file
@ -0,0 +1,91 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:git_touch/models/gitee.dart';
|
||||||
|
import 'package:git_touch/scaffolds/refresh_stateful.dart';
|
||||||
|
import 'package:git_touch/utils/utils.dart';
|
||||||
|
import 'package:git_touch/widgets/action_button.dart';
|
||||||
|
import 'package:git_touch/widgets/avatar.dart';
|
||||||
|
import 'package:git_touch/widgets/files_item.dart';
|
||||||
|
import 'package:git_touch/widgets/link.dart';
|
||||||
|
import 'package:provider/provider.dart';
|
||||||
|
import 'package:git_touch/models/auth.dart';
|
||||||
|
import 'package:git_touch/models/theme.dart';
|
||||||
|
|
||||||
|
class GeCommitScreen extends StatelessWidget {
|
||||||
|
final String owner;
|
||||||
|
final String name;
|
||||||
|
final String sha;
|
||||||
|
GeCommitScreen(this.owner, this.name, this.sha);
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
final theme = context.watch<ThemeModel>();
|
||||||
|
return RefreshStatefulScaffold<GiteeCommit>(
|
||||||
|
title: Text("Commit: ${sha.substring(0, 7)}"),
|
||||||
|
fetch: () async {
|
||||||
|
final auth = context.read<AuthModel>();
|
||||||
|
final items = await auth.fetchGitee('/repos/$owner/$name/commits/$sha');
|
||||||
|
print(GiteeCommit.fromJson(items));
|
||||||
|
return GiteeCommit.fromJson(items);
|
||||||
|
},
|
||||||
|
actionBuilder: (data, _) => ActionButton(
|
||||||
|
title: 'Actions', items: [...ActionItem.getUrlActions(data.htmlUrl)]),
|
||||||
|
bodyBuilder: (data, _) {
|
||||||
|
return Column(children: <Widget>[
|
||||||
|
Container(
|
||||||
|
padding: CommonStyle.padding,
|
||||||
|
child: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: <Widget>[
|
||||||
|
Link(
|
||||||
|
url: '/gitee/$owner/$name',
|
||||||
|
child: Row(
|
||||||
|
children: <Widget>[
|
||||||
|
Avatar(
|
||||||
|
url: data.author.avatarUrl,
|
||||||
|
size: AvatarSize.extraSmall,
|
||||||
|
),
|
||||||
|
SizedBox(width: 4),
|
||||||
|
Text(
|
||||||
|
'$owner / $name',
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 17,
|
||||||
|
color: theme.palette.secondaryText,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
SizedBox(width: 4),
|
||||||
|
Text(
|
||||||
|
'${sha.substring(0, 7)}',
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 17,
|
||||||
|
color: theme.palette.tertiaryText,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
SizedBox(height: 8),
|
||||||
|
Text(
|
||||||
|
data.commit.message,
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 20,
|
||||||
|
fontWeight: FontWeight.w600,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
)),
|
||||||
|
Wrap(
|
||||||
|
children: data.files
|
||||||
|
.map<Widget>((file) => FilesItem(
|
||||||
|
filename: file.filename,
|
||||||
|
additions: file.additions,
|
||||||
|
deletions: file.deletions,
|
||||||
|
status: file.status,
|
||||||
|
patch: file.patch,
|
||||||
|
))
|
||||||
|
.toList(),
|
||||||
|
)
|
||||||
|
]);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
@ -34,7 +34,7 @@ class GeCommitsScreen extends StatelessWidget {
|
|||||||
avatarLink: '/gitee/${c.author.login}',
|
avatarLink: '/gitee/${c.author.login}',
|
||||||
createdAt: c.commit.author.date,
|
createdAt: c.commit.author.date,
|
||||||
message: c.commit.message,
|
message: c.commit.message,
|
||||||
url: c.htmlUrl,
|
url: '/gitee/$owner/$name/commits/${c.sha}',
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
57
lib/screens/ge_files.dart
Normal file
57
lib/screens/ge_files.dart
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter/cupertino.dart';
|
||||||
|
import 'package:git_touch/models/gitee.dart';
|
||||||
|
import 'package:git_touch/scaffolds/list_stateful.dart';
|
||||||
|
import 'package:git_touch/widgets/action_button.dart';
|
||||||
|
import 'package:git_touch/widgets/app_bar_title.dart';
|
||||||
|
import 'package:provider/provider.dart';
|
||||||
|
import 'package:git_touch/widgets/files_item.dart';
|
||||||
|
import 'package:git_touch/models/auth.dart';
|
||||||
|
import '../generated/l10n.dart';
|
||||||
|
|
||||||
|
class GeFilesScreen extends StatelessWidget {
|
||||||
|
final String owner;
|
||||||
|
final String name;
|
||||||
|
final String pullNumber;
|
||||||
|
GeFilesScreen(this.owner, this.name, this.pullNumber);
|
||||||
|
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return ListStatefulScaffold<GiteePullFile, int>(
|
||||||
|
title: AppBarTitle(S.of(context).files),
|
||||||
|
actionBuilder: () {
|
||||||
|
return ActionButton(
|
||||||
|
title: 'Actions',
|
||||||
|
items: [
|
||||||
|
...ActionItem.getUrlActions(
|
||||||
|
'https://gitee.com/$owner/$name/pulls/$pullNumber/files'),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
},
|
||||||
|
fetch: (page) async {
|
||||||
|
page = page ?? 1;
|
||||||
|
final res = await context
|
||||||
|
.read<AuthModel>()
|
||||||
|
.fetchGiteeWithPage(
|
||||||
|
'/repos/$owner/$name/pulls/$pullNumber/files?page=$page',
|
||||||
|
)
|
||||||
|
.then((v) {
|
||||||
|
return [for (var file in v.data) GiteePullFile.fromJson(file)];
|
||||||
|
});
|
||||||
|
return ListPayload(
|
||||||
|
cursor: page + 1,
|
||||||
|
items: res,
|
||||||
|
hasMore: res.isNotEmpty,
|
||||||
|
);
|
||||||
|
},
|
||||||
|
itemBuilder: (v) {
|
||||||
|
return FilesItem(
|
||||||
|
filename: v.filename,
|
||||||
|
additions: int.parse(v.additions),
|
||||||
|
deletions: int.parse(v.deletions),
|
||||||
|
status: v.status,
|
||||||
|
patch: v.patch.diff,
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
@ -11,7 +11,8 @@ class GeIssueCommentScreen extends StatefulWidget {
|
|||||||
final String owner;
|
final String owner;
|
||||||
final String name;
|
final String name;
|
||||||
final String number;
|
final String number;
|
||||||
GeIssueCommentScreen(this.owner, this.name, this.number);
|
final bool isPr;
|
||||||
|
GeIssueCommentScreen(this.owner, this.name, this.number, {this.isPr: false});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
_GeIssueCommentScreenState createState() => _GeIssueCommentScreenState();
|
_GeIssueCommentScreenState createState() => _GeIssueCommentScreenState();
|
||||||
@ -44,18 +45,35 @@ class _GeIssueCommentScreenState extends State<GeIssueCommentScreen> {
|
|||||||
CupertinoButton.filled(
|
CupertinoButton.filled(
|
||||||
child: Text('Comment'),
|
child: Text('Comment'),
|
||||||
onPressed: () async {
|
onPressed: () async {
|
||||||
final res = await auth.fetchGitee(
|
if (!widget.isPr) {
|
||||||
'/repos/${widget.owner}/${widget.name}/issues/${widget.number}/comments',
|
final res = await auth.fetchGitee(
|
||||||
isPost: true,
|
'/repos/${widget.owner}/${widget.name}/issues/${widget.number}/comments',
|
||||||
body: {'body': _body, 'repo': widget.name},
|
isPost: true,
|
||||||
).then((v) {
|
body: {'body': _body, 'repo': widget.name},
|
||||||
return GiteeIssue.fromJson(v);
|
).then((v) {
|
||||||
});
|
return GiteeIssue.fromJson(v);
|
||||||
await theme.push(
|
});
|
||||||
context,
|
Navigator.pop(context, '');
|
||||||
'/gitee/${widget.owner}/${widget.name}/issues/${widget.number}',
|
await theme.push(
|
||||||
replace: true,
|
context,
|
||||||
);
|
'/gitee/${widget.owner}/${widget.name}/issues/${widget.number}',
|
||||||
|
replace: true,
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
final res = await auth.fetchGitee(
|
||||||
|
'/repos/${widget.owner}/${widget.name}/pulls/${widget.number}/comments',
|
||||||
|
isPost: true,
|
||||||
|
body: {'body': _body, 'repo': widget.name},
|
||||||
|
).then((v) {
|
||||||
|
return GiteePull.fromJson(v);
|
||||||
|
});
|
||||||
|
Navigator.pop(context, '');
|
||||||
|
await theme.push(
|
||||||
|
context,
|
||||||
|
'/gitee/${widget.owner}/${widget.name}/pulls/${widget.number}',
|
||||||
|
replace: true,
|
||||||
|
);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
225
lib/screens/ge_pull.dart
Normal file
225
lib/screens/ge_pull.dart
Normal file
@ -0,0 +1,225 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:git_touch/models/gitee.dart';
|
||||||
|
import 'package:git_touch/scaffolds/refresh_stateful.dart';
|
||||||
|
import 'package:git_touch/utils/utils.dart';
|
||||||
|
import 'package:git_touch/widgets/action_entry.dart';
|
||||||
|
import 'package:git_touch/widgets/avatar.dart';
|
||||||
|
import 'package:git_touch/widgets/link.dart';
|
||||||
|
import 'package:git_touch/widgets/comment_item.dart';
|
||||||
|
import 'package:primer/primer.dart';
|
||||||
|
import 'package:provider/provider.dart';
|
||||||
|
import 'package:git_touch/models/auth.dart';
|
||||||
|
import 'package:git_touch/models/theme.dart';
|
||||||
|
import 'package:tuple/tuple.dart';
|
||||||
|
|
||||||
|
class GePullScreen extends StatelessWidget {
|
||||||
|
final String owner;
|
||||||
|
final String name;
|
||||||
|
final String number;
|
||||||
|
final bool isPr;
|
||||||
|
|
||||||
|
GePullScreen(this.owner, this.name, this.number, {this.isPr: false});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return RefreshStatefulScaffold<
|
||||||
|
Tuple4<GiteePull, List<GiteeComment>, List<GiteePullFile>,
|
||||||
|
List<GiteeCommit>>>(
|
||||||
|
title: Text("Pull Request: #$number"),
|
||||||
|
fetch: () async {
|
||||||
|
final auth = context.read<AuthModel>();
|
||||||
|
final items = await Future.wait([
|
||||||
|
auth.fetchGitee('/repos/$owner/$name/pulls/$number'),
|
||||||
|
auth.fetchGitee('/repos/$owner/$name/pulls/$number/comments'),
|
||||||
|
auth.fetchGitee('/repos/$owner/$name/pulls/$number/files'),
|
||||||
|
auth.fetchGitee('/repos/$owner/$name/pulls/$number/commits'),
|
||||||
|
]);
|
||||||
|
return Tuple4(
|
||||||
|
GiteePull.fromJson(items[0]),
|
||||||
|
[for (var v in items[1]) GiteeComment.fromJson(v)],
|
||||||
|
[for (var v in items[2]) GiteePullFile.fromJson(v)],
|
||||||
|
[for (var v in items[3]) GiteeCommit.fromJson(v)]);
|
||||||
|
},
|
||||||
|
actionBuilder: (data, _) => ActionEntry(
|
||||||
|
iconData: Octicons.plus,
|
||||||
|
url: '/gitee/$owner/$name/pulls/$number/comment',
|
||||||
|
),
|
||||||
|
bodyBuilder: (data, _) {
|
||||||
|
final pull = data.item1;
|
||||||
|
final comments = data.item2;
|
||||||
|
final files = data.item3;
|
||||||
|
final commits = data.item4;
|
||||||
|
final theme = context.read<ThemeModel>();
|
||||||
|
var additions = 0;
|
||||||
|
var deletions = 0;
|
||||||
|
for (var file in files) {
|
||||||
|
additions += int.parse(file.additions);
|
||||||
|
deletions += int.parse(file.deletions);
|
||||||
|
}
|
||||||
|
return Column(children: <Widget>[
|
||||||
|
Container(
|
||||||
|
padding: CommonStyle.padding,
|
||||||
|
child: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: <Widget>[
|
||||||
|
Link(
|
||||||
|
child: Container(
|
||||||
|
padding: EdgeInsets.symmetric(vertical: 8),
|
||||||
|
child: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: <Widget>[
|
||||||
|
Link(
|
||||||
|
url: '/gitee/$owner/$name',
|
||||||
|
child: Row(
|
||||||
|
children: <Widget>[
|
||||||
|
Avatar(
|
||||||
|
url: pull.user.avatarUrl,
|
||||||
|
size: AvatarSize.extraSmall,
|
||||||
|
),
|
||||||
|
SizedBox(width: 4),
|
||||||
|
Text(
|
||||||
|
'$owner / $name',
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 17,
|
||||||
|
color: theme.palette.secondaryText,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
SizedBox(width: 4),
|
||||||
|
Text(
|
||||||
|
'#$number',
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 17,
|
||||||
|
color: theme.palette.tertiaryText,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
SizedBox(height: 8),
|
||||||
|
Text(
|
||||||
|
pull.title,
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 20,
|
||||||
|
fontWeight: FontWeight.w600,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
SizedBox(height: 8),
|
||||||
|
StateLabel(
|
||||||
|
pull.state == 'open'
|
||||||
|
? StateLabelStatus.pullOpened
|
||||||
|
: StateLabelStatus.pullClosed,
|
||||||
|
small: true),
|
||||||
|
SizedBox(height: 16),
|
||||||
|
CommonStyle.border,
|
||||||
|
CommonStyle.border,
|
||||||
|
Link(
|
||||||
|
url: '/gitee/$owner/$name/pulls/$number/files',
|
||||||
|
child: Container(
|
||||||
|
padding: EdgeInsets.symmetric(vertical: 8),
|
||||||
|
child: Row(
|
||||||
|
mainAxisAlignment:
|
||||||
|
MainAxisAlignment.spaceBetween,
|
||||||
|
children: <Widget>[
|
||||||
|
Text(
|
||||||
|
'${files.length} files changed',
|
||||||
|
style: TextStyle(
|
||||||
|
color: theme.palette.secondaryText,
|
||||||
|
fontSize: 17,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Row(
|
||||||
|
children: <Widget>[
|
||||||
|
Text(
|
||||||
|
'+$additions',
|
||||||
|
style: TextStyle(
|
||||||
|
color: Colors.green,
|
||||||
|
fontSize: 15,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
SizedBox(width: 2),
|
||||||
|
Text(
|
||||||
|
'-$deletions',
|
||||||
|
style: TextStyle(
|
||||||
|
color: Colors.red,
|
||||||
|
fontSize: 15,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Icon(
|
||||||
|
Icons.chevron_right,
|
||||||
|
color: theme.palette.border,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
CommonStyle.border,
|
||||||
|
ListTileTheme(
|
||||||
|
contentPadding: EdgeInsets.zero,
|
||||||
|
child: ExpansionTile(
|
||||||
|
title: Text(
|
||||||
|
'Commits',
|
||||||
|
style: TextStyle(
|
||||||
|
color: theme.palette.primary,
|
||||||
|
fontSize: 18,
|
||||||
|
fontWeight: FontWeight.w600,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
children: [
|
||||||
|
for (var commit in commits) ...[
|
||||||
|
Link(
|
||||||
|
url:
|
||||||
|
'/gitee/$owner/$name/commits/${commit.sha}',
|
||||||
|
child: Container(
|
||||||
|
padding:
|
||||||
|
EdgeInsets.symmetric(vertical: 8),
|
||||||
|
child: Row(
|
||||||
|
mainAxisAlignment:
|
||||||
|
MainAxisAlignment.spaceBetween,
|
||||||
|
children: <Widget>[
|
||||||
|
Text(
|
||||||
|
'${commit.sha.substring(0, 7)}',
|
||||||
|
style: TextStyle(
|
||||||
|
color: theme.palette.primary,
|
||||||
|
fontSize: 17,
|
||||||
|
fontFamily:
|
||||||
|
CommonStyle.monospace,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
]
|
||||||
|
],
|
||||||
|
)),
|
||||||
|
]),
|
||||||
|
),
|
||||||
|
url: '/gitee/$owner/$name',
|
||||||
|
),
|
||||||
|
CommonStyle.border,
|
||||||
|
],
|
||||||
|
)),
|
||||||
|
Column(children: [
|
||||||
|
for (var comment in comments) ...[
|
||||||
|
Padding(
|
||||||
|
padding: EdgeInsets.only(left: 10),
|
||||||
|
child: CommentItem(
|
||||||
|
avatar: Avatar(
|
||||||
|
url: comment.user.avatarUrl,
|
||||||
|
linkUrl: '/gitee/${comment.user.login}',
|
||||||
|
),
|
||||||
|
createdAt: DateTime.parse(comment.createdAt),
|
||||||
|
body: comment.body,
|
||||||
|
login: comment.user.login,
|
||||||
|
prefix: 'gitee')),
|
||||||
|
CommonStyle.border,
|
||||||
|
SizedBox(height: 16),
|
||||||
|
],
|
||||||
|
]),
|
||||||
|
]);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
@ -33,7 +33,7 @@ class GePullsScreen extends StatelessWidget {
|
|||||||
subtitle: '#' + p.number.toString(),
|
subtitle: '#' + p.number.toString(),
|
||||||
title: p.title,
|
title: p.title,
|
||||||
updatedAt: DateTime.parse(p.updatedAt),
|
updatedAt: DateTime.parse(p.updatedAt),
|
||||||
url: p.htmlUrl,
|
url: '/gitee/$owner/$name/pulls/${p.number}',
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -42,7 +42,6 @@ class GhComparisonScreen extends StatelessWidget {
|
|||||||
additions: vs.additions,
|
additions: vs.additions,
|
||||||
deletions: vs.deletions,
|
deletions: vs.deletions,
|
||||||
status: vs.status,
|
status: vs.status,
|
||||||
changes: vs.changes,
|
|
||||||
patch: vs.patch,
|
patch: vs.patch,
|
||||||
))
|
))
|
||||||
.toList(),
|
.toList(),
|
||||||
|
@ -48,7 +48,6 @@ class GhFilesScreen extends StatelessWidget {
|
|||||||
additions: v.additions,
|
additions: v.additions,
|
||||||
deletions: v.deletions,
|
deletions: v.deletions,
|
||||||
status: v.status,
|
status: v.status,
|
||||||
changes: v.changes,
|
|
||||||
patch: v.patch,
|
patch: v.patch,
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
@ -9,7 +9,6 @@ import 'package:flutter_highlight/theme_map.dart';
|
|||||||
class FilesItem extends StatelessWidget {
|
class FilesItem extends StatelessWidget {
|
||||||
final String filename;
|
final String filename;
|
||||||
final String status;
|
final String status;
|
||||||
final int changes;
|
|
||||||
final int additions;
|
final int additions;
|
||||||
final int deletions;
|
final int deletions;
|
||||||
final String patch;
|
final String patch;
|
||||||
@ -17,7 +16,6 @@ class FilesItem extends StatelessWidget {
|
|||||||
FilesItem({
|
FilesItem({
|
||||||
@required this.filename,
|
@required this.filename,
|
||||||
@required this.status,
|
@required this.status,
|
||||||
@required this.changes,
|
|
||||||
@required this.deletions,
|
@required this.deletions,
|
||||||
@required this.additions,
|
@required this.additions,
|
||||||
@required this.patch,
|
@required this.patch,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user