Remove extension points.

This commit is contained in:
Brent Simmons
2024-02-22 21:47:00 -08:00
parent 071d029818
commit 2640132f36
10 changed files with 162 additions and 786 deletions

View File

@@ -15,7 +15,7 @@ import SwiftUI
class SettingsViewController: UITableViewController {
private weak var opmlAccount: Account?
@IBOutlet weak var timelineSortOrderSwitch: UISwitch!
@IBOutlet weak var groupByFeedSwitch: UISwitch!
@IBOutlet weak var refreshClearsReadArticlesSwitch: UISwitch!
@@ -24,10 +24,10 @@ class SettingsViewController: UITableViewController {
@IBOutlet weak var showFullscreenArticlesSwitch: UISwitch!
@IBOutlet weak var colorPaletteDetailLabel: UILabel!
@IBOutlet weak var openLinksInNetNewsWire: UISwitch!
var scrollToArticlesSection = false
weak var presentingParentController: UIViewController?
override func viewDidLoad() {
// This hack mostly works around a bug in static tables with dynamic type. See: https://spin.atomicobject.com/2018/10/15/dynamic-type-static-uitableview/
NotificationCenter.default.removeObserver(tableView!, name: UIContentSizeCategory.didChangeNotification, object: nil)
@@ -36,19 +36,17 @@ class SettingsViewController: UITableViewController {
NotificationCenter.default.addObserver(self, selector: #selector(accountsDidChange), name: .UserDidAddAccount, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(accountsDidChange), name: .UserDidDeleteAccount, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(displayNameDidChange), name: .DisplayNameDidChange, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(activeExtensionPointsDidChange), name: .ActiveExtensionPointsDidChange, object: nil)
tableView.register(UINib(nibName: "SettingsComboTableViewCell", bundle: nil), forCellReuseIdentifier: "SettingsComboTableViewCell")
tableView.register(UINib(nibName: "SettingsTableViewCell", bundle: nil), forCellReuseIdentifier: "SettingsTableViewCell")
tableView.rowHeight = UITableView.automaticDimension
tableView.estimatedRowHeight = 44
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
if AppDefaults.shared.timelineSortDirection == .orderedAscending {
timelineSortOrderSwitch.isOn = true
} else {
@@ -67,7 +65,7 @@ class SettingsViewController: UITableViewController {
refreshClearsReadArticlesSwitch.isOn = false
}
articleThemeDetailLabel.text = ArticleThemesManager.shared.currentTheme.name
if AppDefaults.shared.confirmMarkAllAsRead {
@@ -81,11 +79,11 @@ class SettingsViewController: UITableViewController {
} else {
showFullscreenArticlesSwitch.isOn = false
}
colorPaletteDetailLabel.text = String(describing: AppDefaults.userInterfaceColorPalette)
openLinksInNetNewsWire.isOn = !AppDefaults.shared.useSystemBrowser
let buildLabel = NonIntrinsicLabel(frame: CGRect(x: 32.0, y: 0.0, width: 0.0, height: 0.0))
buildLabel.font = UIFont.systemFont(ofSize: 11.0)
@@ -93,53 +91,51 @@ class SettingsViewController: UITableViewController {
buildLabel.text = "\(Bundle.main.appName) \(Bundle.main.versionNumber) (Build \(Bundle.main.buildNumber))"
buildLabel.sizeToFit()
buildLabel.translatesAutoresizingMaskIntoConstraints = false
let wrapperView = UIView(frame: CGRect(x: 0, y: 0, width: buildLabel.frame.width, height: buildLabel.frame.height + 10.0))
wrapperView.translatesAutoresizingMaskIntoConstraints = false
wrapperView.addSubview(buildLabel)
tableView.tableFooterView = wrapperView
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
self.tableView.selectRow(at: nil, animated: true, scrollPosition: .none)
if scrollToArticlesSection {
tableView.scrollToRow(at: IndexPath(row: 0, section: 4), at: .top, animated: true)
scrollToArticlesSection = false
}
}
// MARK: UITableView
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
switch section {
case 1:
return AccountManager.shared.accounts.count + 1
case 2:
return ExtensionPointManager.shared.activeExtensionPoints.count + 1
case 3:
let defaultNumberOfRows = super.tableView(tableView, numberOfRowsInSection: section)
if AccountManager.shared.activeAccounts.isEmpty || AccountManager.shared.anyAccountHasNetNewsWireNewsSubscription() {
return defaultNumberOfRows - 1
}
return defaultNumberOfRows
case 5:
case 4:
return traitCollection.userInterfaceIdiom == .phone ? 4 : 3
default:
return super.tableView(tableView, numberOfRowsInSection: section)
}
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell: UITableViewCell
switch indexPath.section {
case 1:
let sortedAccounts = AccountManager.shared.sortedAccounts
if indexPath.row == sortedAccounts.count {
cell = tableView.dequeueReusableCell(withIdentifier: "SettingsTableViewCell", for: indexPath)
@@ -152,26 +148,11 @@ class SettingsViewController: UITableViewController {
acctCell.comboNameLabel?.text = account.nameForDisplay
cell = acctCell
}
case 2:
let extensionPoints = Array(ExtensionPointManager.shared.activeExtensionPoints.values)
if indexPath.row == extensionPoints.count {
cell = tableView.dequeueReusableCell(withIdentifier: "SettingsTableViewCell", for: indexPath)
cell.textLabel?.text = NSLocalizedString("Add Extension", comment: "Extensions")
} else {
let acctCell = tableView.dequeueReusableCell(withIdentifier: "SettingsComboTableViewCell", for: indexPath) as! SettingsComboTableViewCell
acctCell.applyThemeProperties()
let extensionPoint = extensionPoints[indexPath.row]
acctCell.comboImage?.image = extensionPoint.image
acctCell.comboNameLabel?.text = extensionPoint.title
cell = acctCell
}
default:
cell = super.tableView(tableView, cellForRowAt: indexPath)
}
return cell
}
@@ -192,16 +173,6 @@ class SettingsViewController: UITableViewController {
self.navigationController?.pushViewController(controller, animated: true)
}
case 2:
let extensionPoints = Array(ExtensionPointManager.shared.activeExtensionPoints.values)
if indexPath.row == extensionPoints.count {
let controller = UIStoryboard.settings.instantiateController(ofType: AddExtensionPointViewController.self)
self.navigationController?.pushViewController(controller, animated: true)
} else {
let controller = UIStoryboard.inspector.instantiateController(ofType: ExtensionPointInspectorViewController.self)
controller.extensionPoint = extensionPoints[indexPath.row]
self.navigationController?.pushViewController(controller, animated: true)
}
case 3:
switch indexPath.row {
case 0:
tableView.selectRow(at: nil, animated: true, scrollPosition: .none)
@@ -221,7 +192,7 @@ class SettingsViewController: UITableViewController {
default:
break
}
case 4:
case 3:
switch indexPath.row {
case 3:
let timeline = UIStoryboard.settings.instantiateController(ofType: TimelineCustomizerViewController.self)
@@ -229,7 +200,7 @@ class SettingsViewController: UITableViewController {
default:
break
}
case 5:
case 4:
switch indexPath.row {
case 0:
let articleThemes = UIStoryboard.settings.instantiateController(ofType: ArticleThemesTableViewController.self)
@@ -237,13 +208,13 @@ class SettingsViewController: UITableViewController {
default:
break
}
case 6:
case 5:
let colorPalette = UIStoryboard.settings.instantiateController(ofType: ColorPaletteTableViewController.self)
self.navigationController?.pushViewController(colorPalette, animated: true)
case 7:
case 6:
switch indexPath.row {
case 0:
openURL("https://netnewswire.com/help/ios/6.0/en/")
openURL("https://netnewswire.com/help/ios/6.1/en/")
tableView.selectRow(at: nil, animated: true, scrollPosition: .none)
case 1:
openURL("https://netnewswire.com/")
@@ -276,11 +247,11 @@ class SettingsViewController: UITableViewController {
tableView.selectRow(at: nil, animated: true, scrollPosition: .none)
}
}
override func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
return false
}
override func tableView(_ tableView: UITableView, canMoveRowAt indexPath: IndexPath) -> Bool {
return false
}
@@ -288,21 +259,21 @@ class SettingsViewController: UITableViewController {
override func tableView(_ tableView: UITableView, editingStyleForRowAt indexPath: IndexPath) -> UITableViewCell.EditingStyle {
return .none
}
override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return UITableView.automaticDimension
}
override func tableView(_ tableView: UITableView, indentationLevelForRowAt indexPath: IndexPath) -> Int {
return super.tableView(tableView, indentationLevelForRowAt: IndexPath(row: 0, section: 1))
}
// MARK: Actions
@IBAction func done(_ sender: Any) {
dismiss(animated: true)
}
@IBAction func switchTimelineOrder(_ sender: Any) {
if timelineSortOrderSwitch.isOn {
AppDefaults.shared.timelineSortDirection = .orderedAscending
@@ -310,7 +281,7 @@ class SettingsViewController: UITableViewController {
AppDefaults.shared.timelineSortDirection = .orderedDescending
}
}
@IBAction func switchGroupByFeed(_ sender: Any) {
if groupByFeedSwitch.isOn {
AppDefaults.shared.timelineGroupByFeed = true
@@ -318,7 +289,7 @@ class SettingsViewController: UITableViewController {
AppDefaults.shared.timelineGroupByFeed = false
}
}
@IBAction func switchClearsReadArticles(_ sender: Any) {
if refreshClearsReadArticlesSwitch.isOn {
AppDefaults.shared.refreshClearsReadArticles = true
@@ -326,7 +297,7 @@ class SettingsViewController: UITableViewController {
AppDefaults.shared.refreshClearsReadArticles = false
}
}
@IBAction func switchConfirmMarkAllAsRead(_ sender: Any) {
if confirmMarkAllAsReadSwitch.isOn {
AppDefaults.shared.confirmMarkAllAsRead = true
@@ -334,7 +305,7 @@ class SettingsViewController: UITableViewController {
AppDefaults.shared.confirmMarkAllAsRead = false
}
}
@IBAction func switchFullscreenArticles(_ sender: Any) {
if showFullscreenArticlesSwitch.isOn {
AppDefaults.shared.articleFullscreenAvailable = true
@@ -342,7 +313,7 @@ class SettingsViewController: UITableViewController {
AppDefaults.shared.articleFullscreenAvailable = false
}
}
@IBAction func switchBrowserPreference(_ sender: Any) {
if openLinksInNetNewsWire.isOn {
AppDefaults.shared.useSystemBrowser = false
@@ -350,14 +321,14 @@ class SettingsViewController: UITableViewController {
AppDefaults.shared.useSystemBrowser = true
}
}
// MARK: Notifications
@objc func contentSizeCategoryDidChange() {
tableView.reloadData()
}
@objc func accountsDidChange() {
tableView.reloadData()
}
@@ -365,21 +336,17 @@ class SettingsViewController: UITableViewController {
@objc func displayNameDidChange() {
tableView.reloadData()
}
@objc func activeExtensionPointsDidChange() {
tableView.reloadData()
}
@objc func browserPreferenceDidChange() {
tableView.reloadData()
}
}
// MARK: OPML Document Picker
extension SettingsViewController: UIDocumentPickerDelegate {
func documentPicker(_ controller: UIDocumentPickerViewController, didPickDocumentsAt urls: [URL]) {
for url in urls {
opmlAccount?.importOPML(url) { result in
@@ -394,13 +361,13 @@ extension SettingsViewController: UIDocumentPickerDelegate {
}
}
}
}
// MARK: Private
private extension SettingsViewController {
func addFeed() {
self.dismiss(animated: true)
@@ -410,10 +377,10 @@ private extension SettingsViewController {
addViewController.initialFeedName = NSLocalizedString("NetNewsWire News", comment: "NetNewsWire News")
addNavViewController.modalPresentationStyle = .formSheet
addNavViewController.preferredContentSize = AddFeedViewController.preferredContentSizeForFormSheetDisplay
presentingParentController?.present(addNavViewController, animated: true)
}
func importOPML(sourceView: UIView, sourceRect: CGRect) {
switch AccountManager.shared.activeAccounts.count {
case 0:
@@ -425,11 +392,11 @@ private extension SettingsViewController {
importOPMLAccountPicker(sourceView: sourceView, sourceRect: sourceRect)
}
}
func importOPMLAccountPicker(sourceView: UIView, sourceRect: CGRect) {
let title = NSLocalizedString("Choose an account to receive the imported feeds and folders", comment: "Import Account")
let alert = UIAlertController(title: title, message: nil, preferredStyle: .actionSheet)
if let popoverController = alert.popoverPresentationController {
popoverController.sourceView = view
popoverController.sourceRect = sourceRect
@@ -448,9 +415,9 @@ private extension SettingsViewController {
self.present(alert, animated: true)
}
func importOPMLDocumentPicker() {
let utiArray = UTTypeCreateAllIdentifiersForTag(kUTTagClassFilenameExtension, "opml" as NSString, nil)?.takeRetainedValue() as? [String] ?? [String]()
var opmlUTIs = utiArray
@@ -459,13 +426,13 @@ private extension SettingsViewController {
return result + dict.values.compactMap({ $0 as? String })
}
opmlUTIs.append("public.xml")
let docPicker = UIDocumentPickerViewController(documentTypes: opmlUTIs, in: .import)
docPicker.delegate = self
docPicker.modalPresentationStyle = .formSheet
self.present(docPicker, animated: true)
}
func exportOPML(sourceView: UIView, sourceRect: CGRect) {
if AccountManager.shared.accounts.count == 1 {
opmlAccount = AccountManager.shared.accounts.first!
@@ -474,11 +441,11 @@ private extension SettingsViewController {
exportOPMLAccountPicker(sourceView: sourceView, sourceRect: sourceRect)
}
}
func exportOPMLAccountPicker(sourceView: UIView, sourceRect: CGRect) {
let title = NSLocalizedString("Choose an account with the subscriptions to export", comment: "Export Account")
let alert = UIAlertController(title: title, message: nil, preferredStyle: .actionSheet)
if let popoverController = alert.popoverPresentationController {
popoverController.sourceView = view
popoverController.sourceRect = sourceRect
@@ -497,10 +464,10 @@ private extension SettingsViewController {
self.present(alert, animated: true)
}
func exportOPMLDocumentPicker() {
guard let account = opmlAccount else { return }
let accountName = account.nameForDisplay.replacingOccurrences(of: " ", with: "").trimmingCharacters(in: .whitespaces)
let filename = "Subscriptions-\(accountName).opml"
let tempFile = FileManager.default.temporaryDirectory.appendingPathComponent(filename)
@@ -510,16 +477,17 @@ private extension SettingsViewController {
} catch {
self.presentError(title: "OPML Export Error", message: error.localizedDescription)
}
let docPicker = UIDocumentPickerViewController(url: tempFile, in: .exportToService)
docPicker.modalPresentationStyle = .formSheet
self.present(docPicker, animated: true)
}
func openURL(_ urlString: String) {
let vc = SFSafariViewController(url: URL(string: urlString)!)
vc.modalPresentationStyle = .pageSheet
present(vc, animated: true)
}
}