Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 30 additions & 2 deletions App/Data Sources/ThreadListDataSource.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,14 @@ import CoreData
import os
import UIKit

enum BookmarkFilter {
case all
case unreadOnly
case readOnly
case starCategory(StarCategory)
case textSearch(String)
}

private let Log = Logger(subsystem: Bundle.main.bundleIdentifier!, category: "ThreadListDataSource")

final class ThreadListDataSource: NSObject {
Expand All @@ -20,10 +28,30 @@ final class ThreadListDataSource: NSObject {
private let showsTagAndRating: Bool
private let tableView: UITableView

convenience init(bookmarksSortedByUnread sortedByUnread: Bool, showsTagAndRating: Bool, managedObjectContext: NSManagedObjectContext, tableView: UITableView) throws {
convenience init(bookmarksSortedByUnread sortedByUnread: Bool, showsTagAndRating: Bool, filter: BookmarkFilter, managedObjectContext: NSManagedObjectContext, tableView: UITableView) throws {
let fetchRequest = AwfulThread.makeFetchRequest()

fetchRequest.predicate = NSPredicate(format: "%K == YES && %K > 0", #keyPath(AwfulThread.bookmarked), #keyPath(AwfulThread.bookmarkListPage))
var predicates = [
NSPredicate(format: "%K == YES && %K > 0", #keyPath(AwfulThread.bookmarked), #keyPath(AwfulThread.bookmarkListPage))
]

switch filter {
case .all:
break
case .unreadOnly:
predicates.append(NSPredicate(format: "%K == YES", #keyPath(AwfulThread.anyUnreadPosts)))
case .readOnly:
predicates.append(NSPredicate(format: "%K == NO", #keyPath(AwfulThread.anyUnreadPosts)))
case .starCategory(let category):
predicates.append(NSPredicate(format: "%K == %d", "starCategory", category.rawValue))
case .textSearch(let searchText):
let titlePredicate = NSPredicate(format: "%K CONTAINS[cd] %@", #keyPath(AwfulThread.title), searchText)
let authorPredicate = NSPredicate(format: "%K.%K CONTAINS[cd] %@", #keyPath(AwfulThread.author), #keyPath(User.username), searchText)
let textPredicate = NSCompoundPredicate(orPredicateWithSubpredicates: [titlePredicate, authorPredicate])
predicates.append(textPredicate)
}

fetchRequest.predicate = NSCompoundPredicate(andPredicateWithSubpredicates: predicates)

fetchRequest.sortDescriptors = {
var descriptors = [NSSortDescriptor(key: #keyPath(AwfulThread.bookmarkListPage), ascending: true)]
Expand Down
132 changes: 132 additions & 0 deletions App/Resources/Localizable.xcstrings
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,138 @@
}
}
},
"bookmarks.filter.all" : {
"comment" : "Segmented control label for showing all bookmarks.",
"extractionState" : "manual",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "All"
}
}
}
},
"bookmarks.filter.unread" : {
"comment" : "Segmented control label for showing only unread bookmarks.",
"extractionState" : "manual",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "Unread"
}
}
}
},
"bookmarks.filter.read" : {
"comment" : "Segmented control label for showing only read bookmarks.",
"extractionState" : "manual",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "Read"
}
}
}
},
"bookmarks.filter.button.accessibility-label" : {
"comment" : "Accessibility label for the filter button in the bookmarks navigation bar.",
"extractionState" : "manual",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "Filter bookmarks"
}
}
}
},
"bookmarks.filter.menu.accessibility-label" : {
"comment" : "Accessibility label for the filter menu popover.",
"extractionState" : "manual",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "Filter Menu"
}
}
}
},
"bookmarks.filter.menu.accessibility-hint" : {
"comment" : "Accessibility hint for the filter menu popover.",
"extractionState" : "manual",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "Filter bookmarks by read status or star color"
}
}
}
},
"bookmarks.filter.star.accessibility-label" : {
"comment" : "Accessibility label for a star color filter button. %@ is the color name.",
"extractionState" : "manual",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "Filter by %@ star"
}
}
}
},
"bookmarks.filter.star.accessibility-hint.selected" : {
"comment" : "Accessibility hint for a currently selected star color filter button.",
"extractionState" : "manual",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "Currently selected. Double-tap to deselect."
}
}
}
},
"bookmarks.filter.star.accessibility-hint.unselected" : {
"comment" : "Accessibility hint for an unselected star color filter button.",
"extractionState" : "manual",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "Double-tap to filter by this star color."
}
}
}
},
"bookmarks.search.button.accessibility-label" : {
"comment" : "Accessibility label for the search button in the bookmarks navigation bar.",
"extractionState" : "manual",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "Search bookmarks"
}
}
}
},
"bookmarks.search.placeholder" : {
"comment" : "Placeholder text for the bookmarks search bar.",
"extractionState" : "manual",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "Search by title or author\u2026"
}
}
}
},
"cancel" : {
"comment" : "Title of button that dismisses without taking any action.",
"localizations" : {
Expand Down
Loading
Loading