diff --git a/lib/main.dart b/lib/main.dart index 8a73dbe..3bd2fa9 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -8,6 +8,7 @@ import 'package:git_touch/screens/about.dart'; import 'package:git_touch/screens/code_theme.dart'; import 'package:git_touch/screens/commits.dart'; import 'package:git_touch/screens/gitlab_blob.dart'; +import 'package:git_touch/screens/gitlab_commits.dart'; import 'package:git_touch/screens/gitlab_issue.dart'; import 'package:git_touch/screens/gitlab_project.dart'; import 'package:git_touch/screens/gitlab_tree.dart'; @@ -67,6 +68,7 @@ void main() async { gitlabTreeRouter, gitlabProjectRouter, gitlabIssueRouter, + gitlabCommitsRouter, loginRouter, settingsRouter, userRouter, diff --git a/lib/models/gitlab.dart b/lib/models/gitlab.dart index c8dd9c7..0430534 100644 --- a/lib/models/gitlab.dart +++ b/lib/models/gitlab.dart @@ -81,23 +81,6 @@ class GitlabIssueNote { _$GitlabIssueNoteFromJson(json); } -@JsonSerializable(fieldRename: FieldRename.snake) -class GitlabProjectBadge { - String renderedImageUrl; - GitlabProjectBadge(); - factory GitlabProjectBadge.fromJson(Map json) => - _$GitlabProjectBadgeFromJson(json); -} - -@JsonSerializable(fieldRename: FieldRename.snake) -class GitlabProjectStatistics { - int commitCount; - int repositorySize; - GitlabProjectStatistics(); - factory GitlabProjectStatistics.fromJson(Map json) => - _$GitlabProjectStatisticsFromJson(json); -} - @JsonSerializable(fieldRename: FieldRename.snake) class GitlabProject { int id; @@ -119,6 +102,23 @@ class GitlabProject { _$GitlabProjectFromJson(json); } +@JsonSerializable(fieldRename: FieldRename.snake) +class GitlabProjectBadge { + String renderedImageUrl; + GitlabProjectBadge(); + factory GitlabProjectBadge.fromJson(Map json) => + _$GitlabProjectBadgeFromJson(json); +} + +@JsonSerializable(fieldRename: FieldRename.snake) +class GitlabProjectStatistics { + int commitCount; + int repositorySize; + GitlabProjectStatistics(); + factory GitlabProjectStatistics.fromJson(Map json) => + _$GitlabProjectStatisticsFromJson(json); +} + @JsonSerializable(fieldRename: FieldRename.snake) class GitlabProjectNamespace { int id; @@ -175,3 +175,16 @@ class GitlabEventNote { factory GitlabEventNote.fromJson(Map json) => _$GitlabEventNoteFromJson(json); } + +@JsonSerializable(fieldRename: FieldRename.snake) +class GitlabCommit { + String id; + String shortId; + String title; + DateTime createdAt; + String authorName; + String message; + GitlabCommit(); + factory GitlabCommit.fromJson(Map json) => + _$GitlabCommitFromJson(json); +} diff --git a/lib/models/gitlab.g.dart b/lib/models/gitlab.g.dart index e27240c..868352f 100644 --- a/lib/models/gitlab.g.dart +++ b/lib/models/gitlab.g.dart @@ -116,30 +116,6 @@ Map _$GitlabIssueNoteToJson(GitlabIssueNote instance) => 'body': instance.body, }; -GitlabProjectBadge _$GitlabProjectBadgeFromJson(Map json) { - return GitlabProjectBadge() - ..renderedImageUrl = json['rendered_image_url'] as String; -} - -Map _$GitlabProjectBadgeToJson(GitlabProjectBadge instance) => - { - 'rendered_image_url': instance.renderedImageUrl, - }; - -GitlabProjectStatistics _$GitlabProjectStatisticsFromJson( - Map json) { - return GitlabProjectStatistics() - ..commitCount = json['commit_count'] as int - ..repositorySize = json['repository_size'] as int; -} - -Map _$GitlabProjectStatisticsToJson( - GitlabProjectStatistics instance) => - { - 'commit_count': instance.commitCount, - 'repository_size': instance.repositorySize, - }; - GitlabProject _$GitlabProjectFromJson(Map json) { return GitlabProject() ..id = json['id'] as int @@ -182,6 +158,30 @@ Map _$GitlabProjectToJson(GitlabProject instance) => 'statistics': instance.statistics, }; +GitlabProjectBadge _$GitlabProjectBadgeFromJson(Map json) { + return GitlabProjectBadge() + ..renderedImageUrl = json['rendered_image_url'] as String; +} + +Map _$GitlabProjectBadgeToJson(GitlabProjectBadge instance) => + { + 'rendered_image_url': instance.renderedImageUrl, + }; + +GitlabProjectStatistics _$GitlabProjectStatisticsFromJson( + Map json) { + return GitlabProjectStatistics() + ..commitCount = json['commit_count'] as int + ..repositorySize = json['repository_size'] as int; +} + +Map _$GitlabProjectStatisticsToJson( + GitlabProjectStatistics instance) => + { + 'commit_count': instance.commitCount, + 'repository_size': instance.repositorySize, + }; + GitlabProjectNamespace _$GitlabProjectNamespaceFromJson( Map json) { return GitlabProjectNamespace() @@ -252,3 +252,25 @@ Map _$GitlabEventNoteToJson(GitlabEventNote instance) => 'noteable_type': instance.noteableType, 'noteable_iid': instance.noteableIid, }; + +GitlabCommit _$GitlabCommitFromJson(Map json) { + return GitlabCommit() + ..id = json['id'] as String + ..shortId = json['short_id'] as String + ..title = json['title'] as String + ..createdAt = json['created_at'] == null + ? null + : DateTime.parse(json['created_at'] as String) + ..authorName = json['author_name'] as String + ..message = json['message'] as String; +} + +Map _$GitlabCommitToJson(GitlabCommit instance) => + { + 'id': instance.id, + 'short_id': instance.shortId, + 'title': instance.title, + 'created_at': instance.createdAt?.toIso8601String(), + 'author_name': instance.authorName, + 'message': instance.message, + }; diff --git a/lib/screens/commits.dart b/lib/screens/commits.dart index 8879919..e5d08bc 100644 --- a/lib/screens/commits.dart +++ b/lib/screens/commits.dart @@ -1,14 +1,11 @@ import 'package:flutter/material.dart'; import 'package:git_touch/graphql/gh.dart'; import 'package:git_touch/models/auth.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:git_touch/widgets/link.dart'; +import 'package:git_touch/widgets/commit_item.dart'; import 'package:provider/provider.dart'; -import 'package:timeago/timeago.dart' as timeago; -import 'package:git_touch/widgets/avatar.dart'; final commitsRouter = RouterScreen( '/:owner/:name/commits', @@ -55,60 +52,23 @@ class CommitsScreen extends StatelessWidget { @override Widget build(BuildContext context) { - final theme = Provider.of(context); - return ListStatefulScaffold( title: AppBarTitle('Commits'), onRefresh: () => _query(context), onLoadMore: (cursor) => _query(context, cursor), itemBuilder: (payload) { - return Link( + return CommitItem( url: payload.url, - child: Container( - padding: CommonStyle.padding, - child: Row( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Avatar(url: payload.author?.avatarUrl), - SizedBox(width: 10), - Expanded( - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text( - payload.messageHeadline, - style: TextStyle( - fontSize: 17, - color: theme.palette.text, - ), - overflow: TextOverflow.ellipsis, - ), - SizedBox(height: 4), - Wrap( - children: [ - Text( - payload.author?.user?.login ?? - payload.author.name, - style: TextStyle(fontSize: 15)), - Text( - ' committed ${timeago.format(payload.committedDate)}', - style: TextStyle( - color: theme.palette.secondaryText, - fontSize: 15, - ), - ), - if (payload.status != null) ...[ - SizedBox(width: 4), - _buildStatus(payload.status.state), - ], - ], - ) - ], - ), - ) - ], - ), - ), + avatarUrl: payload.author?.avatarUrl, + message: payload.messageHeadline, + author: payload.author?.user?.login ?? payload.author.name, + createdAt: payload.committedDate, + widgets: payload.status == null + ? null + : [ + SizedBox(width: 4), + _buildStatus(payload.status.state), + ], ); }, ); diff --git a/lib/screens/gitlab_commits.dart b/lib/screens/gitlab_commits.dart new file mode 100644 index 0000000..e720746 --- /dev/null +++ b/lib/screens/gitlab_commits.dart @@ -0,0 +1,50 @@ +import 'package:flutter/material.dart'; +import 'package:git_touch/models/auth.dart'; +import 'package:git_touch/models/gitlab.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:git_touch/widgets/commit_item.dart'; +import 'package:provider/provider.dart'; + +final gitlabCommitsRouter = RouterScreen('/gitlab/projects/:id/commits', + (context, params) => GitlabCommitsScreen(params['id'].first)); + +class GitlabCommitsScreen extends StatelessWidget { + final String id; + // final String branch; // TODO: + + GitlabCommitsScreen(this.id); + + Future> _query(BuildContext context, + [int page = 1]) async { + final auth = Provider.of(context); + final res = + await auth.fetchGitlab('/projects/$id/repository/commits?page=$page'); + return ListPayload( + cursor: page + 1, + hasMore: true, // TODO: + items: (res as List).map((v) => GitlabCommit.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.authorName, + avatarUrl: null, + createdAt: c.createdAt, + message: c.message, + // url: '${auth.activeAccount.domain}/', + url: null, // TODO: + ); + }, + ); + } +} diff --git a/lib/widgets/commit_item.dart b/lib/widgets/commit_item.dart new file mode 100644 index 0000000..1427e7a --- /dev/null +++ b/lib/widgets/commit_item.dart @@ -0,0 +1,70 @@ +import 'package:flutter/material.dart'; +import 'package:git_touch/models/theme.dart'; +import 'package:git_touch/utils/utils.dart'; +import 'package:git_touch/widgets/avatar.dart'; +import 'package:git_touch/widgets/link.dart'; +import 'package:provider/provider.dart'; +import 'package:timeago/timeago.dart' as timeago; + +class CommitItem extends StatelessWidget { + final String url; + final String avatarUrl; + final String message; + final String author; + final DateTime createdAt; + final List widgets; + CommitItem({ + @required this.url, + @required this.avatarUrl, + @required this.message, + @required this.author, + @required this.createdAt, + this.widgets, + }); + @override + Widget build(BuildContext context) { + final theme = Provider.of(context); + return Link( + url: url, + child: Container( + padding: CommonStyle.padding, + child: Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Avatar(url: avatarUrl), + SizedBox(width: 10), + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + message, + style: TextStyle( + fontSize: 17, + color: theme.palette.text, + ), + overflow: TextOverflow.ellipsis, + ), + SizedBox(height: 4), + Wrap( + children: [ + Text(author, style: TextStyle(fontSize: 15)), + Text( + ' committed ${timeago.format(createdAt)}', + style: TextStyle( + color: theme.palette.secondaryText, + fontSize: 15, + ), + ), + if (widgets != null) ...widgets, + ], + ) + ], + ), + ) + ], + ), + ), + ); + } +}