2019-04-16 20:38:07 +02:00
|
|
|
|
//
|
|
|
|
|
// AddFeedViewController.swift
|
|
|
|
|
// NetNewsWire
|
|
|
|
|
//
|
|
|
|
|
// Created by Maurice Parker on 4/16/19.
|
|
|
|
|
// Copyright © 2019 Ranchero Software, LLC. All rights reserved.
|
|
|
|
|
//
|
2019-04-15 22:03:05 +02:00
|
|
|
|
|
|
|
|
|
import UIKit
|
|
|
|
|
import Account
|
|
|
|
|
import RSCore
|
|
|
|
|
import RSTree
|
|
|
|
|
import RSParser
|
|
|
|
|
|
2019-04-16 23:03:30 +02:00
|
|
|
|
class AddFeedViewController: UITableViewController, AddContainerViewControllerChild {
|
2019-04-15 22:03:05 +02:00
|
|
|
|
|
2019-05-20 00:48:03 +02:00
|
|
|
|
@IBOutlet private weak var urlTextField: UITextField!
|
|
|
|
|
@IBOutlet private weak var nameTextField: UITextField!
|
|
|
|
|
@IBOutlet private weak var folderPickerView: UIPickerView!
|
|
|
|
|
@IBOutlet private weak var folderLabel: UILabel!
|
2019-04-15 22:03:05 +02:00
|
|
|
|
|
2019-05-20 00:48:03 +02:00
|
|
|
|
private lazy var pickerData: AddFeedFolderPickerData = AddFeedFolderPickerData()
|
|
|
|
|
private var shouldDisplayPicker: Bool {
|
|
|
|
|
return pickerData.containerNames.count > 1
|
|
|
|
|
}
|
2019-04-15 22:03:05 +02:00
|
|
|
|
|
|
|
|
|
private var userCancelled = false
|
2019-04-16 23:03:30 +02:00
|
|
|
|
|
2019-04-26 01:06:53 +02:00
|
|
|
|
weak var delegate: AddContainerViewControllerChildDelegate?
|
|
|
|
|
var initialFeed: String?
|
|
|
|
|
var initialFeedName: String?
|
|
|
|
|
|
2019-04-15 22:03:05 +02:00
|
|
|
|
override func viewDidLoad() {
|
|
|
|
|
|
|
|
|
|
super.viewDidLoad()
|
|
|
|
|
|
|
|
|
|
urlTextField.autocorrectionType = .no
|
|
|
|
|
urlTextField.autocapitalizationType = .none
|
2019-04-26 01:06:53 +02:00
|
|
|
|
urlTextField.text = initialFeed
|
2019-05-19 23:17:10 +02:00
|
|
|
|
urlTextField.delegate = self
|
2019-04-26 01:06:53 +02:00
|
|
|
|
|
|
|
|
|
if initialFeed != nil {
|
|
|
|
|
delegate?.readyToAdd(state: true)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
nameTextField.text = initialFeedName
|
2019-05-19 23:17:10 +02:00
|
|
|
|
nameTextField.delegate = self
|
2019-05-20 00:48:03 +02:00
|
|
|
|
folderLabel.text = pickerData.containerNames.first
|
|
|
|
|
|
|
|
|
|
if shouldDisplayPicker {
|
|
|
|
|
folderPickerView.dataSource = self
|
|
|
|
|
folderPickerView.delegate = self
|
|
|
|
|
folderPickerView.showsSelectionIndicator = true
|
|
|
|
|
} else {
|
|
|
|
|
folderPickerView.isHidden = true
|
|
|
|
|
}
|
2019-04-15 22:03:05 +02:00
|
|
|
|
|
2019-04-16 20:38:07 +02:00
|
|
|
|
// I couldn't figure out the gap at the top of the UITableView, so I took a hammer to it.
|
|
|
|
|
tableView.contentInset = UIEdgeInsets(top: -28, left: 0, bottom: 0, right: 0)
|
2019-04-15 22:03:05 +02:00
|
|
|
|
|
2019-04-16 23:03:30 +02:00
|
|
|
|
NotificationCenter.default.addObserver(self, selector: #selector(textDidChange(_:)), name: UITextField.textDidChangeNotification, object: urlTextField)
|
|
|
|
|
|
|
|
|
|
}
|
2019-04-15 22:03:05 +02:00
|
|
|
|
|
2019-04-16 23:03:30 +02:00
|
|
|
|
func cancel() {
|
2019-04-15 22:03:05 +02:00
|
|
|
|
userCancelled = true
|
2019-04-17 15:54:39 +02:00
|
|
|
|
delegate?.processingDidCancel()
|
2019-04-15 22:03:05 +02:00
|
|
|
|
}
|
|
|
|
|
|
2019-04-16 23:03:30 +02:00
|
|
|
|
func add() {
|
2019-04-15 22:03:05 +02:00
|
|
|
|
|
|
|
|
|
let urlString = urlTextField.text ?? ""
|
|
|
|
|
let normalizedURLString = (urlString as NSString).rs_normalizedURL()
|
|
|
|
|
|
|
|
|
|
guard !normalizedURLString.isEmpty, let url = URL(string: normalizedURLString) else {
|
2019-04-17 15:54:39 +02:00
|
|
|
|
delegate?.processingDidCancel()
|
2019-04-15 22:03:05 +02:00
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
let container = pickerData.containers[folderPickerView.selectedRow(inComponent: 0)]
|
|
|
|
|
|
2019-05-09 00:41:19 +02:00
|
|
|
|
var account: Account?
|
|
|
|
|
var folder: Folder?
|
|
|
|
|
if let containerAccount = container as? Account {
|
|
|
|
|
account = containerAccount
|
|
|
|
|
}
|
|
|
|
|
if let containerFolder = container as? Folder, let containerAccount = containerFolder.account {
|
|
|
|
|
account = containerAccount
|
|
|
|
|
folder = containerFolder
|
2019-04-15 22:03:05 +02:00
|
|
|
|
}
|
|
|
|
|
|
2019-05-09 00:41:19 +02:00
|
|
|
|
if account!.hasFeed(withURL: url.absoluteString) {
|
2019-04-15 22:03:05 +02:00
|
|
|
|
showAlreadySubscribedError()
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
2019-05-09 00:41:19 +02:00
|
|
|
|
let title = nameTextField.text
|
|
|
|
|
|
2019-04-16 23:03:30 +02:00
|
|
|
|
delegate?.processingDidBegin()
|
|
|
|
|
|
2019-05-10 00:30:36 +02:00
|
|
|
|
account!.createFeed(url: url.absoluteString) { [weak self] result in
|
2019-05-09 00:41:19 +02:00
|
|
|
|
|
|
|
|
|
switch result {
|
2019-05-10 17:22:28 +02:00
|
|
|
|
case .success(let feed):
|
|
|
|
|
self?.processFeed(feed, account: account!, folder: folder, url: url, title: title)
|
|
|
|
|
case .failure(let error):
|
|
|
|
|
switch error {
|
|
|
|
|
case AccountError.createErrorAlreadySubscribed:
|
2019-05-09 00:41:19 +02:00
|
|
|
|
self?.showAlreadySubscribedError()
|
|
|
|
|
self?.delegate?.processingDidCancel()
|
2019-05-10 17:22:28 +02:00
|
|
|
|
case AccountError.createErrorNotFound:
|
2019-05-09 00:41:19 +02:00
|
|
|
|
self?.showNoFeedsErrorMessage()
|
|
|
|
|
self?.delegate?.processingDidCancel()
|
2019-05-10 17:22:28 +02:00
|
|
|
|
default:
|
|
|
|
|
self?.presentError(error)
|
|
|
|
|
self?.delegate?.processingDidCancel()
|
2019-05-09 00:41:19 +02:00
|
|
|
|
}
|
|
|
|
|
}
|
2019-05-10 17:22:28 +02:00
|
|
|
|
|
2019-05-09 00:41:19 +02:00
|
|
|
|
}
|
2019-04-15 22:03:05 +02:00
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
2019-04-16 23:03:30 +02:00
|
|
|
|
@objc func textDidChange(_ note: Notification) {
|
|
|
|
|
delegate?.readyToAdd(state: urlTextField.text?.rs_stringMayBeURL() ?? false)
|
|
|
|
|
}
|
|
|
|
|
|
2019-05-20 00:48:03 +02:00
|
|
|
|
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
|
|
|
|
|
if section == 1 {
|
|
|
|
|
return shouldDisplayPicker ? 2 : 1
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return super.tableView(tableView, numberOfRowsInSection: section)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2019-04-15 22:03:05 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
extension AddFeedViewController: UIPickerViewDataSource, UIPickerViewDelegate {
|
|
|
|
|
|
|
|
|
|
func numberOfComponents(in pickerView: UIPickerView) ->Int {
|
|
|
|
|
return 1
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
|
|
|
|
|
return pickerData.containerNames.count
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
|
|
|
|
|
return pickerData.containerNames[row]
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
|
|
|
|
|
folderLabel.text = pickerData.containerNames[row]
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private extension AddFeedViewController {
|
|
|
|
|
|
|
|
|
|
private func showAlreadySubscribedError() {
|
|
|
|
|
let title = NSLocalizedString("Already subscribed", comment: "Feed finder")
|
|
|
|
|
let message = NSLocalizedString("Can’t add this feed because you’ve already subscribed to it.", comment: "Feed finder")
|
|
|
|
|
presentError(title: title, message: message)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private func showNoFeedsErrorMessage() {
|
|
|
|
|
let title = NSLocalizedString("Feed not found", comment: "Feed finder")
|
|
|
|
|
let message = NSLocalizedString("Can’t add a feed because no feed was found.", comment: "Feed finder")
|
|
|
|
|
presentError(title: title, message: message)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private func showInitialDownloadError(_ error: Error) {
|
|
|
|
|
let title = NSLocalizedString("Download Error", comment: "Feed finder")
|
|
|
|
|
let formatString = NSLocalizedString("Can’t add this feed because of a download error: “%@”", comment: "Feed finder")
|
|
|
|
|
let message = NSString.localizedStringWithFormat(formatString as NSString, error.localizedDescription)
|
|
|
|
|
presentError(title: title, message: message as String)
|
|
|
|
|
}
|
|
|
|
|
|
2019-05-09 00:41:19 +02:00
|
|
|
|
func processFeed(_ feed: Feed, account: Account, folder: Folder?, url: URL, title: String?) {
|
2019-04-16 23:03:30 +02:00
|
|
|
|
|
2019-05-09 00:41:19 +02:00
|
|
|
|
if let title = title {
|
|
|
|
|
account.renameFeed(feed, to: title) { [weak self] result in
|
|
|
|
|
switch result {
|
|
|
|
|
case .success:
|
|
|
|
|
break
|
|
|
|
|
case .failure(let error):
|
|
|
|
|
self?.presentError(error)
|
|
|
|
|
}
|
|
|
|
|
}
|
2019-04-15 22:03:05 +02:00
|
|
|
|
}
|
|
|
|
|
|
2019-05-10 00:30:36 +02:00
|
|
|
|
if let folder = folder {
|
|
|
|
|
folder.addFeed(feed) { [weak self] result in
|
|
|
|
|
switch result {
|
|
|
|
|
case .success:
|
|
|
|
|
self?.delegate?.processingDidEnd()
|
|
|
|
|
NotificationCenter.default.post(name: .UserDidAddFeed, object: self, userInfo: [UserInfoKey.feed: feed])
|
|
|
|
|
case .failure(let error):
|
|
|
|
|
self?.delegate?.processingDidEnd()
|
|
|
|
|
self?.presentError(error)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
account.addFeed(feed) { [weak self] result in
|
|
|
|
|
switch result {
|
|
|
|
|
case .success:
|
|
|
|
|
self?.delegate?.processingDidEnd()
|
|
|
|
|
NotificationCenter.default.post(name: .UserDidAddFeed, object: self, userInfo: [UserInfoKey.feed: feed])
|
|
|
|
|
case .failure(let error):
|
|
|
|
|
self?.delegate?.processingDidEnd()
|
|
|
|
|
self?.presentError(error)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2019-05-09 00:41:19 +02:00
|
|
|
|
|
2019-04-15 22:03:05 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
2019-05-19 23:17:10 +02:00
|
|
|
|
|
|
|
|
|
extension AddFeedViewController: UITextFieldDelegate {
|
|
|
|
|
|
|
|
|
|
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
|
|
|
|
|
textField.resignFirstResponder()
|
|
|
|
|
return true
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|