Download feeds as needed for the Feed Directory.

This commit is contained in:
Brent Simmons 2018-01-24 22:20:22 -08:00
parent cf0d5cdc51
commit 717e60fcf6
3 changed files with 128 additions and 12 deletions

View File

@ -8,6 +8,13 @@
import Foundation
import RSCore
import RSParser
import RSWeb
extension Notification.Name {
public static let FeedListFeedDidBecomeAvailable = Notification.Name(rawValue: "FeedListFeedDidBecomeAvailable")
}
final class FeedListFeed: Hashable, DisplayNameProvider {
@ -15,6 +22,13 @@ final class FeedListFeed: Hashable, DisplayNameProvider {
let url: String
let homePageURL: String
let hashValue: Int
var lastDownloadAttemptDate: Date? = nil
var parsedFeed: ParsedFeed? = nil {
didSet {
postFeedListFeedDidBecomeAvailableNotification()
}
}
var nameForDisplay: String { // DisplayNameProvider
get {
@ -46,8 +60,52 @@ final class FeedListFeed: Hashable, DisplayNameProvider {
self.init(name: name, url: url, homePageURL: homePageURL)
}
func downloadIfNeeded() {
guard let lastDownloadAttemptDate = lastDownloadAttemptDate else {
downloadFeed()
return
}
let cutoffDate = Date().addingTimeInterval(-(30 * 60)) // 30 minutes in the past
if lastDownloadAttemptDate < cutoffDate {
downloadFeed()
}
}
static func ==(lhs: FeedListFeed, rhs: FeedListFeed) -> Bool {
return lhs.hashValue == rhs.hashValue && lhs.url == rhs.url && lhs.name == rhs.name && lhs.homePageURL == rhs.homePageURL
}
}
private extension FeedListFeed {
func postFeedListFeedDidBecomeAvailableNotification() {
NotificationCenter.default.post(name: .FeedListFeedDidBecomeAvailable, object: self, userInfo: nil)
}
func downloadFeed() {
lastDownloadAttemptDate = Date()
guard let feedURL = URL(string: url) else {
return
}
downloadUsingCache(feedURL) { (data, response, error) in
guard let data = data, error == nil else {
return
}
let parserData = ParserData(url: self.url, data: data)
FeedParser.parse(parserData) { (parsedFeed, error) in
if let parsedFeed = parsedFeed, parsedFeed.items.count > 0 {
self.parsedFeed = parsedFeed
}
}
}
}
}

View File

@ -10,8 +10,47 @@ import Cocoa
final class FeedListTimelineViewController: NSViewController {
var selectedFeed: FeedListFeed? = nil {
didSet {
if let selectedFeed = selectedFeed {
selectedFeed.downloadIfNeeded()
}
}
}
override func viewDidLoad() {
view.translatesAutoresizingMaskIntoConstraints = false
NotificationCenter.default.addObserver(self, selector: #selector(sidebarSelectionDidChange(_:)), name: .FeedListSidebarSelectionDidChange, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(feedDidBecomeAvailable(_:)), name: .FeedListFeedDidBecomeAvailable, object: nil)
}
@objc func feedDidBecomeAvailable(_ note: Notification) {
guard let feed = note.object as? FeedListFeed else {
return
}
if feed == selectedFeed {
reloadTimeline()
}
}
@objc func sidebarSelectionDidChange(_ note: Notification) {
guard let feed = note.userInfo?[FeedListUserInfoKey.selectedObject] as? FeedListFeed else {
selectedFeed = nil
return
}
selectedFeed = feed
}
}
private extension FeedListTimelineViewController {
func reloadTimeline() {
//
}
}

View File

@ -10,6 +10,16 @@ import Cocoa
import RSTree
import RSCore
extension Notification.Name {
static let FeedListSidebarSelectionDidChange = Notification.Name(rawValue: "FeedListSidebarSelectionDidChange")
}
struct FeedListUserInfoKey {
static let selectedObject = "selectedObject"
}
final class FeedListViewController: NSViewController {
@IBOutlet var outlineView: NSOutlineView!
@ -82,18 +92,16 @@ extension FeedListViewController: NSOutlineViewDelegate {
func outlineViewSelectionDidChange(_ notification: Notification) {
// // TODO: support multiple selection
//
// let selectedRow = self.outlineView.selectedRow
//
// if selectedRow < 0 || selectedRow == NSNotFound {
// postSidebarSelectionDidChangeNotification(nil)
// return
// }
//
// if let selectedNode = self.outlineView.item(atRow: selectedRow) as? Node {
// postSidebarSelectionDidChangeNotification([selectedNode.representedObject])
// }
let selectedRow = self.outlineView.selectedRow
if selectedRow < 0 || selectedRow == NSNotFound {
postSidebarSelectionDidChangeNotification(nil)
return
}
if let selectedNode = self.outlineView.item(atRow: selectedRow) as? Node {
postSidebarSelectionDidChangeNotification(selectedNode.representedObject)
}
}
private func configure(_ cell: SidebarCell, _ node: Node) {
@ -157,4 +165,15 @@ private extension FeedListViewController {
configure(cell, node)
}
}
func postSidebarSelectionDidChangeNotification(_ selectedObject: Any?) {
var userInfo = [AnyHashable: Any]()
if let selectedObject = selectedObject {
userInfo[FeedListUserInfoKey.selectedObject] = selectedObject
}
NotificationCenter.default.post(name: .FeedListSidebarSelectionDidChange, object: self, userInfo: userInfo)
}
}