216 lines
5.9 KiB
Swift
216 lines
5.9 KiB
Swift
//
|
||
// AddFeedController.swift
|
||
// NetNewsWire
|
||
//
|
||
// Created by Brent Simmons on 8/28/16.
|
||
// Copyright © 2016 Ranchero Software, LLC. All rights reserved.
|
||
//
|
||
|
||
import AppKit
|
||
import RSCore
|
||
import RSTree
|
||
import Articles
|
||
import Account
|
||
import RSParser
|
||
|
||
// Run add-feed sheet.
|
||
// If it returns with URL and optional name,
|
||
// run FeedFinder plus modal progress window.
|
||
// If FeedFinder returns feed,
|
||
// add feed.
|
||
// Else,
|
||
// display error sheet.
|
||
|
||
class AddFeedController: AddFeedWindowControllerDelegate {
|
||
|
||
private let hostWindow: NSWindow
|
||
private var addFeedWindowController: AddFeedWindowController?
|
||
private var foundFeedURLString: String?
|
||
private var titleFromFeed: String?
|
||
|
||
init(hostWindow: NSWindow) {
|
||
|
||
self.hostWindow = hostWindow
|
||
}
|
||
|
||
func showAddFeedSheet(_ urlString: String?, _ name: String?, _ account: Account?, _ folder: Folder?) {
|
||
|
||
let folderTreeControllerDelegate = FolderTreeControllerDelegate()
|
||
let folderTreeController = TreeController(delegate: folderTreeControllerDelegate)
|
||
|
||
addFeedWindowController = AddFeedWindowController(urlString: urlString ?? urlStringFromPasteboard, name: name, account: account, folder: folder, folderTreeController: folderTreeController, delegate: self)
|
||
addFeedWindowController!.runSheetOnWindow(hostWindow)
|
||
}
|
||
|
||
// MARK: AddFeedWindowControllerDelegate
|
||
|
||
func addFeedWindowController(_: AddFeedWindowController, userEnteredURL url: URL, userEnteredTitle title: String?, container: Container) {
|
||
|
||
closeAddFeedSheet(NSApplication.ModalResponse.OK)
|
||
|
||
guard let accountAndFolderSpecifier = accountAndFolderFromContainer(container) else {
|
||
return
|
||
}
|
||
let account = accountAndFolderSpecifier.account
|
||
let folder = accountAndFolderSpecifier.folder
|
||
|
||
if account.hasFeed(withURL: url.absoluteString) {
|
||
showAlreadySubscribedError(url.absoluteString)
|
||
return
|
||
}
|
||
|
||
BatchUpdate.shared.start()
|
||
|
||
account.createFeed(url: url.absoluteString) { [weak self] result in
|
||
|
||
self?.endShowingProgress()
|
||
|
||
switch result {
|
||
case .success(let feed):
|
||
self?.processFeed(feed, account: account, folder: folder, url: url, title: title)
|
||
case .failure(let error):
|
||
BatchUpdate.shared.end()
|
||
switch error {
|
||
case AccountError.createErrorAlreadySubscribed:
|
||
self?.showAlreadySubscribedError(url.absoluteString)
|
||
case AccountError.createErrorNotFound:
|
||
self?.showNoFeedsErrorMessage()
|
||
default:
|
||
NSApplication.shared.presentError(error)
|
||
}
|
||
}
|
||
|
||
}
|
||
|
||
beginShowingProgress()
|
||
|
||
}
|
||
|
||
func addFeedWindowControllerUserDidCancel(_: AddFeedWindowController) {
|
||
|
||
closeAddFeedSheet(NSApplication.ModalResponse.cancel)
|
||
}
|
||
|
||
}
|
||
|
||
private extension AddFeedController {
|
||
|
||
var urlStringFromPasteboard: String? {
|
||
if let urlString = NSPasteboard.rs_urlString(from: NSPasteboard.general) {
|
||
return urlString.rs_normalizedURL()
|
||
}
|
||
return nil
|
||
}
|
||
|
||
struct AccountAndFolderSpecifier {
|
||
let account: Account
|
||
let folder: Folder?
|
||
}
|
||
|
||
func accountAndFolderFromContainer(_ container: Container) -> AccountAndFolderSpecifier? {
|
||
|
||
if let account = container as? Account {
|
||
return AccountAndFolderSpecifier(account: account, folder: nil)
|
||
}
|
||
if let folder = container as? Folder, let account = folder.account {
|
||
return AccountAndFolderSpecifier(account: account, folder: folder)
|
||
}
|
||
return nil
|
||
}
|
||
|
||
func closeAddFeedSheet(_ returnCode: NSApplication.ModalResponse) {
|
||
|
||
if let sheetWindow = addFeedWindowController?.window {
|
||
hostWindow.endSheet(sheetWindow, returnCode: returnCode)
|
||
}
|
||
}
|
||
|
||
func processFeed(_ feed: Feed, account: Account, folder: Folder?, url: URL, title: String?) {
|
||
|
||
if let title = title {
|
||
account.renameFeed(feed, to: title) { result in
|
||
switch result {
|
||
case .success:
|
||
break
|
||
case .failure(let error):
|
||
NSApplication.shared.presentError(error)
|
||
}
|
||
}
|
||
}
|
||
|
||
if let folder = folder {
|
||
folder.addFeed(feed) { result in
|
||
switch result {
|
||
case .success:
|
||
BatchUpdate.shared.end()
|
||
NotificationCenter.default.post(name: .UserDidAddFeed, object: self, userInfo: [UserInfoKey.feed: feed])
|
||
case .failure(let error):
|
||
BatchUpdate.shared.end()
|
||
NSApplication.shared.presentError(error)
|
||
}
|
||
}
|
||
} else {
|
||
account.addFeed(feed) { result in
|
||
switch result {
|
||
case .success:
|
||
BatchUpdate.shared.end()
|
||
NotificationCenter.default.post(name: .UserDidAddFeed, object: self, userInfo: [UserInfoKey.feed: feed])
|
||
case .failure(let error):
|
||
BatchUpdate.shared.end()
|
||
NSApplication.shared.presentError(error)
|
||
}
|
||
}
|
||
}
|
||
|
||
}
|
||
|
||
// MARK: Errors
|
||
|
||
func showAlreadySubscribedError(_ urlString: String) {
|
||
|
||
let alert = NSAlert()
|
||
alert.alertStyle = .informational
|
||
alert.messageText = NSLocalizedString("Already subscribed", comment: "Feed finder")
|
||
alert.informativeText = NSLocalizedString("Can’t add this feed because you’ve already subscribed to it.", comment: "Feed finder")
|
||
|
||
alert.beginSheetModal(for: hostWindow)
|
||
}
|
||
|
||
func showInitialDownloadError(_ error: Error) {
|
||
|
||
let alert = NSAlert()
|
||
alert.alertStyle = .informational
|
||
alert.messageText = NSLocalizedString("Download Error", comment: "Feed finder")
|
||
|
||
let formatString = NSLocalizedString("Can’t add this feed because of a download error: “%@”", comment: "Feed finder")
|
||
let errorText = NSString.localizedStringWithFormat(formatString as NSString, error.localizedDescription)
|
||
alert.informativeText = errorText as String
|
||
|
||
alert.beginSheetModal(for: hostWindow)
|
||
}
|
||
|
||
func showNoFeedsErrorMessage() {
|
||
|
||
let alert = NSAlert()
|
||
alert.alertStyle = .informational
|
||
alert.messageText = NSLocalizedString("Feed not found", comment: "Feed finder")
|
||
alert.informativeText = NSLocalizedString("Can’t add a feed because no feed was found.", comment: "Feed finder")
|
||
|
||
alert.beginSheetModal(for: hostWindow)
|
||
}
|
||
|
||
// MARK: Progress
|
||
|
||
func beginShowingProgress() {
|
||
|
||
runIndeterminateProgressWithMessage(NSLocalizedString("Finding feed…", comment:"Feed finder"))
|
||
}
|
||
|
||
func endShowingProgress() {
|
||
|
||
stopIndeterminateProgress()
|
||
hostWindow.makeKeyAndOrderFront(self)
|
||
}
|
||
}
|
||
|