mirror of
https://github.com/git-touch/git-touch
synced 2025-01-31 08:04:51 +01:00
feat(gitlab): commits screen
This commit is contained in:
parent
248212c95c
commit
5d453ccbd5
@ -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,
|
||||
|
@ -81,23 +81,6 @@ class GitlabIssueNote {
|
||||
_$GitlabIssueNoteFromJson(json);
|
||||
}
|
||||
|
||||
@JsonSerializable(fieldRename: FieldRename.snake)
|
||||
class GitlabProjectBadge {
|
||||
String renderedImageUrl;
|
||||
GitlabProjectBadge();
|
||||
factory GitlabProjectBadge.fromJson(Map<String, dynamic> json) =>
|
||||
_$GitlabProjectBadgeFromJson(json);
|
||||
}
|
||||
|
||||
@JsonSerializable(fieldRename: FieldRename.snake)
|
||||
class GitlabProjectStatistics {
|
||||
int commitCount;
|
||||
int repositorySize;
|
||||
GitlabProjectStatistics();
|
||||
factory GitlabProjectStatistics.fromJson(Map<String, dynamic> 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<String, dynamic> json) =>
|
||||
_$GitlabProjectBadgeFromJson(json);
|
||||
}
|
||||
|
||||
@JsonSerializable(fieldRename: FieldRename.snake)
|
||||
class GitlabProjectStatistics {
|
||||
int commitCount;
|
||||
int repositorySize;
|
||||
GitlabProjectStatistics();
|
||||
factory GitlabProjectStatistics.fromJson(Map<String, dynamic> json) =>
|
||||
_$GitlabProjectStatisticsFromJson(json);
|
||||
}
|
||||
|
||||
@JsonSerializable(fieldRename: FieldRename.snake)
|
||||
class GitlabProjectNamespace {
|
||||
int id;
|
||||
@ -175,3 +175,16 @@ class GitlabEventNote {
|
||||
factory GitlabEventNote.fromJson(Map<String, dynamic> 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<String, dynamic> json) =>
|
||||
_$GitlabCommitFromJson(json);
|
||||
}
|
||||
|
@ -116,30 +116,6 @@ Map<String, dynamic> _$GitlabIssueNoteToJson(GitlabIssueNote instance) =>
|
||||
'body': instance.body,
|
||||
};
|
||||
|
||||
GitlabProjectBadge _$GitlabProjectBadgeFromJson(Map<String, dynamic> json) {
|
||||
return GitlabProjectBadge()
|
||||
..renderedImageUrl = json['rendered_image_url'] as String;
|
||||
}
|
||||
|
||||
Map<String, dynamic> _$GitlabProjectBadgeToJson(GitlabProjectBadge instance) =>
|
||||
<String, dynamic>{
|
||||
'rendered_image_url': instance.renderedImageUrl,
|
||||
};
|
||||
|
||||
GitlabProjectStatistics _$GitlabProjectStatisticsFromJson(
|
||||
Map<String, dynamic> json) {
|
||||
return GitlabProjectStatistics()
|
||||
..commitCount = json['commit_count'] as int
|
||||
..repositorySize = json['repository_size'] as int;
|
||||
}
|
||||
|
||||
Map<String, dynamic> _$GitlabProjectStatisticsToJson(
|
||||
GitlabProjectStatistics instance) =>
|
||||
<String, dynamic>{
|
||||
'commit_count': instance.commitCount,
|
||||
'repository_size': instance.repositorySize,
|
||||
};
|
||||
|
||||
GitlabProject _$GitlabProjectFromJson(Map<String, dynamic> json) {
|
||||
return GitlabProject()
|
||||
..id = json['id'] as int
|
||||
@ -182,6 +158,30 @@ Map<String, dynamic> _$GitlabProjectToJson(GitlabProject instance) =>
|
||||
'statistics': instance.statistics,
|
||||
};
|
||||
|
||||
GitlabProjectBadge _$GitlabProjectBadgeFromJson(Map<String, dynamic> json) {
|
||||
return GitlabProjectBadge()
|
||||
..renderedImageUrl = json['rendered_image_url'] as String;
|
||||
}
|
||||
|
||||
Map<String, dynamic> _$GitlabProjectBadgeToJson(GitlabProjectBadge instance) =>
|
||||
<String, dynamic>{
|
||||
'rendered_image_url': instance.renderedImageUrl,
|
||||
};
|
||||
|
||||
GitlabProjectStatistics _$GitlabProjectStatisticsFromJson(
|
||||
Map<String, dynamic> json) {
|
||||
return GitlabProjectStatistics()
|
||||
..commitCount = json['commit_count'] as int
|
||||
..repositorySize = json['repository_size'] as int;
|
||||
}
|
||||
|
||||
Map<String, dynamic> _$GitlabProjectStatisticsToJson(
|
||||
GitlabProjectStatistics instance) =>
|
||||
<String, dynamic>{
|
||||
'commit_count': instance.commitCount,
|
||||
'repository_size': instance.repositorySize,
|
||||
};
|
||||
|
||||
GitlabProjectNamespace _$GitlabProjectNamespaceFromJson(
|
||||
Map<String, dynamic> json) {
|
||||
return GitlabProjectNamespace()
|
||||
@ -252,3 +252,25 @@ Map<String, dynamic> _$GitlabEventNoteToJson(GitlabEventNote instance) =>
|
||||
'noteable_type': instance.noteableType,
|
||||
'noteable_iid': instance.noteableIid,
|
||||
};
|
||||
|
||||
GitlabCommit _$GitlabCommitFromJson(Map<String, dynamic> 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<String, dynamic> _$GitlabCommitToJson(GitlabCommit instance) =>
|
||||
<String, dynamic>{
|
||||
'id': instance.id,
|
||||
'short_id': instance.shortId,
|
||||
'title': instance.title,
|
||||
'created_at': instance.createdAt?.toIso8601String(),
|
||||
'author_name': instance.authorName,
|
||||
'message': instance.message,
|
||||
};
|
||||
|
@ -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<ThemeModel>(context);
|
||||
|
||||
return ListStatefulScaffold<GhCommitsCommit, String>(
|
||||
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: <Widget>[
|
||||
Avatar(url: payload.author?.avatarUrl),
|
||||
SizedBox(width: 10),
|
||||
Expanded(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: <Widget>[
|
||||
Text(
|
||||
payload.messageHeadline,
|
||||
style: TextStyle(
|
||||
fontSize: 17,
|
||||
color: theme.palette.text,
|
||||
),
|
||||
overflow: TextOverflow.ellipsis,
|
||||
),
|
||||
SizedBox(height: 4),
|
||||
Wrap(
|
||||
children: <Widget>[
|
||||
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) ...[
|
||||
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),
|
||||
],
|
||||
],
|
||||
)
|
||||
],
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
|
50
lib/screens/gitlab_commits.dart
Normal file
50
lib/screens/gitlab_commits.dart
Normal file
@ -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<ListPayload<GitlabCommit, int>> _query(BuildContext context,
|
||||
[int page = 1]) async {
|
||||
final auth = Provider.of<AuthModel>(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<GitlabCommit, int>(
|
||||
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:
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
70
lib/widgets/commit_item.dart
Normal file
70
lib/widgets/commit_item.dart
Normal file
@ -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<Widget> 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<ThemeModel>(context);
|
||||
return Link(
|
||||
url: url,
|
||||
child: Container(
|
||||
padding: CommonStyle.padding,
|
||||
child: Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: <Widget>[
|
||||
Avatar(url: avatarUrl),
|
||||
SizedBox(width: 10),
|
||||
Expanded(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: <Widget>[
|
||||
Text(
|
||||
message,
|
||||
style: TextStyle(
|
||||
fontSize: 17,
|
||||
color: theme.palette.text,
|
||||
),
|
||||
overflow: TextOverflow.ellipsis,
|
||||
),
|
||||
SizedBox(height: 4),
|
||||
Wrap(
|
||||
children: <Widget>[
|
||||
Text(author, style: TextStyle(fontSize: 15)),
|
||||
Text(
|
||||
' committed ${timeago.format(createdAt)}',
|
||||
style: TextStyle(
|
||||
color: theme.palette.secondaryText,
|
||||
fontSize: 15,
|
||||
),
|
||||
),
|
||||
if (widgets != null) ...widgets,
|
||||
],
|
||||
)
|
||||
],
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user