Add pull requests view and networking, toggle between views

This commit is contained in:
James Sherlock
2017-07-29 17:41:30 +01:00
parent 7ebba4fb82
commit faa6b6dac7
11 changed files with 394 additions and 97 deletions

View File

@@ -9,14 +9,25 @@
import UIKit
import IGListKit
class RepositoryViewController: UIViewController, FeedDelegate, ListAdapterDataSource {
class RepositoryViewController: UIViewController,
FeedDelegate,
ListAdapterDataSource,
SegmentedControlSectionControllerDelegate,
SearchLoadMoreSectionControllerDelegate {
private let repo: RepositoryLoadable
private let client: GithubClient
private lazy var feed: Feed = { Feed(viewController: self, delegate: self) }()
private var issues = [IssueSummaryType]()
private let selection = SegmentedControlModel.forRepository()
private let loadMore = "loadMore" as ListDiffable
private var firstLoad = true
private var issues = [IssueSummaryModel]()
private var issuesNextPage: String?
private var pullRequests = [IssueSummaryModel]()
private var pullRequestsNextPage: String?
init(client: GithubClient, repo: RepositoryLoadable) {
self.repo = repo
self.client = client
@@ -47,33 +58,50 @@ class RepositoryViewController: UIViewController, FeedDelegate, ListAdapterDataS
}
private func handle(resultType: GithubClient.RepoLoadResultType, append: Bool, animated: Bool) {
firstLoad = false
switch resultType {
case .error:
print("😞 Something went wrong, here's some pizza 🍕")
break
case .success(let nextPage, let results):
case .success(let payload):
if append {
self.issues += results
self.issues += payload.issues ?? []
self.pullRequests += payload.pullRequests ?? []
} else {
self.issues = results
self.issues = payload.issues ?? []
self.pullRequests = payload.pullRequests ?? []
}
self.issuesNextPage = nextPage
self.issuesNextPage = payload.issuesNextPage
self.pullRequestsNextPage = payload.pullRequestsNextPage
self.update(dismissRefresh: !append, animated: animated)
break
}
}
func reload() {
client.load(repo: repo, containerWidth: view.bounds.width) { [weak self] resultType in
client.load(
repo: repo,
includeIssues: firstLoad ? true : selection.issuesSelected,
includePullRequests: firstLoad ? true : !selection.issuesSelected,
containerWidth: view.bounds.width
) { [weak self] resultType in
self?.handle(resultType: resultType, append: false, animated: true)
}
}
func loadNextPage() {
guard let nextPage = issuesNextPage else { return }
client.load(repo: repo, before: nextPage, containerWidth: view.bounds.width) { [weak self] resultType in
self?.handle(resultType: resultType, append: true, animated: false)
if let nextPage = issuesNextPage, selection.issuesSelected {
client.load(repo: repo, before: nextPage, includePullRequests: false, containerWidth: view.bounds.width) {
[weak self] resultType in
self?.handle(resultType: resultType, append: true, animated: false)
}
} else if let nextPage = pullRequestsNextPage, !selection.issuesSelected {
client.load(repo: repo, before: nextPage, includeIssues: false, containerWidth: view.bounds.width) {
[weak self] resultType in
self?.handle(resultType: resultType, append: true, animated: false)
}
}
}
@@ -90,10 +118,20 @@ class RepositoryViewController: UIViewController, FeedDelegate, ListAdapterDataS
// MARK: ListAdapterDataSource
func objects(for listAdapter: ListAdapter) -> [ListDiffable] {
var builder = [ListDiffable]()
var builder: [ListDiffable] = [selection]
if issues.count > 0 {
if issues.count > 0, selection.issuesSelected {
builder += issues as [ListDiffable]
if issuesNextPage != nil {
builder.append(loadMore)
}
} else if pullRequests.count > 0, !selection.issuesSelected {
builder += pullRequests as [ListDiffable]
if pullRequestsNextPage != nil {
builder.append(loadMore)
}
}
return builder
@@ -102,7 +140,12 @@ class RepositoryViewController: UIViewController, FeedDelegate, ListAdapterDataS
func listAdapter(_ listAdapter: ListAdapter, sectionControllerFor object: Any) -> ListSectionController {
guard let object = object as? ListDiffable else { fatalError("Object does not conform to ListDiffable") }
if object is IssueSummaryType { return RepositorySummarySectionController(client: client, repo: repo) }
// 28 is the default height of UISegmentedControl
let controlHeight = 28 + 2*Styles.Sizes.rowSpacing
if object === selection { return SegmentedControlSectionController(delegate: self, height: controlHeight) }
else if object === loadMore { return SearchLoadMoreSectionController(delegate: self) }
else if object is IssueSummaryModel { return RepositorySummarySectionController(client: client, repo: repo) }
fatalError("Could not find section controller for object")
}
@@ -110,4 +153,16 @@ class RepositoryViewController: UIViewController, FeedDelegate, ListAdapterDataS
func emptyView(for listAdapter: ListAdapter) -> UIView? {
return nil
}
// MARK: SegmentedControlSectionControllerDelegate
func didChangeSelection(sectionController: SegmentedControlSectionController, model: SegmentedControlModel) {
update(dismissRefresh: false)
}
// MARK: SearchLoadMoreSectionControllerDelegate
func didSelect(sectionController: SearchLoadMoreSectionController) {
loadNextPage()
}
}