mirror of
https://github.com/git-touch/git-touch
synced 2025-02-08 23:58:46 +01:00
feat(gitea): issue, issueComment, labels, refactor(GeIssueComment) (#155)
* feat(gitea): issue, issueAdd, issueComment * rollback grade.properties change * refactor: GeIssueComment, fix: url GtIssueComment * feat: labels
This commit is contained in:
parent
e9222f414b
commit
d74b141279
@ -245,11 +245,55 @@ class AuthModel with ChangeNotifier {
|
||||
}
|
||||
}
|
||||
|
||||
Future fetchGitea(String p) async {
|
||||
final res = await http.get('${activeAccount.domain}/api/v1$p',
|
||||
headers: {'Authorization': 'token $token'});
|
||||
final info = json.decode(utf8.decode(res.bodyBytes));
|
||||
return info;
|
||||
Future fetchGitea(
|
||||
String p, {
|
||||
requestType = 'GET',
|
||||
Map<String, dynamic> body = const {},
|
||||
}) async {
|
||||
http.Response res;
|
||||
Map<String, String> headers = {
|
||||
'Authorization': 'token $token',
|
||||
HttpHeaders.contentTypeHeader: 'application/json'
|
||||
};
|
||||
switch (requestType) {
|
||||
case 'DELETE':
|
||||
{
|
||||
await http.delete(
|
||||
'${activeAccount.domain}/api/v1$p',
|
||||
headers: headers,
|
||||
);
|
||||
break;
|
||||
}
|
||||
case 'POST':
|
||||
{
|
||||
res = await http.post(
|
||||
'${activeAccount.domain}/api/v1$p',
|
||||
headers: headers,
|
||||
body: jsonEncode(body),
|
||||
);
|
||||
break;
|
||||
}
|
||||
case 'PATCH':
|
||||
{
|
||||
res = await http.patch(
|
||||
'${activeAccount.domain}/api/v1$p',
|
||||
headers: headers,
|
||||
body: jsonEncode(body),
|
||||
);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
res = await http.get('${activeAccount.domain}/api/v1$p',
|
||||
headers: headers);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (requestType != 'DELETE') {
|
||||
final info = json.decode(utf8.decode(res.bodyBytes));
|
||||
return info;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
Future<DataWithPage> fetchGiteaWithPage(String path,
|
||||
|
@ -108,12 +108,23 @@ class GiteaIssue {
|
||||
GiteaUser user;
|
||||
int comments;
|
||||
DateTime updatedAt;
|
||||
String state;
|
||||
String htmlUrl;
|
||||
List<GiteaLabel> labels;
|
||||
GiteaIssue();
|
||||
factory GiteaIssue.fromJson(Map<String, dynamic> json) =>
|
||||
_$GiteaIssueFromJson(json);
|
||||
}
|
||||
|
||||
@JsonSerializable(fieldRename: FieldRename.snake)
|
||||
class GiteaLabel {
|
||||
String color;
|
||||
String name;
|
||||
GiteaLabel();
|
||||
factory GiteaLabel.fromJson(Map<String, dynamic> json) =>
|
||||
_$GiteaLabelFromJson(json);
|
||||
}
|
||||
|
||||
@JsonSerializable(fieldRename: FieldRename.snake)
|
||||
class GiteaHeatmapItem {
|
||||
int timestamp;
|
||||
@ -122,3 +133,17 @@ class GiteaHeatmapItem {
|
||||
factory GiteaHeatmapItem.fromJson(Map<String, dynamic> json) =>
|
||||
_$GiteaHeatmapItemFromJson(json);
|
||||
}
|
||||
|
||||
@JsonSerializable(fieldRename: FieldRename.snake)
|
||||
class GiteaComment {
|
||||
String body;
|
||||
DateTime createdAt;
|
||||
String htmlUrl;
|
||||
String originalAuthor;
|
||||
DateTime updatedAt;
|
||||
int id;
|
||||
GiteaUser user;
|
||||
GiteaComment();
|
||||
factory GiteaComment.fromJson(Map<String, dynamic> json) =>
|
||||
_$GiteaCommentFromJson(json);
|
||||
}
|
||||
|
@ -187,7 +187,12 @@ GiteaIssue _$GiteaIssueFromJson(Map<String, dynamic> json) {
|
||||
..updatedAt = json['updated_at'] == null
|
||||
? null
|
||||
: DateTime.parse(json['updated_at'] as String)
|
||||
..htmlUrl = json['html_url'] as String;
|
||||
..state = json['state'] as String
|
||||
..htmlUrl = json['html_url'] as String
|
||||
..labels = (json['labels'] as List)
|
||||
?.map((e) =>
|
||||
e == null ? null : GiteaLabel.fromJson(e as Map<String, dynamic>))
|
||||
?.toList();
|
||||
}
|
||||
|
||||
Map<String, dynamic> _$GiteaIssueToJson(GiteaIssue instance) =>
|
||||
@ -198,7 +203,21 @@ Map<String, dynamic> _$GiteaIssueToJson(GiteaIssue instance) =>
|
||||
'user': instance.user,
|
||||
'comments': instance.comments,
|
||||
'updated_at': instance.updatedAt?.toIso8601String(),
|
||||
'state': instance.state,
|
||||
'html_url': instance.htmlUrl,
|
||||
'labels': instance.labels,
|
||||
};
|
||||
|
||||
GiteaLabel _$GiteaLabelFromJson(Map<String, dynamic> json) {
|
||||
return GiteaLabel()
|
||||
..color = json['color'] as String
|
||||
..name = json['name'] as String;
|
||||
}
|
||||
|
||||
Map<String, dynamic> _$GiteaLabelToJson(GiteaLabel instance) =>
|
||||
<String, dynamic>{
|
||||
'color': instance.color,
|
||||
'name': instance.name,
|
||||
};
|
||||
|
||||
GiteaHeatmapItem _$GiteaHeatmapItemFromJson(Map<String, dynamic> json) {
|
||||
@ -212,3 +231,31 @@ Map<String, dynamic> _$GiteaHeatmapItemToJson(GiteaHeatmapItem instance) =>
|
||||
'timestamp': instance.timestamp,
|
||||
'contributions': instance.contributions,
|
||||
};
|
||||
|
||||
GiteaComment _$GiteaCommentFromJson(Map<String, dynamic> json) {
|
||||
return GiteaComment()
|
||||
..body = json['body'] as String
|
||||
..createdAt = json['created_at'] == null
|
||||
? null
|
||||
: DateTime.parse(json['created_at'] as String)
|
||||
..htmlUrl = json['html_url'] as String
|
||||
..originalAuthor = json['original_author'] as String
|
||||
..updatedAt = json['updated_at'] == null
|
||||
? null
|
||||
: DateTime.parse(json['updated_at'] as String)
|
||||
..id = json['id'] as int
|
||||
..user = json['user'] == null
|
||||
? null
|
||||
: GiteaUser.fromJson(json['user'] as Map<String, dynamic>);
|
||||
}
|
||||
|
||||
Map<String, dynamic> _$GiteaCommentToJson(GiteaComment instance) =>
|
||||
<String, dynamic>{
|
||||
'body': instance.body,
|
||||
'created_at': instance.createdAt?.toIso8601String(),
|
||||
'html_url': instance.htmlUrl,
|
||||
'original_author': instance.originalAuthor,
|
||||
'updated_at': instance.updatedAt?.toIso8601String(),
|
||||
'id': instance.id,
|
||||
'user': instance.user,
|
||||
};
|
||||
|
@ -35,6 +35,9 @@ import 'package:git_touch/screens/gh_org_repos.dart';
|
||||
import 'package:git_touch/screens/gl_commit.dart';
|
||||
import 'package:git_touch/screens/gl_starrers.dart';
|
||||
import 'package:git_touch/screens/gt_commits.dart';
|
||||
import 'package:git_touch/screens/gt_issue.dart';
|
||||
import 'package:git_touch/screens/gt_issue_comment.dart';
|
||||
import 'package:git_touch/screens/gt_issue_form.dart';
|
||||
import 'package:git_touch/screens/gt_issues.dart';
|
||||
import 'package:git_touch/screens/gt_object.dart';
|
||||
import 'package:git_touch/screens/gt_orgs.dart';
|
||||
@ -321,6 +324,9 @@ class GiteaRouter {
|
||||
GiteaRouter.commits,
|
||||
GiteaRouter.issues,
|
||||
GiteaRouter.pulls,
|
||||
GiteaRouter.issueAdd,
|
||||
GiteaRouter.issue,
|
||||
GiteaRouter.issueComment,
|
||||
];
|
||||
static final status =
|
||||
RouterScreen('/status', (context, parameters) => GtStatusScreen());
|
||||
@ -387,6 +393,20 @@ class GiteaRouter {
|
||||
(context, parameters) => GtIssuesScreen(
|
||||
parameters['owner'].first, parameters['name'].first,
|
||||
isPr: true));
|
||||
static final issueAdd = RouterScreen(
|
||||
'/:owner/:name/issues/new',
|
||||
(context, parameters) => GtIssueFormScreen(
|
||||
parameters['owner'].first, parameters['name'].first));
|
||||
static final issue = RouterScreen(
|
||||
'/:owner/:name/issues/:number',
|
||||
(context, parameters) => GtIssueScreen(parameters['owner'].first,
|
||||
parameters['name'].first, parameters['number'].first));
|
||||
static final issueComment = RouterScreen(
|
||||
'/:owner/:name/issues/:number/comment',
|
||||
(context, parameters) => GtIssueCommentScreen(parameters['owner'].first,
|
||||
parameters['name'].first, parameters['number'].first,
|
||||
body: parameters['body'] != null ? parameters['body'].first : '',
|
||||
id: parameters['id'] != null ? parameters['id'].first : ''));
|
||||
}
|
||||
|
||||
class BitbucketRouter {
|
||||
|
@ -53,53 +53,25 @@ class _GeIssueCommentScreenState extends State<GeIssueCommentScreen> {
|
||||
CupertinoButton.filled(
|
||||
child: Text('Comment'),
|
||||
onPressed: () async {
|
||||
if (!widget.isPr) {
|
||||
if (!isEdit) {
|
||||
final res = await auth.fetchGitee(
|
||||
'/repos/${widget.owner}/${widget.name}/issues/${widget.number}/comments',
|
||||
requestType: 'POST',
|
||||
body: {'body': _controller.text, 'repo': widget.name},
|
||||
);
|
||||
} else {
|
||||
final res = await auth.fetchGitee(
|
||||
'/repos/${widget.owner}/${widget.name}/issues/comments/${int.parse(widget.id)}',
|
||||
requestType: 'PATCH',
|
||||
body: {'body': _controller.text, 'repo': widget.name},
|
||||
);
|
||||
}
|
||||
Navigator.pop(context, '');
|
||||
await theme.push(
|
||||
context,
|
||||
'/gitee/${widget.owner}/${widget.name}/issues/${widget.number}',
|
||||
replace: true,
|
||||
if (!isEdit) {
|
||||
final res = await auth.fetchGitee(
|
||||
'/repos/${widget.owner}/${widget.name}/${widget.isPr ? 'pulls' : 'issues'}/${widget.number}/comments',
|
||||
requestType: 'POST',
|
||||
body: {'body': _controller.text, 'repo': widget.name},
|
||||
);
|
||||
} else {
|
||||
if (!isEdit) {
|
||||
final res = await auth.fetchGitee(
|
||||
'/repos/${widget.owner}/${widget.name}/pulls/${widget.number}/comments',
|
||||
requestType: 'POST',
|
||||
body: {'body': _controller.text, 'repo': widget.name},
|
||||
);
|
||||
Navigator.pop(context, '');
|
||||
await theme.push(
|
||||
context,
|
||||
'/gitee/${widget.owner}/${widget.name}/pulls/${widget.number}',
|
||||
replace: true,
|
||||
);
|
||||
} else {
|
||||
final res = await auth.fetchGitee(
|
||||
'/repos/${widget.owner}/${widget.name}/pulls/comments/${int.parse(widget.id)}',
|
||||
requestType: 'PATCH',
|
||||
body: {'body': _controller.text, 'repo': widget.name},
|
||||
);
|
||||
}
|
||||
Navigator.pop(context, '');
|
||||
await theme.push(
|
||||
context,
|
||||
'/gitee/${widget.owner}/${widget.name}/pulls/${widget.number}',
|
||||
replace: true,
|
||||
final res = await auth.fetchGitee(
|
||||
'/repos/${widget.owner}/${widget.name}/${widget.isPr ? 'pulls' : 'issues'}/comments/${int.parse(widget.id)}',
|
||||
requestType: 'PATCH',
|
||||
body: {'body': _controller.text, 'repo': widget.name},
|
||||
);
|
||||
}
|
||||
Navigator.pop(context, '');
|
||||
await theme.push(
|
||||
context,
|
||||
'/gitee/${widget.owner}/${widget.name}/${widget.isPr ? 'pulls' : 'issues'}/${widget.number}',
|
||||
replace: true,
|
||||
);
|
||||
},
|
||||
),
|
||||
],
|
||||
|
153
lib/screens/gt_issue.dart
Normal file
153
lib/screens/gt_issue.dart
Normal file
@ -0,0 +1,153 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:git_touch/models/gitea.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/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 GtIssueScreen extends StatelessWidget {
|
||||
final String owner;
|
||||
final String name;
|
||||
final String number;
|
||||
final bool isPr;
|
||||
|
||||
GtIssueScreen(this.owner, this.name, this.number, {this.isPr: false});
|
||||
|
||||
List<ActionItem> _buildCommentActionItem(
|
||||
BuildContext context, GiteaComment comment) {
|
||||
final auth = context.read<AuthModel>();
|
||||
final theme = context.read<ThemeModel>();
|
||||
return [
|
||||
ActionItem(
|
||||
iconData: Octicons.pencil,
|
||||
text: 'Edit',
|
||||
onTap: (_) {
|
||||
final uri = Uri(
|
||||
path: '/gitea/$owner/$name/issues/$number/comment',
|
||||
queryParameters: {
|
||||
'body': comment.body,
|
||||
'id': comment.id.toString(),
|
||||
},
|
||||
).toString();
|
||||
theme.push(context, uri);
|
||||
}),
|
||||
ActionItem(
|
||||
iconData: Octicons.trashcan,
|
||||
text: 'Delete',
|
||||
onTap: (_) async {
|
||||
await auth.fetchGitea(
|
||||
'/repos/$owner/$name/issues/comments/${comment.id}',
|
||||
requestType: 'DELETE');
|
||||
await theme.push(context, '/gitea/$owner/$name/issues/$number',
|
||||
replace: true);
|
||||
},
|
||||
),
|
||||
];
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return RefreshStatefulScaffold<Tuple2<GiteaIssue, List<GiteaComment>>>(
|
||||
title: Text("Issue: #$number"),
|
||||
fetch: () async {
|
||||
final auth = context.read<AuthModel>();
|
||||
final items = await Future.wait([
|
||||
auth.fetchGitea('/repos/$owner/$name/issues/$number'),
|
||||
auth.fetchGitea('/repos/$owner/$name/issues/$number/comments')
|
||||
]);
|
||||
return Tuple2(GiteaIssue.fromJson(items[0]),
|
||||
[for (var v in items[1]) GiteaComment.fromJson(v)]);
|
||||
},
|
||||
actionBuilder: (data, _) => ActionEntry(
|
||||
iconData: Octicons.plus,
|
||||
url: '/gitea/$owner/$name/issues/$number/comment',
|
||||
),
|
||||
bodyBuilder: (data, _) {
|
||||
final issue = data.item1;
|
||||
final comments = data.item2;
|
||||
final theme = context.read<ThemeModel>();
|
||||
final auth = context.read<AuthModel>();
|
||||
return Column(children: <Widget>[
|
||||
Container(
|
||||
padding: CommonStyle.padding,
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: <Widget>[
|
||||
Link(
|
||||
url: '/gitea/$owner/$name',
|
||||
child: Row(
|
||||
children: <Widget>[
|
||||
Avatar(
|
||||
url: issue.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(
|
||||
issue.title,
|
||||
style: TextStyle(
|
||||
fontSize: 20,
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
),
|
||||
SizedBox(height: 8),
|
||||
StateLabel(
|
||||
issue.state == 'open'
|
||||
? StateLabelStatus.issueOpened
|
||||
: StateLabelStatus.issueClosed,
|
||||
small: true),
|
||||
SizedBox(height: 16),
|
||||
CommonStyle.border,
|
||||
],
|
||||
)),
|
||||
Column(children: [
|
||||
for (var comment in comments) ...[
|
||||
Padding(
|
||||
padding: EdgeInsets.only(left: 10),
|
||||
child: CommentItem(
|
||||
avatar: Avatar(
|
||||
url: comment.user.avatarUrl,
|
||||
linkUrl: '/gitea/${comment.user.login}',
|
||||
),
|
||||
createdAt: comment.createdAt,
|
||||
body: comment.body,
|
||||
login: comment.user.login,
|
||||
prefix: 'gitea',
|
||||
commentActionItemList:
|
||||
_buildCommentActionItem(context, comment),
|
||||
)),
|
||||
CommonStyle.border,
|
||||
SizedBox(height: 16),
|
||||
],
|
||||
]),
|
||||
]);
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
81
lib/screens/gt_issue_comment.dart
Normal file
81
lib/screens/gt_issue_comment.dart
Normal file
@ -0,0 +1,81 @@
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:git_touch/models/auth.dart';
|
||||
import 'package:git_touch/models/theme.dart';
|
||||
import 'package:git_touch/scaffolds/common.dart';
|
||||
import 'package:git_touch/utils/utils.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
class GtIssueCommentScreen extends StatefulWidget {
|
||||
final String owner;
|
||||
final String name;
|
||||
final String number;
|
||||
final bool isPr;
|
||||
final String body;
|
||||
final String id;
|
||||
GtIssueCommentScreen(this.owner, this.name, this.number,
|
||||
{this.isPr: false, this.body: '', this.id: ''});
|
||||
|
||||
@override
|
||||
_GtIssueCommentScreenState createState() => _GtIssueCommentScreenState();
|
||||
}
|
||||
|
||||
class _GtIssueCommentScreenState extends State<GtIssueCommentScreen> {
|
||||
bool isEdit = false;
|
||||
TextEditingController _controller = new TextEditingController();
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
_controller.text = widget.body;
|
||||
if (_controller.text != '') {
|
||||
isEdit = true;
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final theme = Provider.of<ThemeModel>(context);
|
||||
final auth = Provider.of<AuthModel>(context);
|
||||
return CommonScaffold(
|
||||
title: Text(isEdit ? 'Update Comment' : 'New Comment'),
|
||||
body: Column(
|
||||
children: <Widget>[
|
||||
Padding(
|
||||
padding: CommonStyle.padding,
|
||||
child: CupertinoTextField(
|
||||
controller: _controller,
|
||||
style: TextStyle(color: theme.palette.text),
|
||||
placeholder: 'Body',
|
||||
maxLines: 10,
|
||||
),
|
||||
),
|
||||
CupertinoButton.filled(
|
||||
child: Text('Comment'),
|
||||
onPressed: () async {
|
||||
if (!isEdit) {
|
||||
final res = await auth.fetchGitea(
|
||||
'/repos/${widget.owner}/${widget.name}/${widget.isPr ? 'pulls' : 'issues'}/${widget.number}/comments',
|
||||
requestType: 'POST',
|
||||
body: {'body': _controller.text, 'repo': widget.name},
|
||||
);
|
||||
} else {
|
||||
final res = await auth.fetchGitea(
|
||||
'/repos/${widget.owner}/${widget.name}/${widget.isPr ? 'pulls' : 'issues'}/comments/${int.parse(widget.id)}',
|
||||
requestType: 'PATCH',
|
||||
body: {'body': _controller.text, 'repo': widget.name},
|
||||
);
|
||||
}
|
||||
Navigator.pop(context, '');
|
||||
await theme.push(
|
||||
context,
|
||||
'/gitea/${widget.owner}/${widget.name}/${widget.isPr ? 'pulls' : 'issues'}/${widget.number}',
|
||||
replace: true,
|
||||
);
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
78
lib/screens/gt_issue_form.dart
Normal file
78
lib/screens/gt_issue_form.dart
Normal file
@ -0,0 +1,78 @@
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:git_touch/models/auth.dart';
|
||||
import 'package:git_touch/models/gitea.dart';
|
||||
import 'package:git_touch/models/theme.dart';
|
||||
import 'package:git_touch/scaffolds/common.dart';
|
||||
import 'package:git_touch/utils/utils.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
class GtIssueFormScreen extends StatefulWidget {
|
||||
final String owner;
|
||||
final String name;
|
||||
GtIssueFormScreen(this.owner, this.name);
|
||||
|
||||
@override
|
||||
_GtIssueFormScreenState createState() => _GtIssueFormScreenState();
|
||||
}
|
||||
|
||||
class _GtIssueFormScreenState extends State<GtIssueFormScreen> {
|
||||
var _title = '';
|
||||
var _body = '';
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final theme = Provider.of<ThemeModel>(context);
|
||||
final auth = Provider.of<AuthModel>(context);
|
||||
return CommonScaffold(
|
||||
title: Text('Submit an issue'),
|
||||
body: Column(
|
||||
children: <Widget>[
|
||||
Padding(
|
||||
padding: CommonStyle.padding,
|
||||
child: CupertinoTextField(
|
||||
style: TextStyle(color: theme.palette.text),
|
||||
placeholder: 'Title',
|
||||
onChanged: (v) {
|
||||
setState(() {
|
||||
_title = v;
|
||||
});
|
||||
},
|
||||
),
|
||||
),
|
||||
Padding(
|
||||
padding: CommonStyle.padding,
|
||||
child: CupertinoTextField(
|
||||
style: TextStyle(color: theme.palette.text),
|
||||
placeholder: 'Body',
|
||||
onChanged: (v) {
|
||||
setState(() {
|
||||
_body = v;
|
||||
});
|
||||
},
|
||||
maxLines: 10,
|
||||
),
|
||||
),
|
||||
CupertinoButton.filled(
|
||||
child: Text('Submit'),
|
||||
onPressed: () async {
|
||||
final res = await auth.fetchGitea(
|
||||
'/repos/${widget.owner}/${widget.name}/issues',
|
||||
requestType: 'POST',
|
||||
body: {'body': _body, 'title': _title},
|
||||
).then((v) {
|
||||
return GiteaIssue.fromJson(v);
|
||||
});
|
||||
Navigator.pop(context);
|
||||
await theme.push(
|
||||
context,
|
||||
'/gitea/${widget.owner}/${widget.name}/issues',
|
||||
replace: true,
|
||||
);
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
@ -3,8 +3,11 @@ import 'package:git_touch/generated/l10n.dart';
|
||||
import 'package:git_touch/models/auth.dart';
|
||||
import 'package:git_touch/models/gitea.dart';
|
||||
import 'package:git_touch/scaffolds/list_stateful.dart';
|
||||
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 GtIssuesScreen extends StatelessWidget {
|
||||
@ -18,7 +21,6 @@ class GtIssuesScreen extends StatelessWidget {
|
||||
return ListStatefulScaffold<GiteaIssue, int>(
|
||||
title:
|
||||
AppBarTitle(isPr ? S.of(context).pullRequests : S.of(context).issues),
|
||||
// TODO: create issue
|
||||
fetch: (page) async {
|
||||
final type = isPr ? 'pulls' : 'issues';
|
||||
final res = await context.read<AuthModel>().fetchGiteaWithPage(
|
||||
@ -30,6 +32,12 @@ class GtIssuesScreen extends StatelessWidget {
|
||||
items: (res.data as List).map((v) => GiteaIssue.fromJson(v)).toList(),
|
||||
);
|
||||
},
|
||||
actionBuilder: () => ActionEntry(
|
||||
iconData: isPr ? null : Octicons.plus,
|
||||
url: isPr
|
||||
? '/gitea/$owner/$name/pulls/new'
|
||||
: '/gitea/$owner/$name/issues/new',
|
||||
),
|
||||
itemBuilder: (p) => IssueItem(
|
||||
author: p.user.login,
|
||||
avatarUrl: p.user.avatarUrl,
|
||||
@ -37,7 +45,17 @@ class GtIssuesScreen extends StatelessWidget {
|
||||
subtitle: '#' + p.number.toString(),
|
||||
title: p.title,
|
||||
updatedAt: p.updatedAt,
|
||||
url: p.htmlUrl,
|
||||
url: isPr
|
||||
? p.htmlUrl // TODO: PR endpoints are not complete in Gitea
|
||||
: '/gitea/$owner/$name/issues/${p.number}',
|
||||
labels: isPr
|
||||
? null
|
||||
: p.labels.isEmpty
|
||||
? null
|
||||
: Wrap(spacing: 4, runSpacing: 4, children: [
|
||||
for (var label in p.labels)
|
||||
MyLabel(name: label.name, cssColor: label.color)
|
||||
]),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user