Reduced the Master (feeds) controller down to one controller.

This commit is contained in:
Maurice Parker 2019-04-17 13:35:16 -05:00
parent 17caa31ee5
commit 7e14f8bcd3
5 changed files with 55 additions and 211 deletions

View File

@ -40,8 +40,6 @@
51C4525A226508D600C03939 /* UIStoryboard-Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51C4524E226506F400C03939 /* UIStoryboard-Extensions.swift */; };
51C4525B226508DA00C03939 /* UIImage-Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51C4524F226506F400C03939 /* UIImage-Extensions.swift */; };
51C4525C226508DF00C03939 /* String-Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51C45250226506F400C03939 /* String-Extensions.swift */; };
51C45266226508F600C03939 /* MasterSecondaryViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51C4525E226508F600C03939 /* MasterSecondaryViewController.swift */; };
51C45267226508F600C03939 /* MasterPrimaryViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51C4525F226508F600C03939 /* MasterPrimaryViewController.swift */; };
51C45268226508F600C03939 /* MasterUnreadCountView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51C45261226508F600C03939 /* MasterUnreadCountView.swift */; };
51C45269226508F600C03939 /* MasterTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51C45262226508F600C03939 /* MasterTableViewCell.swift */; };
51C4526A226508F600C03939 /* MasterTableViewCellLayout.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51C45263226508F600C03939 /* MasterTableViewCellLayout.swift */; };
@ -610,8 +608,6 @@
51C45250226506F400C03939 /* String-Extensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "String-Extensions.swift"; sourceTree = "<group>"; };
51C45254226507D200C03939 /* AppAssets.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppAssets.swift; sourceTree = "<group>"; };
51C45255226507D200C03939 /* AppDefaults.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDefaults.swift; sourceTree = "<group>"; };
51C4525E226508F600C03939 /* MasterSecondaryViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MasterSecondaryViewController.swift; sourceTree = "<group>"; };
51C4525F226508F600C03939 /* MasterPrimaryViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MasterPrimaryViewController.swift; sourceTree = "<group>"; };
51C45261226508F600C03939 /* MasterUnreadCountView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MasterUnreadCountView.swift; sourceTree = "<group>"; };
51C45262226508F600C03939 /* MasterTableViewCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MasterTableViewCell.swift; sourceTree = "<group>"; };
51C45263226508F600C03939 /* MasterTableViewCellLayout.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MasterTableViewCellLayout.swift; sourceTree = "<group>"; };
@ -904,8 +900,6 @@
51C4525D226508F600C03939 /* Master */ = {
isa = PBXGroup;
children = (
51C4525E226508F600C03939 /* MasterSecondaryViewController.swift */,
51C4525F226508F600C03939 /* MasterPrimaryViewController.swift */,
51C45264226508F600C03939 /* MasterViewController.swift */,
51C45265226508F600C03939 /* MasterTreeControllerDelegate.swift */,
51C45260226508F600C03939 /* Cell */,
@ -2155,7 +2149,6 @@
51C45258226508CF00C03939 /* AppAssets.swift in Sources */,
51C4527C2265091600C03939 /* MasterTimelineCellLayout.swift in Sources */,
51C4529A22650A0400C03939 /* ArticleStyle.swift in Sources */,
51C45267226508F600C03939 /* MasterPrimaryViewController.swift in Sources */,
51C4527F2265092C00C03939 /* DetailViewController.swift in Sources */,
51C4526A226508F600C03939 /* MasterTableViewCellLayout.swift in Sources */,
51C452AE2265104D00C03939 /* TimelineStringFormatter.swift in Sources */,
@ -2181,7 +2174,6 @@
51C452782265091600C03939 /* MasterTimelineCellData.swift in Sources */,
51C45259226508D300C03939 /* AppDefaults.swift in Sources */,
51C45293226509C800C03939 /* StarredFeedDelegate.swift in Sources */,
51C45266226508F600C03939 /* MasterSecondaryViewController.swift in Sources */,
51C45298226509E600C03939 /* OPMLImporter.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;

View File

@ -13,7 +13,7 @@
<!--Master-->
<scene sceneID="pY4-Hu-kfo">
<objects>
<navigationController storyboardIdentifier="MasterPrimaryNavigationViewController" title="Master" useStoryboardIdentifierAsRestorationIdentifier="YES" toolbarHidden="NO" id="RMx-3f-FxP" sceneMemberID="viewController">
<navigationController storyboardIdentifier="MasterNavigationViewController" title="Master" useStoryboardIdentifierAsRestorationIdentifier="YES" toolbarHidden="NO" id="RMx-3f-FxP" sceneMemberID="viewController">
<navigationBar key="navigationBar" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" largeTitles="YES" id="Pmd-2v-anx">
<rect key="frame" x="0.0" y="44" width="414" height="96"/>
<autoresizingMask key="autoresizingMask"/>
@ -28,7 +28,7 @@
</navigationController>
<placeholder placeholderIdentifier="IBFirstResponder" id="8fS-aE-onr" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="-38" y="-630"/>
<point key="canvasLocation" x="154" y="-759"/>
</scene>
<!--Detail-->
<scene sceneID="yUG-lL-AsK">
@ -91,7 +91,7 @@
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="FJe-Yq-33r" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="709" y="741"/>
<point key="canvasLocation" x="900" y="763"/>
</scene>
<!--Timeline-->
<scene sceneID="fag-XH-avP">
@ -131,7 +131,7 @@
</tableViewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="nzm-Gf-Xce" userLabel="First Responder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="709" y="45"/>
<point key="canvasLocation" x="900" y="-42"/>
</scene>
<!--Navigation Controller-->
<scene sceneID="uQv-y4-hI4">
@ -151,7 +151,7 @@
</navigationController>
<placeholder placeholderIdentifier="IBFirstResponder" id="Kif-ju-wKR" userLabel="First Responder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="-39" y="45"/>
<point key="canvasLocation" x="154" y="-42"/>
</scene>
<!--Split View Controller-->
<scene sceneID="Nki-YV-4Qg">
@ -170,7 +170,7 @@
<!--Master-->
<scene sceneID="smW-Zh-WAh">
<objects>
<tableViewController storyboardIdentifier="MasterPrimaryViewController" title="Master" useStoryboardIdentifierAsRestorationIdentifier="YES" clearsSelectionOnViewWillAppear="NO" id="7bK-jq-Zjz" customClass="MasterPrimaryViewController" customModule="NetNewsWire" customModuleProvider="target" sceneMemberID="viewController">
<tableViewController storyboardIdentifier="MasterViewController" title="Master" useStoryboardIdentifierAsRestorationIdentifier="YES" clearsSelectionOnViewWillAppear="NO" id="7bK-jq-Zjz" customClass="MasterViewController" customModule="NetNewsWire" customModuleProvider="target" sceneMemberID="viewController">
<tableView key="view" clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" dataMode="prototypes" style="plain" separatorStyle="default" rowHeight="-1" estimatedRowHeight="-1" sectionHeaderHeight="28" sectionFooterHeight="28" id="r7i-6Z-zg0">
<rect key="frame" x="0.0" y="0.0" width="414" height="896"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
@ -215,52 +215,7 @@
</tableViewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="Rux-fX-hf1" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="709" y="-630"/>
</scene>
<!--Secondary-->
<scene sceneID="Nfg-Jx-7ig">
<objects>
<tableViewController storyboardIdentifier="MasterSecondaryViewController" useStoryboardIdentifierAsRestorationIdentifier="YES" id="aKa-71-ZA9" customClass="MasterSecondaryViewController" customModule="NetNewsWire" customModuleProvider="target" sceneMemberID="viewController">
<tableView key="view" clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" dataMode="prototypes" style="plain" separatorStyle="default" rowHeight="-1" estimatedRowHeight="-1" sectionHeaderHeight="28" sectionFooterHeight="28" id="6Kx-w7-mE7">
<rect key="frame" x="0.0" y="0.0" width="414" height="896"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<prototypes>
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="default" indentationWidth="10" reuseIdentifier="Cell" id="27q-ZF-kC8" customClass="MasterTableViewCell" customModule="NetNewsWire" customModuleProvider="target">
<rect key="frame" x="0.0" y="28" width="414" height="44"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="27q-ZF-kC8" id="lUQ-Im-VJe">
<rect key="frame" x="0.0" y="0.0" width="414" height="43.5"/>
<autoresizingMask key="autoresizingMask"/>
</tableViewCellContentView>
</tableViewCell>
</prototypes>
<connections>
<outlet property="dataSource" destination="aKa-71-ZA9" id="hzg-mr-du3"/>
<outlet property="delegate" destination="aKa-71-ZA9" id="kS8-Gn-bnZ"/>
</connections>
</tableView>
<navigationItem key="navigationItem" title="Secondary" id="3Ja-fK-wIr"/>
</tableViewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="ILK-0w-PGv" userLabel="First Responder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="2159" y="-630"/>
</scene>
<!--Navigation Controller-->
<scene sceneID="4zT-Jk-55W">
<objects>
<navigationController storyboardIdentifier="MasterSecondaryNavigationViewController" useStoryboardIdentifierAsRestorationIdentifier="YES" id="5et-QD-nMk" sceneMemberID="viewController">
<navigationBar key="navigationBar" contentMode="scaleToFill" insetsLayoutMarginsFromSafeArea="NO" largeTitles="YES" id="kf3-JC-lZU">
<rect key="frame" x="0.0" y="44" width="414" height="96"/>
<autoresizingMask key="autoresizingMask"/>
</navigationBar>
<connections>
<segue destination="aKa-71-ZA9" kind="relationship" relationship="rootViewController" id="KU7-08-42q"/>
</connections>
</navigationController>
<placeholder placeholderIdentifier="IBFirstResponder" id="qBw-2N-kNV" userLabel="First Responder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="1422" y="-629"/>
<point key="canvasLocation" x="900" y="-759"/>
</scene>
<!--Navigation Controller-->
<scene sceneID="r7l-gg-dq7">
@ -276,7 +231,7 @@
</navigationController>
<placeholder placeholderIdentifier="IBFirstResponder" id="SLD-UC-DBI" userLabel="First Responder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="-39" y="741"/>
<point key="canvasLocation" x="154" y="763"/>
</scene>
</scenes>
<resources>

View File

@ -1,64 +0,0 @@
//
// MasterPrimaryViewController.swift
// NetNewsWire
//
// Created by Maurice Parker on 4/8/19.
// Copyright © 2019 Ranchero Software. All rights reserved.
//
import UIKit
import Account
import RSCore
import RSTree
class MasterPrimaryViewController: MasterViewController {
// MARK: - Table View
override func numberOfSections(in tableView: UITableView) -> Int {
return treeController.rootNode.numberOfChildNodes
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return treeController.rootNode.childAtIndex(section)?.numberOfChildNodes ?? 0
}
override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
guard let nameProvider = treeController.rootNode.childAtIndex(section)?.representedObject as? DisplayNameProvider else {
return nil
}
return nameProvider.nameForDisplay
}
// MARK: API
override func delete(indexPath: IndexPath) {
guard let containerNode = treeController.rootNode.childAtIndex(indexPath.section),
let deleteNode = containerNode.childAtIndex(indexPath.row),
let container = containerNode.representedObject as? Container else {
return
}
animatingChanges = true
if let feed = deleteNode.representedObject as? Feed {
container.deleteFeed(feed)
}
if let folder = deleteNode.representedObject as? Folder {
container.deleteFolder(folder)
}
treeController.rebuild()
tableView.deleteRows(at: [indexPath], with: .automatic)
animatingChanges = false
}
override func nodeFor(indexPath: IndexPath) -> Node? {
return treeController.rootNode.childAtIndex(indexPath.section)?.childAtIndex(indexPath.row)
}
}

View File

@ -1,74 +0,0 @@
//
// MasterSecondaryViewController.swift
// NetNewsWire
//
// Created by Maurice Parker on 4/8/19.
// Copyright © 2019 Ranchero Software. All rights reserved.
//
import UIKit
import Account
import RSCore
import RSTree
class MasterSecondaryViewController: MasterViewController {
var viewRootNode: Node?
// MARK: - Table View
override func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return viewRootNode?.numberOfChildNodes ?? 0
}
override func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) {
if editingStyle == .delete {
guard let containerNode = viewRootNode,
let deleteNode = containerNode.childAtIndex(indexPath.row),
let container = containerNode.representedObject as? Container,
let feed = deleteNode.representedObject as? Feed else {
return
}
animatingChanges = true
container.deleteFeed(feed)
treeController.rebuild()
tableView.deleteRows(at: [indexPath], with: .fade)
animatingChanges = false
} else if editingStyle == .insert {
// Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view.
}
}
// MARK: API
override func delete(indexPath: IndexPath) {
guard let containerNode = viewRootNode,
let deleteNode = containerNode.childAtIndex(indexPath.row),
let container = containerNode.representedObject as? Container,
let feed = deleteNode.representedObject as? Feed else {
return
}
animatingChanges = true
container.deleteFeed(feed)
treeController.rebuild()
tableView.deleteRows(at: [indexPath], with: .fade)
animatingChanges = false
}
override func nodeFor(indexPath: IndexPath) -> Node? {
return viewRootNode?.childAtIndex(indexPath.row)
}
}

View File

@ -60,6 +60,8 @@ class MasterViewController: UITableViewController, UndoableCommandRunner {
super.viewWillDisappear(animated)
resignFirstResponder()
}
// MARK: Notifications
@objc private func refreshAccounts(_ sender: Any) {
AccountManager.shared.refreshAll()
@ -117,6 +119,21 @@ class MasterViewController: UITableViewController, UndoableCommandRunner {
// MARK: Table View
override func numberOfSections(in tableView: UITableView) -> Int {
return treeController.rootNode.numberOfChildNodes
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return treeController.rootNode.childAtIndex(section)?.numberOfChildNodes ?? 0
}
override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
guard let nameProvider = treeController.rootNode.childAtIndex(section)?.representedObject as? DisplayNameProvider else {
return nil
}
return nameProvider.nameForDisplay
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) as! MasterTableViewCell
@ -168,27 +185,25 @@ class MasterViewController: UITableViewController, UndoableCommandRunner {
return
}
let timeline = UIStoryboard.main.instantiateController(ofType: MasterTimelineViewController.self)
if let pseudoFeed = node.representedObject as? PseudoFeed {
let timeline = UIStoryboard.main.instantiateController(ofType: MasterTimelineViewController.self)
timeline.title = pseudoFeed.nameForDisplay
timeline.representedObjects = [pseudoFeed]
self.navigationController?.pushViewController(timeline, animated: true)
}
if let folder = node.representedObject as? Folder {
let secondary = UIStoryboard.main.instantiateController(ofType: MasterSecondaryViewController.self)
secondary.title = folder.nameForDisplay
secondary.viewRootNode = node
self.navigationController?.pushViewController(secondary, animated: true)
timeline.title = folder.nameForDisplay
timeline.representedObjects = [folder]
}
if let feed = node.representedObject as? Feed {
let timeline = UIStoryboard.main.instantiateController(ofType: MasterTimelineViewController.self)
timeline.title = feed.nameForDisplay
timeline.representedObjects = [feed]
self.navigationController?.pushViewController(timeline, animated: true)
}
self.navigationController?.pushViewController(timeline, animated: true)
}
// MARK: Actions
@ -324,9 +339,30 @@ class MasterViewController: UITableViewController, UndoableCommandRunner {
}
func delete(indexPath: IndexPath) {
assertionFailure()
guard let containerNode = treeController.rootNode.childAtIndex(indexPath.section),
let deleteNode = containerNode.childAtIndex(indexPath.row),
let container = containerNode.representedObject as? Container else {
return
}
animatingChanges = true
if let feed = deleteNode.representedObject as? Feed {
container.deleteFeed(feed)
}
if let folder = deleteNode.representedObject as? Folder {
container.deleteFolder(folder)
}
treeController.rebuild()
tableView.deleteRows(at: [indexPath], with: .automatic)
animatingChanges = false
}
func rename(indexPath: IndexPath) {
let name = (nodeFor(indexPath: indexPath)?.representedObject as? DisplayNameProvider)?.nameForDisplay ?? ""
@ -368,8 +404,7 @@ class MasterViewController: UITableViewController, UndoableCommandRunner {
}
func nodeFor(indexPath: IndexPath) -> Node? {
assertionFailure()
return nil
return treeController.rootNode.childAtIndex(indexPath.section)?.childAtIndex(indexPath.row)
}
}