mirror of
https://github.com/git-touch/git-touch
synced 2024-12-15 17:59:35 +01:00
feat(gitlab): project screen
This commit is contained in:
parent
97d9fb1004
commit
2636e902f2
@ -2,6 +2,22 @@ import 'package:json_annotation/json_annotation.dart';
|
||||
|
||||
part 'gitlab.g.dart';
|
||||
|
||||
@JsonSerializable(fieldRename: FieldRename.snake)
|
||||
class GitlabUserProject {
|
||||
int id;
|
||||
GitlabUser owner;
|
||||
String name;
|
||||
String description;
|
||||
int starCount;
|
||||
int forksCount;
|
||||
String visibility;
|
||||
|
||||
GitlabUserProject();
|
||||
|
||||
factory GitlabUserProject.fromJson(Map<String, dynamic> json) =>
|
||||
_$GitlabUserProjectFromJson(json);
|
||||
}
|
||||
|
||||
@JsonSerializable(fieldRename: FieldRename.snake)
|
||||
class GitlabUser {
|
||||
int id;
|
||||
@ -15,22 +31,6 @@ class GitlabUser {
|
||||
_$GitlabUserFromJson(json);
|
||||
}
|
||||
|
||||
@JsonSerializable(fieldRename: FieldRename.snake)
|
||||
class GitlabProject {
|
||||
int id;
|
||||
GitlabUser owner;
|
||||
String name;
|
||||
String description;
|
||||
int starCount;
|
||||
int forksCount;
|
||||
String visibility;
|
||||
|
||||
GitlabProject();
|
||||
|
||||
factory GitlabProject.fromJson(Map<String, dynamic> json) =>
|
||||
_$GitlabProjectFromJson(json);
|
||||
}
|
||||
|
||||
@JsonSerializable(fieldRename: FieldRename.snake)
|
||||
class GitlabTodoProject {
|
||||
String pathWithNamespace;
|
||||
@ -80,3 +80,44 @@ class GitlabIssueNote {
|
||||
factory GitlabIssueNote.fromJson(Map<String, dynamic> json) =>
|
||||
_$GitlabIssueNoteFromJson(json);
|
||||
}
|
||||
|
||||
@JsonSerializable(fieldRename: FieldRename.snake)
|
||||
class GitlabProject {
|
||||
int id;
|
||||
String name;
|
||||
String avatarUrl;
|
||||
String description;
|
||||
int starCount;
|
||||
int forksCount;
|
||||
String visibility;
|
||||
String readmeUrl;
|
||||
String webUrl;
|
||||
GitlabProjectNamespace namespace;
|
||||
bool issuesEnabled;
|
||||
int openIssuesCount;
|
||||
bool mergeRequestsEnabled;
|
||||
|
||||
@JsonKey(ignore: true)
|
||||
String readme;
|
||||
|
||||
@JsonKey(ignore: true)
|
||||
Map<String, double> languages;
|
||||
|
||||
@JsonKey(ignore: true)
|
||||
String primaryLanguage;
|
||||
|
||||
GitlabProject();
|
||||
|
||||
factory GitlabProject.fromJson(Map<String, dynamic> json) =>
|
||||
_$GitlabProjectFromJson(json);
|
||||
}
|
||||
|
||||
@JsonSerializable(fieldRename: FieldRename.snake)
|
||||
class GitlabProjectNamespace {
|
||||
int id;
|
||||
String name;
|
||||
GitlabProjectNamespace();
|
||||
|
||||
factory GitlabProjectNamespace.fromJson(Map<String, dynamic> json) =>
|
||||
_$GitlabProjectNamespaceFromJson(json);
|
||||
}
|
||||
|
@ -6,6 +6,30 @@ part of 'gitlab.dart';
|
||||
// JsonSerializableGenerator
|
||||
// **************************************************************************
|
||||
|
||||
GitlabUserProject _$GitlabUserProjectFromJson(Map<String, dynamic> json) {
|
||||
return GitlabUserProject()
|
||||
..id = json['id'] as int
|
||||
..owner = json['owner'] == null
|
||||
? null
|
||||
: GitlabUser.fromJson(json['owner'] as Map<String, dynamic>)
|
||||
..name = json['name'] as String
|
||||
..description = json['description'] as String
|
||||
..starCount = json['star_count'] as int
|
||||
..forksCount = json['forks_count'] as int
|
||||
..visibility = json['visibility'] as String;
|
||||
}
|
||||
|
||||
Map<String, dynamic> _$GitlabUserProjectToJson(GitlabUserProject instance) =>
|
||||
<String, dynamic>{
|
||||
'id': instance.id,
|
||||
'owner': instance.owner,
|
||||
'name': instance.name,
|
||||
'description': instance.description,
|
||||
'star_count': instance.starCount,
|
||||
'forks_count': instance.forksCount,
|
||||
'visibility': instance.visibility,
|
||||
};
|
||||
|
||||
GitlabUser _$GitlabUserFromJson(Map<String, dynamic> json) {
|
||||
return GitlabUser()
|
||||
..id = json['id'] as int
|
||||
@ -22,30 +46,6 @@ Map<String, dynamic> _$GitlabUserToJson(GitlabUser instance) =>
|
||||
'avatar_url': instance.avatarUrl,
|
||||
};
|
||||
|
||||
GitlabProject _$GitlabProjectFromJson(Map<String, dynamic> json) {
|
||||
return GitlabProject()
|
||||
..id = json['id'] as int
|
||||
..owner = json['owner'] == null
|
||||
? null
|
||||
: GitlabUser.fromJson(json['owner'] as Map<String, dynamic>)
|
||||
..name = json['name'] as String
|
||||
..description = json['description'] as String
|
||||
..starCount = json['star_count'] as int
|
||||
..forksCount = json['forks_count'] as int
|
||||
..visibility = json['visibility'] as String;
|
||||
}
|
||||
|
||||
Map<String, dynamic> _$GitlabProjectToJson(GitlabProject instance) =>
|
||||
<String, dynamic>{
|
||||
'id': instance.id,
|
||||
'owner': instance.owner,
|
||||
'name': instance.name,
|
||||
'description': instance.description,
|
||||
'star_count': instance.starCount,
|
||||
'forks_count': instance.forksCount,
|
||||
'visibility': instance.visibility,
|
||||
};
|
||||
|
||||
GitlabTodoProject _$GitlabTodoProjectFromJson(Map<String, dynamic> json) {
|
||||
return GitlabTodoProject()
|
||||
..pathWithNamespace = json['path_with_namespace'] as String;
|
||||
@ -115,3 +115,54 @@ Map<String, dynamic> _$GitlabIssueNoteToJson(GitlabIssueNote instance) =>
|
||||
'author': instance.author,
|
||||
'body': instance.body,
|
||||
};
|
||||
|
||||
GitlabProject _$GitlabProjectFromJson(Map<String, dynamic> json) {
|
||||
return GitlabProject()
|
||||
..id = json['id'] as int
|
||||
..name = json['name'] as String
|
||||
..avatarUrl = json['avatar_url'] as String
|
||||
..description = json['description'] as String
|
||||
..starCount = json['star_count'] as int
|
||||
..forksCount = json['forks_count'] as int
|
||||
..visibility = json['visibility'] as String
|
||||
..readmeUrl = json['readme_url'] as String
|
||||
..webUrl = json['web_url'] as String
|
||||
..namespace = json['namespace'] == null
|
||||
? null
|
||||
: GitlabProjectNamespace.fromJson(
|
||||
json['namespace'] as Map<String, dynamic>)
|
||||
..issuesEnabled = json['issues_enabled'] as bool
|
||||
..openIssuesCount = json['open_issues_count'] as int
|
||||
..mergeRequestsEnabled = json['merge_requests_enabled'] as bool;
|
||||
}
|
||||
|
||||
Map<String, dynamic> _$GitlabProjectToJson(GitlabProject instance) =>
|
||||
<String, dynamic>{
|
||||
'id': instance.id,
|
||||
'name': instance.name,
|
||||
'avatar_url': instance.avatarUrl,
|
||||
'description': instance.description,
|
||||
'star_count': instance.starCount,
|
||||
'forks_count': instance.forksCount,
|
||||
'visibility': instance.visibility,
|
||||
'readme_url': instance.readmeUrl,
|
||||
'web_url': instance.webUrl,
|
||||
'namespace': instance.namespace,
|
||||
'issues_enabled': instance.issuesEnabled,
|
||||
'open_issues_count': instance.openIssuesCount,
|
||||
'merge_requests_enabled': instance.mergeRequestsEnabled,
|
||||
};
|
||||
|
||||
GitlabProjectNamespace _$GitlabProjectNamespaceFromJson(
|
||||
Map<String, dynamic> json) {
|
||||
return GitlabProjectNamespace()
|
||||
..id = json['id'] as int
|
||||
..name = json['name'] as String;
|
||||
}
|
||||
|
||||
Map<String, dynamic> _$GitlabProjectNamespaceToJson(
|
||||
GitlabProjectNamespace instance) =>
|
||||
<String, dynamic>{
|
||||
'id': instance.id,
|
||||
'name': instance.name,
|
||||
};
|
||||
|
147
lib/screens/gitlab_project.dart
Normal file
147
lib/screens/gitlab_project.dart
Normal file
@ -0,0 +1,147 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:git_touch/models/auth.dart';
|
||||
import 'package:git_touch/models/gitlab.dart';
|
||||
import 'package:git_touch/scaffolds/refresh_stateful.dart';
|
||||
import 'package:git_touch/utils/utils.dart';
|
||||
import 'package:git_touch/widgets/app_bar_title.dart';
|
||||
import 'package:git_touch/widgets/entry_item.dart';
|
||||
import 'package:git_touch/widgets/markdown_view.dart';
|
||||
import 'package:git_touch/widgets/table_view.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:git_touch/models/theme.dart';
|
||||
import 'package:git_touch/widgets/repository_item.dart';
|
||||
import 'package:git_touch/widgets/action_button.dart';
|
||||
|
||||
class GitlabProjectScreen extends StatelessWidget {
|
||||
final int id;
|
||||
final String branch;
|
||||
|
||||
GitlabProjectScreen(this.id, {this.branch});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return RefreshStatefulScaffold<GitlabProject>(
|
||||
title: AppBarTitle('Project'),
|
||||
fetchData: () async {
|
||||
final auth = Provider.of<AuthModel>(context);
|
||||
final json = await auth.fetchGitlab('/projects/$id');
|
||||
final project = GitlabProject.fromJson(json);
|
||||
if (project.readmeUrl != null) {
|
||||
project.readme = await auth.fetchWithGitlabToken(
|
||||
project.readmeUrl.replaceFirst(r'/blob/', '/raw/'));
|
||||
}
|
||||
final l = await auth.fetchGitlab('/projects/$id/languages');
|
||||
project.languages = Map<String, double>.from(l);
|
||||
return project;
|
||||
},
|
||||
actionBuilder: (data, setState) {
|
||||
if (data == null)
|
||||
return ActionButton(title: 'Project Actions', items: []);
|
||||
|
||||
return ActionButton(
|
||||
title: 'Project Actions',
|
||||
items: [
|
||||
ActionItem.share(data.webUrl),
|
||||
ActionItem.launch(data.webUrl),
|
||||
],
|
||||
);
|
||||
},
|
||||
bodyBuilder: (data, _) {
|
||||
final langWidth = MediaQuery.of(context).size.width -
|
||||
CommonStyle.padding.left -
|
||||
CommonStyle.padding.right -
|
||||
data.languages.length +
|
||||
1;
|
||||
|
||||
final theme = Provider.of<ThemeModel>(context);
|
||||
|
||||
return Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||
children: <Widget>[
|
||||
RepositoryItem.raw(
|
||||
data.namespace.name,
|
||||
data.avatarUrl,
|
||||
data.name,
|
||||
data.description,
|
||||
Octicons.repo, // TODO:
|
||||
data.starCount,
|
||||
data.forksCount,
|
||||
data.languages.keys.first,
|
||||
null,
|
||||
null,
|
||||
[],
|
||||
inRepoScreen: true),
|
||||
CommonStyle.border,
|
||||
Row(
|
||||
children: <Widget>[
|
||||
EntryItem(
|
||||
count: data.starCount,
|
||||
text: 'Stars',
|
||||
),
|
||||
EntryItem(
|
||||
count: data.forksCount,
|
||||
text: 'Forks', // TODO:
|
||||
),
|
||||
],
|
||||
),
|
||||
CommonStyle.verticalGap,
|
||||
if (data.languages.isNotEmpty)
|
||||
Container(
|
||||
color: theme.palette.background,
|
||||
padding: CommonStyle.padding.copyWith(top: 8, bottom: 8),
|
||||
child: ClipRRect(
|
||||
borderRadius: BorderRadius.circular(2),
|
||||
child: SizedBox(
|
||||
height: 10,
|
||||
child: Row(
|
||||
children: join(
|
||||
SizedBox(width: 1),
|
||||
data.languages.entries
|
||||
.map((e) => Container(
|
||||
color: convertColor('#ff0'),
|
||||
width: langWidth *
|
||||
e.value /
|
||||
data.languages.length))
|
||||
.toList(),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
TableView(
|
||||
hasIcon: true,
|
||||
items: [
|
||||
TableViewItem(
|
||||
leftIconData: Octicons.code,
|
||||
text: Text('Code'),
|
||||
// screenBuilder: (_) => GitlabObjectScreen(),
|
||||
),
|
||||
if (data.issuesEnabled)
|
||||
TableViewItem(
|
||||
leftIconData: Octicons.issue_opened,
|
||||
text: Text('Issues'),
|
||||
rightWidget:
|
||||
Text(numberFormat.format(data.openIssuesCount)),
|
||||
),
|
||||
if (data.mergeRequestsEnabled)
|
||||
TableViewItem(
|
||||
leftIconData: Octicons.git_pull_request,
|
||||
text: Text('Merge requests'),
|
||||
),
|
||||
],
|
||||
),
|
||||
CommonStyle.verticalGap,
|
||||
if (data.readme != null)
|
||||
Container(
|
||||
padding: CommonStyle.padding,
|
||||
color: theme.palette.background,
|
||||
child: MarkdownView(data.readme),
|
||||
),
|
||||
CommonStyle.verticalGap,
|
||||
],
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
@ -15,7 +15,8 @@ class GitlabUserScreen extends StatelessWidget {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return RefreshStatefulScaffold<Tuple2<GitlabUser, Iterable<GitlabProject>>>(
|
||||
return RefreshStatefulScaffold<
|
||||
Tuple2<GitlabUser, Iterable<GitlabUserProject>>>(
|
||||
title: Text('User'),
|
||||
fetchData: () async {
|
||||
final auth = Provider.of<AuthModel>(context);
|
||||
@ -25,7 +26,7 @@ class GitlabUserScreen extends StatelessWidget {
|
||||
|
||||
final v1 = await auth.fetchGitlab('/users/${user.id}/projects');
|
||||
final projects =
|
||||
(v1 as List).map((v) => GitlabProject.fromJson(v)).toList();
|
||||
(v1 as List).map((v) => GitlabUserProject.fromJson(v)).toList();
|
||||
|
||||
return Tuple2(user, projects);
|
||||
},
|
||||
|
@ -29,7 +29,7 @@ class Avatar extends StatelessWidget {
|
||||
borderRadius: BorderRadius.circular(4),
|
||||
child: FadeInImage.assetNetwork(
|
||||
placeholder: 'images/octoface.png',
|
||||
image: url,
|
||||
image: url ?? 'images/octoface.png',
|
||||
width: size,
|
||||
height: size,
|
||||
fadeInDuration: Duration(milliseconds: 200),
|
||||
|
@ -5,6 +5,7 @@ import 'package:git_touch/graphql/github_user.dart';
|
||||
import 'package:git_touch/models/gitea.dart';
|
||||
import 'package:git_touch/models/gitlab.dart';
|
||||
import 'package:git_touch/models/theme.dart';
|
||||
import 'package:git_touch/screens/gitlab_project.dart';
|
||||
import 'package:git_touch/screens/repository.dart';
|
||||
import 'package:git_touch/widgets/action_button.dart';
|
||||
import 'package:git_touch/widgets/avatar.dart';
|
||||
@ -112,7 +113,7 @@ class RepositoryItem extends StatelessWidget {
|
||||
}
|
||||
}
|
||||
|
||||
RepositoryItem.gitlab(GitlabProject payload, {this.inRepoScreen = false})
|
||||
RepositoryItem.gitlab(GitlabUserProject payload, {this.inRepoScreen = false})
|
||||
: this.owner = payload.owner.name,
|
||||
this.avatarUrl = payload.owner.avatarUrl,
|
||||
this.name = payload.name,
|
||||
@ -122,8 +123,7 @@ class RepositoryItem extends StatelessWidget {
|
||||
this.forkCount = payload.forksCount,
|
||||
this.primaryLanguageName = null,
|
||||
this.primaryLanguageColor = null,
|
||||
this.screenBuilder =
|
||||
((_) => RepositoryScreen(payload.owner.username, payload.name)),
|
||||
this.screenBuilder = ((_) => GitlabProjectScreen(payload.id)),
|
||||
this.topics = [];
|
||||
|
||||
RepositoryItem.gitea(GiteaRepository payload, {this.inRepoScreen = false})
|
||||
|
Loading…
Reference in New Issue
Block a user