NetNewsWire/iOS/Add/AddFeedViewController.swift
2024-05-03 23:04:13 -07:00

207 lines
5.5 KiB
Swift

//
// AddFeedViewController.swift
// NetNewsWire
//
// Created by Maurice Parker on 4/16/19.
// Copyright © 2019 Ranchero Software, LLC. All rights reserved.
//
import UIKit
import Account
import Tree
import Parser
import Core
import CommonErrors
enum AddFeedType {
case web
}
class AddFeedViewController: UITableViewController {
@IBOutlet weak var activityIndicator: UIActivityIndicatorView!
@IBOutlet weak var addButton: UIBarButtonItem!
@IBOutlet weak var urlTextField: UITextField!
@IBOutlet weak var urlTextFieldToSuperViewConstraint: NSLayoutConstraint!
@IBOutlet weak var nameTextField: UITextField!
static let preferredContentSizeForFormSheetDisplay = CGSize(width: 460.0, height: 400.0)
private var folderLabel = ""
private var userCancelled = false
var addFeedType = AddFeedType.web
var initialFeed: String?
var initialFeedName: String?
var container: Container?
override func viewDidLoad() {
super.viewDidLoad()
switch addFeedType {
default:
break
}
activityIndicator.isHidden = true
activityIndicator.color = .label
if initialFeed == nil, let urlString = UIPasteboard.general.string {
if urlString.mayBeURL {
initialFeed = urlString.normalizedURL
}
}
urlTextField.autocorrectionType = .no
urlTextField.autocapitalizationType = .none
urlTextField.text = initialFeed
urlTextField.delegate = self
if initialFeed != nil {
addButton.isEnabled = true
}
nameTextField.text = initialFeedName
nameTextField.delegate = self
if let defaultContainer = AddFeedDefaultContainer.defaultContainer {
container = defaultContainer
} else {
addButton.isEnabled = false
}
updateFolderLabel()
tableView.register(UINib(nibName: "AddFeedSelectFolderTableViewCell", bundle: nil), forCellReuseIdentifier: "AddFeedSelectFolderTableViewCell")
NotificationCenter.default.addObserver(self, selector: #selector(textDidChange(_:)), name: UITextField.textDidChangeNotification, object: urlTextField)
if initialFeed == nil {
urlTextField.becomeFirstResponder()
}
}
@IBAction func cancel(_ sender: Any) {
userCancelled = true
dismiss(animated: true)
}
@IBAction func add(_ sender: Any) {
let urlString = urlTextField.text ?? ""
let normalizedURLString = urlString.normalizedURL
guard !normalizedURLString.isEmpty, let url = URL(unicodeString: normalizedURLString) else {
return
}
guard let container = container else { return }
var account: Account?
if let containerAccount = container as? Account {
account = containerAccount
} else if let containerFolder = container as? Folder, let containerAccount = containerFolder.account {
account = containerAccount
}
if account!.hasFeed(withURL: url.absoluteString) {
presentError(AccountError.createErrorAlreadySubscribed)
return
}
addButton.isEnabled = false
activityIndicator.isHidden = false
activityIndicator.startAnimating()
let feedName = (nameTextField.text?.isEmpty ?? true) ? nil : nameTextField.text
BatchUpdate.shared.start()
Task { @MainActor in
do {
let feed = try await account!.createFeed(url: url.absoluteString, name: feedName, container: container, validateFeed: true)
self.dismiss(animated: true)
NotificationCenter.default.post(name: .UserDidAddFeed, object: self, userInfo: [UserInfoKey.feed: feed])
} catch {
self.addButton.isEnabled = true
self.activityIndicator.isHidden = true
self.activityIndicator.stopAnimating()
self.presentError(error)
}
BatchUpdate.shared.end()
}
}
@objc func textDidChange(_ note: Notification) {
updateUI()
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
if indexPath.row == 2 {
let cell = tableView.dequeueReusableCell(withIdentifier: "AddFeedSelectFolderTableViewCell", for: indexPath) as? AddFeedSelectFolderTableViewCell
cell!.detailLabel.text = folderLabel
return cell!
} else {
return super.tableView(tableView, cellForRowAt: indexPath)
}
}
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
if indexPath.row == 2 {
let navController = UIStoryboard.add.instantiateViewController(withIdentifier: "AddFeedFolderNavViewController") as! UINavigationController
navController.modalPresentationStyle = .currentContext
let folderViewController = navController.topViewController as! AddFeedFolderViewController
folderViewController.delegate = self
folderViewController.addFeedType = addFeedType
folderViewController.initialContainer = container
present(navController, animated: true)
}
}
}
// MARK: AddFeedFolderViewControllerDelegate
extension AddFeedViewController: AddFeedFolderViewControllerDelegate {
func didSelect(container: Container) {
self.container = container
updateFolderLabel()
AddFeedDefaultContainer.saveDefaultContainer(container)
}
}
// MARK: UITextFieldDelegate
extension AddFeedViewController: UITextFieldDelegate {
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
textField.resignFirstResponder()
return true
}
}
// MARK: Private
private extension AddFeedViewController {
func updateUI() {
addButton.isEnabled = (urlTextField.text?.mayBeURL ?? false)
}
func updateFolderLabel() {
if let containerName = (container as? DisplayNameProvider)?.nameForDisplay {
if container is Folder {
folderLabel = "\(container?.account?.nameForDisplay ?? "") / \(containerName)"
} else {
folderLabel = containerName
}
tableView.reloadData()
}
}
}