Merge branch 'master' of https://github.com/brentsimmons/NetNewsWire
This commit is contained in:
commit
95b96b9df9
@ -64,7 +64,7 @@ public final class Feed: DisplayNameProvider, Renamable, UnreadCountProvider, Ha
|
||||
set {
|
||||
let oldNameForDisplay = nameForDisplay
|
||||
metadata.name = newValue
|
||||
if oldNameForDisplay != nameForDisplay {
|
||||
if oldNameForDisplay != newValue {
|
||||
postDisplayNameDidChangeNotification()
|
||||
}
|
||||
}
|
||||
|
@ -46,7 +46,7 @@ struct FeedSpecifier: Hashable {
|
||||
return feedSpecifiers.anyObject()
|
||||
}
|
||||
|
||||
var currentHighScore = 0
|
||||
var currentHighScore = Int.min
|
||||
var currentBestFeed: FeedSpecifier? = nil
|
||||
|
||||
for oneFeedSpecifier in feedSpecifiers {
|
||||
|
@ -88,11 +88,13 @@ final class FeedbinAccountDelegate: AccountDelegate {
|
||||
case .success():
|
||||
|
||||
self.refreshArticles(account) {
|
||||
self.refreshArticleStatus(for: account) {
|
||||
self.refreshMissingArticles(account) {
|
||||
self.refreshProgress.clear()
|
||||
DispatchQueue.main.async {
|
||||
completion(.success(()))
|
||||
self.sendArticleStatus(for: account) {
|
||||
self.refreshArticleStatus(for: account) {
|
||||
self.refreshMissingArticles(account) {
|
||||
self.refreshProgress.clear()
|
||||
DispatchQueue.main.async {
|
||||
completion(.success(()))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -241,10 +243,16 @@ final class FeedbinAccountDelegate: AccountDelegate {
|
||||
|
||||
func renameFolder(for account: Account, with folder: Folder, to name: String, completion: @escaping (Result<Void, Error>) -> Void) {
|
||||
|
||||
guard folder.hasAtLeastOneFeed() else {
|
||||
folder.name = name
|
||||
return
|
||||
}
|
||||
|
||||
caller.renameTag(oldName: folder.name ?? "", newName: name) { result in
|
||||
switch result {
|
||||
case .success:
|
||||
DispatchQueue.main.async {
|
||||
self.renameFolderRelationship(for: account, fromName: folder.name ?? "", toName: name)
|
||||
folder.name = name
|
||||
completion(.success(()))
|
||||
}
|
||||
@ -269,16 +277,44 @@ final class FeedbinAccountDelegate: AccountDelegate {
|
||||
let group = DispatchGroup()
|
||||
|
||||
for feed in folder.topLevelFeeds {
|
||||
group.enter()
|
||||
removeFeed(for: account, with: feed, from: folder) { result in
|
||||
group.leave()
|
||||
switch result {
|
||||
case .success:
|
||||
break
|
||||
case .failure(let error):
|
||||
os_log(.error, log: self.log, "Remove feed error: %@.", error.localizedDescription)
|
||||
|
||||
if feed.folderRelationship?.count ?? 0 > 1 {
|
||||
|
||||
if let feedTaggingID = feed.folderRelationship?[folder.name ?? ""] {
|
||||
group.enter()
|
||||
caller.deleteTagging(taggingID: feedTaggingID) { result in
|
||||
group.leave()
|
||||
switch result {
|
||||
case .success:
|
||||
DispatchQueue.main.async {
|
||||
self.clearFolderRelationship(for: feed, withFolderName: folder.name ?? "")
|
||||
}
|
||||
case .failure(let error):
|
||||
os_log(.error, log: self.log, "Remove feed error: %@.", error.localizedDescription)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
if let subscriptionID = feed.subscriptionID {
|
||||
group.enter()
|
||||
caller.deleteSubscription(subscriptionID: subscriptionID) { result in
|
||||
group.leave()
|
||||
switch result {
|
||||
case .success:
|
||||
DispatchQueue.main.async {
|
||||
account.clearFeedMetadata(feed)
|
||||
}
|
||||
case .failure(let error):
|
||||
os_log(.error, log: self.log, "Remove feed error: %@.", error.localizedDescription)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
group.notify(queue: DispatchQueue.main) {
|
||||
@ -347,7 +383,6 @@ final class FeedbinAccountDelegate: AccountDelegate {
|
||||
if feed.folderRelationship?.count ?? 0 > 1 {
|
||||
deleteTagging(for: account, with: feed, from: container, completion: completion)
|
||||
} else {
|
||||
account.clearFeedMetadata(feed)
|
||||
deleteSubscription(for: account, with: feed, from: container, completion: completion)
|
||||
}
|
||||
}
|
||||
@ -399,12 +434,23 @@ final class FeedbinAccountDelegate: AccountDelegate {
|
||||
|
||||
func restoreFeed(for account: Account, feed: Feed, container: Container, completion: @escaping (Result<Void, Error>) -> Void) {
|
||||
|
||||
createFeed(for: account, url: feed.url, name: feed.editedName, container: container) { result in
|
||||
switch result {
|
||||
case .success:
|
||||
completion(.success(()))
|
||||
case .failure(let error):
|
||||
completion(.failure(error))
|
||||
if let existingFeed = account.existingFeed(withURL: feed.url) {
|
||||
account.addFeed(existingFeed, to: container) { result in
|
||||
switch result {
|
||||
case .success:
|
||||
completion(.success(()))
|
||||
case .failure(let error):
|
||||
completion(.failure(error))
|
||||
}
|
||||
}
|
||||
} else {
|
||||
createFeed(for: account, url: feed.url, name: feed.editedName, container: container) { result in
|
||||
switch result {
|
||||
case .success:
|
||||
completion(.success(()))
|
||||
case .failure(let error):
|
||||
completion(.failure(error))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -412,22 +458,27 @@ final class FeedbinAccountDelegate: AccountDelegate {
|
||||
|
||||
func restoreFolder(for account: Account, folder: Folder, completion: @escaping (Result<Void, Error>) -> Void) {
|
||||
|
||||
account.addFolder(folder)
|
||||
let group = DispatchGroup()
|
||||
|
||||
for feed in folder.topLevelFeeds {
|
||||
|
||||
folder.topLevelFeeds.remove(feed)
|
||||
|
||||
group.enter()
|
||||
addFeed(for: account, with: feed, to: folder) { result in
|
||||
if account.topLevelFeeds.contains(feed) {
|
||||
account.removeFeed(feed)
|
||||
}
|
||||
restoreFeed(for: account, feed: feed, container: folder) { result in
|
||||
group.leave()
|
||||
switch result {
|
||||
case .success:
|
||||
break
|
||||
case .failure(let error):
|
||||
os_log(.error, log: self.log, "Restore folder feed error: %@.", error.localizedDescription)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
group.notify(queue: DispatchQueue.main) {
|
||||
account.addFolder(folder)
|
||||
completion(.success(()))
|
||||
}
|
||||
|
||||
@ -647,7 +698,10 @@ private extension FeedbinAccountDelegate {
|
||||
DispatchQueue.main.sync {
|
||||
if let feed = account.idToFeedDictionary[subFeedId] {
|
||||
feed.name = subscription.name
|
||||
// If the name has been changed on the server remove the locally edited name
|
||||
feed.editedName = nil
|
||||
feed.homePageURL = subscription.homePageURL
|
||||
feed.subscriptionID = String(subscription.subscriptionID)
|
||||
} else {
|
||||
let feed = account.createFeed(with: subscription.name, url: subscription.url, feedID: subFeedId, homePageURL: subscription.homePageURL)
|
||||
feed.subscriptionID = String(subscription.subscriptionID)
|
||||
@ -792,6 +846,17 @@ private extension FeedbinAccountDelegate {
|
||||
|
||||
}
|
||||
|
||||
func renameFolderRelationship(for account: Account, fromName: String, toName: String) {
|
||||
for feed in account.flattenedFeeds() {
|
||||
if var folderRelationship = feed.folderRelationship {
|
||||
let relationship = folderRelationship[fromName]
|
||||
folderRelationship[fromName] = nil
|
||||
folderRelationship[toName] = relationship
|
||||
feed.folderRelationship = folderRelationship
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func clearFolderRelationship(for feed: Feed, withFolderName folderName: String) {
|
||||
if var folderRelationship = feed.folderRelationship {
|
||||
folderRelationship[folderName] = nil
|
||||
@ -1158,6 +1223,7 @@ private extension FeedbinAccountDelegate {
|
||||
switch result {
|
||||
case .success:
|
||||
DispatchQueue.main.async {
|
||||
account.clearFeedMetadata(feed)
|
||||
account.removeFeed(feed)
|
||||
if let folders = account.folders {
|
||||
for folder in folders {
|
||||
|
@ -93,41 +93,53 @@ final class LocalAccountDelegate: AccountDelegate {
|
||||
return
|
||||
}
|
||||
|
||||
FeedFinder.find(url: url) { result in
|
||||
DispatchQueue.global(qos: .userInitiated).async {
|
||||
|
||||
switch result {
|
||||
case .success(let feedSpecifiers):
|
||||
FeedFinder.find(url: url) { result in
|
||||
|
||||
guard let bestFeedSpecifier = FeedSpecifier.bestFeed(in: feedSpecifiers),
|
||||
let url = URL(string: bestFeedSpecifier.urlString) else {
|
||||
completion(.failure(AccountError.createErrorNotFound))
|
||||
return
|
||||
}
|
||||
|
||||
if account.hasFeed(withURL: bestFeedSpecifier.urlString) {
|
||||
completion(.failure(AccountError.createErrorAlreadySubscribed))
|
||||
return
|
||||
}
|
||||
|
||||
let feed = account.createFeed(with: nil, url: url.absoluteString, feedID: url.absoluteString, homePageURL: nil)
|
||||
|
||||
InitialFeedDownloader.download(url) { parsedFeed in
|
||||
switch result {
|
||||
case .success(let feedSpecifiers):
|
||||
|
||||
if let parsedFeed = parsedFeed {
|
||||
account.update(feed, with: parsedFeed, {})
|
||||
guard let bestFeedSpecifier = FeedSpecifier.bestFeed(in: feedSpecifiers),
|
||||
let url = URL(string: bestFeedSpecifier.urlString) else {
|
||||
DispatchQueue.main.async {
|
||||
completion(.failure(AccountError.createErrorNotFound))
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
feed.editedName = name
|
||||
if account.hasFeed(withURL: bestFeedSpecifier.urlString) {
|
||||
DispatchQueue.main.async {
|
||||
completion(.failure(AccountError.createErrorAlreadySubscribed))
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
container.addFeed(feed)
|
||||
completion(.success(feed))
|
||||
let feed = account.createFeed(with: nil, url: url.absoluteString, feedID: url.absoluteString, homePageURL: nil)
|
||||
|
||||
InitialFeedDownloader.download(url) { parsedFeed in
|
||||
|
||||
if let parsedFeed = parsedFeed {
|
||||
account.update(feed, with: parsedFeed, {})
|
||||
}
|
||||
|
||||
feed.editedName = name
|
||||
|
||||
container.addFeed(feed)
|
||||
DispatchQueue.main.async {
|
||||
completion(.success(feed))
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
case .failure:
|
||||
DispatchQueue.main.async {
|
||||
completion(.failure(AccountError.createErrorNotFound))
|
||||
}
|
||||
}
|
||||
|
||||
case .failure(let error):
|
||||
completion(.failure(error))
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -413,7 +413,7 @@
|
||||
<items>
|
||||
<menuItem title="Mark as Read" keyEquivalent="U" id="Fc9-c7-2AY">
|
||||
<connections>
|
||||
<action selector="markRead:" target="Ady-hI-5gd" id="RQv-jl-2Nv"/>
|
||||
<action selector="toggleRead:" target="Ady-hI-5gd" id="jLQ-ZF-xye"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Mark All as Read" keyEquivalent="k" id="HdN-Ks-cwh">
|
||||
|
@ -86,10 +86,11 @@ private extension ArticleRenderer {
|
||||
}
|
||||
|
||||
func titleOrTitleLink() -> String {
|
||||
let escapedTitle = title.escapeHTML()
|
||||
if let link = article?.preferredLink {
|
||||
return title.htmlByAddingLink(link)
|
||||
return escapedTitle.htmlByAddingLink(link)
|
||||
}
|
||||
return title
|
||||
return escapedTitle
|
||||
}
|
||||
|
||||
func substitutions() -> [String: String] {
|
||||
|
@ -46,12 +46,30 @@ final class DeleteCommand: UndoableCommand {
|
||||
func perform() {
|
||||
|
||||
BatchUpdate.shared.perform {
|
||||
itemSpecifiers.forEach { $0.delete() }
|
||||
itemSpecifiers.forEach { $0.delete() {} }
|
||||
treeController.rebuild()
|
||||
}
|
||||
registerUndo()
|
||||
}
|
||||
|
||||
func perform(completion: @escaping () -> Void) {
|
||||
|
||||
let group = DispatchGroup()
|
||||
group.enter()
|
||||
itemSpecifiers.forEach {
|
||||
$0.delete() {
|
||||
group.leave()
|
||||
}
|
||||
}
|
||||
treeController.rebuild()
|
||||
|
||||
group.notify(queue: DispatchQueue.main) {
|
||||
self.registerUndo()
|
||||
completion()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func undo() {
|
||||
|
||||
BatchUpdate.shared.perform {
|
||||
@ -132,18 +150,20 @@ private struct SidebarItemSpecifier {
|
||||
self.path = ContainerPath(account: account!, folders: node.containingFolders())
|
||||
}
|
||||
|
||||
func delete() {
|
||||
func delete(completion: @escaping () -> Void) {
|
||||
|
||||
if let feed = feed {
|
||||
BatchUpdate.shared.start()
|
||||
account?.removeFeed(feed, from: path.resolveContainer()) { result in
|
||||
BatchUpdate.shared.end()
|
||||
completion()
|
||||
self.checkResult(result)
|
||||
}
|
||||
} else if let folder = folder {
|
||||
BatchUpdate.shared.start()
|
||||
account?.removeFolder(folder) { result in
|
||||
BatchUpdate.shared.end()
|
||||
completion()
|
||||
self.checkResult(result)
|
||||
}
|
||||
}
|
||||
|
@ -526,14 +526,23 @@ class MasterFeedViewController: ProgressTableViewController, UndoableCommandRunn
|
||||
else {
|
||||
return
|
||||
}
|
||||
|
||||
navState.beginUpdates()
|
||||
|
||||
runCommand(deleteCommand)
|
||||
navState.rebuildShadowTable()
|
||||
tableView.deleteRows(at: [indexPath], with: .automatic)
|
||||
var deleteIndexPaths = [indexPath]
|
||||
if navState.isExpanded(deleteNode) {
|
||||
for i in 0..<deleteNode.numberOfChildNodes {
|
||||
deleteIndexPaths.append(IndexPath(row: indexPath.row + 1 + i, section: indexPath.section))
|
||||
}
|
||||
}
|
||||
|
||||
navState.endUpdates()
|
||||
pushUndoableCommand(deleteCommand)
|
||||
|
||||
navState.beginUpdates()
|
||||
deleteCommand.perform {
|
||||
self.navState.treeController.rebuild()
|
||||
self.navState.rebuildShadowTable()
|
||||
self.tableView.deleteRows(at: deleteIndexPaths, with: .automatic)
|
||||
self.navState.endUpdates()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
@ -10,7 +10,7 @@ import Account
|
||||
import UIKit
|
||||
|
||||
protocol AddAccountDismissDelegate: UIViewController {
|
||||
func dismiss(_ viewController: UIViewController)
|
||||
func dismiss()
|
||||
}
|
||||
|
||||
class AddAccountViewController: UITableViewController, AddAccountDismissDelegate {
|
||||
@ -27,11 +27,13 @@ class AddAccountViewController: UITableViewController, AddAccountDismissDelegate
|
||||
switch indexPath.row {
|
||||
case 0:
|
||||
let navController = UIStoryboard.settings.instantiateViewController(withIdentifier: "AddLocalAccountNavigationViewController") as! UINavigationController
|
||||
navController.modalPresentationStyle = .currentContext
|
||||
let addViewController = navController.topViewController as! AddLocalAccountViewController
|
||||
addViewController.delegate = self
|
||||
present(navController, animated: true)
|
||||
case 1:
|
||||
let navController = UIStoryboard.settings.instantiateViewController(withIdentifier: "FeedbinAccountNavigationViewController") as! UINavigationController
|
||||
navController.modalPresentationStyle = .currentContext
|
||||
let addViewController = navController.topViewController as! FeedbinAccountViewController
|
||||
addViewController.delegate = self
|
||||
present(navController, animated: true)
|
||||
@ -40,8 +42,8 @@ class AddAccountViewController: UITableViewController, AddAccountDismissDelegate
|
||||
}
|
||||
}
|
||||
|
||||
func dismiss(_ viewController: UIViewController) {
|
||||
viewController.dismiss(animated: true, completion: nil)
|
||||
func dismiss() {
|
||||
navigationController?.popViewController(animated: false)
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -25,13 +25,15 @@ class AddLocalAccountViewController: UIViewController {
|
||||
}
|
||||
|
||||
@IBAction func cancel(_ sender: Any) {
|
||||
delegate?.dismiss(self)
|
||||
dismiss(animated: true, completion: nil)
|
||||
delegate?.dismiss()
|
||||
}
|
||||
|
||||
@IBAction func addAccountTapped(_ sender: Any) {
|
||||
let account = AccountManager.shared.createAccount(type: .onMyMac)
|
||||
account.name = nameTextField.text
|
||||
delegate?.dismiss(self)
|
||||
dismiss(animated: true, completion: nil)
|
||||
delegate?.dismiss()
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -37,15 +37,26 @@ class DetailAccountViewController: UITableViewController {
|
||||
extension DetailAccountViewController {
|
||||
|
||||
override func numberOfSections(in tableView: UITableView) -> Int {
|
||||
|
||||
guard let account = account else { return 0 }
|
||||
|
||||
if account == AccountManager.shared.defaultAccount {
|
||||
return 1
|
||||
} else if account.type == .onMyMac {
|
||||
return 2
|
||||
} else {
|
||||
return super.numberOfSections(in: tableView)
|
||||
}
|
||||
}
|
||||
|
||||
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
|
||||
let cell = super.tableView(tableView, cellForRowAt: indexPath)
|
||||
|
||||
let cell: UITableViewCell
|
||||
if indexPath.section == 1, let account = account, account.type == .onMyMac {
|
||||
cell = super.tableView(tableView, cellForRowAt: IndexPath(row: 0, section: 2))
|
||||
} else {
|
||||
cell = super.tableView(tableView, cellForRowAt: indexPath)
|
||||
}
|
||||
|
||||
let bgView = UIView()
|
||||
bgView.backgroundColor = AppAssets.selectionBackgroundColor
|
||||
@ -54,7 +65,7 @@ extension DetailAccountViewController {
|
||||
}
|
||||
|
||||
override func tableView(_ tableView: UITableView, shouldHighlightRowAt indexPath: IndexPath) -> Bool {
|
||||
if indexPath.section == 1 {
|
||||
if indexPath.section > 0 {
|
||||
return true
|
||||
}
|
||||
|
||||
@ -62,8 +73,19 @@ extension DetailAccountViewController {
|
||||
}
|
||||
|
||||
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
|
||||
if indexPath.section == 1 {
|
||||
deleteAccount()
|
||||
if let account = account, account.type == .onMyMac {
|
||||
if indexPath.section == 1 {
|
||||
deleteAccount()
|
||||
}
|
||||
} else {
|
||||
switch indexPath.section {
|
||||
case 1:
|
||||
credentials()
|
||||
case 2:
|
||||
deleteAccount()
|
||||
default:
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
tableView.selectRow(at: nil, animated: true, scrollPosition: .none)
|
||||
@ -73,6 +95,19 @@ extension DetailAccountViewController {
|
||||
|
||||
private extension DetailAccountViewController {
|
||||
|
||||
func credentials() {
|
||||
guard let account = account else { return }
|
||||
switch account.type {
|
||||
case .feedbin:
|
||||
let navController = UIStoryboard.settings.instantiateViewController(withIdentifier: "FeedbinAccountNavigationViewController") as! UINavigationController
|
||||
let addViewController = navController.topViewController as! FeedbinAccountViewController
|
||||
addViewController.account = account
|
||||
present(navController, animated: true)
|
||||
default:
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
func deleteAccount() {
|
||||
let title = NSLocalizedString("Delete Account", comment: "Delete Account")
|
||||
let message = NSLocalizedString("Are you sure you want to delete this account? This can not be undone.", comment: "Delete Account")
|
||||
|
@ -16,7 +16,7 @@ class FeedbinAccountViewController: UIViewController {
|
||||
@IBOutlet weak var cancelBarButtonItem: UIBarButtonItem!
|
||||
@IBOutlet weak var emailTextField: UITextField!
|
||||
@IBOutlet weak var passwordTextField: UITextField!
|
||||
@IBOutlet weak var addAccountButton: UIButton!
|
||||
@IBOutlet weak var actionButton: UIButton!
|
||||
|
||||
@IBOutlet weak var errorMessageLabel: UILabel!
|
||||
|
||||
@ -31,18 +31,22 @@ class FeedbinAccountViewController: UIViewController {
|
||||
passwordTextField.delegate = self
|
||||
|
||||
if let account = account, let credentials = try? account.retrieveBasicCredentials() {
|
||||
actionButton.setTitle(NSLocalizedString("Update Credentials", comment: "Update Credentials"), for: .normal)
|
||||
if case .basic(let username, let password) = credentials {
|
||||
emailTextField.text = username
|
||||
passwordTextField.text = password
|
||||
}
|
||||
} else {
|
||||
actionButton.setTitle(NSLocalizedString("Add Account", comment: "Update Credentials"), for: .normal)
|
||||
}
|
||||
}
|
||||
|
||||
@IBAction func cancel(_ sender: Any) {
|
||||
delegate?.dismiss(self)
|
||||
dismiss(animated: true, completion: nil)
|
||||
delegate?.dismiss()
|
||||
}
|
||||
|
||||
@IBAction func addAccountTapped(_ sender: Any) {
|
||||
@IBAction func action(_ sender: Any) {
|
||||
self.errorMessageLabel.text = nil
|
||||
|
||||
guard emailTextField.text != nil && passwordTextField.text != nil else {
|
||||
@ -56,8 +60,7 @@ class FeedbinAccountViewController: UIViewController {
|
||||
// When you fill in the email address via auto-complete it adds extra whitespace
|
||||
let emailAddress = emailTextField.text?.trimmingCharacters(in: .whitespaces)
|
||||
let credentials = Credentials.basic(username: emailAddress ?? "", password: passwordTextField.text ?? "")
|
||||
Account.validateCredentials(type: .feedbin, credentials: credentials) { [weak self] result in
|
||||
guard let self = self else { return }
|
||||
Account.validateCredentials(type: .feedbin, credentials: credentials) { result in
|
||||
|
||||
self.stopAnimtatingActivityIndicator()
|
||||
self.enableNavigation()
|
||||
@ -73,7 +76,9 @@ class FeedbinAccountViewController: UIViewController {
|
||||
|
||||
do {
|
||||
|
||||
try self.account?.removeBasicCredentials()
|
||||
do {
|
||||
try self.account?.removeBasicCredentials()
|
||||
} catch {}
|
||||
try self.account?.storeCredentials(credentials)
|
||||
|
||||
if newAccount {
|
||||
@ -87,7 +92,8 @@ class FeedbinAccountViewController: UIViewController {
|
||||
}
|
||||
}
|
||||
|
||||
self.delegate?.dismiss(self)
|
||||
self.dismiss(animated: true, completion: nil)
|
||||
self.delegate?.dismiss()
|
||||
} catch {
|
||||
self.errorMessageLabel.text = NSLocalizedString("Keychain error while storing credentials.", comment: "Credentials Error")
|
||||
}
|
||||
@ -103,12 +109,12 @@ class FeedbinAccountViewController: UIViewController {
|
||||
|
||||
private func enableNavigation() {
|
||||
self.cancelBarButtonItem.isEnabled = true
|
||||
self.addAccountButton.isEnabled = true
|
||||
self.actionButton.isEnabled = true
|
||||
}
|
||||
|
||||
private func disableNavigation() {
|
||||
cancelBarButtonItem.isEnabled = false
|
||||
addAccountButton.isEnabled = false
|
||||
actionButton.isEnabled = false
|
||||
}
|
||||
|
||||
private func startAnimatingActivityIndicator() {
|
||||
|
@ -368,7 +368,31 @@
|
||||
<rect key="frame" x="0.0" y="0.0" width="414" height="43.5"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<subviews>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Delete Account" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontForContentSizeCategory="YES" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="OKd-Ps-a1K">
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Credentials" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontForContentSizeCategory="YES" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="OKd-Ps-a1K">
|
||||
<rect key="frame" x="163.5" y="11.5" width="87" height="21"/>
|
||||
<fontDescription key="fontDescription" style="UICTFontTextStyleBody"/>
|
||||
<color key="textColor" cocoaTouchSystemColor="darkTextColor"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
</subviews>
|
||||
<constraints>
|
||||
<constraint firstItem="OKd-Ps-a1K" firstAttribute="centerY" secondItem="mV2-iL-ltS" secondAttribute="centerY" id="ix2-SF-I7U"/>
|
||||
<constraint firstItem="OKd-Ps-a1K" firstAttribute="centerX" secondItem="mV2-iL-ltS" secondAttribute="centerX" id="nZf-Eh-VXu"/>
|
||||
</constraints>
|
||||
</tableViewCellContentView>
|
||||
</tableViewCell>
|
||||
</cells>
|
||||
</tableViewSection>
|
||||
<tableViewSection id="sVG-jo-N8H">
|
||||
<cells>
|
||||
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="default" indentationWidth="10" id="5r9-pq-th4">
|
||||
<rect key="frame" x="0.0" y="239" width="414" height="44"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="5r9-pq-th4" id="Z5N-KD-L3U">
|
||||
<rect key="frame" x="0.0" y="0.0" width="414" height="43.5"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<subviews>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Delete Account" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontForContentSizeCategory="YES" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="a8v-SL-W9q">
|
||||
<rect key="frame" x="148" y="11.5" width="118" height="21"/>
|
||||
<fontDescription key="fontDescription" style="UICTFontTextStyleBody"/>
|
||||
<color key="textColor" red="1" green="0.0" blue="0.0" alpha="1" colorSpace="calibratedRGB"/>
|
||||
@ -376,8 +400,8 @@
|
||||
</label>
|
||||
</subviews>
|
||||
<constraints>
|
||||
<constraint firstItem="OKd-Ps-a1K" firstAttribute="centerY" secondItem="mV2-iL-ltS" secondAttribute="centerY" id="ix2-SF-I7U"/>
|
||||
<constraint firstItem="OKd-Ps-a1K" firstAttribute="centerX" secondItem="mV2-iL-ltS" secondAttribute="centerX" id="nZf-Eh-VXu"/>
|
||||
<constraint firstItem="a8v-SL-W9q" firstAttribute="centerX" secondItem="Z5N-KD-L3U" secondAttribute="centerX" id="F0E-Pt-dt3"/>
|
||||
<constraint firstItem="a8v-SL-W9q" firstAttribute="centerY" secondItem="Z5N-KD-L3U" secondAttribute="centerY" id="TIC-BM-f0j"/>
|
||||
</constraints>
|
||||
</tableViewCellContentView>
|
||||
</tableViewCell>
|
||||
@ -658,10 +682,9 @@
|
||||
<constraint firstAttribute="height" constant="48" id="8Vt-l1-eL1"/>
|
||||
</constraints>
|
||||
<fontDescription key="fontDescription" style="UICTFontTextStyleBody"/>
|
||||
<state key="normal" title="Add Account"/>
|
||||
<state key="normal" title="Action"/>
|
||||
<connections>
|
||||
<action selector="addAccountTapped:" destination="byh-sg-6p5" eventType="touchUpInside" id="BFR-MI-1qW"/>
|
||||
<action selector="addAccountTapped:" destination="lkT-rF-XV3" eventType="touchUpInside" id="YKl-dE-pVK"/>
|
||||
<action selector="action:" destination="byh-sg-6p5" eventType="touchUpInside" id="ZQy-9g-TeU"/>
|
||||
</connections>
|
||||
</button>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontForContentSizeCategory="YES" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="9QD-Wz-fqW">
|
||||
@ -712,8 +735,8 @@
|
||||
</barButtonItem>
|
||||
</navigationItem>
|
||||
<connections>
|
||||
<outlet property="actionButton" destination="pv5-O6-P6Z" id="6Fm-3l-zj1"/>
|
||||
<outlet property="activityIndicator" destination="Pl1-lc-sIl" id="hqg-mX-Yns"/>
|
||||
<outlet property="addAccountButton" destination="pv5-O6-P6Z" id="DEh-oq-rnD"/>
|
||||
<outlet property="cancelBarButtonItem" destination="xVt-VC-XFV" id="yBm-px-sgt"/>
|
||||
<outlet property="emailTextField" destination="UiV-th-dQb" id="fCb-hg-AXa"/>
|
||||
<outlet property="errorMessageLabel" destination="9QD-Wz-fqW" id="Kjo-73-Pgh"/>
|
||||
@ -823,7 +846,7 @@
|
||||
<rect key="frame" x="0.0" y="0.0" width="414" height="61.5"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<subviews>
|
||||
<textView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" scrollEnabled="NO" usesAttributedText="YES" translatesAutoresizingMaskIntoConstraints="NO" id="5fQ-qz-qbW">
|
||||
<textView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" scrollEnabled="NO" editable="NO" usesAttributedText="YES" translatesAutoresizingMaskIntoConstraints="NO" id="5fQ-qz-qbW">
|
||||
<rect key="frame" x="16" y="0.0" width="382" height="61.5"/>
|
||||
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
<attributedString key="attributedText"/>
|
||||
|
@ -1 +1 @@
|
||||
Subproject commit 59685e50640cd4629294bf2c0d63193ffa4ccc74
|
||||
Subproject commit f6bfc2bc74923d800c1e8c8e997009c81aec8f20
|
Loading…
x
Reference in New Issue
Block a user