Rearrange some code to put them in the correct sections

This commit is contained in:
Maurice Parker 2019-08-15 12:42:25 -05:00
parent 99e2a44eed
commit 1eb8da7749
2 changed files with 100 additions and 104 deletions

View File

@ -451,7 +451,39 @@ class MasterFeedViewController: UITableViewController, UndoableCommandRunner {
}
// MARK: API
@objc func refreshAccounts(_ sender: Any) {
refreshControl?.endRefreshing()
// This is a hack to make sure that an error dialog doesn't interfere with dismissing the refreshControl.
// If the error dialog appears too closely to the call to endRefreshing, then the refreshControl never disappears.
DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
AccountManager.shared.refreshAll(errorHandler: ErrorHandler.present(self))
}
}
}
// MARK: MasterTableViewCellDelegate
extension MasterFeedViewController: MasterFeedTableViewCellDelegate {
func disclosureSelected(_ sender: MasterFeedTableViewCell, expanding: Bool) {
if expanding {
expand(sender)
} else {
collapse(sender)
}
}
}
// MARK: Private
private extension MasterFeedViewController {
func updateUI() {
markAllAsReadButton.isEnabled = coordinator.isAnyUnreadAvailable
addNewItemButton.isEnabled = !AccountManager.shared.activeAccounts.isEmpty
}
func configure(_ cell: MasterFeedTableViewCell, _ node: Node) {
@ -496,6 +528,70 @@ class MasterFeedViewController: UITableViewController, UndoableCommandRunner {
return 0
}
func configureCellsForRepresentedObject(_ representedObject: AnyObject) {
applyToCellsForRepresentedObject(representedObject, configure)
}
func applyToCellsForRepresentedObject(_ representedObject: AnyObject, _ callback: (MasterFeedTableViewCell, Node) -> Void) {
applyToAvailableCells { (cell, node) in
if node.representedObject === representedObject {
callback(cell, node)
}
}
}
func applyToAvailableCells(_ callback: (MasterFeedTableViewCell, Node) -> Void) {
tableView.visibleCells.forEach { cell in
guard let indexPath = tableView.indexPath(for: cell), let node = coordinator.nodeFor(indexPath) else {
return
}
callback(cell as! MasterFeedTableViewCell, node)
}
}
private func accountForNode(_ node: Node) -> Account? {
if let account = node.representedObject as? Account {
return account
}
if let folder = node.representedObject as? Folder {
return folder.account
}
if let feed = node.representedObject as? Feed {
return feed.account
}
return nil
}
func expand(_ cell: MasterFeedTableViewCell) {
guard let indexPath = tableView.indexPath(for: cell) else {
return
}
coordinator.expand(indexPath) { [weak self] indexPaths in
self?.tableView.beginUpdates()
self?.tableView.insertRows(at: indexPaths, with: .automatic)
self?.tableView.endUpdates()
}
}
func collapse(_ cell: MasterFeedTableViewCell) {
guard let indexPath = tableView.indexPath(for: cell) else {
return
}
coordinator.collapse(indexPath) { [weak self] indexPaths in
self?.tableView.beginUpdates()
self?.tableView.deleteRows(at: indexPaths, with: .automatic)
self?.tableView.endUpdates()
}
}
func performBlockAndRestoreSelection(_ block: (() -> Void)) {
let indexPaths = tableView.indexPathsForSelectedRows
block()
indexPaths?.forEach { [weak self] indexPath in
self?.tableView.selectRow(at: indexPath, animated: false, scrollPosition: .none)
}
}
func delete(indexPath: IndexPath) {
guard let undoManager = undoManager,
@ -579,102 +675,3 @@ class MasterFeedViewController: UITableViewController, UndoableCommandRunner {
}
}
// MARK: MasterTableViewCellDelegate
extension MasterFeedViewController: MasterFeedTableViewCellDelegate {
func disclosureSelected(_ sender: MasterFeedTableViewCell, expanding: Bool) {
if expanding {
expand(sender)
} else {
collapse(sender)
}
}
}
// MARK: Private
private extension MasterFeedViewController {
@objc private func refreshAccounts(_ sender: Any) {
refreshControl?.endRefreshing()
// This is a hack to make sure that an error dialog doesn't interfere with dismissing the refreshControl.
// If the error dialog appears too closely to the call to endRefreshing, then the refreshControl never disappears.
DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
AccountManager.shared.refreshAll(errorHandler: ErrorHandler.present(self))
}
}
func updateUI() {
markAllAsReadButton.isEnabled = coordinator.isAnyUnreadAvailable
addNewItemButton.isEnabled = !AccountManager.shared.activeAccounts.isEmpty
}
func configureCellsForRepresentedObject(_ representedObject: AnyObject) {
applyToCellsForRepresentedObject(representedObject, configure)
}
func applyToCellsForRepresentedObject(_ representedObject: AnyObject, _ callback: (MasterFeedTableViewCell, Node) -> Void) {
applyToAvailableCells { (cell, node) in
if node.representedObject === representedObject {
callback(cell, node)
}
}
}
func applyToAvailableCells(_ callback: (MasterFeedTableViewCell, Node) -> Void) {
tableView.visibleCells.forEach { cell in
guard let indexPath = tableView.indexPath(for: cell), let node = coordinator.nodeFor(indexPath) else {
return
}
callback(cell as! MasterFeedTableViewCell, node)
}
}
private func accountForNode(_ node: Node) -> Account? {
if let account = node.representedObject as? Account {
return account
}
if let folder = node.representedObject as? Folder {
return folder.account
}
if let feed = node.representedObject as? Feed {
return feed.account
}
return nil
}
func expand(_ cell: MasterFeedTableViewCell) {
guard let indexPath = tableView.indexPath(for: cell) else {
return
}
coordinator.expand(indexPath) { [weak self] indexPaths in
self?.tableView.beginUpdates()
self?.tableView.insertRows(at: indexPaths, with: .automatic)
self?.tableView.endUpdates()
}
}
func collapse(_ cell: MasterFeedTableViewCell) {
guard let indexPath = tableView.indexPath(for: cell) else {
return
}
coordinator.collapse(indexPath) { [weak self] indexPaths in
self?.tableView.beginUpdates()
self?.tableView.deleteRows(at: indexPaths, with: .automatic)
self?.tableView.endUpdates()
}
}
func performBlockAndRestoreSelection(_ block: (() -> Void)) {
let indexPaths = tableView.indexPathsForSelectedRows
block()
indexPaths?.forEach { [weak self] indexPath in
self?.tableView.selectRow(at: indexPath, animated: false, scrollPosition: .none)
}
}
}

View File

@ -1,11 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="14810.11" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="9cW-lu-HoC">
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="14854.2" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="9cW-lu-HoC">
<device id="retina6_1" orientation="portrait" appearance="light"/>
<dependencies>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="14766.13"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="14806.4"/>
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
<capability name="iOS 13.0 system colors" minToolsVersion="11.0"/>
</dependencies>
<scenes>
<!--Settings-->
@ -720,7 +719,7 @@
</barButtonItem>
<barButtonItem key="rightBarButtonItem" style="plain" id="L90-ti-E7I">
<view key="customView" contentMode="scaleToFill" id="xpt-lr-f2h">
<rect key="frame" x="0.0" y="0.0" width="20" height="20"/>
<rect key="frame" x="374" y="12" width="20" height="20"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<subviews>
<activityIndicatorView hidden="YES" opaque="NO" contentMode="scaleToFill" horizontalHuggingPriority="750" verticalHuggingPriority="750" fixedFrame="YES" style="gray" translatesAutoresizingMaskIntoConstraints="NO" id="Pl1-lc-sIl">