Add filter button show/hide unread feeds. Issue #1311

This commit is contained in:
Maurice Parker 2019-11-21 15:55:50 -06:00
parent eed6333368
commit 89e9a7b80e
6 changed files with 81 additions and 20 deletions

View File

@ -8,13 +8,14 @@
import Foundation
import RSCore
import Account
final class SmartFeedsController: DisplayNameProvider {
public static let shared = SmartFeedsController()
let nameForDisplay = NSLocalizedString("Smart Feeds", comment: "Smart Feeds group title")
var smartFeeds = [AnyObject]()
var smartFeeds = [Feed]()
let todayFeed = SmartFeed(delegate: TodayFeedDelegate())
let unreadFeed = UnreadFeed()
let starredFeed = SmartFeed(delegate: StarredFeedDelegate())

View File

@ -13,8 +13,9 @@ import Account
final class WebFeedTreeControllerDelegate: TreeControllerDelegate {
var isUnreadFiltered = false
func treeController(treeController: TreeController, childNodesFor node: Node) -> [Node]? {
if node.isRoot {
return childNodesForRootNode(node)
}
@ -32,29 +33,47 @@ final class WebFeedTreeControllerDelegate: TreeControllerDelegate {
private extension WebFeedTreeControllerDelegate {
func childNodesForRootNode(_ rootNode: Node) -> [Node]? {
var topLevelNodes = [Node]()
// The top-level nodes are Smart Feeds and accounts.
// Check to see if we should show the SmartFeeds top level by checking the unreadFeed
if !(isUnreadFiltered && SmartFeedsController.shared.unreadFeed.unreadCount == 0) {
let smartFeedsNode = rootNode.existingOrNewChildNode(with: SmartFeedsController.shared)
smartFeedsNode.canHaveChildNodes = true
smartFeedsNode.isGroupItem = true
topLevelNodes.append(smartFeedsNode)
}
let smartFeedsNode = rootNode.existingOrNewChildNode(with: SmartFeedsController.shared)
smartFeedsNode.canHaveChildNodes = true
smartFeedsNode.isGroupItem = true
return [smartFeedsNode] + sortedAccountNodes(rootNode)
topLevelNodes.append(contentsOf: sortedAccountNodes(rootNode))
return topLevelNodes
}
func childNodesForSmartFeeds(_ parentNode: Node) -> [Node] {
return SmartFeedsController.shared.smartFeeds.map { parentNode.existingOrNewChildNode(with: $0) }
return SmartFeedsController.shared.smartFeeds.compactMap { (feed) -> Node? in
if isUnreadFiltered && feed.unreadCount == 0 {
return nil
}
return parentNode.existingOrNewChildNode(with: feed as AnyObject)
}
}
func childNodesForContainerNode(_ containerNode: Node) -> [Node]? {
let container = containerNode.representedObject as! Container
var children = [AnyObject]()
children.append(contentsOf: Array(container.topLevelWebFeeds))
for webFeed in container.topLevelWebFeeds {
if !(isUnreadFiltered && webFeed.unreadCount == 0) {
children.append(webFeed)
}
}
if let folders = container.folders {
children.append(contentsOf: Array(folders))
for folder in folders {
if !(isUnreadFiltered && folder.unreadCount == 0) {
children.append(folder)
}
}
}
var updatedChildNodes = [Node]()
@ -77,13 +96,14 @@ private extension WebFeedTreeControllerDelegate {
}
func createNode(representedObject: Any, parent: Node) -> Node? {
if let webFeed = representedObject as? WebFeed {
return createNode(webFeed: webFeed, parent: parent)
}
if let folder = representedObject as? Folder {
return createNode(folder: folder, parent: parent)
}
if let account = representedObject as? Account {
return createNode(account: account, parent: parent)
}
@ -92,19 +112,16 @@ private extension WebFeedTreeControllerDelegate {
}
func createNode(webFeed: WebFeed, parent: Node) -> Node {
return parent.createChildNode(webFeed)
}
func createNode(folder: Folder, parent: Node) -> Node {
let node = parent.createChildNode(folder)
node.canHaveChildNodes = true
return node
}
func createNode(account: Account, parent: Node) -> Node {
let node = parent.createChildNode(account)
node.canHaveChildNodes = true
node.isGroupItem = true
@ -112,8 +129,10 @@ private extension WebFeedTreeControllerDelegate {
}
func sortedAccountNodes(_ parent: Node) -> [Node] {
let nodes = AccountManager.shared.sortedActiveAccounts.map { (account) -> Node in
let nodes = AccountManager.shared.sortedActiveAccounts.compactMap { (account) -> Node? in
if isUnreadFiltered && account.unreadCount == 0 {
return nil
}
let accountNode = parent.existingOrNewChildNode(with: account)
accountNode.canHaveChildNodes = true
accountNode.isGroupItem = true
@ -123,7 +142,6 @@ private extension WebFeedTreeControllerDelegate {
}
func nodeInArrayRepresentingObject(_ nodes: [Node], _ representedObject: AnyObject) -> Node? {
for oneNode in nodes {
if oneNode.representedObject === representedObject {
return oneNode

View File

@ -89,6 +89,14 @@ struct AppAssets {
return RSImage(named: "faviconTemplateImage")!
}()
static var filterInactiveImage: UIImage = {
UIImage(systemName: "line.horizontal.3.decrease.circle")!
}()
static var filterActiveImage: UIImage = {
UIImage(systemName: "line.horizontal.3.decrease.circle.fill")!
}()
static var fullScreenBackgroundColor: UIColor = {
return UIColor(named: "fullScreenBackgroundColor")!
}()

View File

@ -214,9 +214,17 @@
<action selector="settings:" destination="7bK-jq-Zjz" id="Y8a-lz-Im7"/>
</connections>
</barButtonItem>
<barButtonItem key="rightBarButtonItem" image="line.horizontal.3.decrease.circle" catalog="system" id="ZJu-oJ-c1R">
<connections>
<action selector="toggleFilter:" destination="7bK-jq-Zjz" id="7lh-Bz-nfD"/>
</connections>
</barButtonItem>
</navigationItem>
<simulatedNavigationBarMetrics key="simulatedTopBarMetrics" prompted="NO"/>
<simulatedToolbarMetrics key="simulatedBottomBarMetrics"/>
<connections>
<outlet property="filterButton" destination="ZJu-oJ-c1R" id="jiO-wg-qrG"/>
</connections>
</tableViewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="Rux-fX-hf1" sceneMemberID="firstResponder"/>
</objects>
@ -289,6 +297,7 @@
<image name="chevron.up" catalog="system" width="64" height="36"/>
<image name="circle" catalog="system" width="64" height="60"/>
<image name="gear" catalog="system" width="64" height="58"/>
<image name="line.horizontal.3.decrease.circle" catalog="system" width="64" height="60"/>
<image name="multiply.circle.fill" catalog="system" width="64" height="60"/>
<image name="square.and.arrow.up" catalog="system" width="56" height="64"/>
<image name="square.and.arrow.up.fill" catalog="system" width="56" height="64"/>

View File

@ -14,6 +14,7 @@ import RSTree
class MasterFeedViewController: UITableViewController, UndoableCommandRunner {
@IBOutlet weak var filterButton: UIBarButtonItem!
private var refreshProgressView: RefreshProgressView?
private var addNewItemButton: UIBarButtonItem!
@ -370,6 +371,16 @@ class MasterFeedViewController: UITableViewController, UndoableCommandRunner {
coordinator.showSettings()
}
@IBAction func toggleFilter(_ sender: Any) {
if coordinator.isUnreadFeedsFiltered {
filterButton.image = AppAssets.filterInactiveImage
coordinator.showAllFeeds()
} else {
filterButton.image = AppAssets.filterActiveImage
coordinator.hideUnreadFeeds()
}
}
@IBAction func add(_ sender: UIBarButtonItem) {
coordinator.showAdd(.feed)
}

View File

@ -112,6 +112,10 @@ class SceneCoordinator: NSObject, UndoableCommandRunner, UnreadCountProvider {
return panelMode == .three
}
var isUnreadFeedsFiltered: Bool {
return treeControllerDelegate.isUnreadFiltered
}
var rootNode: Node {
return treeController.rootNode
}
@ -484,6 +488,16 @@ class SceneCoordinator: NSObject, UndoableCommandRunner, UnreadCountProvider {
}
return 0
}
func showAllFeeds() {
treeControllerDelegate.isUnreadFiltered = false
rebuildBackingStores()
}
func hideUnreadFeeds() {
treeControllerDelegate.isUnreadFiltered = true
rebuildBackingStores()
}
func expand(_ node: Node) {
node.isExpanded = true