mirror of
https://github.com/git-touch/git-touch
synced 2025-02-26 08:17:42 +01:00
feat: add graphql types for user screen
This commit is contained in:
parent
405cc03a30
commit
b11d6be74b
@ -27,9 +27,7 @@ targets:
|
|||||||
- schema: lib/github.schema.json
|
- schema: lib/github.schema.json
|
||||||
output: lib/graphql/gh_user.dart
|
output: lib/graphql/gh_user.dart
|
||||||
queries_glob: lib/graphql/user.graphql
|
queries_glob: lib/graphql/user.graphql
|
||||||
- schema: lib/github.schema.json
|
resolve_type_field: __typename
|
||||||
output: lib/graphql/gh_repository.dart
|
|
||||||
queries_glob: lib/graphql/repository.graphql
|
|
||||||
scalar_mapping:
|
scalar_mapping:
|
||||||
- graphql_type: URI
|
- graphql_type: URI
|
||||||
dart_type: String
|
dart_type: String
|
||||||
|
99007
lib/github.schema.json
Normal file
99007
lib/github.schema.json
Normal file
File diff suppressed because it is too large
Load Diff
1400
lib/graphql/gh_user.dart
Normal file
1400
lib/graphql/gh_user.dart
Normal file
File diff suppressed because it is too large
Load Diff
431
lib/graphql/gh_user.g.dart
Normal file
431
lib/graphql/gh_user.g.dart
Normal file
@ -0,0 +1,431 @@
|
|||||||
|
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||||
|
|
||||||
|
part of 'gh_user.dart';
|
||||||
|
|
||||||
|
// **************************************************************************
|
||||||
|
// JsonSerializableGenerator
|
||||||
|
// **************************************************************************
|
||||||
|
|
||||||
|
GhUser _$GhUserFromJson(Map<String, dynamic> json) {
|
||||||
|
return GhUser()
|
||||||
|
..repositoryOwner = json['repositoryOwner'] == null
|
||||||
|
? null
|
||||||
|
: RepositoryOwner.fromJson(
|
||||||
|
json['repositoryOwner'] as Map<String, dynamic>);
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, dynamic> _$GhUserToJson(GhUser instance) => <String, dynamic>{
|
||||||
|
'repositoryOwner': instance.repositoryOwner?.toJson(),
|
||||||
|
};
|
||||||
|
|
||||||
|
RepositoryOwner _$RepositoryOwnerFromJson(Map<String, dynamic> json) {
|
||||||
|
return RepositoryOwner()..resolveType = json['__typename'] as String;
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, dynamic> _$RepositoryOwnerToJson(RepositoryOwner instance) =>
|
||||||
|
<String, dynamic>{
|
||||||
|
'__typename': instance.resolveType,
|
||||||
|
};
|
||||||
|
|
||||||
|
User _$UserFromJson(Map<String, dynamic> json) {
|
||||||
|
return User()
|
||||||
|
..login = json['login'] as String
|
||||||
|
..name = json['name'] as String
|
||||||
|
..avatarUrl = json['avatarUrl'] as String
|
||||||
|
..bio = json['bio'] as String
|
||||||
|
..company = json['company'] as String
|
||||||
|
..location = json['location'] as String
|
||||||
|
..email = json['email'] as String
|
||||||
|
..websiteUrl = json['websiteUrl'] as String
|
||||||
|
..starredRepositories = json['starredRepositories'] == null
|
||||||
|
? null
|
||||||
|
: StarredRepositoryConnection.fromJson(
|
||||||
|
json['starredRepositories'] as Map<String, dynamic>)
|
||||||
|
..followers = json['followers'] == null
|
||||||
|
? null
|
||||||
|
: FollowerConnection.fromJson(json['followers'] as Map<String, dynamic>)
|
||||||
|
..following = json['following'] == null
|
||||||
|
? null
|
||||||
|
: FollowingConnection.fromJson(
|
||||||
|
json['following'] as Map<String, dynamic>)
|
||||||
|
..repositories = json['repositories'] == null
|
||||||
|
? null
|
||||||
|
: RepositoryConnection.fromJson(
|
||||||
|
json['repositories'] as Map<String, dynamic>)
|
||||||
|
..pinnedItems = json['pinnedItems'] == null
|
||||||
|
? null
|
||||||
|
: PinnableItemConnection.fromJson(
|
||||||
|
json['pinnedItems'] as Map<String, dynamic>)
|
||||||
|
..viewerCanFollow = json['viewerCanFollow'] as bool
|
||||||
|
..viewerIsFollowing = json['viewerIsFollowing'] as bool
|
||||||
|
..url = json['url'] as String
|
||||||
|
..resolveType = json['__typename'] as String;
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, dynamic> _$UserToJson(User instance) => <String, dynamic>{
|
||||||
|
'login': instance.login,
|
||||||
|
'name': instance.name,
|
||||||
|
'avatarUrl': instance.avatarUrl,
|
||||||
|
'bio': instance.bio,
|
||||||
|
'company': instance.company,
|
||||||
|
'location': instance.location,
|
||||||
|
'email': instance.email,
|
||||||
|
'websiteUrl': instance.websiteUrl,
|
||||||
|
'starredRepositories': instance.starredRepositories?.toJson(),
|
||||||
|
'followers': instance.followers?.toJson(),
|
||||||
|
'following': instance.following?.toJson(),
|
||||||
|
'repositories': instance.repositories?.toJson(),
|
||||||
|
'pinnedItems': instance.pinnedItems?.toJson(),
|
||||||
|
'viewerCanFollow': instance.viewerCanFollow,
|
||||||
|
'viewerIsFollowing': instance.viewerIsFollowing,
|
||||||
|
'url': instance.url,
|
||||||
|
'__typename': instance.resolveType,
|
||||||
|
};
|
||||||
|
|
||||||
|
StarredRepositoryConnection _$StarredRepositoryConnectionFromJson(
|
||||||
|
Map<String, dynamic> json) {
|
||||||
|
return StarredRepositoryConnection()..totalCount = json['totalCount'] as int;
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, dynamic> _$StarredRepositoryConnectionToJson(
|
||||||
|
StarredRepositoryConnection instance) =>
|
||||||
|
<String, dynamic>{
|
||||||
|
'totalCount': instance.totalCount,
|
||||||
|
};
|
||||||
|
|
||||||
|
FollowerConnection _$FollowerConnectionFromJson(Map<String, dynamic> json) {
|
||||||
|
return FollowerConnection()..totalCount = json['totalCount'] as int;
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, dynamic> _$FollowerConnectionToJson(FollowerConnection instance) =>
|
||||||
|
<String, dynamic>{
|
||||||
|
'totalCount': instance.totalCount,
|
||||||
|
};
|
||||||
|
|
||||||
|
FollowingConnection _$FollowingConnectionFromJson(Map<String, dynamic> json) {
|
||||||
|
return FollowingConnection()..totalCount = json['totalCount'] as int;
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, dynamic> _$FollowingConnectionToJson(
|
||||||
|
FollowingConnection instance) =>
|
||||||
|
<String, dynamic>{
|
||||||
|
'totalCount': instance.totalCount,
|
||||||
|
};
|
||||||
|
|
||||||
|
RepositoryConnection _$RepositoryConnectionFromJson(Map<String, dynamic> json) {
|
||||||
|
return RepositoryConnection()
|
||||||
|
..totalCount = json['totalCount'] as int
|
||||||
|
..nodes = (json['nodes'] as List)
|
||||||
|
?.map((e) =>
|
||||||
|
e == null ? null : Repository.fromJson(e as Map<String, dynamic>))
|
||||||
|
?.toList();
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, dynamic> _$RepositoryConnectionToJson(
|
||||||
|
RepositoryConnection instance) =>
|
||||||
|
<String, dynamic>{
|
||||||
|
'totalCount': instance.totalCount,
|
||||||
|
'nodes': instance.nodes?.map((e) => e?.toJson())?.toList(),
|
||||||
|
};
|
||||||
|
|
||||||
|
Repository _$RepositoryFromJson(Map<String, dynamic> json) {
|
||||||
|
return Repository()
|
||||||
|
..owner = json['owner'] == null
|
||||||
|
? null
|
||||||
|
: RepositoryOwner.fromJson(json['owner'] as Map<String, dynamic>)
|
||||||
|
..name = json['name'] as String
|
||||||
|
..description = json['description'] as String
|
||||||
|
..isPrivate = json['isPrivate'] as bool
|
||||||
|
..isFork = json['isFork'] as bool
|
||||||
|
..stargazers = json['stargazers'] == null
|
||||||
|
? null
|
||||||
|
: StargazerConnection.fromJson(
|
||||||
|
json['stargazers'] as Map<String, dynamic>)
|
||||||
|
..forks = json['forks'] == null
|
||||||
|
? null
|
||||||
|
: RepositoryConnection.fromJson(json['forks'] as Map<String, dynamic>)
|
||||||
|
..primaryLanguage = json['primaryLanguage'] == null
|
||||||
|
? null
|
||||||
|
: Language.fromJson(json['primaryLanguage'] as Map<String, dynamic>)
|
||||||
|
..resolveType = json['__typename'] as String;
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, dynamic> _$RepositoryToJson(Repository instance) =>
|
||||||
|
<String, dynamic>{
|
||||||
|
'owner': instance.owner?.toJson(),
|
||||||
|
'name': instance.name,
|
||||||
|
'description': instance.description,
|
||||||
|
'isPrivate': instance.isPrivate,
|
||||||
|
'isFork': instance.isFork,
|
||||||
|
'stargazers': instance.stargazers?.toJson(),
|
||||||
|
'forks': instance.forks?.toJson(),
|
||||||
|
'primaryLanguage': instance.primaryLanguage?.toJson(),
|
||||||
|
'__typename': instance.resolveType,
|
||||||
|
};
|
||||||
|
|
||||||
|
StargazerConnection _$StargazerConnectionFromJson(Map<String, dynamic> json) {
|
||||||
|
return StargazerConnection()..totalCount = json['totalCount'] as int;
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, dynamic> _$StargazerConnectionToJson(
|
||||||
|
StargazerConnection instance) =>
|
||||||
|
<String, dynamic>{
|
||||||
|
'totalCount': instance.totalCount,
|
||||||
|
};
|
||||||
|
|
||||||
|
Language _$LanguageFromJson(Map<String, dynamic> json) {
|
||||||
|
return Language()
|
||||||
|
..color = json['color'] as String
|
||||||
|
..name = json['name'] as String
|
||||||
|
..resolveType = json['__typename'] as String;
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, dynamic> _$LanguageToJson(Language instance) => <String, dynamic>{
|
||||||
|
'color': instance.color,
|
||||||
|
'name': instance.name,
|
||||||
|
'__typename': instance.resolveType,
|
||||||
|
};
|
||||||
|
|
||||||
|
Node _$NodeFromJson(Map<String, dynamic> json) {
|
||||||
|
return Node()..resolveType = json['__typename'] as String;
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, dynamic> _$NodeToJson(Node instance) => <String, dynamic>{
|
||||||
|
'__typename': instance.resolveType,
|
||||||
|
};
|
||||||
|
|
||||||
|
PinnableItem _$PinnableItemFromJson(Map<String, dynamic> json) {
|
||||||
|
return PinnableItem();
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, dynamic> _$PinnableItemToJson(PinnableItem instance) =>
|
||||||
|
<String, dynamic>{};
|
||||||
|
|
||||||
|
ProjectOwner _$ProjectOwnerFromJson(Map<String, dynamic> json) {
|
||||||
|
return ProjectOwner()..resolveType = json['__typename'] as String;
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, dynamic> _$ProjectOwnerToJson(ProjectOwner instance) =>
|
||||||
|
<String, dynamic>{
|
||||||
|
'__typename': instance.resolveType,
|
||||||
|
};
|
||||||
|
|
||||||
|
RegistryPackageOwner _$RegistryPackageOwnerFromJson(Map<String, dynamic> json) {
|
||||||
|
return RegistryPackageOwner()..resolveType = json['__typename'] as String;
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, dynamic> _$RegistryPackageOwnerToJson(
|
||||||
|
RegistryPackageOwner instance) =>
|
||||||
|
<String, dynamic>{
|
||||||
|
'__typename': instance.resolveType,
|
||||||
|
};
|
||||||
|
|
||||||
|
RegistryPackageSearch _$RegistryPackageSearchFromJson(
|
||||||
|
Map<String, dynamic> json) {
|
||||||
|
return RegistryPackageSearch()..resolveType = json['__typename'] as String;
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, dynamic> _$RegistryPackageSearchToJson(
|
||||||
|
RegistryPackageSearch instance) =>
|
||||||
|
<String, dynamic>{
|
||||||
|
'__typename': instance.resolveType,
|
||||||
|
};
|
||||||
|
|
||||||
|
Subscribable _$SubscribableFromJson(Map<String, dynamic> json) {
|
||||||
|
return Subscribable()..resolveType = json['__typename'] as String;
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, dynamic> _$SubscribableToJson(Subscribable instance) =>
|
||||||
|
<String, dynamic>{
|
||||||
|
'__typename': instance.resolveType,
|
||||||
|
};
|
||||||
|
|
||||||
|
Starrable _$StarrableFromJson(Map<String, dynamic> json) {
|
||||||
|
return Starrable()
|
||||||
|
..stargazers = json['stargazers'] == null
|
||||||
|
? null
|
||||||
|
: StargazerConnection.fromJson(
|
||||||
|
json['stargazers'] as Map<String, dynamic>)
|
||||||
|
..resolveType = json['__typename'] as String;
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, dynamic> _$StarrableToJson(Starrable instance) => <String, dynamic>{
|
||||||
|
'stargazers': instance.stargazers?.toJson(),
|
||||||
|
'__typename': instance.resolveType,
|
||||||
|
};
|
||||||
|
|
||||||
|
UniformResourceLocatable _$UniformResourceLocatableFromJson(
|
||||||
|
Map<String, dynamic> json) {
|
||||||
|
return UniformResourceLocatable()..resolveType = json['__typename'] as String;
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, dynamic> _$UniformResourceLocatableToJson(
|
||||||
|
UniformResourceLocatable instance) =>
|
||||||
|
<String, dynamic>{
|
||||||
|
'__typename': instance.resolveType,
|
||||||
|
};
|
||||||
|
|
||||||
|
RepositoryInfo _$RepositoryInfoFromJson(Map<String, dynamic> json) {
|
||||||
|
return RepositoryInfo()
|
||||||
|
..owner = json['owner'] == null
|
||||||
|
? null
|
||||||
|
: RepositoryOwner.fromJson(json['owner'] as Map<String, dynamic>)
|
||||||
|
..name = json['name'] as String
|
||||||
|
..description = json['description'] as String
|
||||||
|
..isPrivate = json['isPrivate'] as bool
|
||||||
|
..isFork = json['isFork'] as bool
|
||||||
|
..resolveType = json['__typename'] as String;
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, dynamic> _$RepositoryInfoToJson(RepositoryInfo instance) =>
|
||||||
|
<String, dynamic>{
|
||||||
|
'owner': instance.owner?.toJson(),
|
||||||
|
'name': instance.name,
|
||||||
|
'description': instance.description,
|
||||||
|
'isPrivate': instance.isPrivate,
|
||||||
|
'isFork': instance.isFork,
|
||||||
|
'__typename': instance.resolveType,
|
||||||
|
};
|
||||||
|
|
||||||
|
PinnableItemConnection _$PinnableItemConnectionFromJson(
|
||||||
|
Map<String, dynamic> json) {
|
||||||
|
return PinnableItemConnection()
|
||||||
|
..nodes = (json['nodes'] as List)
|
||||||
|
?.map((e) =>
|
||||||
|
e == null ? null : PinnableItem.fromJson(e as Map<String, dynamic>))
|
||||||
|
?.toList();
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, dynamic> _$PinnableItemConnectionToJson(
|
||||||
|
PinnableItemConnection instance) =>
|
||||||
|
<String, dynamic>{
|
||||||
|
'nodes': instance.nodes?.map((e) => e?.toJson())?.toList(),
|
||||||
|
};
|
||||||
|
|
||||||
|
AuditEntryActor _$AuditEntryActorFromJson(Map<String, dynamic> json) {
|
||||||
|
return AuditEntryActor();
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, dynamic> _$AuditEntryActorToJson(AuditEntryActor instance) =>
|
||||||
|
<String, dynamic>{};
|
||||||
|
|
||||||
|
Actor _$ActorFromJson(Map<String, dynamic> json) {
|
||||||
|
return Actor()
|
||||||
|
..login = json['login'] as String
|
||||||
|
..avatarUrl = json['avatarUrl'] as String
|
||||||
|
..url = json['url'] as String
|
||||||
|
..resolveType = json['__typename'] as String;
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, dynamic> _$ActorToJson(Actor instance) => <String, dynamic>{
|
||||||
|
'login': instance.login,
|
||||||
|
'avatarUrl': instance.avatarUrl,
|
||||||
|
'url': instance.url,
|
||||||
|
'__typename': instance.resolveType,
|
||||||
|
};
|
||||||
|
|
||||||
|
ProfileOwner _$ProfileOwnerFromJson(Map<String, dynamic> json) {
|
||||||
|
return ProfileOwner()
|
||||||
|
..login = json['login'] as String
|
||||||
|
..name = json['name'] as String
|
||||||
|
..location = json['location'] as String
|
||||||
|
..email = json['email'] as String
|
||||||
|
..websiteUrl = json['websiteUrl'] as String
|
||||||
|
..pinnedItems = json['pinnedItems'] == null
|
||||||
|
? null
|
||||||
|
: PinnableItemConnection.fromJson(
|
||||||
|
json['pinnedItems'] as Map<String, dynamic>)
|
||||||
|
..resolveType = json['__typename'] as String;
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, dynamic> _$ProfileOwnerToJson(ProfileOwner instance) =>
|
||||||
|
<String, dynamic>{
|
||||||
|
'login': instance.login,
|
||||||
|
'name': instance.name,
|
||||||
|
'location': instance.location,
|
||||||
|
'email': instance.email,
|
||||||
|
'websiteUrl': instance.websiteUrl,
|
||||||
|
'pinnedItems': instance.pinnedItems?.toJson(),
|
||||||
|
'__typename': instance.resolveType,
|
||||||
|
};
|
||||||
|
|
||||||
|
Sponsorable _$SponsorableFromJson(Map<String, dynamic> json) {
|
||||||
|
return Sponsorable()..resolveType = json['__typename'] as String;
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, dynamic> _$SponsorableToJson(Sponsorable instance) =>
|
||||||
|
<String, dynamic>{
|
||||||
|
'__typename': instance.resolveType,
|
||||||
|
};
|
||||||
|
|
||||||
|
Organization _$OrganizationFromJson(Map<String, dynamic> json) {
|
||||||
|
return Organization()
|
||||||
|
..login = json['login'] as String
|
||||||
|
..name = json['name'] as String
|
||||||
|
..avatarUrl = json['avatarUrl'] as String
|
||||||
|
..description = json['description'] as String
|
||||||
|
..location = json['location'] as String
|
||||||
|
..email = json['email'] as String
|
||||||
|
..websiteUrl = json['websiteUrl'] as String
|
||||||
|
..url = json['url'] as String
|
||||||
|
..pinnedItems = json['pinnedItems'] == null
|
||||||
|
? null
|
||||||
|
: PinnableItemConnection.fromJson(
|
||||||
|
json['pinnedItems'] as Map<String, dynamic>)
|
||||||
|
..pinnableItems = json['pinnableItems'] == null
|
||||||
|
? null
|
||||||
|
: PinnableItemConnection.fromJson(
|
||||||
|
json['pinnableItems'] as Map<String, dynamic>)
|
||||||
|
..membersWithRole = json['membersWithRole'] == null
|
||||||
|
? null
|
||||||
|
: OrganizationMemberConnection.fromJson(
|
||||||
|
json['membersWithRole'] as Map<String, dynamic>)
|
||||||
|
..resolveType = json['__typename'] as String;
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, dynamic> _$OrganizationToJson(Organization instance) =>
|
||||||
|
<String, dynamic>{
|
||||||
|
'login': instance.login,
|
||||||
|
'name': instance.name,
|
||||||
|
'avatarUrl': instance.avatarUrl,
|
||||||
|
'description': instance.description,
|
||||||
|
'location': instance.location,
|
||||||
|
'email': instance.email,
|
||||||
|
'websiteUrl': instance.websiteUrl,
|
||||||
|
'url': instance.url,
|
||||||
|
'pinnedItems': instance.pinnedItems?.toJson(),
|
||||||
|
'pinnableItems': instance.pinnableItems?.toJson(),
|
||||||
|
'membersWithRole': instance.membersWithRole?.toJson(),
|
||||||
|
'__typename': instance.resolveType,
|
||||||
|
};
|
||||||
|
|
||||||
|
OrganizationMemberConnection _$OrganizationMemberConnectionFromJson(
|
||||||
|
Map<String, dynamic> json) {
|
||||||
|
return OrganizationMemberConnection()..totalCount = json['totalCount'] as int;
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, dynamic> _$OrganizationMemberConnectionToJson(
|
||||||
|
OrganizationMemberConnection instance) =>
|
||||||
|
<String, dynamic>{
|
||||||
|
'totalCount': instance.totalCount,
|
||||||
|
};
|
||||||
|
|
||||||
|
MemberStatusable _$MemberStatusableFromJson(Map<String, dynamic> json) {
|
||||||
|
return MemberStatusable()..resolveType = json['__typename'] as String;
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, dynamic> _$MemberStatusableToJson(MemberStatusable instance) =>
|
||||||
|
<String, dynamic>{
|
||||||
|
'__typename': instance.resolveType,
|
||||||
|
};
|
||||||
|
|
||||||
|
GhUserArguments _$GhUserArgumentsFromJson(Map<String, dynamic> json) {
|
||||||
|
return GhUserArguments(
|
||||||
|
login: json['login'] as String,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, dynamic> _$GhUserArgumentsToJson(GhUserArguments instance) =>
|
||||||
|
<String, dynamic>{
|
||||||
|
'login': instance.login,
|
||||||
|
};
|
144
lib/graphql/user.graphql
Normal file
144
lib/graphql/user.graphql
Normal file
@ -0,0 +1,144 @@
|
|||||||
|
query($login: String!) {
|
||||||
|
repositoryOwner(login: $login) {
|
||||||
|
__typename
|
||||||
|
... on User {
|
||||||
|
login
|
||||||
|
name
|
||||||
|
avatarUrl
|
||||||
|
bio
|
||||||
|
company
|
||||||
|
location
|
||||||
|
email
|
||||||
|
websiteUrl
|
||||||
|
starredRepositories {
|
||||||
|
totalCount
|
||||||
|
}
|
||||||
|
followers {
|
||||||
|
totalCount
|
||||||
|
}
|
||||||
|
following {
|
||||||
|
totalCount
|
||||||
|
}
|
||||||
|
repositories(
|
||||||
|
first: 6
|
||||||
|
ownerAffiliations: OWNER
|
||||||
|
orderBy: { field: STARGAZERS, direction: DESC }
|
||||||
|
) {
|
||||||
|
totalCount
|
||||||
|
nodes {
|
||||||
|
owner {
|
||||||
|
__typename
|
||||||
|
login
|
||||||
|
avatarUrl
|
||||||
|
}
|
||||||
|
name
|
||||||
|
description
|
||||||
|
isPrivate
|
||||||
|
isFork
|
||||||
|
stargazers {
|
||||||
|
totalCount
|
||||||
|
}
|
||||||
|
forks {
|
||||||
|
totalCount
|
||||||
|
}
|
||||||
|
primaryLanguage {
|
||||||
|
color
|
||||||
|
name
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pinnedItems(first: 6) {
|
||||||
|
nodes {
|
||||||
|
... on Repository {
|
||||||
|
owner {
|
||||||
|
__typename
|
||||||
|
login
|
||||||
|
avatarUrl
|
||||||
|
}
|
||||||
|
name
|
||||||
|
description
|
||||||
|
isPrivate
|
||||||
|
isFork
|
||||||
|
stargazers {
|
||||||
|
totalCount
|
||||||
|
}
|
||||||
|
forks {
|
||||||
|
totalCount
|
||||||
|
}
|
||||||
|
primaryLanguage {
|
||||||
|
color
|
||||||
|
name
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
viewerCanFollow
|
||||||
|
viewerIsFollowing
|
||||||
|
url
|
||||||
|
}
|
||||||
|
... on Organization {
|
||||||
|
login
|
||||||
|
name
|
||||||
|
avatarUrl
|
||||||
|
description
|
||||||
|
location
|
||||||
|
email
|
||||||
|
websiteUrl
|
||||||
|
url
|
||||||
|
pinnedItems(first: 6) {
|
||||||
|
nodes {
|
||||||
|
... on Repository {
|
||||||
|
owner {
|
||||||
|
__typename
|
||||||
|
login
|
||||||
|
avatarUrl
|
||||||
|
}
|
||||||
|
name
|
||||||
|
description
|
||||||
|
isPrivate
|
||||||
|
isFork
|
||||||
|
stargazers {
|
||||||
|
totalCount
|
||||||
|
}
|
||||||
|
forks {
|
||||||
|
totalCount
|
||||||
|
}
|
||||||
|
primaryLanguage {
|
||||||
|
color
|
||||||
|
name
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pinnableItems(first: 6, types: [REPOSITORY]) {
|
||||||
|
totalCount
|
||||||
|
nodes {
|
||||||
|
... on Repository {
|
||||||
|
owner {
|
||||||
|
__typename
|
||||||
|
login
|
||||||
|
avatarUrl
|
||||||
|
}
|
||||||
|
name
|
||||||
|
description
|
||||||
|
isPrivate
|
||||||
|
isFork
|
||||||
|
stargazers {
|
||||||
|
totalCount
|
||||||
|
}
|
||||||
|
forks {
|
||||||
|
totalCount
|
||||||
|
}
|
||||||
|
primaryLanguage {
|
||||||
|
color
|
||||||
|
name
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
membersWithRole {
|
||||||
|
totalCount
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,18 +1,16 @@
|
|||||||
import 'dart:io';
|
import 'dart:io';
|
||||||
import 'dart:convert';
|
import 'dart:convert';
|
||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
// import 'package:artemis/client.dart';
|
import 'package:gql_http_link/gql_http_link.dart';
|
||||||
// import 'package:gql_http_link/gql_http_link.dart';
|
import 'package:artemis/artemis.dart';
|
||||||
import 'package:fimber/fimber.dart';
|
import 'package:fimber/fimber.dart';
|
||||||
import 'package:http/http.dart' as http;
|
import 'package:http/http.dart' as http;
|
||||||
import 'package:uni_links/uni_links.dart';
|
import 'package:uni_links/uni_links.dart';
|
||||||
import 'package:nanoid/nanoid.dart';
|
import 'package:nanoid/nanoid.dart';
|
||||||
import 'package:url_launcher/url_launcher.dart';
|
import 'package:url_launcher/url_launcher.dart';
|
||||||
// import 'package:flutter/services.dart';
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter/cupertino.dart';
|
import 'package:flutter/cupertino.dart';
|
||||||
import 'package:shared_preferences/shared_preferences.dart';
|
import 'package:shared_preferences/shared_preferences.dart';
|
||||||
// import '../utils/utils.dart';
|
|
||||||
import '../utils/constants.dart';
|
import '../utils/constants.dart';
|
||||||
import '../utils/utils.dart';
|
import '../utils/utils.dart';
|
||||||
import 'account.dart';
|
import 'account.dart';
|
||||||
@ -188,19 +186,19 @@ class AuthModel with ChangeNotifier {
|
|||||||
var _timeoutDuration = Duration(seconds: 10);
|
var _timeoutDuration = Duration(seconds: 10);
|
||||||
// var _timeoutDuration = Duration(seconds: 1);
|
// var _timeoutDuration = Duration(seconds: 1);
|
||||||
|
|
||||||
// ArtemisClient _gqlClient;
|
ArtemisClient _gqlClient;
|
||||||
// ArtemisClient get gqlClient {
|
ArtemisClient get gqlClient {
|
||||||
// if (token == null) return null;
|
if (token == null) return null;
|
||||||
|
|
||||||
// if (_gqlClient == null) {
|
if (_gqlClient == null) {
|
||||||
// _gqlClient = ArtemisClient.fromLink(
|
_gqlClient = ArtemisClient.fromLink(
|
||||||
// HttpLink(_apiPrefix + '/graphql',
|
HttpLink(_apiPrefix + '/graphql',
|
||||||
// defaultHeaders: {HttpHeaders.authorizationHeader: 'token $token'}),
|
defaultHeaders: {HttpHeaders.authorizationHeader: 'token $token'}),
|
||||||
// );
|
);
|
||||||
// }
|
}
|
||||||
|
|
||||||
// return _gqlClient;
|
return _gqlClient;
|
||||||
// }
|
}
|
||||||
|
|
||||||
Future<dynamic> query(String query, [String _token]) async {
|
Future<dynamic> query(String query, [String _token]) async {
|
||||||
if (_token == null) {
|
if (_token == null) {
|
||||||
|
0
lib/screens/gitlab/repository.dart
Normal file
0
lib/screens/gitlab/repository.dart
Normal file
@ -1,5 +1,6 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter/cupertino.dart';
|
import 'package:flutter/cupertino.dart';
|
||||||
|
import 'package:git_touch/graphql/gh_user.dart';
|
||||||
import 'package:git_touch/models/theme.dart';
|
import 'package:git_touch/models/theme.dart';
|
||||||
import 'package:git_touch/scaffolds/refresh_stateful.dart';
|
import 'package:git_touch/scaffolds/refresh_stateful.dart';
|
||||||
import 'package:git_touch/screens/settings.dart';
|
import 'package:git_touch/screens/settings.dart';
|
||||||
@ -9,6 +10,7 @@ import 'package:git_touch/widgets/action_entry.dart';
|
|||||||
import 'package:git_touch/widgets/app_bar_title.dart';
|
import 'package:git_touch/widgets/app_bar_title.dart';
|
||||||
import 'package:git_touch/screens/repositories.dart';
|
import 'package:git_touch/screens/repositories.dart';
|
||||||
import 'package:git_touch/widgets/entry_item.dart';
|
import 'package:git_touch/widgets/entry_item.dart';
|
||||||
|
import 'package:git_touch/widgets/repository_item.dart';
|
||||||
import 'package:git_touch/widgets/table_view.dart';
|
import 'package:git_touch/widgets/table_view.dart';
|
||||||
import 'package:git_touch/widgets/text_contains_organization.dart';
|
import 'package:git_touch/widgets/text_contains_organization.dart';
|
||||||
import 'package:git_touch/widgets/user_contributions.dart';
|
import 'package:git_touch/widgets/user_contributions.dart';
|
||||||
@ -16,85 +18,19 @@ import 'package:git_touch/widgets/user_item.dart';
|
|||||||
import 'package:github_contributions/github_contributions.dart';
|
import 'package:github_contributions/github_contributions.dart';
|
||||||
import 'package:git_touch/models/auth.dart';
|
import 'package:git_touch/models/auth.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
import 'package:git_touch/widgets/repository_item.dart';
|
|
||||||
import 'package:git_touch/widgets/action_button.dart';
|
import 'package:git_touch/widgets/action_button.dart';
|
||||||
|
import 'package:tuple/tuple.dart';
|
||||||
|
|
||||||
class UserScreen extends StatelessWidget {
|
class UserScreen extends StatelessWidget {
|
||||||
final String login;
|
final String login;
|
||||||
|
|
||||||
UserScreen(this.login);
|
UserScreen(this.login);
|
||||||
|
|
||||||
Future _query(BuildContext context) async {
|
Future<RepositoryOwner> _query(BuildContext context) async {
|
||||||
var _login = login ?? Provider.of<AuthModel>(context).activeAccount.login;
|
final data = await Provider.of<AuthModel>(context)
|
||||||
var data = await Provider.of<AuthModel>(context).query('''
|
.gqlClient
|
||||||
{
|
.execute(GhUserQuery(variables: GhUserArguments(login: 'pd4d10')));
|
||||||
repositoryOwner(login: "$_login") {
|
return data.data.repositoryOwner;
|
||||||
__typename
|
|
||||||
... on User {
|
|
||||||
$userGqlChunk
|
|
||||||
company
|
|
||||||
location
|
|
||||||
email
|
|
||||||
websiteUrl
|
|
||||||
starredRepositories {
|
|
||||||
totalCount
|
|
||||||
}
|
|
||||||
followers {
|
|
||||||
totalCount
|
|
||||||
}
|
|
||||||
following {
|
|
||||||
totalCount
|
|
||||||
}
|
|
||||||
repositories(first: 6, ownerAffiliations: OWNER, orderBy: {field: STARGAZERS, direction: DESC}) {
|
|
||||||
totalCount
|
|
||||||
nodes {
|
|
||||||
$repoChunk
|
|
||||||
}
|
|
||||||
}
|
|
||||||
pinnedItems(first: 6) {
|
|
||||||
nodes {
|
|
||||||
... on Repository {
|
|
||||||
$repoChunk
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
viewerCanFollow
|
|
||||||
viewerIsFollowing
|
|
||||||
url
|
|
||||||
}
|
|
||||||
... on Organization {
|
|
||||||
login
|
|
||||||
name
|
|
||||||
avatarUrl
|
|
||||||
description
|
|
||||||
location
|
|
||||||
email
|
|
||||||
websiteUrl
|
|
||||||
url
|
|
||||||
pinnedItems(first: 6) {
|
|
||||||
nodes {
|
|
||||||
... on Repository {
|
|
||||||
$repoChunk
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
pinnableItems(first: 6, types: [REPOSITORY]) {
|
|
||||||
totalCount
|
|
||||||
nodes {
|
|
||||||
... on Repository {
|
|
||||||
$repoChunk
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
membersWithRole {
|
|
||||||
totalCount
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
'''); // Use pinnableItems instead of organization here due to token permission
|
|
||||||
|
|
||||||
return data['repositoryOwner'];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<List<ContributionsInfo>> _fetchContributions(
|
Future<List<ContributionsInfo>> _fetchContributions(
|
||||||
@ -112,14 +48,209 @@ class UserScreen extends StatelessWidget {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Iterable<Widget> _buildPinnedItems(
|
||||||
|
Iterable<Repository> pinnedItems, Iterable<Repository> repositories) {
|
||||||
|
String title;
|
||||||
|
Iterable<Repository> items = [];
|
||||||
|
|
||||||
|
if (pinnedItems.isNotEmpty) {
|
||||||
|
title = 'pinned repositories';
|
||||||
|
items = pinnedItems;
|
||||||
|
} else if (repositories.isNotEmpty) {
|
||||||
|
title = 'popular repositories';
|
||||||
|
items = repositories;
|
||||||
|
}
|
||||||
|
if (items.isEmpty) return [];
|
||||||
|
|
||||||
|
return [
|
||||||
|
CommonStyle.verticalGap,
|
||||||
|
if (title != null) TableViewHeader(title),
|
||||||
|
...join(
|
||||||
|
CommonStyle.border,
|
||||||
|
items.map((item) {
|
||||||
|
return RepositoryItem.github(item);
|
||||||
|
}).toList(),
|
||||||
|
),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _buildUser(
|
||||||
|
BuildContext context, User user, List<ContributionsInfo> contributions) {
|
||||||
|
final theme = Provider.of<ThemeModel>(context);
|
||||||
|
return Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||||
|
children: <Widget>[
|
||||||
|
UserItem(
|
||||||
|
login: user.login,
|
||||||
|
name: user.name,
|
||||||
|
avatarUrl: user.avatarUrl,
|
||||||
|
bio: user.bio,
|
||||||
|
inUserScreen: true,
|
||||||
|
),
|
||||||
|
CommonStyle.border,
|
||||||
|
Row(children: [
|
||||||
|
EntryItem(
|
||||||
|
count: user.repositories.totalCount,
|
||||||
|
text: 'Repositories',
|
||||||
|
screenBuilder: (context) => RepositoriesScreen(user.login),
|
||||||
|
),
|
||||||
|
EntryItem(
|
||||||
|
count: user.starredRepositories.totalCount,
|
||||||
|
text: 'Stars',
|
||||||
|
screenBuilder: (context) => RepositoriesScreen.stars(user.login),
|
||||||
|
),
|
||||||
|
EntryItem(
|
||||||
|
count: user.followers.totalCount,
|
||||||
|
text: 'Followers',
|
||||||
|
screenBuilder: (context) => UsersScreen.followers(user.login),
|
||||||
|
),
|
||||||
|
EntryItem(
|
||||||
|
count: user.following.totalCount,
|
||||||
|
text: 'Following',
|
||||||
|
screenBuilder: (context) => UsersScreen.following(user.login),
|
||||||
|
),
|
||||||
|
]),
|
||||||
|
CommonStyle.verticalGap,
|
||||||
|
UserContributions(contributions),
|
||||||
|
CommonStyle.verticalGap,
|
||||||
|
TableView(
|
||||||
|
hasIcon: true,
|
||||||
|
items: [
|
||||||
|
if (isNotNullOrEmpty(user.company))
|
||||||
|
TableViewItem(
|
||||||
|
leftIconData: Octicons.organization,
|
||||||
|
text: TextContainsOrganization(
|
||||||
|
user.company,
|
||||||
|
style: TextStyle(fontSize: 16, color: theme.palette.text),
|
||||||
|
overflow: TextOverflow.ellipsis,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
if (isNotNullOrEmpty(user.location))
|
||||||
|
TableViewItem(
|
||||||
|
leftIconData: Octicons.location,
|
||||||
|
text: Text(user.location),
|
||||||
|
onTap: () {
|
||||||
|
launchUrl('https://www.google.com/maps/place/' +
|
||||||
|
user.location.replaceAll(RegExp(r'\s+'), ''));
|
||||||
|
},
|
||||||
|
),
|
||||||
|
if (isNotNullOrEmpty(user.email))
|
||||||
|
TableViewItem(
|
||||||
|
leftIconData: Octicons.mail,
|
||||||
|
text: Text(user.email),
|
||||||
|
onTap: () {
|
||||||
|
launchUrl('mailto:' + user.email);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
if (isNotNullOrEmpty(user.websiteUrl))
|
||||||
|
TableViewItem(
|
||||||
|
leftIconData: Octicons.link,
|
||||||
|
text: Text(user.websiteUrl),
|
||||||
|
onTap: () {
|
||||||
|
var url = user.websiteUrl;
|
||||||
|
if (!url.startsWith('http')) {
|
||||||
|
url = 'http://$url';
|
||||||
|
}
|
||||||
|
launchUrl(url);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
..._buildPinnedItems(
|
||||||
|
user.pinnedItems.nodes
|
||||||
|
.where((n) => n is Repository)
|
||||||
|
.cast<Repository>(),
|
||||||
|
user.repositories.nodes),
|
||||||
|
CommonStyle.verticalGap,
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _buildOrganization(BuildContext context, Organization payload) {
|
||||||
|
return Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||||
|
children: <Widget>[
|
||||||
|
UserItem(
|
||||||
|
login: payload.login,
|
||||||
|
name: payload.name,
|
||||||
|
avatarUrl: payload.avatarUrl,
|
||||||
|
bio: payload.description,
|
||||||
|
inUserScreen: true,
|
||||||
|
),
|
||||||
|
CommonStyle.border,
|
||||||
|
Row(children: [
|
||||||
|
EntryItem(
|
||||||
|
// count: payload.pinnableItems.totalCount,
|
||||||
|
count: 0, // TODO:
|
||||||
|
text: 'Repositories',
|
||||||
|
screenBuilder: (context) =>
|
||||||
|
RepositoriesScreen.ofOrganization(payload.login),
|
||||||
|
),
|
||||||
|
EntryItem(
|
||||||
|
count: payload.membersWithRole.totalCount,
|
||||||
|
text: 'Members',
|
||||||
|
screenBuilder: (context) => UsersScreen.members(payload.login),
|
||||||
|
),
|
||||||
|
]),
|
||||||
|
CommonStyle.verticalGap,
|
||||||
|
TableView(
|
||||||
|
hasIcon: true,
|
||||||
|
items: [
|
||||||
|
if (isNotNullOrEmpty(payload.location))
|
||||||
|
TableViewItem(
|
||||||
|
leftIconData: Octicons.location,
|
||||||
|
text: Text(payload.location),
|
||||||
|
onTap: () {
|
||||||
|
launchUrl('https://www.google.com/maps/place/' +
|
||||||
|
payload.location.replaceAll(RegExp(r'\s+'), ''));
|
||||||
|
},
|
||||||
|
),
|
||||||
|
if (isNotNullOrEmpty(payload.email))
|
||||||
|
TableViewItem(
|
||||||
|
leftIconData: Octicons.mail,
|
||||||
|
text: Text(payload.email),
|
||||||
|
onTap: () {
|
||||||
|
launchUrl('mailto:' + payload.email);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
if (isNotNullOrEmpty(payload.websiteUrl))
|
||||||
|
TableViewItem(
|
||||||
|
leftIconData: Octicons.link,
|
||||||
|
text: Text(payload.websiteUrl),
|
||||||
|
onTap: () {
|
||||||
|
var url = payload.websiteUrl;
|
||||||
|
if (!url.startsWith('http')) {
|
||||||
|
url = 'http://$url';
|
||||||
|
}
|
||||||
|
launchUrl(url);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
..._buildPinnedItems(
|
||||||
|
payload.pinnedItems.nodes
|
||||||
|
.where((n) => n is Repository)
|
||||||
|
.cast<Repository>(),
|
||||||
|
payload.pinnableItems.nodes
|
||||||
|
.where((n) => n is Repository)
|
||||||
|
.cast<Repository>(),
|
||||||
|
),
|
||||||
|
CommonStyle.verticalGap,
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return RefreshStatefulScaffold(
|
return RefreshStatefulScaffold<
|
||||||
fetchData: () {
|
Tuple2<RepositoryOwner, List<ContributionsInfo>>>(
|
||||||
return Future.wait([
|
fetchData: () async {
|
||||||
|
final vs = await Future.wait([
|
||||||
_query(context),
|
_query(context),
|
||||||
_fetchContributions(context),
|
_fetchContributions(context),
|
||||||
]);
|
]);
|
||||||
|
return Tuple2(
|
||||||
|
vs[0] as RepositoryOwner, vs[1] as List<ContributionsInfo>);
|
||||||
},
|
},
|
||||||
title: AppBarTitle('User'), // TODO:
|
title: AppBarTitle('User'), // TODO:
|
||||||
actionBuilder: (data, _) {
|
actionBuilder: (data, _) {
|
||||||
@ -129,8 +260,10 @@ class UserScreen extends StatelessWidget {
|
|||||||
items: [],
|
items: [],
|
||||||
);
|
);
|
||||||
|
|
||||||
switch (data[0]['__typename']) {
|
final payload = data.item1;
|
||||||
|
switch (payload.resolveType) {
|
||||||
case 'User':
|
case 'User':
|
||||||
|
final user = payload as User;
|
||||||
if (login == null) {
|
if (login == null) {
|
||||||
return ActionEntry(
|
return ActionEntry(
|
||||||
iconData: Icons.settings,
|
iconData: Icons.settings,
|
||||||
@ -144,37 +277,37 @@ class UserScreen extends StatelessWidget {
|
|||||||
return ActionButton(
|
return ActionButton(
|
||||||
title: 'User Actions',
|
title: 'User Actions',
|
||||||
items: [
|
items: [
|
||||||
if (data != null && data[0]['viewerCanFollow'])
|
if (user.viewerCanFollow)
|
||||||
ActionItem(
|
ActionItem(
|
||||||
text:
|
text: user.viewerIsFollowing ? 'Unfollow' : 'Follow',
|
||||||
data[0]['viewerIsFollowing'] ? 'Unfollow' : 'Follow',
|
|
||||||
onPress: (_) async {
|
onPress: (_) async {
|
||||||
if (data[0]['viewerIsFollowing']) {
|
if (user.viewerIsFollowing) {
|
||||||
await Provider.of<AuthModel>(context)
|
await Provider.of<AuthModel>(context)
|
||||||
.deleteWithCredentials('/user/following/$login');
|
.deleteWithCredentials('/user/following/$login');
|
||||||
data[0]['viewerIsFollowing'] = false;
|
user.viewerIsFollowing = false;
|
||||||
} else {
|
} else {
|
||||||
Provider.of<AuthModel>(context)
|
Provider.of<AuthModel>(context)
|
||||||
.putWithCredentials('/user/following/$login');
|
.putWithCredentials('/user/following/$login');
|
||||||
data[0]['viewerIsFollowing'] = true;
|
user.viewerIsFollowing = true;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
if (data != null) ...[
|
if (data != null) ...[
|
||||||
ActionItem.share(data[0]['url']),
|
ActionItem.share(user.url),
|
||||||
ActionItem.launch(data[0]['url']),
|
ActionItem.launch(user.url),
|
||||||
],
|
],
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'Organization':
|
case 'Organization':
|
||||||
|
final organization = payload as Organization;
|
||||||
return ActionButton(
|
return ActionButton(
|
||||||
title: 'Organization Actions',
|
title: 'Organization Actions',
|
||||||
items: [
|
items: [
|
||||||
if (data != null) ...[
|
if (data != null) ...[
|
||||||
ActionItem.share(data[0]['url']),
|
ActionItem.share(organization.url),
|
||||||
ActionItem.launch(data[0]['url']),
|
ActionItem.launch(organization.url),
|
||||||
],
|
],
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
@ -183,118 +316,15 @@ class UserScreen extends StatelessWidget {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
bodyBuilder: (data, _) {
|
bodyBuilder: (data, _) {
|
||||||
var user = data[0];
|
final payload = data.item1;
|
||||||
var contributions = data[1];
|
switch (payload.resolveType) {
|
||||||
final isOrganization = user['__typename'] == 'Organization';
|
case 'User':
|
||||||
final theme = Provider.of<ThemeModel>(context);
|
return _buildUser(context, payload as User, data.item2);
|
||||||
|
case 'Organization':
|
||||||
return Column(
|
return _buildOrganization(context, payload as Organization);
|
||||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
default:
|
||||||
children: <Widget>[
|
return null;
|
||||||
UserItem(
|
|
||||||
login: user['login'],
|
|
||||||
name: user['name'],
|
|
||||||
avatarUrl: user['avatarUrl'],
|
|
||||||
bio: isOrganization ? user['description'] : user['bio'],
|
|
||||||
inUserScreen: true,
|
|
||||||
),
|
|
||||||
CommonStyle.border,
|
|
||||||
Row(children: [
|
|
||||||
if (isOrganization) ...[
|
|
||||||
EntryItem(
|
|
||||||
count: user['pinnableItems']['totalCount'],
|
|
||||||
text: 'Repositories',
|
|
||||||
screenBuilder: (context) =>
|
|
||||||
RepositoriesScreen.ofOrganization(user['login']),
|
|
||||||
),
|
|
||||||
EntryItem(
|
|
||||||
count: user['membersWithRole']['totalCount'],
|
|
||||||
text: 'Members',
|
|
||||||
screenBuilder: (context) =>
|
|
||||||
UsersScreen.members(user['login']),
|
|
||||||
),
|
|
||||||
] else ...[
|
|
||||||
EntryItem(
|
|
||||||
count: user['repositories']['totalCount'],
|
|
||||||
text: 'Repositories',
|
|
||||||
screenBuilder: (context) => RepositoriesScreen(user['login']),
|
|
||||||
),
|
|
||||||
EntryItem(
|
|
||||||
count: user['starredRepositories']['totalCount'],
|
|
||||||
text: 'Stars',
|
|
||||||
screenBuilder: (context) =>
|
|
||||||
RepositoriesScreen.stars(user['login']),
|
|
||||||
),
|
|
||||||
EntryItem(
|
|
||||||
count: user['followers']['totalCount'],
|
|
||||||
text: 'Followers',
|
|
||||||
screenBuilder: (context) =>
|
|
||||||
UsersScreen.followers(user['login']),
|
|
||||||
),
|
|
||||||
EntryItem(
|
|
||||||
count: user['following']['totalCount'],
|
|
||||||
text: 'Following',
|
|
||||||
screenBuilder: (context) =>
|
|
||||||
UsersScreen.following(user['login']),
|
|
||||||
),
|
|
||||||
]
|
|
||||||
]),
|
|
||||||
CommonStyle.verticalGap,
|
|
||||||
if (contributions.isNotEmpty) ...[
|
|
||||||
UserContributions(contributions),
|
|
||||||
CommonStyle.verticalGap,
|
|
||||||
],
|
|
||||||
TableView(
|
|
||||||
hasIcon: true,
|
|
||||||
items: [
|
|
||||||
if (!isOrganization && isNotNullOrEmpty(user['company']))
|
|
||||||
TableViewItem(
|
|
||||||
leftIconData: Octicons.organization,
|
|
||||||
text: TextContainsOrganization(
|
|
||||||
user['company'],
|
|
||||||
style: TextStyle(fontSize: 16, color: theme.palette.text),
|
|
||||||
overflow: TextOverflow.ellipsis,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
if (isNotNullOrEmpty(user['location']))
|
|
||||||
TableViewItem(
|
|
||||||
leftIconData: Octicons.location,
|
|
||||||
text: Text(user['location']),
|
|
||||||
onTap: () {
|
|
||||||
launchUrl('https://www.google.com/maps/place/' +
|
|
||||||
(user['location'] as String)
|
|
||||||
.replaceAll(RegExp(r'\s+'), ''));
|
|
||||||
},
|
|
||||||
),
|
|
||||||
if (isNotNullOrEmpty(user['email']))
|
|
||||||
TableViewItem(
|
|
||||||
leftIconData: Octicons.mail,
|
|
||||||
text: Text(user['email']),
|
|
||||||
onTap: () {
|
|
||||||
launchUrl('mailto:' + user['email']);
|
|
||||||
},
|
|
||||||
),
|
|
||||||
if (isNotNullOrEmpty(user['websiteUrl']))
|
|
||||||
TableViewItem(
|
|
||||||
leftIconData: Octicons.link,
|
|
||||||
text: Text(user['websiteUrl']),
|
|
||||||
onTap: () {
|
|
||||||
var url = user['websiteUrl'] as String;
|
|
||||||
if (!url.startsWith('http')) {
|
|
||||||
url = 'http://$url';
|
|
||||||
}
|
}
|
||||||
launchUrl(url);
|
|
||||||
},
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
...buildPinnedItems(
|
|
||||||
user['pinnedItems']['nodes'],
|
|
||||||
user[isOrganization ? 'pinnableItems' : 'repositories']
|
|
||||||
['nodes']),
|
|
||||||
CommonStyle.verticalGap,
|
|
||||||
],
|
|
||||||
);
|
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -178,32 +178,3 @@ launchUrl(String url) async {
|
|||||||
// TODO: fallback
|
// TODO: fallback
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Iterable<Widget> buildPinnedItems(List pinnedItems, List repositories) {
|
|
||||||
String title;
|
|
||||||
List items = [];
|
|
||||||
|
|
||||||
if (pinnedItems.isNotEmpty) {
|
|
||||||
title = 'pinned repositories';
|
|
||||||
items = pinnedItems;
|
|
||||||
} else if (repositories.isNotEmpty) {
|
|
||||||
title = 'popular repositories';
|
|
||||||
items = repositories;
|
|
||||||
}
|
|
||||||
|
|
||||||
items = items
|
|
||||||
.where((x) => x.isNotEmpty)
|
|
||||||
.toList(); // TODO: Pinned items may include Gist
|
|
||||||
if (items.isEmpty) return [];
|
|
||||||
|
|
||||||
return [
|
|
||||||
CommonStyle.verticalGap,
|
|
||||||
if (title != null) TableViewHeader(title),
|
|
||||||
...join(
|
|
||||||
CommonStyle.border,
|
|
||||||
items.map((item) {
|
|
||||||
return RepositoryItem(item);
|
|
||||||
}).toList(),
|
|
||||||
),
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
@ -10,7 +10,12 @@ class EntryItem extends StatelessWidget {
|
|||||||
final WidgetBuilder screenBuilder;
|
final WidgetBuilder screenBuilder;
|
||||||
final String url;
|
final String url;
|
||||||
|
|
||||||
EntryItem({this.count, this.text, this.screenBuilder, this.url});
|
EntryItem({
|
||||||
|
@required this.count,
|
||||||
|
@required this.text,
|
||||||
|
this.screenBuilder,
|
||||||
|
this.url,
|
||||||
|
});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter/cupertino.dart';
|
import 'package:flutter/cupertino.dart';
|
||||||
|
import 'package:git_touch/graphql/gh_user.dart';
|
||||||
import 'package:git_touch/models/gitea.dart';
|
import 'package:git_touch/models/gitea.dart';
|
||||||
import 'package:git_touch/models/gitlab.dart';
|
import 'package:git_touch/models/gitlab.dart';
|
||||||
import 'package:git_touch/models/theme.dart';
|
import 'package:git_touch/models/theme.dart';
|
||||||
@ -67,6 +68,23 @@ class RepositoryItem extends StatelessWidget {
|
|||||||
? []
|
? []
|
||||||
: payload['repositoryTopics']['nodes'];
|
: payload['repositoryTopics']['nodes'];
|
||||||
|
|
||||||
|
RepositoryItem.github(Repository payload, {this.inRepoScreen = false})
|
||||||
|
: this.owner = (payload.owner as User).login,
|
||||||
|
this.avatarUrl = (payload.owner as User).avatarUrl,
|
||||||
|
this.name = payload.name,
|
||||||
|
this.description = payload.description,
|
||||||
|
this.iconData = Octicons.repo, // TODO:
|
||||||
|
this.starCount = payload.stargazers.totalCount,
|
||||||
|
this.forkCount = payload.forks.totalCount,
|
||||||
|
this.primaryLanguageName = payload.primaryLanguage?.name,
|
||||||
|
this.primaryLanguageColor = payload.primaryLanguage?.color,
|
||||||
|
this.screenBuilder = ((_) =>
|
||||||
|
RepositoryScreen((payload.owner as User).login, payload.name)),
|
||||||
|
this.topics = []; // TODO:
|
||||||
|
// this.topics = payload['repositoryTopics'] == null
|
||||||
|
// ? []
|
||||||
|
// : payload['repositoryTopics']['nodes'];
|
||||||
|
|
||||||
RepositoryItem.gitlab(GitlabRepository payload, {this.inRepoScreen = false})
|
RepositoryItem.gitlab(GitlabRepository payload, {this.inRepoScreen = false})
|
||||||
: this.owner = payload.owner.name,
|
: this.owner = payload.owner.name,
|
||||||
this.avatarUrl = payload.owner.avatarUrl,
|
this.avatarUrl = payload.owner.avatarUrl,
|
||||||
|
@ -38,7 +38,8 @@ dependencies:
|
|||||||
fimber: ^0.3.2
|
fimber: ^0.3.2
|
||||||
photo_view: ^0.7.0
|
photo_view: ^0.7.0
|
||||||
gql: ^0.11.1
|
gql: ^0.11.1
|
||||||
artemis: ^2.0.7
|
artemis: ^2.1.2
|
||||||
|
gql_link: ^0.2.0
|
||||||
|
|
||||||
# The following adds the Cupertino Icons font to your application.
|
# The following adds the Cupertino Icons font to your application.
|
||||||
# Use with the CupertinoIcons class for iOS style icons.
|
# Use with the CupertinoIcons class for iOS style icons.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user