diff --git a/lib/models/auth.dart b/lib/models/auth.dart index fdcb014..0b0ce32 100644 --- a/lib/models/auth.dart +++ b/lib/models/auth.dart @@ -208,6 +208,18 @@ class AuthModel with ChangeNotifier { return info; } + Future fetchGiteaWithPage(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 DataWithPage( + data: info, + cursor: int.tryParse(res.headers["x-page"]) + 1, + hasMore: res.headers['x-hasmore'] != null, + total: int.tryParse(res.headers['x-total'] ?? ''), + ); + } + Future init() async { // Listen scheme _sub = getUriLinksStream().listen(_onSchemeDetected, onError: (err) { diff --git a/lib/models/gitea.dart b/lib/models/gitea.dart index b99bd17..e937c5d 100644 --- a/lib/models/gitea.dart +++ b/lib/models/gitea.dart @@ -51,3 +51,37 @@ class GiteaBlob extends GiteaTree { factory GiteaBlob.fromJson(Map json) => _$GiteaBlobFromJson(json); } + +@JsonSerializable(fieldRename: FieldRename.snake) +class GiteaCommit { + int number; + GiteaUser author; + String title; + String body; + GiteaCommitDetail commit; + String sha; + String htmlUrl; + GiteaCommit(); + factory GiteaCommit.fromJson(Map json) => + _$GiteaCommitFromJson(json); +} + +@JsonSerializable(fieldRename: FieldRename.snake) +class GiteaCommitDetail { + String message; + GiteaCommitAuthor author; + GiteaCommitAuthor committer; + GiteaCommitDetail(); + factory GiteaCommitDetail.fromJson(Map json) => + _$GiteaCommitDetailFromJson(json); +} + +@JsonSerializable(fieldRename: FieldRename.snake) +class GiteaCommitAuthor { + String name; + String email; + DateTime date; + GiteaCommitAuthor(); + factory GiteaCommitAuthor.fromJson(Map json) => + _$GiteaCommitAuthorFromJson(json); +} diff --git a/lib/models/gitea.g.dart b/lib/models/gitea.g.dart index 442b911..abbdc33 100644 --- a/lib/models/gitea.g.dart +++ b/lib/models/gitea.g.dart @@ -94,3 +94,62 @@ Map _$GiteaBlobToJson(GiteaBlob instance) => { 'download_url': instance.downloadUrl, 'content': instance.content, }; + +GiteaCommit _$GiteaCommitFromJson(Map json) { + return GiteaCommit() + ..number = json['number'] as int + ..author = json['author'] == null + ? null + : GiteaUser.fromJson(json['author'] as Map) + ..title = json['title'] as String + ..body = json['body'] as String + ..commit = json['commit'] == null + ? null + : GiteaCommitDetail.fromJson(json['commit'] as Map) + ..sha = json['sha'] as String + ..htmlUrl = json['html_url'] as String; +} + +Map _$GiteaCommitToJson(GiteaCommit instance) => + { + 'number': instance.number, + 'author': instance.author, + 'title': instance.title, + 'body': instance.body, + 'commit': instance.commit, + 'sha': instance.sha, + 'html_url': instance.htmlUrl, + }; + +GiteaCommitDetail _$GiteaCommitDetailFromJson(Map json) { + return GiteaCommitDetail() + ..message = json['message'] as String + ..author = json['author'] == null + ? null + : GiteaCommitAuthor.fromJson(json['author'] as Map) + ..committer = json['committer'] == null + ? null + : GiteaCommitAuthor.fromJson(json['committer'] as Map); +} + +Map _$GiteaCommitDetailToJson(GiteaCommitDetail instance) => + { + 'message': instance.message, + 'author': instance.author, + 'committer': instance.committer, + }; + +GiteaCommitAuthor _$GiteaCommitAuthorFromJson(Map json) { + return GiteaCommitAuthor() + ..name = json['name'] as String + ..email = json['email'] as String + ..date = + json['date'] == null ? null : DateTime.parse(json['date'] as String); +} + +Map _$GiteaCommitAuthorToJson(GiteaCommitAuthor instance) => + { + 'name': instance.name, + 'email': instance.email, + 'date': instance.date?.toIso8601String(), + }; diff --git a/lib/router.dart b/lib/router.dart index ae7d20a..49fa03a 100644 --- a/lib/router.dart +++ b/lib/router.dart @@ -1,6 +1,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_object.dart'; import 'package:git_touch/screens/gitea_repo.dart'; import 'package:git_touch/screens/gitea_user.dart'; @@ -194,7 +195,8 @@ class GiteaRouter { static final routes = [ GiteaRouter.user, GiteaRouter.repo, - GiteaRouter.object + GiteaRouter.object, + GiteaRouter.commits, ]; static final user = RouterScreen( '/:login', @@ -206,11 +208,13 @@ class GiteaRouter { GiteaRepoScreen(params['owner'].first, params['name'].first), ); static final object = RouterScreen( - '/gitea/:owner/:name/blob', + '/:owner/:name/blob', (context, params) => GiteaObjectScreen( params['owner'].first, params['name'].first, path: params['path']?.first, ), ); + static final commits = RouterScreen('/:owner/:name/commits', + (_, p) => GiteaCommitsScreen(p['owner'].first, p['name'].first)); } diff --git a/lib/screens/gitea_commits.dart b/lib/screens/gitea_commits.dart new file mode 100644 index 0000000..034d256 --- /dev/null +++ b/lib/screens/gitea_commits.dart @@ -0,0 +1,44 @@ +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/commit_item.dart'; +import 'package:provider/provider.dart'; + +class GiteaCommitsScreen extends StatelessWidget { + final String owner; + final String name; + // final String branch; // TODO: + GiteaCommitsScreen(this.owner, this.name); + + Future> _query(BuildContext context, + [int page = 1]) async { + final auth = Provider.of(context); + final res = await auth + .fetchGiteaWithPage('/repos/$owner/$name/commits?page=$page&limit=20'); + return ListPayload( + cursor: res.cursor, + hasMore: res.hasMore, + items: (res.data as List).map((v) => GiteaCommit.fromJson(v)).toList(), + ); + } + + @override + Widget build(BuildContext context) { + return ListStatefulScaffold( + title: AppBarTitle('Commits'), + onRefresh: () => _query(context), + onLoadMore: (cursor) => _query(context, cursor), + itemBuilder: (c) { + return CommitItem( + author: c.author?.login ?? c.commit.author.name, + avatarUrl: null, + createdAt: c.commit.author.date, + message: c.commit.message, + url: c.htmlUrl, + ); + }, + ); + } +}