diff --git a/Frameworks/Account/Account.swift b/Frameworks/Account/Account.swift
index f5bc4f199..ed6365030 100644
--- a/Frameworks/Account/Account.swift
+++ b/Frameworks/Account/Account.swift
@@ -67,6 +67,21 @@ public final class Account: DisplayNameProvider, UnreadCountProvider, Container,
public static let feeds = "feeds" // AccountDidDownloadArticles, StatusesDidChange
}
+ public static let defaultLocalAccountName: String = {
+ let defaultName: String
+ #if os(macOS)
+ defaultName = NSLocalizedString("On My Mac", comment: "Account name")
+ #else
+ if UIDevice.current.userInterfaceIdiom == .pad {
+ defaultName = NSLocalizedString("On My iPad", comment: "Account name")
+ } else {
+ defaultName = NSLocalizedString("On My iPhone", comment: "Account name")
+ }
+ #endif
+
+ return defaultName
+ }()
+
public let accountID: String
public let type: AccountType
public var nameForDisplay: String {
@@ -220,15 +235,7 @@ public final class Account: DisplayNameProvider, UnreadCountProvider, Container,
switch type {
case .onMyMac:
- #if os(macOS)
- defaultName = NSLocalizedString("On My Mac", comment: "Account name")
- #else
- if UIDevice.current.userInterfaceIdiom == .pad {
- defaultName = NSLocalizedString("On My iPad", comment: "Account name")
- } else {
- defaultName = NSLocalizedString("On My iPhone", comment: "Account name")
- }
- #endif
+ defaultName = Account.defaultLocalAccountName
case .feedly:
defaultName = "Feedly"
case .feedbin:
diff --git a/Mac/Preferences/Accounts/AccountsAddLocal.xib b/Mac/Preferences/Accounts/AccountsAddLocal.xib
index ea2ffd4b8..c035af932 100644
--- a/Mac/Preferences/Accounts/AccountsAddLocal.xib
+++ b/Mac/Preferences/Accounts/AccountsAddLocal.xib
@@ -7,6 +7,7 @@
+
@@ -17,13 +18,13 @@
-
+
-
+
@@ -34,7 +35,7 @@
-
+
diff --git a/Mac/Preferences/Accounts/AccountsAddLocalWindowController.swift b/Mac/Preferences/Accounts/AccountsAddLocalWindowController.swift
index f89ee0e4a..753fc4e75 100644
--- a/Mac/Preferences/Accounts/AccountsAddLocalWindowController.swift
+++ b/Mac/Preferences/Accounts/AccountsAddLocalWindowController.swift
@@ -11,14 +11,21 @@ import Account
class AccountsAddLocalWindowController: NSWindowController {
- @IBOutlet weak var nameTextField: NSTextField!
-
+ @IBOutlet private weak var nameTextField: NSTextField!
+ @IBOutlet private weak var localAccountNameTextField: NSTextField!
+
private weak var hostWindow: NSWindow?
convenience init() {
self.init(windowNibName: NSNib.Name("AccountsAddLocal"))
}
+ override func windowDidLoad() {
+ super.windowDidLoad()
+
+ localAccountNameTextField.stringValue = Account.defaultLocalAccountName
+ }
+
// MARK: API
func runSheetOnWindow(_ hostWindow: NSWindow) {
diff --git a/Mac/Preferences/Accounts/AccountsAddViewController.swift b/Mac/Preferences/Accounts/AccountsAddViewController.swift
index 92c9d6ddf..a77a4bdd3 100644
--- a/Mac/Preferences/Accounts/AccountsAddViewController.swift
+++ b/Mac/Preferences/Accounts/AccountsAddViewController.swift
@@ -7,6 +7,7 @@
//
import AppKit
+import Account
class AccountsAddViewController: NSViewController {
@@ -57,7 +58,7 @@ extension AccountsAddViewController: NSTableViewDelegate {
if let cell = tableView.makeView(withIdentifier: NSUserInterfaceItemIdentifier(rawValue: "Cell"), owner: nil) as? AccountsAddTableCellView {
switch row {
case 0:
- cell.accountNameLabel?.stringValue = NSLocalizedString("On My Mac", comment: "Local")
+ cell.accountNameLabel?.stringValue = Account.defaultLocalAccountName
cell.accountImageView?.image = AppImages.accountLocal
case 1:
cell.accountNameLabel?.stringValue = NSLocalizedString("Feedbin", comment: "Feedbin")
diff --git a/iOS/Add/Add.storyboard b/iOS/Add/Add.storyboard
index 95c8fb579..12745974f 100644
--- a/iOS/Add/Add.storyboard
+++ b/iOS/Add/Add.storyboard
@@ -14,7 +14,7 @@
-
+
@@ -28,10 +28,10 @@
-
+
-
+
@@ -50,10 +50,10 @@
-
+
-
+
@@ -76,39 +76,38 @@
-
-
-
-
-
-
-
-
+
+
+
+
+
+
-
-
+
+
-
+
-
+
@@ -242,7 +241,7 @@
-
+
@@ -256,10 +255,10 @@
-
+
-
+
@@ -282,38 +281,38 @@
-
+
-
+
-
-
-
+
+
+
-
-
+
+
-
+
-
-
+
+
-
+
-
+
diff --git a/iOS/Add/AddContainerViewController.swift b/iOS/Add/AddContainerViewController.swift
index 28ed46514..16d92719c 100644
--- a/iOS/Add/AddContainerViewController.swift
+++ b/iOS/Add/AddContainerViewController.swift
@@ -23,6 +23,8 @@ protocol AddContainerViewControllerChildDelegate: UIViewController {
class AddContainerViewController: UIViewController {
+ static let preferredContentSizeForFormSheetDisplay = CGSize(width: 460.0, height: 400.0)
+
@IBOutlet weak var cancelButton: UIBarButtonItem!
@IBOutlet weak var activityIndicatorView: UIActivityIndicatorView!
@IBOutlet weak var addButton: UIBarButtonItem!
diff --git a/iOS/Add/AddFeedViewController.swift b/iOS/Add/AddFeedViewController.swift
index 13dc65c26..b2b84cee0 100644
--- a/iOS/Add/AddFeedViewController.swift
+++ b/iOS/Add/AddFeedViewController.swift
@@ -14,12 +14,15 @@ import RSParser
class AddFeedViewController: UITableViewController, AddContainerViewControllerChild {
- @IBOutlet weak var urlTextField: UITextField!
- @IBOutlet weak var nameTextField: UITextField!
- @IBOutlet weak var folderPickerView: UIPickerView!
- @IBOutlet weak var folderLabel: UILabel!
+ @IBOutlet private weak var urlTextField: UITextField!
+ @IBOutlet private weak var nameTextField: UITextField!
+ @IBOutlet private weak var folderPickerView: UIPickerView!
+ @IBOutlet private weak var folderLabel: UILabel!
- private var pickerData: AddFeedFolderPickerData!
+ private lazy var pickerData: AddFeedFolderPickerData = AddFeedFolderPickerData()
+ private var shouldDisplayPicker: Bool {
+ return pickerData.containerNames.count > 1
+ }
private var userCancelled = false
@@ -34,19 +37,24 @@ class AddFeedViewController: UITableViewController, AddContainerViewControllerCh
urlTextField.autocorrectionType = .no
urlTextField.autocapitalizationType = .none
urlTextField.text = initialFeed
+ urlTextField.delegate = self
if initialFeed != nil {
delegate?.readyToAdd(state: true)
}
nameTextField.text = initialFeedName
+ nameTextField.delegate = self
+ folderLabel.text = pickerData.containerNames.first
+
+ if shouldDisplayPicker {
+ folderPickerView.dataSource = self
+ folderPickerView.delegate = self
+ folderPickerView.showsSelectionIndicator = true
+ } else {
+ folderPickerView.isHidden = true
+ }
- pickerData = AddFeedFolderPickerData()
- folderPickerView.dataSource = self
- folderPickerView.delegate = self
- folderPickerView.showsSelectionIndicator = true
- folderLabel.text = pickerData.containerNames[0]
-
// 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)
@@ -117,6 +125,16 @@ class AddFeedViewController: UITableViewController, AddContainerViewControllerCh
delegate?.readyToAdd(state: urlTextField.text?.rs_stringMayBeURL() ?? false)
}
+ override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
+ let defaultNumberOfRows = super.tableView(tableView, numberOfRowsInSection: section)
+ if section == 1 && !shouldDisplayPicker {
+ return defaultNumberOfRows - 1
+ }
+
+ return defaultNumberOfRows
+ }
+
+
}
extension AddFeedViewController: UIPickerViewDataSource, UIPickerViewDelegate {
@@ -200,3 +218,12 @@ private extension AddFeedViewController {
}
}
+
+extension AddFeedViewController: UITextFieldDelegate {
+
+ func textFieldShouldReturn(_ textField: UITextField) -> Bool {
+ textField.resignFirstResponder()
+ return true
+ }
+
+}
diff --git a/iOS/Add/AddFolderViewController.swift b/iOS/Add/AddFolderViewController.swift
index 7bca799e3..3e7849937 100644
--- a/iOS/Add/AddFolderViewController.swift
+++ b/iOS/Add/AddFolderViewController.swift
@@ -12,9 +12,13 @@ import RSCore
class AddFolderViewController: UITableViewController, AddContainerViewControllerChild {
- @IBOutlet weak var nameTextField: UITextField!
- @IBOutlet weak var accountLabel: UILabel!
- @IBOutlet weak var accountPickerView: UIPickerView!
+ @IBOutlet private weak var nameTextField: UITextField!
+ @IBOutlet private weak var accountLabel: UILabel!
+ @IBOutlet private weak var accountPickerView: UIPickerView!
+
+ private var shouldDisplayPicker: Bool {
+ return accounts.count > 1
+ }
private var accounts: [Account]!
@@ -25,10 +29,16 @@ class AddFolderViewController: UITableViewController, AddContainerViewController
super.viewDidLoad()
accounts = AccountManager.shared.sortedActiveAccounts
+
+ nameTextField.delegate = self
accountLabel.text = (accounts[0] as DisplayNameProvider).nameForDisplay
- accountPickerView.dataSource = self
- accountPickerView.delegate = self
+ if shouldDisplayPicker {
+ accountPickerView.dataSource = self
+ accountPickerView.delegate = self
+ } else {
+ accountPickerView.isHidden = true
+ }
// 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)
@@ -53,6 +63,14 @@ class AddFolderViewController: UITableViewController, AddContainerViewController
delegate?.readyToAdd(state: !(nameTextField.text?.isEmpty ?? false))
}
+ override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
+ let defaultNumberOfRows = super.tableView(tableView, numberOfRowsInSection: section)
+ if section == 1 && !shouldDisplayPicker {
+ return defaultNumberOfRows - 1
+ }
+
+ return defaultNumberOfRows
+ }
}
extension AddFolderViewController: UIPickerViewDataSource, UIPickerViewDelegate {
@@ -74,3 +92,12 @@ extension AddFolderViewController: UIPickerViewDataSource, UIPickerViewDelegate
}
}
+
+extension AddFolderViewController: UITextFieldDelegate {
+
+ func textFieldShouldReturn(_ textField: UITextField) -> Bool {
+ textField.resignFirstResponder()
+ return true
+ }
+
+}
diff --git a/iOS/Base.lproj/Main.storyboard b/iOS/Base.lproj/Main.storyboard
index a72b987e5..3911beb62 100644
--- a/iOS/Base.lproj/Main.storyboard
+++ b/iOS/Base.lproj/Main.storyboard
@@ -259,6 +259,7 @@
+
diff --git a/iOS/MasterFeed/MasterFeedViewController.swift b/iOS/MasterFeed/MasterFeedViewController.swift
index 3a2e69d3a..cfb6fb1c2 100644
--- a/iOS/MasterFeed/MasterFeedViewController.swift
+++ b/iOS/MasterFeed/MasterFeedViewController.swift
@@ -14,7 +14,8 @@ import RSTree
class MasterFeedViewController: ProgressTableViewController, UndoableCommandRunner {
- @IBOutlet weak var markAllAsReadButton: UIBarButtonItem!
+ @IBOutlet private weak var markAllAsReadButton: UIBarButtonItem!
+ @IBOutlet private weak var addNewItemButton: UIBarButtonItem!
var undoableCommands = [UndoableCommand]()
@@ -35,7 +36,9 @@ class MasterFeedViewController: ProgressTableViewController, UndoableCommandRunn
NotificationCenter.default.addObserver(self, selector: #selector(faviconDidBecomeAvailable(_:)), name: .FaviconDidBecomeAvailable, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(feedSettingDidChange(_:)), name: .FeedSettingDidChange, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(userDidAddFeed(_:)), name: .UserDidAddFeed, object: nil)
-
+ NotificationCenter.default.addObserver(self, selector: #selector(accountsDidChange(_:)), name: .AccountsDidChange, object: nil)
+ NotificationCenter.default.addObserver(self, selector: #selector(accountStateDidChange(_:)), name: .AccountStateDidChange, object: nil)
+
NotificationCenter.default.addObserver(self, selector: #selector(backingStoresDidRebuild(_:)), name: .BackingStoresDidRebuild, object: navState)
NotificationCenter.default.addObserver(self, selector: #selector(masterSelectionDidChange(_:)), name: .MasterSelectionDidChange, object: navState)
NotificationCenter.default.addObserver(self, selector: #selector(contentSizeCategoryDidChange), name: UIContentSizeCategory.didChangeNotification, object: nil)
@@ -48,7 +51,7 @@ class MasterFeedViewController: ProgressTableViewController, UndoableCommandRunn
}
override func viewWillAppear(_ animated: Bool) {
- clearsSelectionOnViewWillAppear = splitViewController!.isCollapsed
+ clearsSelectionOnViewWillAppear = true
navigationController?.title = NSLocalizedString("Feeds", comment: "Feeds")
super.viewWillAppear(animated)
}
@@ -140,7 +143,15 @@ class MasterFeedViewController: ProgressTableViewController, UndoableCommandRunn
}
}
-
+
+ @objc func accountsDidChange(_ notification: Notification) {
+ updateUI()
+ }
+
+ @objc func accountStateDidChange(_ notification: Notification) {
+ updateUI()
+ }
+
@objc func masterSelectionDidChange(_ note: Notification) {
if let indexPath = navState.currentMasterIndexPath {
if tableView.indexPathForSelectedRow != indexPath {
@@ -433,8 +444,10 @@ class MasterFeedViewController: ProgressTableViewController, UndoableCommandRunn
@IBAction func add(_ sender: UIBarButtonItem) {
let addViewController = UIStoryboard.add.instantiateInitialViewController()!
- addViewController.modalPresentationStyle = .popover
+ addViewController.modalPresentationStyle = .formSheet
+ addViewController.preferredContentSize = AddContainerViewController.preferredContentSizeForFormSheetDisplay
addViewController.popoverPresentationController?.barButtonItem = sender
+
self.present(addViewController, animated: true)
}
@@ -596,6 +609,7 @@ private extension MasterFeedViewController {
func updateUI() {
markAllAsReadButton.isEnabled = navState.isAnyUnreadAvailable
+ addNewItemButton.isEnabled = !AccountManager.shared.activeAccounts.isEmpty
}
func configureCellsForRepresentedObject(_ representedObject: AnyObject) {
diff --git a/iOS/Settings/AddAccountViewController.swift b/iOS/Settings/AddAccountViewController.swift
index d05a15f37..c4e7a6285 100644
--- a/iOS/Settings/AddAccountViewController.swift
+++ b/iOS/Settings/AddAccountViewController.swift
@@ -6,6 +6,7 @@
// Copyright © 2019 Ranchero Software. All rights reserved.
//
+import Account
import UIKit
protocol AddAccountDismissDelegate: UIViewController {
@@ -14,6 +15,14 @@ protocol AddAccountDismissDelegate: UIViewController {
class AddAccountViewController: UITableViewController, AddAccountDismissDelegate {
+ @IBOutlet private weak var localAccountNameLabel: UILabel!
+
+ override func viewDidLoad() {
+ super.viewDidLoad()
+
+ localAccountNameLabel.text = Account.defaultLocalAccountName
+ }
+
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
switch indexPath.row {
case 0:
diff --git a/iOS/Settings/AddLocalAccountViewController.swift b/iOS/Settings/AddLocalAccountViewController.swift
index 3c09f0b03..6973a48d8 100644
--- a/iOS/Settings/AddLocalAccountViewController.swift
+++ b/iOS/Settings/AddLocalAccountViewController.swift
@@ -11,9 +11,18 @@ import Account
class AddLocalAccountViewController: UIViewController {
+ @IBOutlet private weak var localAccountNameLabel: UILabel!
@IBOutlet weak var nameTextField: UITextField!
- weak var delegate: AddAccountDismissDelegate?
+ weak var delegate: AddAccountDismissDelegate?
+
+ override func viewDidLoad() {
+ super.viewDidLoad()
+
+ localAccountNameLabel.text = Account.defaultLocalAccountName
+ nameTextField.delegate = self
+ }
+
@IBAction func cancel(_ sender: Any) {
dismiss(animated: true)
}
@@ -26,3 +35,12 @@ class AddLocalAccountViewController: UIViewController {
}
}
+
+extension AddLocalAccountViewController: UITextFieldDelegate {
+
+ func textFieldShouldReturn(_ textField: UITextField) -> Bool {
+ textField.resignFirstResponder()
+ return true
+ }
+
+}
diff --git a/iOS/Settings/DetailAccountViewController.swift b/iOS/Settings/DetailAccountViewController.swift
index d1edb4bf0..9ab945120 100644
--- a/iOS/Settings/DetailAccountViewController.swift
+++ b/iOS/Settings/DetailAccountViewController.swift
@@ -21,6 +21,7 @@ class DetailAccountViewController: UITableViewController {
guard let account = account else { return }
nameTextField.text = account.name
+ nameTextField.delegate = self
activeSwitch.isOn = account.isActive
}
@@ -28,6 +29,10 @@ class DetailAccountViewController: UITableViewController {
account?.name = nameTextField.text
account?.isActive = activeSwitch.isOn
}
+
+}
+
+extension DetailAccountViewController {
override func numberOfSections(in tableView: UITableView) -> Int {
if account == AccountManager.shared.defaultAccount {
@@ -46,6 +51,14 @@ class DetailAccountViewController: UITableViewController {
return cell
}
+ override func tableView(_ tableView: UITableView, shouldHighlightRowAt indexPath: IndexPath) -> Bool {
+ if indexPath.section == 1 {
+ return true
+ }
+
+ return false
+ }
+
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
if indexPath.section == 1 {
deleteAccount()
@@ -79,3 +92,12 @@ private extension DetailAccountViewController {
}
}
+
+extension DetailAccountViewController: UITextFieldDelegate {
+
+ func textFieldShouldReturn(_ textField: UITextField) -> Bool {
+ textField.resignFirstResponder()
+ return true
+ }
+
+}
diff --git a/iOS/Settings/Settings.storyboard b/iOS/Settings/Settings.storyboard
index 77f35406c..7a67ec398 100644
--- a/iOS/Settings/Settings.storyboard
+++ b/iOS/Settings/Settings.storyboard
@@ -127,12 +127,29 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
@@ -153,7 +170,7 @@
-
+
@@ -183,7 +200,7 @@
-
+
@@ -211,7 +228,7 @@
-
+
@@ -234,23 +251,6 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
@@ -337,7 +337,7 @@
-
+
@@ -508,6 +508,9 @@
+
+
+
@@ -572,6 +575,7 @@
+
diff --git a/iOS/Settings/SettingsViewController.swift b/iOS/Settings/SettingsViewController.swift
index 2e1664f1a..f395d62d1 100644
--- a/iOS/Settings/SettingsViewController.swift
+++ b/iOS/Settings/SettingsViewController.swift
@@ -58,6 +58,13 @@ class SettingsViewController: UITableViewController {
switch section {
case 0:
return AccountManager.shared.accounts.count + 1
+ case 1:
+ let defaultNumberOfRows = super.tableView(tableView, numberOfRowsInSection: section)
+ if AccountManager.shared.activeAccounts.isEmpty {
+ // Hide the add NetNewsWire feed row if they don't have any active accounts
+ return defaultNumberOfRows - 1
+ }
+ return defaultNumberOfRows
default:
return super.tableView(tableView, numberOfRowsInSection: section)
}
@@ -116,8 +123,12 @@ class SettingsViewController: UITableViewController {
UIApplication.shared.open(URL(string: "https://github.com/brentsimmons/NetNewsWire")!, options: [:])
case 3:
UIApplication.shared.open(URL(string: "https://github.com/brentsimmons/NetNewsWire/issues")!, options: [:])
- default:
+ case 4:
UIApplication.shared.open(URL(string: "https://github.com/brentsimmons/NetNewsWire/tree/master/Technotes")!, options: [:])
+ case 5:
+ addFeed()
+ default:
+ UIApplication.shared.open(URL(string: "https://ranchero.com/netnewswire/")!, options: [:])
}
case 2:
UIApplication.shared.open(URL(string: "https://appcamp4girls.com/contribute/")!, options: [:])
@@ -132,10 +143,8 @@ class SettingsViewController: UITableViewController {
let timeline = UIStoryboard.settings.instantiateController(ofType: RefreshIntervalViewController.self)
self.navigationController?.pushViewController(timeline, animated: true)
case 1:
- addFeed()
- case 2:
importOPML()
- case 3:
+ case 2:
exportOPML()
default:
print("export")
@@ -227,6 +236,7 @@ private extension SettingsViewController {
let addNavViewController = UIStoryboard.add.instantiateInitialViewController() as! UINavigationController
let addViewController = addNavViewController.topViewController as! AddContainerViewController
addNavViewController.modalPresentationStyle = .formSheet
+ addNavViewController.preferredContentSize = AddContainerViewController.preferredContentSizeForFormSheetDisplay
addViewController.initialFeed = appNewsURLString
addViewController.initialFeedName = "NetNewsWire News"