Add filter button show/hide unread feeds. Issue #1311
This commit is contained in:
parent
eed6333368
commit
89e9a7b80e
|
@ -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())
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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")!
|
||||
}()
|
||||
|
|
|
@ -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"/>
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue