feat(gitea): issue and pr screen

This commit is contained in:
Rongjian Zhang 2020-02-01 15:42:10 +08:00
parent 7d1065eaae
commit a7af4cdcd0
5 changed files with 97 additions and 2 deletions

View File

@ -214,8 +214,8 @@ class AuthModel with ChangeNotifier {
final info = json.decode(utf8.decode(res.bodyBytes));
return DataWithPage(
data: info,
cursor: int.tryParse(res.headers["x-page"]) + 1,
hasMore: res.headers['x-hasmore'] != null,
cursor: int.tryParse(res.headers["x-page"] ?? ''),
hasMore: res.headers['x-hasmore'] == 'true',
total: int.tryParse(res.headers['x-total'] ?? ''),
);
}

View File

@ -85,3 +85,17 @@ class GiteaCommitAuthor {
factory GiteaCommitAuthor.fromJson(Map<String, dynamic> json) =>
_$GiteaCommitAuthorFromJson(json);
}
@JsonSerializable(fieldRename: FieldRename.snake)
class GiteaIssue {
String title;
String body;
int number;
GiteaUser user;
int comments;
DateTime updatedAt;
String htmlUrl;
GiteaIssue();
factory GiteaIssue.fromJson(Map<String, dynamic> json) =>
_$GiteaIssueFromJson(json);
}

View File

@ -153,3 +153,29 @@ Map<String, dynamic> _$GiteaCommitAuthorToJson(GiteaCommitAuthor instance) =>
'email': instance.email,
'date': instance.date?.toIso8601String(),
};
GiteaIssue _$GiteaIssueFromJson(Map<String, dynamic> json) {
return GiteaIssue()
..title = json['title'] as String
..body = json['body'] as String
..number = json['number'] as int
..user = json['user'] == null
? null
: GiteaUser.fromJson(json['user'] as Map<String, dynamic>)
..comments = json['comments'] as int
..updatedAt = json['updated_at'] == null
? null
: DateTime.parse(json['updated_at'] as String)
..htmlUrl = json['html_url'] as String;
}
Map<String, dynamic> _$GiteaIssueToJson(GiteaIssue instance) =>
<String, dynamic>{
'title': instance.title,
'body': instance.body,
'number': instance.number,
'user': instance.user,
'comments': instance.comments,
'updated_at': instance.updatedAt?.toIso8601String(),
'html_url': instance.htmlUrl,
};

View File

@ -2,6 +2,7 @@ import 'package:fluro/fluro.dart';
import 'package:git_touch/screens/code_theme.dart';
import 'package:git_touch/screens/commits.dart';
import 'package:git_touch/screens/gitea_commits.dart';
import 'package:git_touch/screens/gitea_issues.dart';
import 'package:git_touch/screens/gitea_object.dart';
import 'package:git_touch/screens/gitea_repo.dart';
import 'package:git_touch/screens/gitea_user.dart';
@ -197,6 +198,8 @@ class GiteaRouter {
GiteaRouter.repo,
GiteaRouter.object,
GiteaRouter.commits,
GiteaRouter.issues,
GiteaRouter.pulls,
];
static final user = RouterScreen(
'/:login',
@ -217,4 +220,10 @@ class GiteaRouter {
);
static final commits = RouterScreen('/:owner/:name/commits',
(_, p) => GiteaCommitsScreen(p['owner'].first, p['name'].first));
static final issues = RouterScreen('/:owner/:name/issues',
(_, p) => GiteaIssuesScreen(p['owner'].first, p['name'].first));
static final pulls = RouterScreen(
'/:owner/:name/pulls',
(_, p) =>
GiteaIssuesScreen(p['owner'].first, p['name'].first, isPr: true));
}

View File

@ -0,0 +1,46 @@
import 'package:flutter/material.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/widgets/app_bar_title.dart';
import 'package:git_touch/widgets/issue_item.dart';
import 'package:provider/provider.dart';
class GiteaIssuesScreen extends StatelessWidget {
final String owner;
final String name;
final bool isPr;
GiteaIssuesScreen(this.owner, this.name, {this.isPr = false});
Future<ListPayload<GiteaIssue, int>> _query(BuildContext context,
[int page = 1]) async {
final auth = Provider.of<AuthModel>(context);
final type = isPr ? 'pulls' : 'issues';
final res = await auth.fetchGiteaWithPage(
'/repos/$owner/$name/issues?state=open&page=$page&limit=20&type=$type');
return ListPayload(
cursor: res.cursor,
hasMore: res.hasMore,
items: (res.data as List).map((v) => GiteaIssue.fromJson(v)).toList(),
);
}
@override
Widget build(BuildContext context) {
return ListStatefulScaffold<GiteaIssue, int>(
title: AppBarTitle(isPr ? 'Pull Requests' : 'Issues'),
// TODO: create issue
onRefresh: () => _query(context),
onLoadMore: (cursor) => _query(context, cursor),
itemBuilder: (p) => IssueItem(
author: p.user.login,
avatarUrl: p.user.avatarUrl,
commentCount: p.comments,
number: p.number,
title: p.title,
updatedAt: p.updatedAt,
url: p.htmlUrl,
),
);
}
}