Files
GitHawk/Classes/Repository/RepositoryCodeDirectoryViewController.swift
Ivan Magda 6c3c451677 Add PDF support (#1596)
* Add string extension for searching pdf files (#1552)

* Create RepositoryWebViewController (#1552)

* Initial presenting of the pdf files (#1552)

* refactor: Rename String+Resource -> String+BinaryFile (#1552)

* Build destination URL (#1552)

* Configure title (#1552)

* Encode file path

* Use EmptyView for errors

* Replace UIWebView with WKWebView

* Review fixes

* refactor: Make binarySuffix computed property

* Unify if-else path

* Group guard statements
2018-03-11 15:59:51 -04:00

181 lines
5.5 KiB
Swift

//
// RepositoryCodeDirectoryViewController.swift
// Freetime
//
// Created by Ryan Nystrom on 10/8/17.
// Copyright © 2017 Ryan Nystrom. All rights reserved.
//
import UIKit
import IGListKit
final class RepositoryCodeDirectoryViewController: BaseListViewController<NSNumber>,
BaseListViewControllerDataSource,
ListSingleSectionControllerDelegate {
private let client: GithubClient
private let branch: String
private let path: FilePath
private let repo: RepositoryDetails
private var files = [RepositoryFile]()
init(
client: GithubClient,
repo: RepositoryDetails,
branch: String,
path: FilePath
) {
self.client = client
self.repo = repo
self.branch = branch
self.path = path
super.init(
emptyErrorMessage: NSLocalizedString("Cannot load directory.", comment: ""),
dataSource: self
)
// set on init in case used by Tabman
self.title = NSLocalizedString("Code", comment: "")
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func viewDidLoad() {
super.viewDidLoad()
configureTitle(filePath: path, target: self, action: #selector(onFileNavigationTitle(sender:)))
makeBackBarItemEmpty()
}
// MARK: Public API
static func createRoot(
client: GithubClient,
repo: RepositoryDetails,
branch: String
) -> RepositoryCodeDirectoryViewController {
return RepositoryCodeDirectoryViewController(
client: client,
repo: repo,
branch: branch,
path: FilePath(components: [])
)
}
// MARK: Private API
@objc func onFileNavigationTitle(sender: UIView) {
showAlert(filePath: path, sender: sender)
}
// MARK: Overrides
override func fetch(page: NSNumber?) {
client.fetchFiles(
owner: repo.owner,
repo: repo.name,
branch: branch,
path: path.path
) { [weak self] (result) in
switch result {
case .error:
self?.error(animated: trueUnlessReduceMotionEnabled)
case .success(let files):
self?.files = files
self?.update(animated: trueUnlessReduceMotionEnabled)
}
}
}
// MARK: BaseListViewControllerDataSource
func headModels(listAdapter: ListAdapter) -> [ListDiffable] {
return []
}
func models(listAdapter: ListAdapter) -> [ListDiffable] {
return files
}
func sectionController(model: Any, listAdapter: ListAdapter) -> ListSectionController {
let controller = ListSingleSectionController(cellClass: RepositoryFileCell.self, configureBlock: { (file, cell: UICollectionViewCell) in
guard let cell = cell as? RepositoryFileCell, let file = file as? RepositoryFile else { return }
cell.configure(path: file.name, isDirectory: file.isDirectory)
}, sizeBlock: { (_, context: ListCollectionContext?) -> CGSize in
guard let width = context?.containerSize.width else { return .zero }
return CGSize(width: width, height: Styles.Sizes.tableCellHeight)
})
controller.selectionDelegate = self
return controller
}
func emptySectionController(listAdapter: ListAdapter) -> ListSectionController {
return ListSingleSectionController(cellClass: LabelCell.self, configureBlock: { (_, cell: UICollectionViewCell) in
guard let cell = cell as? LabelCell else { return }
cell.label.text = NSLocalizedString("No files found.", comment: "")
}, sizeBlock: { [weak self] (_, context: ListCollectionContext?) -> CGSize in
guard let context = context,
let strongSelf = self
else { return .zero }
return CGSize(
width: context.containerSize.width,
height: context.containerSize.height - strongSelf.view.safeAreaInsets.top - strongSelf.view.safeAreaInsets.bottom
)
})
}
// MARK: ListSingleSectionControllerDelegate
func didSelect(_ sectionController: ListSingleSectionController, with object: Any) {
guard let file = object as? RepositoryFile else { return }
let nextPath = path.appending(file.name)
if file.isDirectory {
showDirectory(at: nextPath)
} else {
showFile(at: nextPath)
}
}
}
// MARK: - RepositoryCodeDirectoryViewController (Navigation) -
extension RepositoryCodeDirectoryViewController {
private func showDirectory(at path: FilePath) {
let controller = RepositoryCodeDirectoryViewController(
client: client,
repo: repo,
branch: branch,
path: path
)
navigationController?.pushViewController(controller, animated: trueUnlessReduceMotionEnabled)
}
private func showFile(at path: FilePath) {
let controller: UIViewController
if path.hasBinarySuffix {
controller = RepositoryWebViewController(
repo: repo,
branch: branch,
path: path
)
} else {
controller = RepositoryCodeBlobViewController(
client: client,
repo: repo,
branch: branch,
path: path
)
}
navigationController?.pushViewController(controller, animated: trueUnlessReduceMotionEnabled)
}
}