feat: repo watch

This commit is contained in:
Rongjian Zhang 2020-01-20 14:18:45 +08:00
parent c2ea91ef56
commit 42c733fe4c
5 changed files with 600 additions and 80 deletions

View File

@ -75,6 +75,9 @@ class GhRepoRepository extends GhRepoPinnableItem
@override
bool viewerHasStarred;
@override
GhRepoSubscriptionState viewerSubscription;
@override
String projectsUrl;
@ -122,6 +125,7 @@ class GhRepoRepository extends GhRepoPinnableItem
hasIssuesEnabled,
url,
viewerHasStarred,
viewerSubscription,
projectsUrl,
watchers,
issues,
@ -669,6 +673,12 @@ class GhRepoRepositoryInfo with EquatableMixin {
Map<String, dynamic> toJson() => _$GhRepoRepositoryInfoToJson(this);
}
enum GhRepoSubscriptionState {
UNSUBSCRIBED,
SUBSCRIBED,
IGNORED,
}
@JsonSerializable(explicitToJson: true)
class GhRepoArguments extends JsonSerializable with EquatableMixin {
GhRepoArguments({this.owner, this.name, this.branchSpecified, this.branch});
@ -868,6 +878,12 @@ class GhRepoQuery extends GraphQLQuery<GhRepo, GhRepoArguments> {
arguments: [],
directives: [],
selectionSet: null),
FieldNode(
name: NameNode(value: 'viewerSubscription'),
alias: null,
arguments: [],
directives: [],
selectionSet: null),
FieldNode(
name: NameNode(value: 'projectsUrl'),
alias: null,
@ -8092,3 +8108,306 @@ class GhRepoIdQuery extends GraphQLQuery<GhRepoId, GhRepoIdArguments> {
@override
GhRepoId parse(Map<String, dynamic> json) => GhRepoId.fromJson(json);
}
@JsonSerializable(explicitToJson: true)
class GhWatch with EquatableMixin {
GhWatch();
factory GhWatch.fromJson(Map<String, dynamic> json) =>
_$GhWatchFromJson(json);
GhWatchUpdateSubscriptionPayload updateSubscription;
@override
List<Object> get props => [updateSubscription];
Map<String, dynamic> toJson() => _$GhWatchToJson(this);
}
@JsonSerializable(explicitToJson: true)
class GhWatchUpdateSubscriptionPayload with EquatableMixin {
GhWatchUpdateSubscriptionPayload();
factory GhWatchUpdateSubscriptionPayload.fromJson(
Map<String, dynamic> json) =>
_$GhWatchUpdateSubscriptionPayloadFromJson(json);
GhWatchSubscribable subscribable;
@override
List<Object> get props => [subscribable];
Map<String, dynamic> toJson() =>
_$GhWatchUpdateSubscriptionPayloadToJson(this);
}
@JsonSerializable(explicitToJson: true)
class GhWatchSubscribable with EquatableMixin {
GhWatchSubscribable();
factory GhWatchSubscribable.fromJson(Map<String, dynamic> json) {
switch (json['__typename'].toString()) {
case 'Repository':
return GhWatchRepository.fromJson(json);
default:
}
return _$GhWatchSubscribableFromJson(json);
}
@JsonKey(name: '__typename')
String resolveType;
@override
List<Object> get props => [resolveType];
Map<String, dynamic> toJson() {
switch (resolveType) {
case 'Repository':
return (this as GhWatchRepository).toJson();
default:
}
return _$GhWatchSubscribableToJson(this);
}
}
@JsonSerializable(explicitToJson: true)
class GhWatchRepository extends GhWatchPinnableItem
with EquatableMixin
implements
GhWatchNode,
GhWatchProjectOwner,
GhWatchRegistryPackageOwner,
GhWatchRegistryPackageSearch,
GhWatchSubscribable,
GhWatchStarrable,
GhWatchUniformResourceLocatable,
GhWatchRepositoryInfo {
GhWatchRepository();
factory GhWatchRepository.fromJson(Map<String, dynamic> json) =>
_$GhWatchRepositoryFromJson(json);
GhWatchSubscriptionState viewerSubscription;
@override
@JsonKey(name: '__typename')
String resolveType;
@override
List<Object> get props => [viewerSubscription, resolveType];
Map<String, dynamic> toJson() => _$GhWatchRepositoryToJson(this);
}
@JsonSerializable(explicitToJson: true)
class GhWatchPinnableItem with EquatableMixin {
GhWatchPinnableItem();
factory GhWatchPinnableItem.fromJson(Map<String, dynamic> json) =>
_$GhWatchPinnableItemFromJson(json);
@override
List<Object> get props => [];
Map<String, dynamic> toJson() => _$GhWatchPinnableItemToJson(this);
}
@JsonSerializable(explicitToJson: true)
class GhWatchNode with EquatableMixin {
GhWatchNode();
factory GhWatchNode.fromJson(Map<String, dynamic> json) =>
_$GhWatchNodeFromJson(json);
@JsonKey(name: '__typename')
String resolveType;
@override
List<Object> get props => [resolveType];
Map<String, dynamic> toJson() => _$GhWatchNodeToJson(this);
}
@JsonSerializable(explicitToJson: true)
class GhWatchProjectOwner with EquatableMixin {
GhWatchProjectOwner();
factory GhWatchProjectOwner.fromJson(Map<String, dynamic> json) =>
_$GhWatchProjectOwnerFromJson(json);
@JsonKey(name: '__typename')
String resolveType;
@override
List<Object> get props => [resolveType];
Map<String, dynamic> toJson() => _$GhWatchProjectOwnerToJson(this);
}
@JsonSerializable(explicitToJson: true)
class GhWatchRegistryPackageOwner with EquatableMixin {
GhWatchRegistryPackageOwner();
factory GhWatchRegistryPackageOwner.fromJson(Map<String, dynamic> json) =>
_$GhWatchRegistryPackageOwnerFromJson(json);
@JsonKey(name: '__typename')
String resolveType;
@override
List<Object> get props => [resolveType];
Map<String, dynamic> toJson() => _$GhWatchRegistryPackageOwnerToJson(this);
}
@JsonSerializable(explicitToJson: true)
class GhWatchRegistryPackageSearch with EquatableMixin {
GhWatchRegistryPackageSearch();
factory GhWatchRegistryPackageSearch.fromJson(Map<String, dynamic> json) =>
_$GhWatchRegistryPackageSearchFromJson(json);
@JsonKey(name: '__typename')
String resolveType;
@override
List<Object> get props => [resolveType];
Map<String, dynamic> toJson() => _$GhWatchRegistryPackageSearchToJson(this);
}
@JsonSerializable(explicitToJson: true)
class GhWatchStarrable with EquatableMixin {
GhWatchStarrable();
factory GhWatchStarrable.fromJson(Map<String, dynamic> json) =>
_$GhWatchStarrableFromJson(json);
@JsonKey(name: '__typename')
String resolveType;
@override
List<Object> get props => [resolveType];
Map<String, dynamic> toJson() => _$GhWatchStarrableToJson(this);
}
@JsonSerializable(explicitToJson: true)
class GhWatchUniformResourceLocatable with EquatableMixin {
GhWatchUniformResourceLocatable();
factory GhWatchUniformResourceLocatable.fromJson(Map<String, dynamic> json) =>
_$GhWatchUniformResourceLocatableFromJson(json);
@JsonKey(name: '__typename')
String resolveType;
@override
List<Object> get props => [resolveType];
Map<String, dynamic> toJson() =>
_$GhWatchUniformResourceLocatableToJson(this);
}
@JsonSerializable(explicitToJson: true)
class GhWatchRepositoryInfo with EquatableMixin {
GhWatchRepositoryInfo();
factory GhWatchRepositoryInfo.fromJson(Map<String, dynamic> json) =>
_$GhWatchRepositoryInfoFromJson(json);
@JsonKey(name: '__typename')
String resolveType;
@override
List<Object> get props => [resolveType];
Map<String, dynamic> toJson() => _$GhWatchRepositoryInfoToJson(this);
}
enum GhWatchSubscriptionState {
UNSUBSCRIBED,
SUBSCRIBED,
IGNORED,
}
@JsonSerializable(explicitToJson: true)
class GhWatchArguments extends JsonSerializable with EquatableMixin {
GhWatchArguments({this.id, this.state});
factory GhWatchArguments.fromJson(Map<String, dynamic> json) =>
_$GhWatchArgumentsFromJson(json);
final String id;
final GhWatchSubscriptionState state;
@override
List<Object> get props => [id, state];
Map<String, dynamic> toJson() => _$GhWatchArgumentsToJson(this);
}
class GhWatchQuery extends GraphQLQuery<GhWatch, GhWatchArguments> {
GhWatchQuery({this.variables});
@override
final DocumentNode document = DocumentNode(definitions: [
OperationDefinitionNode(
type: OperationType.mutation,
name: NameNode(value: 'GhWatch'),
variableDefinitions: [
VariableDefinitionNode(
variable: VariableNode(name: NameNode(value: 'id')),
type: NamedTypeNode(name: NameNode(value: 'ID'), isNonNull: true),
defaultValue: DefaultValueNode(value: null),
directives: []),
VariableDefinitionNode(
variable: VariableNode(name: NameNode(value: 'state')),
type: NamedTypeNode(
name: NameNode(value: 'SubscriptionState'), isNonNull: true),
defaultValue: DefaultValueNode(value: null),
directives: [])
],
directives: [],
selectionSet: SelectionSetNode(selections: [
FieldNode(
name: NameNode(value: 'updateSubscription'),
alias: null,
arguments: [
ArgumentNode(
name: NameNode(value: 'input'),
value: ObjectValueNode(fields: [
ObjectFieldNode(
name: NameNode(value: 'subscribableId'),
value: VariableNode(name: NameNode(value: 'id'))),
ObjectFieldNode(
name: NameNode(value: 'state'),
value: VariableNode(name: NameNode(value: 'state')))
]))
],
directives: [],
selectionSet: SelectionSetNode(selections: [
FieldNode(
name: NameNode(value: 'subscribable'),
alias: null,
arguments: [],
directives: [],
selectionSet: SelectionSetNode(selections: [
InlineFragmentNode(
typeCondition: TypeConditionNode(
on: NamedTypeNode(
name: NameNode(value: 'Repository'),
isNonNull: false)),
directives: [],
selectionSet: SelectionSetNode(selections: [
FieldNode(
name: NameNode(value: 'viewerSubscription'),
alias: null,
arguments: [],
directives: [],
selectionSet: null)
]))
]))
]))
]))
]);
@override
final String operationName = 'GhWatch';
@override
final GhWatchArguments variables;
@override
List<Object> get props => [document, operationName, variables];
@override
GhWatch parse(Map<String, dynamic> json) => GhWatch.fromJson(json);
}

View File

@ -44,6 +44,8 @@ GhRepoRepository _$GhRepoRepositoryFromJson(Map<String, dynamic> json) {
..hasIssuesEnabled = json['hasIssuesEnabled'] as bool
..url = json['url'] as String
..viewerHasStarred = json['viewerHasStarred'] as bool
..viewerSubscription = _$enumDecodeNullable(
_$GhRepoSubscriptionStateEnumMap, json['viewerSubscription'])
..projectsUrl = json['projectsUrl'] as String
..watchers = json['watchers'] == null
? null
@ -71,18 +73,11 @@ GhRepoRepository _$GhRepoRepositoryFromJson(Map<String, dynamic> json) {
..defaultBranchRef = json['defaultBranchRef'] == null
? null
: GhRepoRef.fromJson(json['defaultBranchRef'] as Map<String, dynamic>)
..ref = json['ref'] == null
? null
: GhRepoRef.fromJson(json['ref'] as Map<String, dynamic>)
..refs = json['refs'] == null
? null
: GhRepoRefConnection.fromJson(json['refs'] as Map<String, dynamic>)
..licenseInfo = json['licenseInfo'] == null
? null
: GhRepoLicense.fromJson(json['licenseInfo'] as Map<String, dynamic>)
..repositoryTopics = json['repositoryTopics'] == null
? null
: GhRepoRepositoryTopicConnection.fromJson(json['repositoryTopics'] as Map<String, dynamic>)
..ref =
json['ref'] == null ? null : GhRepoRef.fromJson(json['ref'] as Map<String, dynamic>)
..refs = json['refs'] == null ? null : GhRepoRefConnection.fromJson(json['refs'] as Map<String, dynamic>)
..licenseInfo = json['licenseInfo'] == null ? null : GhRepoLicense.fromJson(json['licenseInfo'] as Map<String, dynamic>)
..repositoryTopics = json['repositoryTopics'] == null ? null : GhRepoRepositoryTopicConnection.fromJson(json['repositoryTopics'] as Map<String, dynamic>)
..resolveType = json['__typename'] as String;
}
@ -102,6 +97,8 @@ Map<String, dynamic> _$GhRepoRepositoryToJson(GhRepoRepository instance) =>
'hasIssuesEnabled': instance.hasIssuesEnabled,
'url': instance.url,
'viewerHasStarred': instance.viewerHasStarred,
'viewerSubscription':
_$GhRepoSubscriptionStateEnumMap[instance.viewerSubscription],
'projectsUrl': instance.projectsUrl,
'watchers': instance.watchers?.toJson(),
'issues': instance.issues?.toJson(),
@ -117,6 +114,44 @@ Map<String, dynamic> _$GhRepoRepositoryToJson(GhRepoRepository instance) =>
'__typename': instance.resolveType,
};
T _$enumDecode<T>(
Map<T, dynamic> enumValues,
dynamic source, {
T unknownValue,
}) {
if (source == null) {
throw ArgumentError('A value must be provided. Supported values: '
'${enumValues.values.join(', ')}');
}
final value = enumValues.entries
.singleWhere((e) => e.value == source, orElse: () => null)
?.key;
if (value == null && unknownValue == null) {
throw ArgumentError('`$source` is not one of the supported values: '
'${enumValues.values.join(', ')}');
}
return value ?? unknownValue;
}
T _$enumDecodeNullable<T>(
Map<T, dynamic> enumValues,
dynamic source, {
T unknownValue,
}) {
if (source == null) {
return null;
}
return _$enumDecode<T>(enumValues, source, unknownValue: unknownValue);
}
const _$GhRepoSubscriptionStateEnumMap = {
GhRepoSubscriptionState.UNSUBSCRIBED: 'UNSUBSCRIBED',
GhRepoSubscriptionState.SUBSCRIBED: 'SUBSCRIBED',
GhRepoSubscriptionState.IGNORED: 'IGNORED',
};
GhRepoRepositoryOwner _$GhRepoRepositoryOwnerFromJson(
Map<String, dynamic> json) {
return GhRepoRepositoryOwner()
@ -3062,38 +3097,6 @@ Map<String, dynamic> _$GhCommitsStatusToJson(GhCommitsStatus instance) =>
'__typename': instance.resolveType,
};
T _$enumDecode<T>(
Map<T, dynamic> enumValues,
dynamic source, {
T unknownValue,
}) {
if (source == null) {
throw ArgumentError('A value must be provided. Supported values: '
'${enumValues.values.join(', ')}');
}
final value = enumValues.entries
.singleWhere((e) => e.value == source, orElse: () => null)
?.key;
if (value == null && unknownValue == null) {
throw ArgumentError('`$source` is not one of the supported values: '
'${enumValues.values.join(', ')}');
}
return value ?? unknownValue;
}
T _$enumDecodeNullable<T>(
Map<T, dynamic> enumValues,
dynamic source, {
T unknownValue,
}) {
if (source == null) {
return null;
}
return _$enumDecode<T>(enumValues, source, unknownValue: unknownValue);
}
const _$GhCommitsStatusStateEnumMap = {
GhCommitsStatusState.EXPECTED: 'EXPECTED',
GhCommitsStatusState.ERROR: 'ERROR',
@ -3347,3 +3350,157 @@ Map<String, dynamic> _$GhRepoIdArgumentsToJson(GhRepoIdArguments instance) =>
'owner': instance.owner,
'name': instance.name,
};
GhWatch _$GhWatchFromJson(Map<String, dynamic> json) {
return GhWatch()
..updateSubscription = json['updateSubscription'] == null
? null
: GhWatchUpdateSubscriptionPayload.fromJson(
json['updateSubscription'] as Map<String, dynamic>);
}
Map<String, dynamic> _$GhWatchToJson(GhWatch instance) => <String, dynamic>{
'updateSubscription': instance.updateSubscription?.toJson(),
};
GhWatchUpdateSubscriptionPayload _$GhWatchUpdateSubscriptionPayloadFromJson(
Map<String, dynamic> json) {
return GhWatchUpdateSubscriptionPayload()
..subscribable = json['subscribable'] == null
? null
: GhWatchSubscribable.fromJson(
json['subscribable'] as Map<String, dynamic>);
}
Map<String, dynamic> _$GhWatchUpdateSubscriptionPayloadToJson(
GhWatchUpdateSubscriptionPayload instance) =>
<String, dynamic>{
'subscribable': instance.subscribable?.toJson(),
};
GhWatchSubscribable _$GhWatchSubscribableFromJson(Map<String, dynamic> json) {
return GhWatchSubscribable()..resolveType = json['__typename'] as String;
}
Map<String, dynamic> _$GhWatchSubscribableToJson(
GhWatchSubscribable instance) =>
<String, dynamic>{
'__typename': instance.resolveType,
};
GhWatchRepository _$GhWatchRepositoryFromJson(Map<String, dynamic> json) {
return GhWatchRepository()
..viewerSubscription = _$enumDecodeNullable(
_$GhWatchSubscriptionStateEnumMap, json['viewerSubscription'])
..resolveType = json['__typename'] as String;
}
Map<String, dynamic> _$GhWatchRepositoryToJson(GhWatchRepository instance) =>
<String, dynamic>{
'viewerSubscription':
_$GhWatchSubscriptionStateEnumMap[instance.viewerSubscription],
'__typename': instance.resolveType,
};
const _$GhWatchSubscriptionStateEnumMap = {
GhWatchSubscriptionState.UNSUBSCRIBED: 'UNSUBSCRIBED',
GhWatchSubscriptionState.SUBSCRIBED: 'SUBSCRIBED',
GhWatchSubscriptionState.IGNORED: 'IGNORED',
};
GhWatchPinnableItem _$GhWatchPinnableItemFromJson(Map<String, dynamic> json) {
return GhWatchPinnableItem();
}
Map<String, dynamic> _$GhWatchPinnableItemToJson(
GhWatchPinnableItem instance) =>
<String, dynamic>{};
GhWatchNode _$GhWatchNodeFromJson(Map<String, dynamic> json) {
return GhWatchNode()..resolveType = json['__typename'] as String;
}
Map<String, dynamic> _$GhWatchNodeToJson(GhWatchNode instance) =>
<String, dynamic>{
'__typename': instance.resolveType,
};
GhWatchProjectOwner _$GhWatchProjectOwnerFromJson(Map<String, dynamic> json) {
return GhWatchProjectOwner()..resolveType = json['__typename'] as String;
}
Map<String, dynamic> _$GhWatchProjectOwnerToJson(
GhWatchProjectOwner instance) =>
<String, dynamic>{
'__typename': instance.resolveType,
};
GhWatchRegistryPackageOwner _$GhWatchRegistryPackageOwnerFromJson(
Map<String, dynamic> json) {
return GhWatchRegistryPackageOwner()
..resolveType = json['__typename'] as String;
}
Map<String, dynamic> _$GhWatchRegistryPackageOwnerToJson(
GhWatchRegistryPackageOwner instance) =>
<String, dynamic>{
'__typename': instance.resolveType,
};
GhWatchRegistryPackageSearch _$GhWatchRegistryPackageSearchFromJson(
Map<String, dynamic> json) {
return GhWatchRegistryPackageSearch()
..resolveType = json['__typename'] as String;
}
Map<String, dynamic> _$GhWatchRegistryPackageSearchToJson(
GhWatchRegistryPackageSearch instance) =>
<String, dynamic>{
'__typename': instance.resolveType,
};
GhWatchStarrable _$GhWatchStarrableFromJson(Map<String, dynamic> json) {
return GhWatchStarrable()..resolveType = json['__typename'] as String;
}
Map<String, dynamic> _$GhWatchStarrableToJson(GhWatchStarrable instance) =>
<String, dynamic>{
'__typename': instance.resolveType,
};
GhWatchUniformResourceLocatable _$GhWatchUniformResourceLocatableFromJson(
Map<String, dynamic> json) {
return GhWatchUniformResourceLocatable()
..resolveType = json['__typename'] as String;
}
Map<String, dynamic> _$GhWatchUniformResourceLocatableToJson(
GhWatchUniformResourceLocatable instance) =>
<String, dynamic>{
'__typename': instance.resolveType,
};
GhWatchRepositoryInfo _$GhWatchRepositoryInfoFromJson(
Map<String, dynamic> json) {
return GhWatchRepositoryInfo()..resolveType = json['__typename'] as String;
}
Map<String, dynamic> _$GhWatchRepositoryInfoToJson(
GhWatchRepositoryInfo instance) =>
<String, dynamic>{
'__typename': instance.resolveType,
};
GhWatchArguments _$GhWatchArgumentsFromJson(Map<String, dynamic> json) {
return GhWatchArguments(
id: json['id'] as String,
state:
_$enumDecodeNullable(_$GhWatchSubscriptionStateEnumMap, json['state']),
);
}
Map<String, dynamic> _$GhWatchArgumentsToJson(GhWatchArguments instance) =>
<String, dynamic>{
'id': instance.id,
'state': _$GhWatchSubscriptionStateEnumMap[instance.state],
};

View File

@ -30,7 +30,7 @@ query GhRepo(
hasIssuesEnabled
url
viewerHasStarred
# viewerSubscription # TODO
viewerSubscription
projectsUrl
watchers {
totalCount

View File

@ -0,0 +1,9 @@
mutation GhWatch($id: ID!, $state: SubscriptionState!) {
updateSubscription(input: { subscribableId: $id, state: $state }) {
subscribable {
... on Repository {
viewerSubscription
}
}
}
}

View File

@ -8,6 +8,7 @@ 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/avatar.dart';
import 'package:git_touch/widgets/entry_item.dart';
import 'package:git_touch/widgets/label.dart';
import 'package:git_touch/widgets/mutation_button.dart';
import 'package:git_touch/widgets/link.dart';
@ -16,7 +17,6 @@ import 'package:git_touch/widgets/table_view.dart';
import 'package:provider/provider.dart';
import 'package:git_touch/models/theme.dart';
import 'package:tuple/tuple.dart';
import '../widgets/entry_item.dart';
import 'package:git_touch/widgets/action_button.dart';
import 'package:charts_flutter/flutter.dart' as charts;
@ -76,24 +76,6 @@ class RepositoryScreen extends StatelessWidget {
return ActionButton(
title: 'Repository Actions',
items: [
// TODO:
// ActionItem(
// text: data[0]['viewerSubscription'] == 'SUBSCRIBED'
// ? 'Unwatch'
// : 'Watch',
// onPress: (_) async {
// if (data[0]['viewerSubscription'] == 'SUBSCRIBED') {
// await Provider.of<AuthModel>(context).deleteWithCredentials(
// '/repos/$owner/$name/subscription');
// data[0]['viewerSubscription'] = 'UNSUBSCRIBED';
// } else {
// await Provider.of<AuthModel>(context)
// .putWithCredentials('/repos/$owner/$name/subscription');
// data[0]['viewerSubscription'] = 'SUBSCRIBED';
// }
// setState(() {});
// },
// ),
ActionItem(
text: 'Projects(${repo.projects.totalCount})',
url: repo.projectsUrl,
@ -148,23 +130,76 @@ class RepositoryScreen extends StatelessWidget {
),
],
),
MutationButton(
text: repo.viewerHasStarred ? 'Unstar' : 'Star',
onPressed: () async {
final res = await auth.gqlClient.execute(
GhStarQuery(
variables: GhStarArguments(
id: repo.id,
flag: !repo.viewerHasStarred,
),
),
);
setState(() {
repo.viewerHasStarred =
res.data.removeStar?.starrable?.viewerHasStarred ??
Row(
children: <Widget>[
MutationButton(
text: repo.viewerHasStarred ? 'Unstar' : 'Star',
onPressed: () async {
final res = await auth.gqlClient.execute(
GhStarQuery(
variables: GhStarArguments(
id: repo.id,
flag: !repo.viewerHasStarred,
),
),
);
setState(() {
repo.viewerHasStarred = res.data.removeStar
?.starrable?.viewerHasStarred ??
res.data.addStar.starrable.viewerHasStarred;
});
},
});
},
),
// TODO:
// SizedBox(width: 4),
// MutationButton(
// text: repo.viewerSubscription ==
// GhRepoSubscriptionState.SUBSCRIBED
// ? 'Unwatch'
// : 'Watch',
// onPressed: () async {
// theme.showActions(
// context,
// GhWatchSubscriptionState.values.map((v) {
// return ActionItem(
// text: v.toString(),
// onTap: (_) async {
// final res = await auth.gqlClient.execute(
// GhWatchQuery(
// variables: GhWatchArguments(
// id: repo.id,
// state:
// GhWatchSubscriptionState.SUBSCRIBED,
// ),
// ),
// );
// setState(() {
// final r = res.data.updateSubscription
// .subscribable as GhWatchRepository;
// switch (r.viewerSubscription) {
// case GhWatchSubscriptionState.IGNORED:
// repo.viewerSubscription =
// GhRepoSubscriptionState.IGNORED;
// break;
// case GhWatchSubscriptionState.SUBSCRIBED:
// repo.viewerSubscription =
// GhRepoSubscriptionState.SUBSCRIBED;
// break;
// case GhWatchSubscriptionState
// .UNSUBSCRIBED:
// repo.viewerSubscription =
// GhRepoSubscriptionState
// .UNSUBSCRIBED;
// break;
// }
// });
// },
// );
// }).toList(),
// );
// },
// ),
],
),
if (repo.description != null && repo.description.isNotEmpty)
Text(