diff --git a/Classes/Issues/GithubClient+Issues.swift b/Classes/Issues/GithubClient+Issues.swift index 48d0c260a..b06f89e7d 100644 --- a/Classes/Issues/GithubClient+Issues.swift +++ b/Classes/Issues/GithubClient+Issues.swift @@ -168,7 +168,8 @@ extension GithubClient { viewerCanAdminister: canAdmin, defaultBranch: repository.defaultBranchRef?.name ?? "master", fileChanges: issueType.fileChanges, - mergeModel: issueType.mergeModel(availableTypes: availableMergeTypes) + mergeModel: issueType.mergeModel(availableTypes: availableMergeTypes), + subscriptionState: issueType.subscriptionState ) DispatchQueue.main.async { @@ -297,6 +298,37 @@ extension GithubClient { } } + func setSubscription( + previous: IssueResult, + subscribe: Bool, + completion: ((Result) -> Void)? = nil + ) { + + let state: SubscriptionState = subscribe + ? .subscribed + : .unsubscribed + + let optimisticResult = previous.updated(subscriptionState: state) + + let cache = self.cache + cache.set(value: optimisticResult) + + let mutation = UpdateSubscriptionMutation(subscribable_Id: previous.id, subscription_state: state) + + client.mutate(mutation, result: { data in + data.updateSubscription?.subscribable + }, completion: { result in + switch result { + case .success(let subscribable): + completion?(.success(subscribable.viewerSubscription)) + case .failure(let error): + cache.set(value: previous) + completion?(.error(error)) + Squawk.show(error: error) + } + }) + } + enum CollaboratorPermission: String { case admin case write diff --git a/Classes/Issues/Issue+IssueType.swift b/Classes/Issues/Issue+IssueType.swift index f8c2b6c39..3fe3f4ce6 100644 --- a/Classes/Issues/Issue+IssueType.swift +++ b/Classes/Issues/Issue+IssueType.swift @@ -11,6 +11,10 @@ import IGListKit extension IssueOrPullRequestQuery.Data.Repository.IssueOrPullRequest.AsIssue: IssueType { + var subscriptionState: SubscriptionState { + return viewerSubscription ?? .unsubscribed + } + var pullRequest: Bool { return false } diff --git a/Classes/Issues/IssueManagingContextController.swift b/Classes/Issues/IssueManagingContextController.swift index cf42cbaf6..73a2d1122 100644 --- a/Classes/Issues/IssueManagingContextController.swift +++ b/Classes/Issues/IssueManagingContextController.swift @@ -84,10 +84,12 @@ final class IssueManagingContextController: NSObject, ContextMenuDelegate { case lock case reopen case close + case subscribe + case unsubscribe } var actions: [Action] { - if case .none = permissions { return [] } + guard let result = self.result else { return [] } var actions = [Action]() @@ -97,21 +99,30 @@ final class IssueManagingContextController: NSObject, ContextMenuDelegate { if result.pullRequest { actions.append(.reviewers) } + } + + if result.subscriptionState == .subscribed { + actions.append(.unsubscribe) + } else { + actions.append(.subscribe) + } + + if case .collaborator = permissions { if result.labels.locked { actions.append(.unlock) } else { actions.append(.lock) } } - - switch result.labels.status.status { - case .closed: - actions.append(.reopen) - case .open: - actions.append(.close) - case .merged: break + if permissions == .collaborator || permissions == .author { + switch result.labels.status.status { + case .closed: + actions.append(.reopen) + case .open: + actions.append(.close) + case .merged: break + } } - return actions } @@ -144,13 +155,19 @@ final class IssueManagingContextController: NSObject, ContextMenuDelegate { case .close: title = Constants.Strings.close iconName = "x" + case .subscribe: + title = Constants.Strings.subscribe + iconName = "unmute" + case .unsubscribe: + title = Constants.Strings.unsubscribe + iconName = "mute" } // Lock always has the divider above it assuming you're a collaborator. // If you aren't a collaborator (Lock does not show), close has the divider above it. let separator: Bool switch action { - case .lock, .unlock: separator = true + case .subscribe, .unsubscribe: separator = true case .reopen, .close: separator = permissions != .collaborator default: separator = false } @@ -186,6 +203,8 @@ final class IssueManagingContextController: NSObject, ContextMenuDelegate { case .lock: strongSelf.lock(true) case .reopen: strongSelf.close(false) case .close: strongSelf.close(true) + case .subscribe: strongSelf.subscribe(true) + case .unsubscribe: strongSelf.subscribe(false) } } } @@ -271,6 +290,12 @@ final class IssueManagingContextController: NSObject, ContextMenuDelegate { ) } + func subscribe(_ doSubscribe: Bool) { + guard let previous = result else { return } + delegate?.willMutateModel(from: self) + client.setSubscription(previous: previous, subscribe: doSubscribe) + Haptic.triggerNotification(.success) + } func close(_ doClose: Bool) { guard let previous = result else { return } delegate?.willMutateModel(from: self) diff --git a/Classes/Issues/IssueResult.swift b/Classes/Issues/IssueResult.swift index 08ff5e32e..dbf5c469a 100644 --- a/Classes/Issues/IssueResult.swift +++ b/Classes/Issues/IssueResult.swift @@ -31,6 +31,7 @@ struct IssueResult: Cachable { let defaultBranch: String let fileChanges: FileChanges? let mergeModel: IssueMergeModel? + let subscriptionState: SubscriptionState var timelineViewModels: [ListDiffable] { return timelinePages.reduce([], { $0 + $1.viewModels }) @@ -77,7 +78,8 @@ struct IssueResult: Cachable { hasIssuesEnabled: Bool? = nil, viewerCanAdminister: Bool? = nil, defaultBranch: String? = nil, - mergeModel: IssueMergeModel? = nil + mergeModel: IssueMergeModel? = nil, + subscriptionState: SubscriptionState? = nil ) -> IssueResult { return IssueResult( id: id ?? self.id, @@ -95,7 +97,8 @@ struct IssueResult: Cachable { viewerCanAdminister: viewerCanAdminister ?? self.viewerCanAdminister, defaultBranch: defaultBranch ?? self.defaultBranch, fileChanges: fileChanges, - mergeModel: mergeModel ?? self.mergeModel + mergeModel: mergeModel ?? self.mergeModel, + subscriptionState: subscriptionState ?? self.subscriptionState ) } @@ -119,7 +122,8 @@ struct IssueResult: Cachable { viewerCanAdminister: self.viewerCanAdminister, defaultBranch: self.defaultBranch, fileChanges: self.fileChanges, - mergeModel: self.mergeModel + mergeModel: self.mergeModel, + subscriptionState: self.subscriptionState ) } @@ -143,7 +147,8 @@ struct IssueResult: Cachable { viewerCanAdminister: self.viewerCanAdminister, defaultBranch: self.defaultBranch, fileChanges: self.fileChanges, - mergeModel: self.mergeModel + mergeModel: self.mergeModel, + subscriptionState: self.subscriptionState ) } diff --git a/Classes/Issues/IssueType.swift b/Classes/Issues/IssueType.swift index d3c4e8b6b..1265ff639 100644 --- a/Classes/Issues/IssueType.swift +++ b/Classes/Issues/IssueType.swift @@ -34,6 +34,8 @@ protocol IssueType { var headPaging: HeadPaging { get } var viewerCanUpdate: Bool { get } var fileChanges: FileChanges? { get } + var subscriptionState: SubscriptionState { get } + var reviewRequestModel: IssueAssigneesModel? { get } func mergeModel(availableTypes: [IssueMergeType]) -> IssueMergeModel? diff --git a/Classes/Issues/PullRequest+IssueType.swift b/Classes/Issues/PullRequest+IssueType.swift index b320bb597..319310ed6 100644 --- a/Classes/Issues/PullRequest+IssueType.swift +++ b/Classes/Issues/PullRequest+IssueType.swift @@ -12,6 +12,10 @@ import StyledTextKit extension IssueOrPullRequestQuery.Data.Repository.IssueOrPullRequest.AsPullRequest: IssueType { + var subscriptionState: SubscriptionState { + return viewerSubscription ?? .unsubscribed + } + var pullRequest: Bool { return true } diff --git a/Classes/Views/Constants.swift b/Classes/Views/Constants.swift index 4c79f5339..2f1975ced 100644 --- a/Classes/Views/Constants.swift +++ b/Classes/Views/Constants.swift @@ -52,6 +52,8 @@ enum Constants { static let reviewers = NSLocalizedString("Reviewers", comment: "") static let clear = NSLocalizedString("Clear", comment: "") static let preview = NSLocalizedString("Preview", comment: "") + static let subscribe = NSLocalizedString("Subscribe", comment: "") + static let unsubscribe = NSLocalizedString("Unsubscribe", comment: "") static let overview = NSLocalizedString("Overview", comment: "") } } diff --git a/FreetimeTests/SplitViewTests.swift b/FreetimeTests/SplitViewTests.swift index dcc9e697b..4b2dfda51 100644 --- a/FreetimeTests/SplitViewTests.swift +++ b/FreetimeTests/SplitViewTests.swift @@ -114,9 +114,7 @@ class SplitViewTests: XCTestCase { client: GithubClient(userSession: nil), repo: RepositoryDetails( owner: "Foo", - name: "Bar", - defaultBranch: "Baz", - hasIssuesEnabled: false + name: "Bar" )) let detail2 = IssuesViewController( diff --git a/gql/API.swift b/gql/API.swift index e20f93b8c..491fce9a9 100644 --- a/gql/API.swift +++ b/gql/API.swift @@ -135,6 +135,47 @@ public enum PullRequestState: RawRepresentable, Equatable, Apollo.JSONDecodable, } } +/// The possible states of a subscription. +public enum SubscriptionState: RawRepresentable, Equatable, Apollo.JSONDecodable, Apollo.JSONEncodable { + public typealias RawValue = String + /// The User is only notified when particpating or @mentioned. + case unsubscribed + /// The User is notified of all conversations. + case subscribed + /// The User is never notified. + case ignored + /// Auto generated constant for unknown enum values + case __unknown(RawValue) + + public init?(rawValue: RawValue) { + switch rawValue { + case "UNSUBSCRIBED": self = .unsubscribed + case "SUBSCRIBED": self = .subscribed + case "IGNORED": self = .ignored + default: self = .__unknown(rawValue) + } + } + + public var rawValue: RawValue { + switch self { + case .unsubscribed: return "UNSUBSCRIBED" + case .subscribed: return "SUBSCRIBED" + case .ignored: return "IGNORED" + case .__unknown(let value): return value + } + } + + public static func == (lhs: SubscriptionState, rhs: SubscriptionState) -> Bool { + switch (lhs, rhs) { + case (.unsubscribed, .unsubscribed): return true + case (.subscribed, .subscribed): return true + case (.ignored, .ignored): return true + case (.__unknown(let lhsValue), .__unknown(let rhsValue)): return lhsValue == rhsValue + default: return false + } + } +} + /// The possible commit status states. public enum StatusState: RawRepresentable, Equatable, Apollo.JSONDecodable, Apollo.JSONEncodable { public typealias RawValue = String @@ -2343,7 +2384,7 @@ public final class IssueAutocompleteQuery: GraphQLQuery { public final class IssueOrPullRequestQuery: GraphQLQuery { public static let operationString = - "query IssueOrPullRequest($owner: String!, $repo: String!, $number: Int!, $page_size: Int!, $before: String) {\n repository(owner: $owner, name: $repo) {\n __typename\n name\n hasIssuesEnabled\n viewerCanAdminister\n mergeCommitAllowed\n rebaseMergeAllowed\n squashMergeAllowed\n mentionableUsers(first: 50) {\n __typename\n nodes {\n __typename\n avatarUrl\n login\n }\n }\n defaultBranchRef {\n __typename\n name\n }\n issueOrPullRequest(number: $number) {\n __typename\n ... on Issue {\n timeline(last: $page_size, before: $before) {\n __typename\n pageInfo {\n __typename\n ...headPaging\n }\n nodes {\n __typename\n ... on Commit {\n ...nodeFields\n author {\n __typename\n user {\n __typename\n login\n avatarUrl\n }\n }\n oid\n messageHeadline\n }\n ... on IssueComment {\n ...nodeFields\n ...reactionFields\n ...commentFields\n ...updatableFields\n ...deletableFields\n }\n ... on LabeledEvent {\n ...nodeFields\n actor {\n __typename\n login\n }\n label {\n __typename\n color\n name\n }\n createdAt\n }\n ... on UnlabeledEvent {\n ...nodeFields\n actor {\n __typename\n login\n }\n label {\n __typename\n color\n name\n }\n createdAt\n }\n ... on ClosedEvent {\n ...nodeFields\n actor {\n __typename\n login\n }\n createdAt\n closer {\n __typename\n ... on Commit {\n oid\n }\n ... on PullRequest {\n mergeCommit {\n __typename\n oid\n }\n }\n }\n }\n ... on ReopenedEvent {\n ...nodeFields\n actor {\n __typename\n login\n }\n createdAt\n }\n ... on RenamedTitleEvent {\n ...nodeFields\n actor {\n __typename\n login\n }\n createdAt\n currentTitle\n }\n ... on LockedEvent {\n ...nodeFields\n actor {\n __typename\n login\n }\n createdAt\n }\n ... on UnlockedEvent {\n ...nodeFields\n actor {\n __typename\n login\n }\n createdAt\n }\n ... on CrossReferencedEvent {\n ...nodeFields\n actor {\n __typename\n login\n }\n createdAt\n source {\n __typename\n ... on Issue {\n title\n number\n closed\n repository {\n __typename\n name\n owner {\n __typename\n login\n }\n }\n }\n ... on PullRequest {\n title\n number\n closed\n merged\n repository {\n __typename\n name\n owner {\n __typename\n login\n }\n }\n }\n }\n }\n ... on ReferencedEvent {\n createdAt\n ...nodeFields\n refCommit: commit {\n __typename\n oid\n }\n actor {\n __typename\n login\n }\n commitRepository {\n __typename\n ...referencedRepositoryFields\n }\n subject {\n __typename\n ... on Issue {\n title\n number\n closed\n }\n ... on PullRequest {\n title\n number\n closed\n merged\n }\n }\n }\n ... on RenamedTitleEvent {\n ...nodeFields\n createdAt\n currentTitle\n previousTitle\n actor {\n __typename\n login\n }\n }\n ... on AssignedEvent {\n ...nodeFields\n createdAt\n actor {\n __typename\n login\n }\n user {\n __typename\n login\n }\n }\n ... on UnassignedEvent {\n ...nodeFields\n createdAt\n actor {\n __typename\n login\n }\n user {\n __typename\n login\n }\n }\n ... on MilestonedEvent {\n ...nodeFields\n createdAt\n actor {\n __typename\n login\n }\n milestoneTitle\n }\n ... on DemilestonedEvent {\n ...nodeFields\n createdAt\n actor {\n __typename\n login\n }\n milestoneTitle\n }\n }\n }\n milestone {\n __typename\n ...milestoneFields\n }\n ...reactionFields\n ...commentFields\n ...lockableFields\n ...closableFields\n ...labelableFields\n ...updatableFields\n ...nodeFields\n ...assigneeFields\n number\n title\n }\n ... on PullRequest {\n timeline(last: $page_size, before: $before) {\n __typename\n pageInfo {\n __typename\n ...headPaging\n }\n nodes {\n __typename\n ... on Commit {\n ...nodeFields\n author {\n __typename\n user {\n __typename\n login\n avatarUrl\n }\n }\n oid\n messageHeadline\n }\n ... on IssueComment {\n ...nodeFields\n ...reactionFields\n ...commentFields\n ...updatableFields\n ...deletableFields\n }\n ... on LabeledEvent {\n ...nodeFields\n actor {\n __typename\n login\n }\n label {\n __typename\n color\n name\n }\n createdAt\n }\n ... on UnlabeledEvent {\n ...nodeFields\n actor {\n __typename\n login\n }\n label {\n __typename\n color\n name\n }\n createdAt\n }\n ... on ClosedEvent {\n ...nodeFields\n actor {\n __typename\n login\n }\n createdAt\n closer {\n __typename\n ... on Commit {\n oid\n }\n ... on PullRequest {\n mergeCommit {\n __typename\n oid\n }\n }\n }\n }\n ... on ReopenedEvent {\n ...nodeFields\n actor {\n __typename\n login\n }\n createdAt\n }\n ... on RenamedTitleEvent {\n ...nodeFields\n actor {\n __typename\n login\n }\n createdAt\n currentTitle\n }\n ... on LockedEvent {\n ...nodeFields\n actor {\n __typename\n login\n }\n createdAt\n }\n ... on UnlockedEvent {\n ...nodeFields\n actor {\n __typename\n login\n }\n createdAt\n }\n ... on MergedEvent {\n ...nodeFields\n mergedCommit: commit {\n __typename\n oid\n }\n actor {\n __typename\n login\n }\n createdAt\n }\n ... on PullRequestReviewThread {\n comments(first: $page_size) {\n __typename\n nodes {\n __typename\n ...reactionFields\n ...nodeFields\n ...commentFields\n path\n diffHunk\n }\n }\n }\n ... on PullRequestReview {\n ...nodeFields\n ...commentFields\n state\n submittedAt\n author {\n __typename\n login\n }\n comments {\n __typename\n totalCount\n }\n }\n ... on CrossReferencedEvent {\n ...nodeFields\n actor {\n __typename\n login\n }\n createdAt\n source {\n __typename\n ... on Issue {\n title\n number\n closed\n repository {\n __typename\n name\n owner {\n __typename\n login\n }\n }\n }\n ... on PullRequest {\n title\n number\n closed\n merged\n repository {\n __typename\n name\n owner {\n __typename\n login\n }\n }\n }\n }\n }\n ... on ReferencedEvent {\n createdAt\n ...nodeFields\n actor {\n __typename\n login\n }\n commitRepository {\n __typename\n ...referencedRepositoryFields\n }\n subject {\n __typename\n ... on Issue {\n title\n number\n closed\n }\n ... on PullRequest {\n title\n number\n closed\n merged\n }\n }\n }\n ... on RenamedTitleEvent {\n ...nodeFields\n createdAt\n currentTitle\n previousTitle\n actor {\n __typename\n login\n }\n }\n ... on AssignedEvent {\n ...nodeFields\n createdAt\n actor {\n __typename\n login\n }\n user {\n __typename\n login\n }\n }\n ... on UnassignedEvent {\n ...nodeFields\n createdAt\n actor {\n __typename\n login\n }\n user {\n __typename\n login\n }\n }\n ... on ReviewRequestedEvent {\n ...nodeFields\n createdAt\n actor {\n __typename\n login\n }\n requestedReviewer {\n __typename\n ... on Actor {\n login\n }\n }\n }\n ... on ReviewRequestRemovedEvent {\n ...nodeFields\n createdAt\n actor {\n __typename\n login\n }\n requestedReviewer {\n __typename\n ... on Actor {\n login\n }\n }\n }\n ... on MilestonedEvent {\n ...nodeFields\n createdAt\n actor {\n __typename\n login\n }\n milestoneTitle\n }\n ... on DemilestonedEvent {\n ...nodeFields\n createdAt\n actor {\n __typename\n login\n }\n milestoneTitle\n }\n }\n }\n reviewRequests(first: $page_size) {\n __typename\n nodes {\n __typename\n requestedReviewer {\n __typename\n ... on Actor {\n login\n avatarUrl\n }\n }\n }\n }\n commits(last: 1) {\n __typename\n nodes {\n __typename\n commit {\n __typename\n ...commitContext\n }\n }\n }\n milestone {\n __typename\n ...milestoneFields\n }\n ...reactionFields\n ...commentFields\n ...lockableFields\n ...closableFields\n ...labelableFields\n ...updatableFields\n ...nodeFields\n ...assigneeFields\n number\n title\n merged\n baseRefName\n changedFiles\n additions\n deletions\n mergeable\n mergeStateStatus\n }\n }\n }\n}" + "query IssueOrPullRequest($owner: String!, $repo: String!, $number: Int!, $page_size: Int!, $before: String) {\n repository(owner: $owner, name: $repo) {\n __typename\n name\n hasIssuesEnabled\n viewerCanAdminister\n mergeCommitAllowed\n rebaseMergeAllowed\n squashMergeAllowed\n mentionableUsers(first: 50) {\n __typename\n nodes {\n __typename\n avatarUrl\n login\n }\n }\n defaultBranchRef {\n __typename\n name\n }\n issueOrPullRequest(number: $number) {\n __typename\n ... on Issue {\n viewerSubscription\n timeline(last: $page_size, before: $before) {\n __typename\n pageInfo {\n __typename\n ...headPaging\n }\n nodes {\n __typename\n ... on Commit {\n ...nodeFields\n author {\n __typename\n user {\n __typename\n login\n avatarUrl\n }\n }\n oid\n messageHeadline\n }\n ... on IssueComment {\n ...nodeFields\n ...reactionFields\n ...commentFields\n ...updatableFields\n ...deletableFields\n }\n ... on LabeledEvent {\n ...nodeFields\n actor {\n __typename\n login\n }\n label {\n __typename\n color\n name\n }\n createdAt\n }\n ... on UnlabeledEvent {\n ...nodeFields\n actor {\n __typename\n login\n }\n label {\n __typename\n color\n name\n }\n createdAt\n }\n ... on ClosedEvent {\n ...nodeFields\n actor {\n __typename\n login\n }\n createdAt\n closer {\n __typename\n ... on Commit {\n oid\n }\n ... on PullRequest {\n mergeCommit {\n __typename\n oid\n }\n }\n }\n }\n ... on ReopenedEvent {\n ...nodeFields\n actor {\n __typename\n login\n }\n createdAt\n }\n ... on RenamedTitleEvent {\n ...nodeFields\n actor {\n __typename\n login\n }\n createdAt\n currentTitle\n }\n ... on LockedEvent {\n ...nodeFields\n actor {\n __typename\n login\n }\n createdAt\n }\n ... on UnlockedEvent {\n ...nodeFields\n actor {\n __typename\n login\n }\n createdAt\n }\n ... on CrossReferencedEvent {\n ...nodeFields\n actor {\n __typename\n login\n }\n createdAt\n source {\n __typename\n ... on Issue {\n title\n number\n closed\n repository {\n __typename\n name\n owner {\n __typename\n login\n }\n }\n }\n ... on PullRequest {\n title\n number\n closed\n merged\n repository {\n __typename\n name\n owner {\n __typename\n login\n }\n }\n }\n }\n }\n ... on ReferencedEvent {\n createdAt\n ...nodeFields\n refCommit: commit {\n __typename\n oid\n }\n actor {\n __typename\n login\n }\n commitRepository {\n __typename\n ...referencedRepositoryFields\n }\n subject {\n __typename\n ... on Issue {\n title\n number\n closed\n }\n ... on PullRequest {\n title\n number\n closed\n merged\n }\n }\n }\n ... on RenamedTitleEvent {\n ...nodeFields\n createdAt\n currentTitle\n previousTitle\n actor {\n __typename\n login\n }\n }\n ... on AssignedEvent {\n ...nodeFields\n createdAt\n actor {\n __typename\n login\n }\n user {\n __typename\n login\n }\n }\n ... on UnassignedEvent {\n ...nodeFields\n createdAt\n actor {\n __typename\n login\n }\n user {\n __typename\n login\n }\n }\n ... on MilestonedEvent {\n ...nodeFields\n createdAt\n actor {\n __typename\n login\n }\n milestoneTitle\n }\n ... on DemilestonedEvent {\n ...nodeFields\n createdAt\n actor {\n __typename\n login\n }\n milestoneTitle\n }\n }\n }\n milestone {\n __typename\n ...milestoneFields\n }\n ...reactionFields\n ...commentFields\n ...lockableFields\n ...closableFields\n ...labelableFields\n ...updatableFields\n ...nodeFields\n ...assigneeFields\n number\n title\n }\n ... on PullRequest {\n viewerSubscription\n timeline(last: $page_size, before: $before) {\n __typename\n pageInfo {\n __typename\n ...headPaging\n }\n nodes {\n __typename\n ... on Commit {\n ...nodeFields\n author {\n __typename\n user {\n __typename\n login\n avatarUrl\n }\n }\n oid\n messageHeadline\n }\n ... on IssueComment {\n ...nodeFields\n ...reactionFields\n ...commentFields\n ...updatableFields\n ...deletableFields\n }\n ... on LabeledEvent {\n ...nodeFields\n actor {\n __typename\n login\n }\n label {\n __typename\n color\n name\n }\n createdAt\n }\n ... on UnlabeledEvent {\n ...nodeFields\n actor {\n __typename\n login\n }\n label {\n __typename\n color\n name\n }\n createdAt\n }\n ... on ClosedEvent {\n ...nodeFields\n actor {\n __typename\n login\n }\n createdAt\n closer {\n __typename\n ... on Commit {\n oid\n }\n ... on PullRequest {\n mergeCommit {\n __typename\n oid\n }\n }\n }\n }\n ... on ReopenedEvent {\n ...nodeFields\n actor {\n __typename\n login\n }\n createdAt\n }\n ... on RenamedTitleEvent {\n ...nodeFields\n actor {\n __typename\n login\n }\n createdAt\n currentTitle\n }\n ... on LockedEvent {\n ...nodeFields\n actor {\n __typename\n login\n }\n createdAt\n }\n ... on UnlockedEvent {\n ...nodeFields\n actor {\n __typename\n login\n }\n createdAt\n }\n ... on MergedEvent {\n ...nodeFields\n mergedCommit: commit {\n __typename\n oid\n }\n actor {\n __typename\n login\n }\n createdAt\n }\n ... on PullRequestReviewThread {\n comments(first: $page_size) {\n __typename\n nodes {\n __typename\n ...reactionFields\n ...nodeFields\n ...commentFields\n path\n diffHunk\n }\n }\n }\n ... on PullRequestReview {\n ...nodeFields\n ...commentFields\n state\n submittedAt\n author {\n __typename\n login\n }\n comments {\n __typename\n totalCount\n }\n }\n ... on CrossReferencedEvent {\n ...nodeFields\n actor {\n __typename\n login\n }\n createdAt\n source {\n __typename\n ... on Issue {\n title\n number\n closed\n repository {\n __typename\n name\n owner {\n __typename\n login\n }\n }\n }\n ... on PullRequest {\n title\n number\n closed\n merged\n repository {\n __typename\n name\n owner {\n __typename\n login\n }\n }\n }\n }\n }\n ... on ReferencedEvent {\n createdAt\n ...nodeFields\n actor {\n __typename\n login\n }\n commitRepository {\n __typename\n ...referencedRepositoryFields\n }\n subject {\n __typename\n ... on Issue {\n title\n number\n closed\n }\n ... on PullRequest {\n title\n number\n closed\n merged\n }\n }\n }\n ... on RenamedTitleEvent {\n ...nodeFields\n createdAt\n currentTitle\n previousTitle\n actor {\n __typename\n login\n }\n }\n ... on AssignedEvent {\n ...nodeFields\n createdAt\n actor {\n __typename\n login\n }\n user {\n __typename\n login\n }\n }\n ... on UnassignedEvent {\n ...nodeFields\n createdAt\n actor {\n __typename\n login\n }\n user {\n __typename\n login\n }\n }\n ... on ReviewRequestedEvent {\n ...nodeFields\n createdAt\n actor {\n __typename\n login\n }\n requestedReviewer {\n __typename\n ... on Actor {\n login\n }\n }\n }\n ... on ReviewRequestRemovedEvent {\n ...nodeFields\n createdAt\n actor {\n __typename\n login\n }\n requestedReviewer {\n __typename\n ... on Actor {\n login\n }\n }\n }\n ... on MilestonedEvent {\n ...nodeFields\n createdAt\n actor {\n __typename\n login\n }\n milestoneTitle\n }\n ... on DemilestonedEvent {\n ...nodeFields\n createdAt\n actor {\n __typename\n login\n }\n milestoneTitle\n }\n }\n }\n reviewRequests(first: $page_size) {\n __typename\n nodes {\n __typename\n requestedReviewer {\n __typename\n ... on Actor {\n login\n avatarUrl\n }\n }\n }\n }\n commits(last: 1) {\n __typename\n nodes {\n __typename\n commit {\n __typename\n ...commitContext\n }\n }\n }\n milestone {\n __typename\n ...milestoneFields\n }\n ...reactionFields\n ...commentFields\n ...lockableFields\n ...closableFields\n ...labelableFields\n ...updatableFields\n ...nodeFields\n ...assigneeFields\n number\n title\n merged\n baseRefName\n changedFiles\n additions\n deletions\n mergeable\n mergeStateStatus\n }\n }\n }\n}" public static var requestString: String { return operationString.appending(HeadPaging.fragmentString).appending(NodeFields.fragmentString).appending(ReactionFields.fragmentString).appending(CommentFields.fragmentString).appending(UpdatableFields.fragmentString).appending(DeletableFields.fragmentString).appending(ReferencedRepositoryFields.fragmentString).appending(MilestoneFields.fragmentString).appending(LockableFields.fragmentString).appending(ClosableFields.fragmentString).appending(LabelableFields.fragmentString).appending(AssigneeFields.fragmentString).appending(CommitContext.fragmentString) } @@ -2660,12 +2701,12 @@ public final class IssueOrPullRequestQuery: GraphQLQuery { self.snapshot = snapshot } - public static func makeIssue(timeline: AsIssue.Timeline, milestone: AsIssue.Milestone? = nil, viewerCanReact: Bool, reactionGroups: [AsIssue.ReactionGroup]? = nil, author: AsIssue.Author? = nil, editor: AsIssue.Editor? = nil, lastEditedAt: String? = nil, body: String, createdAt: String, viewerDidAuthor: Bool, locked: Bool, closed: Bool, labels: AsIssue.Label? = nil, viewerCanUpdate: Bool, id: GraphQLID, assignees: AsIssue.Assignee, number: Int, title: String) -> IssueOrPullRequest { - return IssueOrPullRequest(snapshot: ["__typename": "Issue", "timeline": timeline.snapshot, "milestone": milestone.flatMap { (value: AsIssue.Milestone) -> Snapshot in value.snapshot }, "viewerCanReact": viewerCanReact, "reactionGroups": reactionGroups.flatMap { (value: [AsIssue.ReactionGroup]) -> [Snapshot] in value.map { (value: AsIssue.ReactionGroup) -> Snapshot in value.snapshot } }, "author": author.flatMap { (value: AsIssue.Author) -> Snapshot in value.snapshot }, "editor": editor.flatMap { (value: AsIssue.Editor) -> Snapshot in value.snapshot }, "lastEditedAt": lastEditedAt, "body": body, "createdAt": createdAt, "viewerDidAuthor": viewerDidAuthor, "locked": locked, "closed": closed, "labels": labels.flatMap { (value: AsIssue.Label) -> Snapshot in value.snapshot }, "viewerCanUpdate": viewerCanUpdate, "id": id, "assignees": assignees.snapshot, "number": number, "title": title]) + public static func makeIssue(viewerSubscription: SubscriptionState? = nil, timeline: AsIssue.Timeline, milestone: AsIssue.Milestone? = nil, viewerCanReact: Bool, reactionGroups: [AsIssue.ReactionGroup]? = nil, author: AsIssue.Author? = nil, editor: AsIssue.Editor? = nil, lastEditedAt: String? = nil, body: String, createdAt: String, viewerDidAuthor: Bool, locked: Bool, closed: Bool, labels: AsIssue.Label? = nil, viewerCanUpdate: Bool, id: GraphQLID, assignees: AsIssue.Assignee, number: Int, title: String) -> IssueOrPullRequest { + return IssueOrPullRequest(snapshot: ["__typename": "Issue", "viewerSubscription": viewerSubscription, "timeline": timeline.snapshot, "milestone": milestone.flatMap { (value: AsIssue.Milestone) -> Snapshot in value.snapshot }, "viewerCanReact": viewerCanReact, "reactionGroups": reactionGroups.flatMap { (value: [AsIssue.ReactionGroup]) -> [Snapshot] in value.map { (value: AsIssue.ReactionGroup) -> Snapshot in value.snapshot } }, "author": author.flatMap { (value: AsIssue.Author) -> Snapshot in value.snapshot }, "editor": editor.flatMap { (value: AsIssue.Editor) -> Snapshot in value.snapshot }, "lastEditedAt": lastEditedAt, "body": body, "createdAt": createdAt, "viewerDidAuthor": viewerDidAuthor, "locked": locked, "closed": closed, "labels": labels.flatMap { (value: AsIssue.Label) -> Snapshot in value.snapshot }, "viewerCanUpdate": viewerCanUpdate, "id": id, "assignees": assignees.snapshot, "number": number, "title": title]) } - public static func makePullRequest(timeline: AsPullRequest.Timeline, reviewRequests: AsPullRequest.ReviewRequest? = nil, commits: AsPullRequest.Commit, milestone: AsPullRequest.Milestone? = nil, viewerCanReact: Bool, reactionGroups: [AsPullRequest.ReactionGroup]? = nil, author: AsPullRequest.Author? = nil, editor: AsPullRequest.Editor? = nil, lastEditedAt: String? = nil, body: String, createdAt: String, viewerDidAuthor: Bool, locked: Bool, closed: Bool, labels: AsPullRequest.Label? = nil, viewerCanUpdate: Bool, id: GraphQLID, assignees: AsPullRequest.Assignee, number: Int, title: String, merged: Bool, baseRefName: String, changedFiles: Int, additions: Int, deletions: Int, mergeable: MergeableState, mergeStateStatus: MergeStateStatus) -> IssueOrPullRequest { - return IssueOrPullRequest(snapshot: ["__typename": "PullRequest", "timeline": timeline.snapshot, "reviewRequests": reviewRequests.flatMap { (value: AsPullRequest.ReviewRequest) -> Snapshot in value.snapshot }, "commits": commits.snapshot, "milestone": milestone.flatMap { (value: AsPullRequest.Milestone) -> Snapshot in value.snapshot }, "viewerCanReact": viewerCanReact, "reactionGroups": reactionGroups.flatMap { (value: [AsPullRequest.ReactionGroup]) -> [Snapshot] in value.map { (value: AsPullRequest.ReactionGroup) -> Snapshot in value.snapshot } }, "author": author.flatMap { (value: AsPullRequest.Author) -> Snapshot in value.snapshot }, "editor": editor.flatMap { (value: AsPullRequest.Editor) -> Snapshot in value.snapshot }, "lastEditedAt": lastEditedAt, "body": body, "createdAt": createdAt, "viewerDidAuthor": viewerDidAuthor, "locked": locked, "closed": closed, "labels": labels.flatMap { (value: AsPullRequest.Label) -> Snapshot in value.snapshot }, "viewerCanUpdate": viewerCanUpdate, "id": id, "assignees": assignees.snapshot, "number": number, "title": title, "merged": merged, "baseRefName": baseRefName, "changedFiles": changedFiles, "additions": additions, "deletions": deletions, "mergeable": mergeable, "mergeStateStatus": mergeStateStatus]) + public static func makePullRequest(viewerSubscription: SubscriptionState? = nil, timeline: AsPullRequest.Timeline, reviewRequests: AsPullRequest.ReviewRequest? = nil, commits: AsPullRequest.Commit, milestone: AsPullRequest.Milestone? = nil, viewerCanReact: Bool, reactionGroups: [AsPullRequest.ReactionGroup]? = nil, author: AsPullRequest.Author? = nil, editor: AsPullRequest.Editor? = nil, lastEditedAt: String? = nil, body: String, createdAt: String, viewerDidAuthor: Bool, locked: Bool, closed: Bool, labels: AsPullRequest.Label? = nil, viewerCanUpdate: Bool, id: GraphQLID, assignees: AsPullRequest.Assignee, number: Int, title: String, merged: Bool, baseRefName: String, changedFiles: Int, additions: Int, deletions: Int, mergeable: MergeableState, mergeStateStatus: MergeStateStatus) -> IssueOrPullRequest { + return IssueOrPullRequest(snapshot: ["__typename": "PullRequest", "viewerSubscription": viewerSubscription, "timeline": timeline.snapshot, "reviewRequests": reviewRequests.flatMap { (value: AsPullRequest.ReviewRequest) -> Snapshot in value.snapshot }, "commits": commits.snapshot, "milestone": milestone.flatMap { (value: AsPullRequest.Milestone) -> Snapshot in value.snapshot }, "viewerCanReact": viewerCanReact, "reactionGroups": reactionGroups.flatMap { (value: [AsPullRequest.ReactionGroup]) -> [Snapshot] in value.map { (value: AsPullRequest.ReactionGroup) -> Snapshot in value.snapshot } }, "author": author.flatMap { (value: AsPullRequest.Author) -> Snapshot in value.snapshot }, "editor": editor.flatMap { (value: AsPullRequest.Editor) -> Snapshot in value.snapshot }, "lastEditedAt": lastEditedAt, "body": body, "createdAt": createdAt, "viewerDidAuthor": viewerDidAuthor, "locked": locked, "closed": closed, "labels": labels.flatMap { (value: AsPullRequest.Label) -> Snapshot in value.snapshot }, "viewerCanUpdate": viewerCanUpdate, "id": id, "assignees": assignees.snapshot, "number": number, "title": title, "merged": merged, "baseRefName": baseRefName, "changedFiles": changedFiles, "additions": additions, "deletions": deletions, "mergeable": mergeable, "mergeStateStatus": mergeStateStatus]) } public var __typename: String { @@ -2693,6 +2734,7 @@ public final class IssueOrPullRequestQuery: GraphQLQuery { public static let selections: [GraphQLSelection] = [ GraphQLField("__typename", type: .nonNull(.scalar(String.self))), + GraphQLField("viewerSubscription", type: .scalar(SubscriptionState.self)), GraphQLField("timeline", arguments: ["last": GraphQLVariable("page_size"), "before": GraphQLVariable("before")], type: .nonNull(.object(Timeline.selections))), GraphQLField("milestone", type: .object(Milestone.selections)), GraphQLField("__typename", type: .nonNull(.scalar(String.self))), @@ -2727,8 +2769,8 @@ public final class IssueOrPullRequestQuery: GraphQLQuery { self.snapshot = snapshot } - public init(timeline: Timeline, milestone: Milestone? = nil, viewerCanReact: Bool, reactionGroups: [ReactionGroup]? = nil, author: Author? = nil, editor: Editor? = nil, lastEditedAt: String? = nil, body: String, createdAt: String, viewerDidAuthor: Bool, locked: Bool, closed: Bool, labels: Label? = nil, viewerCanUpdate: Bool, id: GraphQLID, assignees: Assignee, number: Int, title: String) { - self.init(snapshot: ["__typename": "Issue", "timeline": timeline.snapshot, "milestone": milestone.flatMap { (value: Milestone) -> Snapshot in value.snapshot }, "viewerCanReact": viewerCanReact, "reactionGroups": reactionGroups.flatMap { (value: [ReactionGroup]) -> [Snapshot] in value.map { (value: ReactionGroup) -> Snapshot in value.snapshot } }, "author": author.flatMap { (value: Author) -> Snapshot in value.snapshot }, "editor": editor.flatMap { (value: Editor) -> Snapshot in value.snapshot }, "lastEditedAt": lastEditedAt, "body": body, "createdAt": createdAt, "viewerDidAuthor": viewerDidAuthor, "locked": locked, "closed": closed, "labels": labels.flatMap { (value: Label) -> Snapshot in value.snapshot }, "viewerCanUpdate": viewerCanUpdate, "id": id, "assignees": assignees.snapshot, "number": number, "title": title]) + public init(viewerSubscription: SubscriptionState? = nil, timeline: Timeline, milestone: Milestone? = nil, viewerCanReact: Bool, reactionGroups: [ReactionGroup]? = nil, author: Author? = nil, editor: Editor? = nil, lastEditedAt: String? = nil, body: String, createdAt: String, viewerDidAuthor: Bool, locked: Bool, closed: Bool, labels: Label? = nil, viewerCanUpdate: Bool, id: GraphQLID, assignees: Assignee, number: Int, title: String) { + self.init(snapshot: ["__typename": "Issue", "viewerSubscription": viewerSubscription, "timeline": timeline.snapshot, "milestone": milestone.flatMap { (value: Milestone) -> Snapshot in value.snapshot }, "viewerCanReact": viewerCanReact, "reactionGroups": reactionGroups.flatMap { (value: [ReactionGroup]) -> [Snapshot] in value.map { (value: ReactionGroup) -> Snapshot in value.snapshot } }, "author": author.flatMap { (value: Author) -> Snapshot in value.snapshot }, "editor": editor.flatMap { (value: Editor) -> Snapshot in value.snapshot }, "lastEditedAt": lastEditedAt, "body": body, "createdAt": createdAt, "viewerDidAuthor": viewerDidAuthor, "locked": locked, "closed": closed, "labels": labels.flatMap { (value: Label) -> Snapshot in value.snapshot }, "viewerCanUpdate": viewerCanUpdate, "id": id, "assignees": assignees.snapshot, "number": number, "title": title]) } public var __typename: String { @@ -2740,6 +2782,16 @@ public final class IssueOrPullRequestQuery: GraphQLQuery { } } + /// Identifies if the viewer is watching, not watching, or ignoring the subscribable entity. + public var viewerSubscription: SubscriptionState? { + get { + return snapshot["viewerSubscription"] as? SubscriptionState + } + set { + snapshot.updateValue(newValue, forKey: "viewerSubscription") + } + } + /// A list of events, comments, commits, etc. associated with the issue. public var timeline: Timeline { get { @@ -7569,6 +7621,7 @@ public final class IssueOrPullRequestQuery: GraphQLQuery { public static let selections: [GraphQLSelection] = [ GraphQLField("__typename", type: .nonNull(.scalar(String.self))), + GraphQLField("viewerSubscription", type: .scalar(SubscriptionState.self)), GraphQLField("timeline", arguments: ["last": GraphQLVariable("page_size"), "before": GraphQLVariable("before")], type: .nonNull(.object(Timeline.selections))), GraphQLField("reviewRequests", arguments: ["first": GraphQLVariable("page_size")], type: .object(ReviewRequest.selections)), GraphQLField("commits", arguments: ["last": 1], type: .nonNull(.object(Commit.selections))), @@ -7612,8 +7665,8 @@ public final class IssueOrPullRequestQuery: GraphQLQuery { self.snapshot = snapshot } - public init(timeline: Timeline, reviewRequests: ReviewRequest? = nil, commits: Commit, milestone: Milestone? = nil, viewerCanReact: Bool, reactionGroups: [ReactionGroup]? = nil, author: Author? = nil, editor: Editor? = nil, lastEditedAt: String? = nil, body: String, createdAt: String, viewerDidAuthor: Bool, locked: Bool, closed: Bool, labels: Label? = nil, viewerCanUpdate: Bool, id: GraphQLID, assignees: Assignee, number: Int, title: String, merged: Bool, baseRefName: String, changedFiles: Int, additions: Int, deletions: Int, mergeable: MergeableState, mergeStateStatus: MergeStateStatus) { - self.init(snapshot: ["__typename": "PullRequest", "timeline": timeline.snapshot, "reviewRequests": reviewRequests.flatMap { (value: ReviewRequest) -> Snapshot in value.snapshot }, "commits": commits.snapshot, "milestone": milestone.flatMap { (value: Milestone) -> Snapshot in value.snapshot }, "viewerCanReact": viewerCanReact, "reactionGroups": reactionGroups.flatMap { (value: [ReactionGroup]) -> [Snapshot] in value.map { (value: ReactionGroup) -> Snapshot in value.snapshot } }, "author": author.flatMap { (value: Author) -> Snapshot in value.snapshot }, "editor": editor.flatMap { (value: Editor) -> Snapshot in value.snapshot }, "lastEditedAt": lastEditedAt, "body": body, "createdAt": createdAt, "viewerDidAuthor": viewerDidAuthor, "locked": locked, "closed": closed, "labels": labels.flatMap { (value: Label) -> Snapshot in value.snapshot }, "viewerCanUpdate": viewerCanUpdate, "id": id, "assignees": assignees.snapshot, "number": number, "title": title, "merged": merged, "baseRefName": baseRefName, "changedFiles": changedFiles, "additions": additions, "deletions": deletions, "mergeable": mergeable, "mergeStateStatus": mergeStateStatus]) + public init(viewerSubscription: SubscriptionState? = nil, timeline: Timeline, reviewRequests: ReviewRequest? = nil, commits: Commit, milestone: Milestone? = nil, viewerCanReact: Bool, reactionGroups: [ReactionGroup]? = nil, author: Author? = nil, editor: Editor? = nil, lastEditedAt: String? = nil, body: String, createdAt: String, viewerDidAuthor: Bool, locked: Bool, closed: Bool, labels: Label? = nil, viewerCanUpdate: Bool, id: GraphQLID, assignees: Assignee, number: Int, title: String, merged: Bool, baseRefName: String, changedFiles: Int, additions: Int, deletions: Int, mergeable: MergeableState, mergeStateStatus: MergeStateStatus) { + self.init(snapshot: ["__typename": "PullRequest", "viewerSubscription": viewerSubscription, "timeline": timeline.snapshot, "reviewRequests": reviewRequests.flatMap { (value: ReviewRequest) -> Snapshot in value.snapshot }, "commits": commits.snapshot, "milestone": milestone.flatMap { (value: Milestone) -> Snapshot in value.snapshot }, "viewerCanReact": viewerCanReact, "reactionGroups": reactionGroups.flatMap { (value: [ReactionGroup]) -> [Snapshot] in value.map { (value: ReactionGroup) -> Snapshot in value.snapshot } }, "author": author.flatMap { (value: Author) -> Snapshot in value.snapshot }, "editor": editor.flatMap { (value: Editor) -> Snapshot in value.snapshot }, "lastEditedAt": lastEditedAt, "body": body, "createdAt": createdAt, "viewerDidAuthor": viewerDidAuthor, "locked": locked, "closed": closed, "labels": labels.flatMap { (value: Label) -> Snapshot in value.snapshot }, "viewerCanUpdate": viewerCanUpdate, "id": id, "assignees": assignees.snapshot, "number": number, "title": title, "merged": merged, "baseRefName": baseRefName, "changedFiles": changedFiles, "additions": additions, "deletions": deletions, "mergeable": mergeable, "mergeStateStatus": mergeStateStatus]) } public var __typename: String { @@ -7625,6 +7678,16 @@ public final class IssueOrPullRequestQuery: GraphQLQuery { } } + /// Identifies if the viewer is watching, not watching, or ignoring the subscribable entity. + public var viewerSubscription: SubscriptionState? { + get { + return snapshot["viewerSubscription"] as? SubscriptionState + } + set { + snapshot.updateValue(newValue, forKey: "viewerSubscription") + } + } + /// A list of events, comments, commits, etc. associated with the pull request. public var timeline: Timeline { get { @@ -17780,6 +17843,267 @@ public final class SearchReposQuery: GraphQLQuery { } } +public final class UpdateSubscriptionMutation: GraphQLMutation { + public static let operationString = + "mutation UpdateSubscription($subscribable_Id: ID!, $subscription_state: SubscriptionState!) {\n updateSubscription(input: {subscribableId: $subscribable_Id, state: $subscription_state}) {\n __typename\n subscribable {\n __typename\n ...subscribableFields\n }\n }\n}" + + public static var requestString: String { return operationString.appending(SubscribableFields.fragmentString) } + + public var subscribable_Id: GraphQLID + public var subscription_state: SubscriptionState + + public init(subscribable_Id: GraphQLID, subscription_state: SubscriptionState) { + self.subscribable_Id = subscribable_Id + self.subscription_state = subscription_state + } + + public var variables: GraphQLMap? { + return ["subscribable_Id": subscribable_Id, "subscription_state": subscription_state] + } + + public struct Data: GraphQLSelectionSet { + public static let possibleTypes = ["Mutation"] + + public static let selections: [GraphQLSelection] = [ + GraphQLField("updateSubscription", arguments: ["input": ["subscribableId": GraphQLVariable("subscribable_Id"), "state": GraphQLVariable("subscription_state")]], type: .object(UpdateSubscription.selections)), + ] + + public var snapshot: Snapshot + + public init(snapshot: Snapshot) { + self.snapshot = snapshot + } + + public init(updateSubscription: UpdateSubscription? = nil) { + self.init(snapshot: ["__typename": "Mutation", "updateSubscription": updateSubscription.flatMap { (value: UpdateSubscription) -> Snapshot in value.snapshot }]) + } + + /// Updates the state for subscribable subjects. + public var updateSubscription: UpdateSubscription? { + get { + return (snapshot["updateSubscription"] as? Snapshot).flatMap { UpdateSubscription(snapshot: $0) } + } + set { + snapshot.updateValue(newValue?.snapshot, forKey: "updateSubscription") + } + } + + public struct UpdateSubscription: GraphQLSelectionSet { + public static let possibleTypes = ["UpdateSubscriptionPayload"] + + public static let selections: [GraphQLSelection] = [ + GraphQLField("__typename", type: .nonNull(.scalar(String.self))), + GraphQLField("subscribable", type: .nonNull(.object(Subscribable.selections))), + ] + + public var snapshot: Snapshot + + public init(snapshot: Snapshot) { + self.snapshot = snapshot + } + + public init(subscribable: Subscribable) { + self.init(snapshot: ["__typename": "UpdateSubscriptionPayload", "subscribable": subscribable.snapshot]) + } + + public var __typename: String { + get { + return snapshot["__typename"]! as! String + } + set { + snapshot.updateValue(newValue, forKey: "__typename") + } + } + + /// The input subscribable entity. + public var subscribable: Subscribable { + get { + return Subscribable(snapshot: snapshot["subscribable"]! as! Snapshot) + } + set { + snapshot.updateValue(newValue.snapshot, forKey: "subscribable") + } + } + + public struct Subscribable: GraphQLSelectionSet { + public static let possibleTypes = ["Issue", "Repository", "Commit", "PullRequest", "Team"] + + public static let selections: [GraphQLSelection] = [ + GraphQLField("__typename", type: .nonNull(.scalar(String.self))), + GraphQLField("__typename", type: .nonNull(.scalar(String.self))), + GraphQLField("id", type: .nonNull(.scalar(GraphQLID.self))), + GraphQLField("viewerCanSubscribe", type: .nonNull(.scalar(Bool.self))), + GraphQLField("viewerSubscription", type: .scalar(SubscriptionState.self)), + ] + + public var snapshot: Snapshot + + public init(snapshot: Snapshot) { + self.snapshot = snapshot + } + + public static func makeIssue(id: GraphQLID, viewerCanSubscribe: Bool, viewerSubscription: SubscriptionState? = nil) -> Subscribable { + return Subscribable(snapshot: ["__typename": "Issue", "id": id, "viewerCanSubscribe": viewerCanSubscribe, "viewerSubscription": viewerSubscription]) + } + + public static func makeRepository(id: GraphQLID, viewerCanSubscribe: Bool, viewerSubscription: SubscriptionState? = nil) -> Subscribable { + return Subscribable(snapshot: ["__typename": "Repository", "id": id, "viewerCanSubscribe": viewerCanSubscribe, "viewerSubscription": viewerSubscription]) + } + + public static func makeCommit(id: GraphQLID, viewerCanSubscribe: Bool, viewerSubscription: SubscriptionState? = nil) -> Subscribable { + return Subscribable(snapshot: ["__typename": "Commit", "id": id, "viewerCanSubscribe": viewerCanSubscribe, "viewerSubscription": viewerSubscription]) + } + + public static func makePullRequest(id: GraphQLID, viewerCanSubscribe: Bool, viewerSubscription: SubscriptionState? = nil) -> Subscribable { + return Subscribable(snapshot: ["__typename": "PullRequest", "id": id, "viewerCanSubscribe": viewerCanSubscribe, "viewerSubscription": viewerSubscription]) + } + + public static func makeTeam(id: GraphQLID, viewerCanSubscribe: Bool, viewerSubscription: SubscriptionState? = nil) -> Subscribable { + return Subscribable(snapshot: ["__typename": "Team", "id": id, "viewerCanSubscribe": viewerCanSubscribe, "viewerSubscription": viewerSubscription]) + } + + public var __typename: String { + get { + return snapshot["__typename"]! as! String + } + set { + snapshot.updateValue(newValue, forKey: "__typename") + } + } + + public var id: GraphQLID { + get { + return snapshot["id"]! as! GraphQLID + } + set { + snapshot.updateValue(newValue, forKey: "id") + } + } + + /// Check if the viewer is able to change their subscription status for the repository. + public var viewerCanSubscribe: Bool { + get { + return snapshot["viewerCanSubscribe"]! as! Bool + } + set { + snapshot.updateValue(newValue, forKey: "viewerCanSubscribe") + } + } + + /// Identifies if the viewer is watching, not watching, or ignoring the subscribable entity. + public var viewerSubscription: SubscriptionState? { + get { + return snapshot["viewerSubscription"] as? SubscriptionState + } + set { + snapshot.updateValue(newValue, forKey: "viewerSubscription") + } + } + + public var fragments: Fragments { + get { + return Fragments(snapshot: snapshot) + } + set { + snapshot += newValue.snapshot + } + } + + public struct Fragments { + public var snapshot: Snapshot + + public var subscribableFields: SubscribableFields { + get { + return SubscribableFields(snapshot: snapshot) + } + set { + snapshot += newValue.snapshot + } + } + } + } + } + } +} + +public struct SubscribableFields: GraphQLFragment { + public static let fragmentString = + "fragment subscribableFields on Subscribable {\n __typename\n id\n viewerCanSubscribe\n viewerSubscription\n}" + + public static let possibleTypes = ["Issue", "Repository", "Commit", "PullRequest", "Team"] + + public static let selections: [GraphQLSelection] = [ + GraphQLField("__typename", type: .nonNull(.scalar(String.self))), + GraphQLField("id", type: .nonNull(.scalar(GraphQLID.self))), + GraphQLField("viewerCanSubscribe", type: .nonNull(.scalar(Bool.self))), + GraphQLField("viewerSubscription", type: .scalar(SubscriptionState.self)), + ] + + public var snapshot: Snapshot + + public init(snapshot: Snapshot) { + self.snapshot = snapshot + } + + public static func makeIssue(id: GraphQLID, viewerCanSubscribe: Bool, viewerSubscription: SubscriptionState? = nil) -> SubscribableFields { + return SubscribableFields(snapshot: ["__typename": "Issue", "id": id, "viewerCanSubscribe": viewerCanSubscribe, "viewerSubscription": viewerSubscription]) + } + + public static func makeRepository(id: GraphQLID, viewerCanSubscribe: Bool, viewerSubscription: SubscriptionState? = nil) -> SubscribableFields { + return SubscribableFields(snapshot: ["__typename": "Repository", "id": id, "viewerCanSubscribe": viewerCanSubscribe, "viewerSubscription": viewerSubscription]) + } + + public static func makeCommit(id: GraphQLID, viewerCanSubscribe: Bool, viewerSubscription: SubscriptionState? = nil) -> SubscribableFields { + return SubscribableFields(snapshot: ["__typename": "Commit", "id": id, "viewerCanSubscribe": viewerCanSubscribe, "viewerSubscription": viewerSubscription]) + } + + public static func makePullRequest(id: GraphQLID, viewerCanSubscribe: Bool, viewerSubscription: SubscriptionState? = nil) -> SubscribableFields { + return SubscribableFields(snapshot: ["__typename": "PullRequest", "id": id, "viewerCanSubscribe": viewerCanSubscribe, "viewerSubscription": viewerSubscription]) + } + + public static func makeTeam(id: GraphQLID, viewerCanSubscribe: Bool, viewerSubscription: SubscriptionState? = nil) -> SubscribableFields { + return SubscribableFields(snapshot: ["__typename": "Team", "id": id, "viewerCanSubscribe": viewerCanSubscribe, "viewerSubscription": viewerSubscription]) + } + + public var __typename: String { + get { + return snapshot["__typename"]! as! String + } + set { + snapshot.updateValue(newValue, forKey: "__typename") + } + } + + public var id: GraphQLID { + get { + return snapshot["id"]! as! GraphQLID + } + set { + snapshot.updateValue(newValue, forKey: "id") + } + } + + /// Check if the viewer is able to change their subscription status for the repository. + public var viewerCanSubscribe: Bool { + get { + return snapshot["viewerCanSubscribe"]! as! Bool + } + set { + snapshot.updateValue(newValue, forKey: "viewerCanSubscribe") + } + } + + /// Identifies if the viewer is watching, not watching, or ignoring the subscribable entity. + public var viewerSubscription: SubscriptionState? { + get { + return snapshot["viewerSubscription"] as? SubscriptionState + } + set { + snapshot.updateValue(newValue, forKey: "viewerSubscription") + } + } +} + public struct ReactionFields: GraphQLFragment { public static let fragmentString = "fragment reactionFields on Reactable {\n __typename\n viewerCanReact\n reactionGroups {\n __typename\n viewerHasReacted\n users(first: 3) {\n __typename\n nodes {\n __typename\n login\n }\n totalCount\n }\n content\n }\n}" diff --git a/gql/Fragments.graphql b/gql/Fragments.graphql index 5e90f9b67..bd67a8168 100644 --- a/gql/Fragments.graphql +++ b/gql/Fragments.graphql @@ -1,3 +1,9 @@ +fragment subscribableFields on Subscribable { + id + viewerCanSubscribe + viewerSubscription +} + fragment reactionFields on Reactable { viewerCanReact reactionGroups { diff --git a/gql/IssueOrPullRequest.graphql b/gql/IssueOrPullRequest.graphql index c5fe1c742..1aca51503 100644 --- a/gql/IssueOrPullRequest.graphql +++ b/gql/IssueOrPullRequest.graphql @@ -17,6 +17,7 @@ query IssueOrPullRequest($owner: String!, $repo: String!, $number: Int!, $page_s } issueOrPullRequest(number: $number) { ... on Issue { + viewerSubscription timeline(last: $page_size, before: $before) { pageInfo{...headPaging} nodes { @@ -182,6 +183,7 @@ query IssueOrPullRequest($owner: String!, $repo: String!, $number: Int!, $page_s title } ... on PullRequest { + viewerSubscription timeline(last: $page_size, before: $before) { pageInfo{...headPaging} nodes { diff --git a/gql/UpdateSubscription.graphql b/gql/UpdateSubscription.graphql new file mode 100644 index 000000000..aaa45a139 --- /dev/null +++ b/gql/UpdateSubscription.graphql @@ -0,0 +1,7 @@ +mutation UpdateSubscription($subscribable_Id: ID!, $subscription_state: SubscriptionState!) { + updateSubscription(input:{subscribableId: $subscribable_Id, state: $subscription_state}) { + subscribable{ + ...subscribableFields + } + } +}