mirror of
https://github.com/git-touch/git-touch
synced 2025-03-13 01:30:09 +01:00
feat(github): organization sponsors
This commit is contained in:
parent
830441ba05
commit
f7eb0e6f62
@ -18,9 +18,51 @@ import 'package:git_touch/widgets/user_header.dart';
|
|||||||
import 'package:go_router/go_router.dart';
|
import 'package:go_router/go_router.dart';
|
||||||
import 'package:gql_github/user.data.gql.dart';
|
import 'package:gql_github/user.data.gql.dart';
|
||||||
import 'package:gql_github/user.req.gql.dart';
|
import 'package:gql_github/user.req.gql.dart';
|
||||||
|
import 'package:intl/intl.dart';
|
||||||
import 'package:maps_launcher/maps_launcher.dart';
|
import 'package:maps_launcher/maps_launcher.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
|
|
||||||
|
class _SponsorItem extends StatelessWidget {
|
||||||
|
const _SponsorItem({
|
||||||
|
required this.count,
|
||||||
|
required this.login,
|
||||||
|
required this.nodes,
|
||||||
|
required this.sponsoring,
|
||||||
|
});
|
||||||
|
final int count;
|
||||||
|
final String login;
|
||||||
|
final Iterable<GSponsorConnectionParts_nodes> nodes;
|
||||||
|
final bool sponsoring;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return AntListItem(
|
||||||
|
prefix: Icon(sponsoring ? Octicons.heart : Octicons.heart_fill),
|
||||||
|
extra: Text(count.toString()),
|
||||||
|
onClick: () {
|
||||||
|
context.pushUrl(sponsoring
|
||||||
|
? 'https://github.com/$login?tab=sponsoring'
|
||||||
|
: 'https://github.com/sponsors/$login#sponsors');
|
||||||
|
},
|
||||||
|
child: Row(
|
||||||
|
children: [
|
||||||
|
Text(toBeginningOfSentenceCase(
|
||||||
|
sponsoring ? 'sponsoring' : 'sponsors')!),
|
||||||
|
const Spacer(),
|
||||||
|
for (final sponsor in nodes) ...[
|
||||||
|
const SizedBox(width: 6),
|
||||||
|
Avatar(
|
||||||
|
square: sponsor.G__typename != 'User',
|
||||||
|
url: (sponsor as dynamic).avatarUrl, // TODO: same key here
|
||||||
|
size: AvatarSize.small,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
class _Repos extends StatelessWidget {
|
class _Repos extends StatelessWidget {
|
||||||
_Repos(final Iterable<GRepoParts> pinned, final Iterable<GRepoParts>? repos)
|
_Repos(final Iterable<GRepoParts> pinned, final Iterable<GRepoParts>? repos)
|
||||||
: title =
|
: title =
|
||||||
@ -153,58 +195,18 @@ class _User extends StatelessWidget {
|
|||||||
CommonStyle.verticalGap,
|
CommonStyle.verticalGap,
|
||||||
AntList(children: [
|
AntList(children: [
|
||||||
if (p.sponsors.totalCount > 0)
|
if (p.sponsors.totalCount > 0)
|
||||||
AntListItem(
|
_SponsorItem(
|
||||||
prefix: const Icon(Octicons.heart_fill),
|
count: p.sponsors.totalCount,
|
||||||
extra: Text(p.sponsors.totalCount.toString()),
|
login: p.login,
|
||||||
child: Row(
|
nodes: p.sponsors.nodes!,
|
||||||
children: [
|
sponsoring: false,
|
||||||
const Text('Sponsors'),
|
|
||||||
const Spacer(),
|
|
||||||
for (final sponsor in p.sponsors.nodes!) ...[
|
|
||||||
const SizedBox(width: 6),
|
|
||||||
Avatar(
|
|
||||||
isOrg: sponsor.G__typename != 'User',
|
|
||||||
url: sponsor.G__typename == 'User'
|
|
||||||
? (sponsor as GUserData_user_sponsors_nodes__asUser)
|
|
||||||
.avatarUrl
|
|
||||||
: (sponsor
|
|
||||||
as GUserParts_sponsors_nodes__asOrganization)
|
|
||||||
.avatarUrl,
|
|
||||||
size: AvatarSize.small,
|
|
||||||
),
|
|
||||||
],
|
|
||||||
],
|
|
||||||
),
|
|
||||||
onClick: () {
|
|
||||||
context.goNamed('/github/${p.login}?tab=sponsors');
|
|
||||||
},
|
|
||||||
),
|
),
|
||||||
if (p.sponsoring.totalCount > 0)
|
if (p.sponsoring.totalCount > 0)
|
||||||
AntListItem(
|
_SponsorItem(
|
||||||
prefix: const Icon(Octicons.heart),
|
count: p.sponsoring.totalCount,
|
||||||
extra: Text(p.sponsoring.totalCount.toString()),
|
login: p.login,
|
||||||
child: Row(
|
nodes: p.sponsoring.nodes!,
|
||||||
children: [
|
sponsoring: true,
|
||||||
const Text('Sponsoring'),
|
|
||||||
const Spacer(),
|
|
||||||
for (final sponsor in p.sponsoring.nodes!) ...[
|
|
||||||
const SizedBox(width: 6),
|
|
||||||
Avatar(
|
|
||||||
isOrg: sponsor.G__typename != 'User',
|
|
||||||
url: sponsor.G__typename == 'User'
|
|
||||||
? (sponsor as GUserData_user_sponsoring_nodes__asUser)
|
|
||||||
.avatarUrl
|
|
||||||
: (sponsor
|
|
||||||
as GUserParts_sponsoring_nodes__asOrganization)
|
|
||||||
.avatarUrl,
|
|
||||||
size: AvatarSize.small,
|
|
||||||
),
|
|
||||||
],
|
|
||||||
],
|
|
||||||
),
|
|
||||||
onClick: () {
|
|
||||||
context.goNamed('/github/${p.login}?tab=sponsoring');
|
|
||||||
},
|
|
||||||
),
|
),
|
||||||
if (p.organizations.totalCount > 0)
|
if (p.organizations.totalCount > 0)
|
||||||
AntListItem(
|
AntListItem(
|
||||||
@ -217,7 +219,7 @@ class _User extends StatelessWidget {
|
|||||||
for (final org in p.organizations.nodes!) ...[
|
for (final org in p.organizations.nodes!) ...[
|
||||||
const SizedBox(width: 6),
|
const SizedBox(width: 6),
|
||||||
Avatar(
|
Avatar(
|
||||||
isOrg: true,
|
square: true,
|
||||||
url: org.avatarUrl,
|
url: org.avatarUrl,
|
||||||
size: AvatarSize.small,
|
size: AvatarSize.small,
|
||||||
),
|
),
|
||||||
@ -349,7 +351,9 @@ class GhUserScreen extends StatelessWidget {
|
|||||||
)
|
)
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
} else if (data?.organization != null) {
|
}
|
||||||
|
|
||||||
|
if (data?.organization != null) {
|
||||||
final p = data!.organization!;
|
final p = data!.organization!;
|
||||||
return Column(
|
return Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||||
@ -380,21 +384,6 @@ class GhUserScreen extends StatelessWidget {
|
|||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
CommonStyle.border,
|
|
||||||
Row(
|
|
||||||
children: [
|
|
||||||
EntryItem(
|
|
||||||
count: p.sponsors.totalCount,
|
|
||||||
text: 'Sponsors',
|
|
||||||
url: 'https://github.com/sponsors/${p.login}',
|
|
||||||
),
|
|
||||||
EntryItem(
|
|
||||||
count: p.membersWithRole.totalCount,
|
|
||||||
text: AppLocalizations.of(context)!.members,
|
|
||||||
url: '/github/${p.login}?tab=people',
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
AntList(
|
AntList(
|
||||||
children: [
|
children: [
|
||||||
if (p.location != null)
|
if (p.location != null)
|
||||||
@ -438,6 +427,25 @@ class GhUserScreen extends StatelessWidget {
|
|||||||
],
|
],
|
||||||
),
|
),
|
||||||
CommonStyle.verticalGap,
|
CommonStyle.verticalGap,
|
||||||
|
AntList(
|
||||||
|
children: [
|
||||||
|
if (p.sponsors.totalCount > 0)
|
||||||
|
_SponsorItem(
|
||||||
|
count: p.sponsors.totalCount,
|
||||||
|
login: p.login,
|
||||||
|
nodes: p.sponsors.nodes!,
|
||||||
|
sponsoring: false,
|
||||||
|
),
|
||||||
|
if (p.sponsoring.totalCount > 0)
|
||||||
|
_SponsorItem(
|
||||||
|
count: p.sponsoring.totalCount,
|
||||||
|
login: p.login,
|
||||||
|
nodes: p.sponsoring.nodes!,
|
||||||
|
sponsoring: true,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
CommonStyle.verticalGap,
|
||||||
AntList(
|
AntList(
|
||||||
children: [
|
children: [
|
||||||
AntListItem(
|
AntListItem(
|
||||||
@ -466,6 +474,7 @@ class GhUserScreen extends StatelessWidget {
|
|||||||
],
|
],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return null; // TODO: not found
|
return null; // TODO: not found
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
@ -18,12 +18,12 @@ class Avatar extends StatelessWidget {
|
|||||||
required this.url,
|
required this.url,
|
||||||
this.size = AvatarSize.medium,
|
this.size = AvatarSize.medium,
|
||||||
this.linkUrl,
|
this.linkUrl,
|
||||||
this.isOrg = false,
|
this.square = false,
|
||||||
});
|
});
|
||||||
final String? url;
|
final String? url;
|
||||||
final double size;
|
final double size;
|
||||||
final String? linkUrl;
|
final String? linkUrl;
|
||||||
final bool isOrg;
|
final bool square;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
@ -35,7 +35,7 @@ class Avatar extends StatelessWidget {
|
|||||||
final fallbackWidget = Image.asset(fallback, width: size, height: size);
|
final fallbackWidget = Image.asset(fallback, width: size, height: size);
|
||||||
|
|
||||||
final widget = ClipRRect(
|
final widget = ClipRRect(
|
||||||
borderRadius: BorderRadius.circular(isOrg ? 4 : size),
|
borderRadius: BorderRadius.circular(square ? 4 : size),
|
||||||
child: url == null
|
child: url == null
|
||||||
? fallbackWidget
|
? fallbackWidget
|
||||||
: FadeInImage.assetNetwork(
|
: FadeInImage.assetNetwork(
|
||||||
|
@ -19,6 +19,19 @@ fragment RepoParts on Repository {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fragment SponsorConnectionParts on SponsorConnection {
|
||||||
|
totalCount
|
||||||
|
nodes {
|
||||||
|
__typename
|
||||||
|
... on User {
|
||||||
|
avatarUrl
|
||||||
|
}
|
||||||
|
... on Organization {
|
||||||
|
avatarUrl
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fragment UserParts on User {
|
fragment UserParts on User {
|
||||||
login
|
login
|
||||||
name
|
name
|
||||||
@ -48,29 +61,11 @@ fragment UserParts on User {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
sponsors(first: 3) {
|
|
||||||
totalCount
|
|
||||||
nodes {
|
|
||||||
__typename
|
|
||||||
... on User {
|
|
||||||
avatarUrl
|
|
||||||
}
|
|
||||||
... on Organization {
|
|
||||||
avatarUrl
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
sponsoring(first: 3) {
|
sponsoring(first: 3) {
|
||||||
totalCount
|
...SponsorConnectionParts
|
||||||
nodes {
|
}
|
||||||
__typename
|
sponsors(first: 3) {
|
||||||
... on User {
|
...SponsorConnectionParts
|
||||||
avatarUrl
|
|
||||||
}
|
|
||||||
... on Organization {
|
|
||||||
avatarUrl
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
organizations(first: 3) {
|
organizations(first: 3) {
|
||||||
totalCount
|
totalCount
|
||||||
@ -125,12 +120,15 @@ query User($login: String!) {
|
|||||||
twitterUsername
|
twitterUsername
|
||||||
createdAt
|
createdAt
|
||||||
viewerIsFollowing
|
viewerIsFollowing
|
||||||
sponsors {
|
|
||||||
totalCount
|
|
||||||
}
|
|
||||||
membersWithRole {
|
membersWithRole {
|
||||||
totalCount
|
totalCount
|
||||||
}
|
}
|
||||||
|
sponsoring(first: 3) {
|
||||||
|
...SponsorConnectionParts
|
||||||
|
}
|
||||||
|
sponsors(first: 3) {
|
||||||
|
...SponsorConnectionParts
|
||||||
|
}
|
||||||
pinnedItems(first: 6) {
|
pinnedItems(first: 6) {
|
||||||
nodes {
|
nodes {
|
||||||
... on Repository {
|
... on Repository {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user