Skip to content
This repository was archived by the owner on Sep 20, 2023. It is now read-only.

Commit 97a8fbb

Browse files
LamourBtBasThomas
authored andcommitted
Feature/show issues and pr count (#2767)
* fetching and displaying issueCount within RepositoryIssuesViewController * proper naming of certain methods * applying changes from pr * applying changes from pr * adding new lines * fetching count of issues and prs from RepositoryViewController instead of RepositoryIssuesViewController
1 parent 90cc726 commit 97a8fbb

File tree

6 files changed

+1760
-833
lines changed

6 files changed

+1760
-833
lines changed

Classes/Repository/RepositoryClient.swift

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,6 @@ extension RepoSearchPagesQuery: RepositoryQuery {
2929
results.search.pageInfo.hasNextPage else { return nil }
3030
return results.search.pageInfo.endCursor
3131
}
32-
3332
}
3433

3534
func createSummaryModel(

Classes/Repository/RepositoryIssuesViewController.swift

Lines changed: 32 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -31,13 +31,15 @@ IndicatorInfoProvider {
3131
private let debouncer = Debouncer()
3232
private var previousSearchString = "is:open "
3333
private var label: String?
34+
private var numberOfItems: Int?
3435

35-
init(client: GithubClient, owner: String, repo: String, type: RepositoryIssuesType, label: String? = nil) {
36+
init(client: GithubClient, owner: String, repo: String, type: RepositoryIssuesType, label: String? = nil, numberOfItems: Int? = nil) {
3637
self.owner = owner
3738
self.repo = repo
3839
self.client = RepositoryClient(githubClient: client, owner: owner, name: repo)
3940
self.type = type
4041
self.label = label
42+
self.numberOfItems = numberOfItems
4143
if let label = label {
4244
previousSearchString += "label:\"\(label)\" "
4345
}
@@ -49,10 +51,12 @@ IndicatorInfoProvider {
4951
self.dataSource = self
5052
self.emptyDataSource = self
5153
self.headerDataSource = self
52-
53-
switch type {
54-
case .issues: title = NSLocalizedString("Issues", comment: "")
55-
case .pullRequests: title = NSLocalizedString("Pull Requests", comment: "")
54+
55+
if let itemCount = numberOfItems,
56+
itemCount > 0 {
57+
title = self.composeLocalizedTitle(using: itemCount)
58+
} else {
59+
title = self.composeLocalizedTitle()
5660
}
5761
}
5862

@@ -81,20 +85,39 @@ IndicatorInfoProvider {
8185
nextPage: page as String?,
8286
containerWidth: view.safeContentWidth(with: feed.collectionView)
8387
) { [weak self] (result: Result<RepositoryClient.RepositoryPayload>) in
88+
guard let `self` = self else { return }
8489
switch result {
8590
case .error:
86-
self?.error(animated: trueUnlessReduceMotionEnabled)
91+
self.error(animated: trueUnlessReduceMotionEnabled)
8792
case .success(let payload):
8893
if page != nil {
89-
self?.models += payload.models
94+
self.models += payload.models
9095
} else {
91-
self?.models = payload.models
96+
self.models = payload.models
9297
}
93-
self?.update(page: payload.nextPage, animated: trueUnlessReduceMotionEnabled)
98+
self.update(page: payload.nextPage, animated: trueUnlessReduceMotionEnabled)
9499
}
95100
}
96101
}
97102

103+
func composeLocalizedTitle(using itemCount: Int) -> String {
104+
let newTitle: String
105+
switch type {
106+
case .issues: newTitle = "Issues (\(itemCount))"
107+
case .pullRequests: newTitle = "Pull Requests (\(itemCount))"
108+
}
109+
return NSLocalizedString(newTitle, comment: "")
110+
}
111+
112+
func composeLocalizedTitle() -> String {
113+
let localizedTitle: String
114+
switch type {
115+
case .issues: localizedTitle = "Issues"
116+
case .pullRequests: localizedTitle = "Pull Requests"
117+
}
118+
return NSLocalizedString(localizedTitle, comment: "")
119+
}
120+
98121
// MARK: SearchBarSectionControllerDelegate
99122

100123
func didChangeSelection(sectionController: SearchBarSectionController, query: String) {
@@ -159,5 +182,4 @@ IndicatorInfoProvider {
159182
func indicatorInfo(for pagerTabStripController: PagerTabStripViewController) -> IndicatorInfo {
160183
return IndicatorInfo(title: title)
161184
}
162-
163185
}

Classes/Repository/RepositoryViewController.swift

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ EmptyViewDelegate {
2222
let hasIssuesEnabled: Bool
2323
let defaultBranch: String
2424
let graphQLID: String
25+
let numberOfIssues: Int?
26+
let numberOfPullRequests: Int?
2527
}
2628

2729
private enum State {
@@ -135,15 +137,18 @@ EmptyViewDelegate {
135137
client: client,
136138
owner: repo.owner,
137139
repo: repo.name,
138-
type: .issues
140+
type: .issues,
141+
numberOfItems: details.numberOfIssues
139142
))
140143
}
141144
controllers += [
142145
RepositoryIssuesViewController(
143146
client: client,
144147
owner: repo.owner,
145148
repo: repo.name,
146-
type: .pullRequests
149+
type: .pullRequests,
150+
numberOfItems: details.numberOfPullRequests
151+
147152
),
148153
RepositoryCodeDirectoryViewController.createRoot(
149154
client: client,
@@ -157,14 +162,23 @@ EmptyViewDelegate {
157162

158163
self.controllers = controllers
159164
}
165+
166+
func buildQueryString(using repo: RepositoryDetails, _ searchString: String) -> String {
167+
return "repo:\(repo.owner)/\(repo.name) \(searchString) ".lowercased()
168+
}
160169

161170
func fetchDetails() {
162171
state = .loading
163172
buildViewControllers()
164173
reloadPagerTabStripView()
165-
174+
let issueSearchQueryString = "is:issue is:open"
175+
let prSearchQueryString = "is:pr is:open"
166176
client.client.query(
167-
RepositoryInfoQuery(owner: repo.owner, name: repo.name),
177+
RepositoryInfoQuery(owner: repo.owner,
178+
name: repo.name,
179+
issueQuery: buildQueryString(using: repo, issueSearchQueryString),
180+
prQuery: buildQueryString(using: repo, prSearchQueryString)
181+
),
168182
result: { $0 },
169183
completion: { [weak self] result in
170184
switch result {
@@ -176,7 +190,9 @@ EmptyViewDelegate {
176190
let details = Details(
177191
hasIssuesEnabled: repo.hasIssuesEnabled,
178192
defaultBranch: repo.defaultBranchRef?.name ?? "master",
179-
graphQLID: repo.id
193+
graphQLID: repo.id,
194+
numberOfIssues: data.repoIssueOverview.issueCount,
195+
numberOfPullRequests: data.repoPullRequestOverView.issueCount
180196
)
181197
self?.state = .value(details)
182198
} else {

gql/API.swift

Lines changed: 107 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2088,25 +2088,31 @@ public final class RepoFileHistoryQuery: GraphQLQuery {
20882088

20892089
public final class RepositoryInfoQuery: GraphQLQuery {
20902090
public let operationDefinition =
2091-
"query RepositoryInfo($owner: String!, $name: String!) {\n repository(owner: $owner, name: $name) {\n __typename\n id\n defaultBranchRef {\n __typename\n name\n }\n hasIssuesEnabled\n }\n}"
2091+
"query RepositoryInfo($owner: String!, $name: String!, $issueQuery: String!, $prQuery: String!) {\n repository(owner: $owner, name: $name) {\n __typename\n id\n defaultBranchRef {\n __typename\n name\n }\n hasIssuesEnabled\n }\n repoIssueOverview: search(query: $issueQuery, type: ISSUE) {\n __typename\n issueCount\n }\n repoPullRequestOverView: search(query: $prQuery, type: ISSUE) {\n __typename\n issueCount\n }\n}"
20922092

20932093
public var owner: String
20942094
public var name: String
2095+
public var issueQuery: String
2096+
public var prQuery: String
20952097

2096-
public init(owner: String, name: String) {
2098+
public init(owner: String, name: String, issueQuery: String, prQuery: String) {
20972099
self.owner = owner
20982100
self.name = name
2101+
self.issueQuery = issueQuery
2102+
self.prQuery = prQuery
20992103
}
21002104

21012105
public var variables: GraphQLMap? {
2102-
return ["owner": owner, "name": name]
2106+
return ["owner": owner, "name": name, "issueQuery": issueQuery, "prQuery": prQuery]
21032107
}
21042108

21052109
public struct Data: GraphQLSelectionSet {
21062110
public static let possibleTypes = ["Query"]
21072111

21082112
public static let selections: [GraphQLSelection] = [
21092113
GraphQLField("repository", arguments: ["owner": GraphQLVariable("owner"), "name": GraphQLVariable("name")], type: .object(Repository.selections)),
2114+
GraphQLField("search", alias: "repoIssueOverview", arguments: ["query": GraphQLVariable("issueQuery"), "type": "ISSUE"], type: .nonNull(.object(RepoIssueOverview.selections))),
2115+
GraphQLField("search", alias: "repoPullRequestOverView", arguments: ["query": GraphQLVariable("prQuery"), "type": "ISSUE"], type: .nonNull(.object(RepoPullRequestOverView.selections))),
21102116
]
21112117

21122118
public private(set) var resultMap: ResultMap
@@ -2115,8 +2121,8 @@ public final class RepositoryInfoQuery: GraphQLQuery {
21152121
self.resultMap = unsafeResultMap
21162122
}
21172123

2118-
public init(repository: Repository? = nil) {
2119-
self.init(unsafeResultMap: ["__typename": "Query", "repository": repository.flatMap { (value: Repository) -> ResultMap in value.resultMap }])
2124+
public init(repository: Repository? = nil, repoIssueOverview: RepoIssueOverview, repoPullRequestOverView: RepoPullRequestOverView) {
2125+
self.init(unsafeResultMap: ["__typename": "Query", "repository": repository.flatMap { (value: Repository) -> ResultMap in value.resultMap }, "repoIssueOverview": repoIssueOverview.resultMap, "repoPullRequestOverView": repoPullRequestOverView.resultMap])
21202126
}
21212127

21222128
/// Lookup a given repository by the owner and repository name.
@@ -2129,6 +2135,26 @@ public final class RepositoryInfoQuery: GraphQLQuery {
21292135
}
21302136
}
21312137

2138+
/// Perform a search across resources.
2139+
public var repoIssueOverview: RepoIssueOverview {
2140+
get {
2141+
return RepoIssueOverview(unsafeResultMap: resultMap["repoIssueOverview"]! as! ResultMap)
2142+
}
2143+
set {
2144+
resultMap.updateValue(newValue.resultMap, forKey: "repoIssueOverview")
2145+
}
2146+
}
2147+
2148+
/// Perform a search across resources.
2149+
public var repoPullRequestOverView: RepoPullRequestOverView {
2150+
get {
2151+
return RepoPullRequestOverView(unsafeResultMap: resultMap["repoPullRequestOverView"]! as! ResultMap)
2152+
}
2153+
set {
2154+
resultMap.updateValue(newValue.resultMap, forKey: "repoPullRequestOverView")
2155+
}
2156+
}
2157+
21322158
public struct Repository: GraphQLSelectionSet {
21332159
public static let possibleTypes = ["Repository"]
21342160

@@ -2225,6 +2251,82 @@ public final class RepositoryInfoQuery: GraphQLQuery {
22252251
}
22262252
}
22272253
}
2254+
2255+
public struct RepoIssueOverview: GraphQLSelectionSet {
2256+
public static let possibleTypes = ["SearchResultItemConnection"]
2257+
2258+
public static let selections: [GraphQLSelection] = [
2259+
GraphQLField("__typename", type: .nonNull(.scalar(String.self))),
2260+
GraphQLField("issueCount", type: .nonNull(.scalar(Int.self))),
2261+
]
2262+
2263+
public private(set) var resultMap: ResultMap
2264+
2265+
public init(unsafeResultMap: ResultMap) {
2266+
self.resultMap = unsafeResultMap
2267+
}
2268+
2269+
public init(issueCount: Int) {
2270+
self.init(unsafeResultMap: ["__typename": "SearchResultItemConnection", "issueCount": issueCount])
2271+
}
2272+
2273+
public var __typename: String {
2274+
get {
2275+
return resultMap["__typename"]! as! String
2276+
}
2277+
set {
2278+
resultMap.updateValue(newValue, forKey: "__typename")
2279+
}
2280+
}
2281+
2282+
/// The number of issues that matched the search query.
2283+
public var issueCount: Int {
2284+
get {
2285+
return resultMap["issueCount"]! as! Int
2286+
}
2287+
set {
2288+
resultMap.updateValue(newValue, forKey: "issueCount")
2289+
}
2290+
}
2291+
}
2292+
2293+
public struct RepoPullRequestOverView: GraphQLSelectionSet {
2294+
public static let possibleTypes = ["SearchResultItemConnection"]
2295+
2296+
public static let selections: [GraphQLSelection] = [
2297+
GraphQLField("__typename", type: .nonNull(.scalar(String.self))),
2298+
GraphQLField("issueCount", type: .nonNull(.scalar(Int.self))),
2299+
]
2300+
2301+
public private(set) var resultMap: ResultMap
2302+
2303+
public init(unsafeResultMap: ResultMap) {
2304+
self.resultMap = unsafeResultMap
2305+
}
2306+
2307+
public init(issueCount: Int) {
2308+
self.init(unsafeResultMap: ["__typename": "SearchResultItemConnection", "issueCount": issueCount])
2309+
}
2310+
2311+
public var __typename: String {
2312+
get {
2313+
return resultMap["__typename"]! as! String
2314+
}
2315+
set {
2316+
resultMap.updateValue(newValue, forKey: "__typename")
2317+
}
2318+
}
2319+
2320+
/// The number of issues that matched the search query.
2321+
public var issueCount: Int {
2322+
get {
2323+
return resultMap["issueCount"]! as! Int
2324+
}
2325+
set {
2326+
resultMap.updateValue(newValue, forKey: "issueCount")
2327+
}
2328+
}
2329+
}
22282330
}
22292331
}
22302332

gql/RepositoryInfo.graphql

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,16 @@
1-
query RepositoryInfo($owner: String!, $name: String!) {
1+
query RepositoryInfo($owner: String!, $name: String!, $issueQuery: String!, $prQuery: String!) {
22
repository(owner: $owner, name: $name) {
33
id
44
defaultBranchRef {
55
name
66
}
77
hasIssuesEnabled
88
}
9+
10+
repoIssueOverview: search(query: $issueQuery, type: ISSUE) {
11+
issueCount
12+
}
13+
repoPullRequestOverView: search(query: $prQuery, type: ISSUE) {
14+
issueCount
15+
}
916
}

0 commit comments

Comments
 (0)