Added scrolling to new feed after a user adds it.
This commit is contained in:
parent
b01b45cf9c
commit
929d7714ab
|
@ -43,7 +43,7 @@ class MasterViewController: UITableViewController, UndoableCommandRunner {
|
||||||
NotificationCenter.default.addObserver(self, selector: #selector(faviconDidBecomeAvailable(_:)), name: .FaviconDidBecomeAvailable, object: nil)
|
NotificationCenter.default.addObserver(self, selector: #selector(faviconDidBecomeAvailable(_:)), name: .FaviconDidBecomeAvailable, object: nil)
|
||||||
NotificationCenter.default.addObserver(self, selector: #selector(feedSettingDidChange(_:)), name: .FeedSettingDidChange, object: nil)
|
NotificationCenter.default.addObserver(self, selector: #selector(feedSettingDidChange(_:)), name: .FeedSettingDidChange, object: nil)
|
||||||
NotificationCenter.default.addObserver(self, selector: #selector(displayNameDidChange(_:)), name: .DisplayNameDidChange, object: nil)
|
NotificationCenter.default.addObserver(self, selector: #selector(displayNameDidChange(_:)), name: .DisplayNameDidChange, object: nil)
|
||||||
|
NotificationCenter.default.addObserver(self, selector: #selector(userDidAddFeed(_:)), name: .UserDidAddFeed, object: nil)
|
||||||
NotificationCenter.default.addObserver(self, selector: #selector(progressDidChange(_:)), name: .AccountRefreshProgressDidChange, object: nil)
|
NotificationCenter.default.addObserver(self, selector: #selector(progressDidChange(_:)), name: .AccountRefreshProgressDidChange, object: nil)
|
||||||
|
|
||||||
refreshControl = UIRefreshControl()
|
refreshControl = UIRefreshControl()
|
||||||
|
@ -88,11 +88,11 @@ class MasterViewController: UITableViewController, UndoableCommandRunner {
|
||||||
}
|
}
|
||||||
|
|
||||||
@objc func containerChildrenDidChange(_ note: Notification) {
|
@objc func containerChildrenDidChange(_ note: Notification) {
|
||||||
rebuildTreeAndReloadDataIfNeeded()
|
rebuildBackingStoresAndReloadDataIfNeeded()
|
||||||
}
|
}
|
||||||
|
|
||||||
@objc func batchUpdateDidPerform(_ notification: Notification) {
|
@objc func batchUpdateDidPerform(_ notification: Notification) {
|
||||||
rebuildTreeAndReloadDataIfNeeded()
|
rebuildBackingStoresAndReloadDataIfNeeded()
|
||||||
}
|
}
|
||||||
|
|
||||||
@objc func unreadCountDidChange(_ note: Notification) {
|
@objc func unreadCountDidChange(_ note: Notification) {
|
||||||
|
@ -136,11 +136,36 @@ class MasterViewController: UITableViewController, UndoableCommandRunner {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
rebuildTreeAndReloadDataIfNeeded()
|
rebuildBackingStoresAndReloadDataIfNeeded()
|
||||||
configureCellsForRepresentedObject(object as AnyObject)
|
configureCellsForRepresentedObject(object as AnyObject)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@objc func userDidAddFeed(_ notification: Notification) {
|
||||||
|
|
||||||
|
guard let feed = notification.userInfo?[UserInfoKey.feed],
|
||||||
|
let node = treeController.rootNode.descendantNodeRepresentingObject(feed as AnyObject) else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if let indexPath = indexPathFor(node) {
|
||||||
|
tableView.scrollToRow(at: indexPath, at: .middle, animated: true)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// It wasn't already visable, so expand its folder and try again
|
||||||
|
guard let parent = node.parent, let indexPath = indexPathFor(parent) else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
expand(indexPath)
|
||||||
|
|
||||||
|
if let indexPath = indexPathFor(node) {
|
||||||
|
tableView.scrollToRow(at: indexPath, at: .middle, animated: true)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
// MARK: Table View
|
// MARK: Table View
|
||||||
|
|
||||||
override func numberOfSections(in tableView: UITableView) -> Int {
|
override func numberOfSections(in tableView: UITableView) -> Int {
|
||||||
|
@ -172,7 +197,7 @@ class MasterViewController: UITableViewController, UndoableCommandRunner {
|
||||||
|
|
||||||
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) as! MasterTableViewCell
|
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) as! MasterTableViewCell
|
||||||
|
|
||||||
guard let node = nodeFor(indexPath: indexPath) else {
|
guard let node = nodeFor(indexPath) else {
|
||||||
return cell
|
return cell
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -182,7 +207,7 @@ class MasterViewController: UITableViewController, UndoableCommandRunner {
|
||||||
}
|
}
|
||||||
|
|
||||||
override func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
|
override func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
|
||||||
guard let node = nodeFor(indexPath: indexPath), !(node.representedObject is PseudoFeed) else {
|
guard let node = nodeFor(indexPath), !(node.representedObject is PseudoFeed) else {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
|
@ -214,7 +239,7 @@ class MasterViewController: UITableViewController, UndoableCommandRunner {
|
||||||
|
|
||||||
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
|
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
|
||||||
|
|
||||||
guard let node = nodeFor(indexPath: indexPath) else {
|
guard let node = nodeFor(indexPath) else {
|
||||||
assertionFailure()
|
assertionFailure()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -381,7 +406,7 @@ class MasterViewController: UITableViewController, UndoableCommandRunner {
|
||||||
func delete(indexPath: IndexPath) {
|
func delete(indexPath: IndexPath) {
|
||||||
|
|
||||||
guard let undoManager = undoManager,
|
guard let undoManager = undoManager,
|
||||||
let deleteNode = nodeFor(indexPath: indexPath),
|
let deleteNode = nodeFor(indexPath),
|
||||||
let deleteCommand = DeleteCommand(nodesToDelete: [deleteNode], treeController: treeController, undoManager: undoManager)
|
let deleteCommand = DeleteCommand(nodesToDelete: [deleteNode], treeController: treeController, undoManager: undoManager)
|
||||||
else {
|
else {
|
||||||
return
|
return
|
||||||
|
@ -399,7 +424,7 @@ class MasterViewController: UITableViewController, UndoableCommandRunner {
|
||||||
|
|
||||||
func rename(indexPath: IndexPath) {
|
func rename(indexPath: IndexPath) {
|
||||||
|
|
||||||
let name = (nodeFor(indexPath: indexPath)?.representedObject as? DisplayNameProvider)?.nameForDisplay ?? ""
|
let name = (nodeFor(indexPath)?.representedObject as? DisplayNameProvider)?.nameForDisplay ?? ""
|
||||||
let formatString = NSLocalizedString("Rename “%@”", comment: "Feed finder")
|
let formatString = NSLocalizedString("Rename “%@”", comment: "Feed finder")
|
||||||
let title = NSString.localizedStringWithFormat(formatString as NSString, name) as String
|
let title = NSString.localizedStringWithFormat(formatString as NSString, name) as String
|
||||||
|
|
||||||
|
@ -411,7 +436,7 @@ class MasterViewController: UITableViewController, UndoableCommandRunner {
|
||||||
let renameTitle = NSLocalizedString("Rename", comment: "Rename")
|
let renameTitle = NSLocalizedString("Rename", comment: "Rename")
|
||||||
let renameAction = UIAlertAction(title: renameTitle, style: .default) { [weak self] action in
|
let renameAction = UIAlertAction(title: renameTitle, style: .default) { [weak self] action in
|
||||||
|
|
||||||
guard let node = self?.nodeFor(indexPath: indexPath),
|
guard let node = self?.nodeFor(indexPath),
|
||||||
let name = alertController.textFields?[0].text,
|
let name = alertController.textFields?[0].text,
|
||||||
!name.isEmpty else {
|
!name.isEmpty else {
|
||||||
return
|
return
|
||||||
|
@ -437,10 +462,19 @@ class MasterViewController: UITableViewController, UndoableCommandRunner {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func nodeFor(indexPath: IndexPath) -> Node? {
|
func nodeFor(_ indexPath: IndexPath) -> Node? {
|
||||||
return shadowTable[indexPath.section][indexPath.row]
|
return shadowTable[indexPath.section][indexPath.row]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func indexPathFor(_ node: Node) -> IndexPath? {
|
||||||
|
for i in 0..<shadowTable.count {
|
||||||
|
if let row = shadowTable[i].firstIndex(of: node) {
|
||||||
|
return IndexPath(row: row, section: i)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK: OPML Document Picker
|
// MARK: OPML Document Picker
|
||||||
|
@ -467,9 +501,9 @@ extension MasterViewController: MasterTableViewCellDelegate {
|
||||||
|
|
||||||
func disclosureSelected(_ sender: MasterTableViewCell, expanding: Bool) {
|
func disclosureSelected(_ sender: MasterTableViewCell, expanding: Bool) {
|
||||||
if expanding {
|
if expanding {
|
||||||
expandCell(sender)
|
expand(sender)
|
||||||
} else {
|
} else {
|
||||||
collapseCell(sender)
|
collapse(sender)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -479,9 +513,10 @@ extension MasterViewController: MasterTableViewCellDelegate {
|
||||||
|
|
||||||
private extension MasterViewController {
|
private extension MasterViewController {
|
||||||
|
|
||||||
func rebuildTreeAndReloadDataIfNeeded() {
|
func rebuildBackingStoresAndReloadDataIfNeeded() {
|
||||||
if !animatingChanges && !BatchUpdate.shared.isPerforming {
|
if !animatingChanges && !BatchUpdate.shared.isPerforming {
|
||||||
rebuildBackingStructures()
|
treeController.rebuild()
|
||||||
|
rebuildShadowTable()
|
||||||
tableView.reloadData()
|
tableView.reloadData()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -505,18 +540,13 @@ private extension MasterViewController {
|
||||||
|
|
||||||
func applyToAvailableCells(_ callback: (MasterTableViewCell, Node) -> Void) {
|
func applyToAvailableCells(_ callback: (MasterTableViewCell, Node) -> Void) {
|
||||||
tableView.visibleCells.forEach { cell in
|
tableView.visibleCells.forEach { cell in
|
||||||
guard let indexPath = tableView.indexPath(for: cell), let node = nodeFor(indexPath: indexPath) else {
|
guard let indexPath = tableView.indexPath(for: cell), let node = nodeFor(indexPath) else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
callback(cell as! MasterTableViewCell, node)
|
callback(cell as! MasterTableViewCell, node)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func rebuildBackingStructures() {
|
|
||||||
treeController.rebuild()
|
|
||||||
rebuildShadowTable()
|
|
||||||
}
|
|
||||||
|
|
||||||
func rebuildShadowTable() {
|
func rebuildShadowTable() {
|
||||||
|
|
||||||
for i in 0..<treeController.rootNode.numberOfChildNodes {
|
for i in 0..<treeController.rootNode.numberOfChildNodes {
|
||||||
|
@ -540,13 +570,16 @@ private extension MasterViewController {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func expandCell(_ cell: MasterTableViewCell) {
|
func expand(_ cell: MasterTableViewCell) {
|
||||||
|
|
||||||
animatingChanges = true
|
|
||||||
|
|
||||||
guard let indexPath = tableView.indexPath(for: cell) else {
|
guard let indexPath = tableView.indexPath(for: cell) else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
expand(indexPath)
|
||||||
|
}
|
||||||
|
|
||||||
|
func expand(_ indexPath: IndexPath) {
|
||||||
|
|
||||||
|
animatingChanges = true
|
||||||
|
|
||||||
let expandNode = shadowTable[indexPath.section][indexPath.row]
|
let expandNode = shadowTable[indexPath.section][indexPath.row]
|
||||||
expandedNodes.append(expandNode)
|
expandedNodes.append(expandNode)
|
||||||
|
@ -568,13 +601,16 @@ private extension MasterViewController {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func collapseCell(_ cell: MasterTableViewCell) {
|
func collapse(_ cell: MasterTableViewCell) {
|
||||||
|
|
||||||
animatingChanges = true
|
|
||||||
|
|
||||||
guard let indexPath = tableView.indexPath(for: cell) else {
|
guard let indexPath = tableView.indexPath(for: cell) else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
collapse(indexPath)
|
||||||
|
}
|
||||||
|
|
||||||
|
func collapse(_ indexPath: IndexPath) {
|
||||||
|
|
||||||
|
animatingChanges = true
|
||||||
|
|
||||||
let collapseNode = shadowTable[indexPath.section][indexPath.row]
|
let collapseNode = shadowTable[indexPath.section][indexPath.row]
|
||||||
if let removeNode = expandedNodes.firstIndex(of: collapseNode) {
|
if let removeNode = expandedNodes.firstIndex(of: collapseNode) {
|
||||||
|
|
Loading…
Reference in New Issue