Add scoped searching of articles

This commit is contained in:
Maurice Parker
2019-08-31 15:53:47 -05:00
parent ba36572497
commit fe2e0155da
7 changed files with 130 additions and 24 deletions

View File

@@ -12,6 +12,11 @@ import Articles
import RSCore
import RSTree
enum SearchScope: Int {
case timeline = 0
case global = 1
}
class AppCoordinator: NSObject, UndoableCommandRunner, UnreadCountProvider {
var undoableCommands = [UndoableCommand]()
@@ -49,7 +54,9 @@ class AppCoordinator: NSObject, UndoableCommandRunner, UnreadCountProvider {
private var expandedNodes = [Node]()
private var shadowTable = [[Node]]()
private var lastSearchString = ""
private var lastSearchScope: SearchScope? = nil
private var isSearching: Bool = false
private var searchArticleIds: Set<String>? = nil
private(set) var sortDirection = AppDefaults.timelineSortDirection {
didSet {
@@ -517,25 +524,41 @@ class AppCoordinator: NSObject, UndoableCommandRunner, UnreadCountProvider {
}
}
func searchArticles(_ searchString: String) {
func searchArticles(_ searchString: String, _ searchScope: SearchScope) {
guard !searchString.isEmpty else {
isSearching = false
lastSearchString = ""
lastSearchScope = nil
searchArticleIds = nil
if let ip = currentMasterIndexPath, let node = nodeFor(ip), let fetcher = node.representedObject as? ArticleFetcher {
timelineFetcher = fetcher
}
return
}
isSearching = true
if !isSearching {
isSearching = true
searchArticleIds = Set(articles.map { $0.articleID })
}
if searchString.count < 3 {
timelineFetcher = nil
return
}
if searchString != lastSearchString {
timelineFetcher = SmartFeed(delegate: SearchFeedDelegate(searchString: searchString))
if searchString != lastSearchString || searchScope != lastSearchScope {
switch searchScope {
case .global:
timelineFetcher = SmartFeed(delegate: SearchFeedDelegate(searchString: searchString))
case .timeline:
timelineFetcher = SmartFeed(delegate: SearchTimelineFeedDelegate(searchString: searchString, articleIDs: searchArticleIds!))
}
lastSearchString = searchString
lastSearchScope = searchScope
}
}

View File

@@ -44,10 +44,16 @@ class MasterTimelineViewController: UITableViewController, UndoableCommandRunner
// Setup the Search Controller
searchController.searchResultsUpdater = self
searchController.obscuresBackgroundDuringPresentation = false
searchController.searchBar.delegate = self
searchController.searchBar.placeholder = NSLocalizedString("Search Articles", comment: "Search Articles")
searchController.searchBar.showsScopeBar = true
searchController.searchBar.scopeButtonTitles = [
NSLocalizedString("Here", comment: "Here"),
NSLocalizedString("All Articles", comment: "All Articles")
]
navigationItem.searchController = searchController
definesPresentationContext = true
// Setup the Refresh Control
refreshControl = UIRefreshControl()
refreshControl!.addTarget(self, action: #selector(refreshAccounts(_:)), for: .valueChanged)
@@ -403,12 +409,24 @@ class MasterTimelineViewController: UITableViewController, UndoableCommandRunner
}
// MARK: UISearchResultsUpdating
// MARK: Searching
extension MasterTimelineViewController: UISearchResultsUpdating {
func updateSearchResults(for searchController: UISearchController) {
coordinator.searchArticles(searchController.searchBar.text!)
let searchScope = SearchScope(rawValue: searchController.searchBar.selectedScopeButtonIndex)!
coordinator.searchArticles(searchController.searchBar.text!, searchScope)
}
}
extension MasterTimelineViewController: UISearchBarDelegate {
func searchBar(_ searchBar: UISearchBar, selectedScopeButtonIndexDidChange selectedScope: Int) {
let searchScope = SearchScope(rawValue: selectedScope)!
coordinator.searchArticles(searchBar.text!, searchScope)
}
}
// MARK: Private