Add credentials account view and model
- refactors feedbin account view and model - groups feedbin, feedly, newsblur into credentials account
This commit is contained in:
parent
e315687cc9
commit
86c9100e70
|
@ -0,0 +1,37 @@
|
||||||
|
//
|
||||||
|
// AccountCredentialsError.swift
|
||||||
|
// Multiplatform iOS
|
||||||
|
//
|
||||||
|
// Created by Rizwan on 21/07/20.
|
||||||
|
// Copyright © 2020 Ranchero Software. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
enum AccountCredentialsError: CustomStringConvertible, Equatable {
|
||||||
|
case none, keyChain, invalidCredentials, noNetwork, other(error: Error)
|
||||||
|
|
||||||
|
var description: String {
|
||||||
|
switch self {
|
||||||
|
case .keyChain:
|
||||||
|
return NSLocalizedString("Keychain error while storing credentials.", comment: "")
|
||||||
|
case .invalidCredentials:
|
||||||
|
return NSLocalizedString("Invalid email/password combination.", comment: "")
|
||||||
|
case .noNetwork:
|
||||||
|
return NSLocalizedString("Network error. Try again later.", comment: "")
|
||||||
|
case .other(let error):
|
||||||
|
return NSLocalizedString(error.localizedDescription, comment: "Other add account error")
|
||||||
|
default:
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static func ==(lhs: AccountCredentialsError, rhs: AccountCredentialsError) -> Bool {
|
||||||
|
switch (lhs, rhs) {
|
||||||
|
case (.other(let lhsError), .other(let rhsError)):
|
||||||
|
return lhsError.localizedDescription == rhsError.localizedDescription
|
||||||
|
default:
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -27,17 +27,13 @@ struct SettingsAddAccountView: View {
|
||||||
}
|
}
|
||||||
.listStyle(InsetGroupedListStyle())
|
.listStyle(InsetGroupedListStyle())
|
||||||
.sheet(isPresented: $model.isAddPresented) {
|
.sheet(isPresented: $model.isAddPresented) {
|
||||||
|
|
||||||
switch model.selectedAccountType {
|
switch model.selectedAccountType {
|
||||||
case .onMyMac:
|
case .onMyMac:
|
||||||
SettingsLocalAccountView()
|
SettingsLocalAccountView()
|
||||||
|
case .feedbin, .feedWrangler, .newsBlur:
|
||||||
case .feedbin:
|
SettingsCredentialsAccountView(accountType: model.selectedAccountType!)
|
||||||
SettingsFeedbinAccountView()
|
|
||||||
|
|
||||||
case .cloudKit:
|
case .cloudKit:
|
||||||
SettingsCloudKitAccountView()
|
SettingsCloudKitAccountView()
|
||||||
|
|
||||||
default:
|
default:
|
||||||
EmptyView()
|
EmptyView()
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,224 @@
|
||||||
|
//
|
||||||
|
// SettingsCredentialsAccountModel.swift
|
||||||
|
// Multiplatform iOS
|
||||||
|
//
|
||||||
|
// Created by Rizwan on 21/07/20.
|
||||||
|
// Copyright © 2020 Ranchero Software. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
import Account
|
||||||
|
import Secrets
|
||||||
|
|
||||||
|
class SettingsCredentialsAccountModel: ObservableObject {
|
||||||
|
var account: Account? = nil
|
||||||
|
var accountType: AccountType
|
||||||
|
@Published var shouldDismiss: Bool = false
|
||||||
|
@Published var email: String = ""
|
||||||
|
@Published var password: String = ""
|
||||||
|
@Published var busy: Bool = false
|
||||||
|
@Published var accountCredentialsError: AccountCredentialsError? {
|
||||||
|
didSet {
|
||||||
|
accountCredentialsError != AccountCredentialsError.none ? (showError = true) : (showError = false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@Published var showError: Bool = false
|
||||||
|
@Published var showPassword: Bool = false
|
||||||
|
|
||||||
|
init(account: Account) {
|
||||||
|
self.account = account
|
||||||
|
self.accountType = account.type
|
||||||
|
if let credentials = try? account.retrieveCredentials(type: .basic) {
|
||||||
|
self.email = credentials.username
|
||||||
|
self.password = credentials.secret
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
init(accountType: AccountType) {
|
||||||
|
self.accountType = accountType
|
||||||
|
}
|
||||||
|
|
||||||
|
var isUpdate: Bool {
|
||||||
|
return account != nil
|
||||||
|
}
|
||||||
|
|
||||||
|
var isValid: Bool {
|
||||||
|
return !email.isEmpty && !password.isEmpty
|
||||||
|
}
|
||||||
|
|
||||||
|
var accountName: String {
|
||||||
|
switch accountType {
|
||||||
|
case .onMyMac:
|
||||||
|
return Account.defaultLocalAccountName
|
||||||
|
case .cloudKit:
|
||||||
|
return "iCloud"
|
||||||
|
case .feedbin:
|
||||||
|
return "Feedbin"
|
||||||
|
case .feedly:
|
||||||
|
return "Feedly"
|
||||||
|
case .feedWrangler:
|
||||||
|
return "Feed Wrangler"
|
||||||
|
case .newsBlur:
|
||||||
|
return "NewsBlur"
|
||||||
|
default:
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var emailText: String {
|
||||||
|
return accountType == .newsBlur ? NSLocalizedString("Username or Email", comment: "") : NSLocalizedString("Email", comment: "")
|
||||||
|
}
|
||||||
|
|
||||||
|
func addAccount() {
|
||||||
|
switch accountType {
|
||||||
|
case .feedbin:
|
||||||
|
addFeedbinAccount()
|
||||||
|
case .feedWrangler:
|
||||||
|
addFeedWranglerAccount()
|
||||||
|
case .newsBlur:
|
||||||
|
addNewsBlurAccount()
|
||||||
|
default:
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extension SettingsCredentialsAccountModel {
|
||||||
|
// MARK:- Feedbin
|
||||||
|
|
||||||
|
func addFeedbinAccount() {
|
||||||
|
busy = true
|
||||||
|
accountCredentialsError = AccountCredentialsError.none
|
||||||
|
|
||||||
|
let emailAddress = email.trimmingCharacters(in: .whitespaces)
|
||||||
|
let credentials = Credentials(type: .basic, username: emailAddress, secret: password)
|
||||||
|
|
||||||
|
Account.validateCredentials(type: .feedbin, credentials: credentials) { (result) in
|
||||||
|
self.busy = false
|
||||||
|
|
||||||
|
switch result {
|
||||||
|
case .success(let authenticated):
|
||||||
|
if (authenticated != nil) {
|
||||||
|
var newAccount = false
|
||||||
|
let workAccount: Account
|
||||||
|
if self.account == nil {
|
||||||
|
workAccount = AccountManager.shared.createAccount(type: .feedbin)
|
||||||
|
newAccount = true
|
||||||
|
} else {
|
||||||
|
workAccount = self.account!
|
||||||
|
}
|
||||||
|
|
||||||
|
do {
|
||||||
|
do {
|
||||||
|
try workAccount.removeCredentials(type: .basic)
|
||||||
|
} catch {}
|
||||||
|
try workAccount.storeCredentials(credentials)
|
||||||
|
|
||||||
|
if newAccount {
|
||||||
|
workAccount.refreshAll() { result in }
|
||||||
|
}
|
||||||
|
|
||||||
|
self.shouldDismiss = true
|
||||||
|
} catch {
|
||||||
|
self.accountCredentialsError = AccountCredentialsError.keyChain
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
self.accountCredentialsError = AccountCredentialsError.invalidCredentials
|
||||||
|
}
|
||||||
|
case .failure:
|
||||||
|
self.accountCredentialsError = AccountCredentialsError.noNetwork
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: FeedWrangler
|
||||||
|
|
||||||
|
func addFeedWranglerAccount() {
|
||||||
|
busy = true
|
||||||
|
let credentials = Credentials(type: .feedWranglerBasic, username: email, secret: password)
|
||||||
|
|
||||||
|
Account.validateCredentials(type: .feedWrangler, credentials: credentials) { [weak self] result in
|
||||||
|
guard let self = self else { return }
|
||||||
|
|
||||||
|
self.busy = false
|
||||||
|
switch result {
|
||||||
|
case .success(let validatedCredentials):
|
||||||
|
guard let validatedCredentials = validatedCredentials else {
|
||||||
|
self.accountCredentialsError = .invalidCredentials
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
let account = AccountManager.shared.createAccount(type: .feedWrangler)
|
||||||
|
do {
|
||||||
|
try account.removeCredentials(type: .feedWranglerBasic)
|
||||||
|
try account.removeCredentials(type: .feedWranglerToken)
|
||||||
|
try account.storeCredentials(credentials)
|
||||||
|
try account.storeCredentials(validatedCredentials)
|
||||||
|
self.shouldDismiss = true
|
||||||
|
account.refreshAll(completion: { result in
|
||||||
|
switch result {
|
||||||
|
case .success:
|
||||||
|
break
|
||||||
|
case .failure(let error):
|
||||||
|
self.accountCredentialsError = .other(error: error)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
} catch {
|
||||||
|
self.accountCredentialsError = .keyChain
|
||||||
|
}
|
||||||
|
|
||||||
|
case .failure:
|
||||||
|
self.accountCredentialsError = .noNetwork
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK:- NewsBlur
|
||||||
|
|
||||||
|
func addNewsBlurAccount() {
|
||||||
|
busy = true
|
||||||
|
let credentials = Credentials(type: .newsBlurBasic, username: email, secret: password)
|
||||||
|
|
||||||
|
Account.validateCredentials(type: .newsBlur, credentials: credentials) { [weak self] result in
|
||||||
|
|
||||||
|
guard let self = self else { return }
|
||||||
|
|
||||||
|
self.busy = false
|
||||||
|
|
||||||
|
switch result {
|
||||||
|
case .success(let validatedCredentials):
|
||||||
|
|
||||||
|
guard let validatedCredentials = validatedCredentials else {
|
||||||
|
self.accountCredentialsError = .invalidCredentials
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
let account = AccountManager.shared.createAccount(type: .newsBlur)
|
||||||
|
|
||||||
|
do {
|
||||||
|
try account.removeCredentials(type: .newsBlurBasic)
|
||||||
|
try account.removeCredentials(type: .newsBlurSessionId)
|
||||||
|
try account.storeCredentials(credentials)
|
||||||
|
try account.storeCredentials(validatedCredentials)
|
||||||
|
self.shouldDismiss = true
|
||||||
|
account.refreshAll(completion: { result in
|
||||||
|
switch result {
|
||||||
|
case .success:
|
||||||
|
break
|
||||||
|
case .failure(let error):
|
||||||
|
self.accountCredentialsError = .other(error: error)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
} catch {
|
||||||
|
self.accountCredentialsError = .keyChain
|
||||||
|
}
|
||||||
|
|
||||||
|
case .failure:
|
||||||
|
self.accountCredentialsError = .noNetwork
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,35 +1,31 @@
|
||||||
//
|
//
|
||||||
// SettingsFeedbinAccountView.swift
|
// SettingsCredentialsAccountView.swift
|
||||||
// Multiplatform iOS
|
// Multiplatform iOS
|
||||||
//
|
//
|
||||||
// Created by Rizwan on 07/07/20.
|
// Created by Rizwan on 21/07/20.
|
||||||
// Copyright © 2020 Ranchero Software. All rights reserved.
|
// Copyright © 2020 Ranchero Software. All rights reserved.
|
||||||
//
|
//
|
||||||
|
|
||||||
import SwiftUI
|
import SwiftUI
|
||||||
import Account
|
import Account
|
||||||
import Combine
|
|
||||||
import RSWeb
|
|
||||||
import Secrets
|
|
||||||
|
|
||||||
struct SettingsFeedbinAccountView: View {
|
struct SettingsCredentialsAccountView: View {
|
||||||
@Environment(\.presentationMode) var presentationMode
|
@Environment(\.presentationMode) var presentationMode
|
||||||
@ObservedObject var settingsModel: SettingsFeedbinAccountModel
|
@ObservedObject var settingsModel: SettingsCredentialsAccountModel
|
||||||
|
|
||||||
init(account: Account? = nil) {
|
init(account: Account) {
|
||||||
if let account = account {
|
self.settingsModel = SettingsCredentialsAccountModel(account: account)
|
||||||
self.settingsModel = SettingsFeedbinAccountModel(account: account)
|
}
|
||||||
}
|
|
||||||
else {
|
init(accountType: AccountType) {
|
||||||
self.settingsModel = SettingsFeedbinAccountModel()
|
self.settingsModel = SettingsCredentialsAccountModel(accountType: accountType)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
NavigationView {
|
NavigationView {
|
||||||
List {
|
List {
|
||||||
Section(header: AccountHeaderImageView(image: AppAssets.image(for: .feedbin)!)) {
|
Section(header: AccountHeaderImageView(image: AppAssets.image(for: settingsModel.accountType)!)) {
|
||||||
TextField("Email", text: $settingsModel.email).textContentType(.emailAddress)
|
TextField(settingsModel.emailText, text: $settingsModel.email).textContentType(.emailAddress)
|
||||||
HStack {
|
HStack {
|
||||||
if settingsModel.showPassword {
|
if settingsModel.showPassword {
|
||||||
TextField("Password", text:$settingsModel.password)
|
TextField("Password", text:$settingsModel.password)
|
||||||
|
@ -69,7 +65,7 @@ struct SettingsFeedbinAccountView: View {
|
||||||
presentationMode.wrappedValue.dismiss()
|
presentationMode.wrappedValue.dismiss()
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.navigationBarTitle(Text(verbatim: "Feedbin"), displayMode: .inline)
|
.navigationBarTitle(Text(verbatim: settingsModel.accountName), displayMode: .inline)
|
||||||
.navigationBarItems(leading:
|
.navigationBarItems(leading:
|
||||||
Button(action: { self.dismiss() }) { Text("Cancel") }
|
Button(action: { self.dismiss() }) { Text("Cancel") }
|
||||||
)
|
)
|
||||||
|
@ -80,7 +76,7 @@ struct SettingsFeedbinAccountView: View {
|
||||||
HStack {
|
HStack {
|
||||||
Spacer()
|
Spacer()
|
||||||
if settingsModel.showError {
|
if settingsModel.showError {
|
||||||
Text(verbatim: settingsModel.feedbinAccountError!.localizedDescription).foregroundColor(.red)
|
Text(verbatim: settingsModel.accountCredentialsError!.description).foregroundColor(.red)
|
||||||
}
|
}
|
||||||
Spacer()
|
Spacer()
|
||||||
}
|
}
|
||||||
|
@ -91,8 +87,8 @@ struct SettingsFeedbinAccountView: View {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct SettingsFeedbinAccountView_Previews: PreviewProvider {
|
struct SettingsCredentialsAccountView_Previews: PreviewProvider {
|
||||||
static var previews: some View {
|
static var previews: some View {
|
||||||
SettingsFeedbinAccountView()
|
SettingsCredentialsAccountView(accountType: .feedbin)
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -45,7 +45,7 @@ struct SettingsDetailAccountView: View {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.sheet(isPresented: $isFeedbinCredentialsPresented) {
|
.sheet(isPresented: $isFeedbinCredentialsPresented) {
|
||||||
self.settingsFeedbinAccountView
|
self.settingsCredentialsAccountView
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if settingsModel.isDeletable {
|
if settingsModel.isDeletable {
|
||||||
|
@ -78,8 +78,8 @@ struct SettingsDetailAccountView: View {
|
||||||
.navigationBarTitle(Text(verbatim: settingsModel.nameForDisplay), displayMode: .inline)
|
.navigationBarTitle(Text(verbatim: settingsModel.nameForDisplay), displayMode: .inline)
|
||||||
}
|
}
|
||||||
|
|
||||||
var settingsFeedbinAccountView: SettingsFeedbinAccountView {
|
var settingsCredentialsAccountView: SettingsCredentialsAccountView {
|
||||||
return SettingsFeedbinAccountView(account: settingsModel.account)
|
return SettingsCredentialsAccountView(account: settingsModel.account)
|
||||||
}
|
}
|
||||||
|
|
||||||
func dismiss() {
|
func dismiss() {
|
||||||
|
|
|
@ -1,112 +0,0 @@
|
||||||
//
|
|
||||||
// SettingsFeedbinAccountModel.swift
|
|
||||||
// Multiplatform iOS
|
|
||||||
//
|
|
||||||
// Created by Rizwan on 08/07/20.
|
|
||||||
// Copyright © 2020 Ranchero Software. All rights reserved.
|
|
||||||
//
|
|
||||||
|
|
||||||
import SwiftUI
|
|
||||||
import Account
|
|
||||||
import Secrets
|
|
||||||
|
|
||||||
enum FeedbinAccountError: LocalizedError {
|
|
||||||
|
|
||||||
case none, keyChain, invalidCredentials, noNetwork
|
|
||||||
|
|
||||||
var errorDescription: String? {
|
|
||||||
switch self {
|
|
||||||
case .keyChain:
|
|
||||||
return NSLocalizedString("Keychain error while storing credentials.", comment: "")
|
|
||||||
case .invalidCredentials:
|
|
||||||
return NSLocalizedString("Invalid email/password combination.", comment: "")
|
|
||||||
case .noNetwork:
|
|
||||||
return NSLocalizedString("Network error. Try again later.", comment: "")
|
|
||||||
default:
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
class SettingsFeedbinAccountModel: ObservableObject {
|
|
||||||
var account: Account? = nil
|
|
||||||
@Published var shouldDismiss: Bool = false
|
|
||||||
@Published var email: String = ""
|
|
||||||
@Published var password: String = ""
|
|
||||||
@Published var busy: Bool = false
|
|
||||||
@Published var feedbinAccountError: FeedbinAccountError? {
|
|
||||||
didSet {
|
|
||||||
feedbinAccountError != FeedbinAccountError.none ? (showError = true) : (showError = false)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@Published var showError: Bool = false
|
|
||||||
@Published var showPassword: Bool = false
|
|
||||||
|
|
||||||
init() {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
init(account: Account) {
|
|
||||||
self.account = account
|
|
||||||
if let credentials = try? account.retrieveCredentials(type: .basic) {
|
|
||||||
self.email = credentials.username
|
|
||||||
self.password = credentials.secret
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var isUpdate: Bool {
|
|
||||||
return account != nil
|
|
||||||
}
|
|
||||||
|
|
||||||
var isValid: Bool {
|
|
||||||
return !email.isEmpty && !password.isEmpty
|
|
||||||
}
|
|
||||||
|
|
||||||
func addAccount() {
|
|
||||||
busy = true
|
|
||||||
feedbinAccountError = FeedbinAccountError.none
|
|
||||||
|
|
||||||
let emailAddress = email.trimmingCharacters(in: .whitespaces)
|
|
||||||
let credentials = Credentials(type: .basic, username: emailAddress, secret: password)
|
|
||||||
|
|
||||||
Account.validateCredentials(type: .feedbin, credentials: credentials) { (result) in
|
|
||||||
self.busy = false
|
|
||||||
|
|
||||||
switch result {
|
|
||||||
case .success(let authenticated):
|
|
||||||
if (authenticated != nil) {
|
|
||||||
var newAccount = false
|
|
||||||
let workAccount: Account
|
|
||||||
if self.account == nil {
|
|
||||||
workAccount = AccountManager.shared.createAccount(type: .feedbin)
|
|
||||||
newAccount = true
|
|
||||||
} else {
|
|
||||||
workAccount = self.account!
|
|
||||||
}
|
|
||||||
|
|
||||||
do {
|
|
||||||
do {
|
|
||||||
try workAccount.removeCredentials(type: .basic)
|
|
||||||
} catch {}
|
|
||||||
try workAccount.storeCredentials(credentials)
|
|
||||||
|
|
||||||
if newAccount {
|
|
||||||
workAccount.refreshAll() { result in }
|
|
||||||
}
|
|
||||||
|
|
||||||
self.shouldDismiss = true
|
|
||||||
} catch {
|
|
||||||
self.feedbinAccountError = FeedbinAccountError.keyChain
|
|
||||||
}
|
|
||||||
|
|
||||||
} else {
|
|
||||||
self.feedbinAccountError = FeedbinAccountError.invalidCredentials
|
|
||||||
}
|
|
||||||
case .failure:
|
|
||||||
self.feedbinAccountError = FeedbinAccountError.noNetwork
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -706,6 +706,9 @@
|
||||||
55E15BCB229D65A900D6602A /* AccountsReaderAPI.xib in Resources */ = {isa = PBXBuildFile; fileRef = 55E15BC1229D65A900D6602A /* AccountsReaderAPI.xib */; };
|
55E15BCB229D65A900D6602A /* AccountsReaderAPI.xib in Resources */ = {isa = PBXBuildFile; fileRef = 55E15BC1229D65A900D6602A /* AccountsReaderAPI.xib */; };
|
||||||
55E15BCC229D65A900D6602A /* AccountsReaderAPIWindowController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 55E15BCA229D65A900D6602A /* AccountsReaderAPIWindowController.swift */; };
|
55E15BCC229D65A900D6602A /* AccountsReaderAPIWindowController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 55E15BCA229D65A900D6602A /* AccountsReaderAPIWindowController.swift */; };
|
||||||
5F323809231DF9F000706F6B /* VibrantTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5F323808231DF9F000706F6B /* VibrantTableViewCell.swift */; };
|
5F323809231DF9F000706F6B /* VibrantTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5F323808231DF9F000706F6B /* VibrantTableViewCell.swift */; };
|
||||||
|
65082A2F24C72AC8009FA994 /* SettingsCredentialsAccountView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 65082A2E24C72AC8009FA994 /* SettingsCredentialsAccountView.swift */; };
|
||||||
|
65082A5224C72B88009FA994 /* SettingsCredentialsAccountModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 65082A5124C72B88009FA994 /* SettingsCredentialsAccountModel.swift */; };
|
||||||
|
65082A5424C73D2F009FA994 /* AccountCredentialsError.swift in Sources */ = {isa = PBXBuildFile; fileRef = 65082A5324C73D2F009FA994 /* AccountCredentialsError.swift */; };
|
||||||
653A4E7924BCA5BB00EF2D7F /* SettingsCloudKitAccountView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 653A4E7824BCA5BB00EF2D7F /* SettingsCloudKitAccountView.swift */; };
|
653A4E7924BCA5BB00EF2D7F /* SettingsCloudKitAccountView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 653A4E7824BCA5BB00EF2D7F /* SettingsCloudKitAccountView.swift */; };
|
||||||
65422D1724B75CD1008A2FA2 /* SettingsAddAccountModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 65422D1624B75CD1008A2FA2 /* SettingsAddAccountModel.swift */; };
|
65422D1724B75CD1008A2FA2 /* SettingsAddAccountModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 65422D1624B75CD1008A2FA2 /* SettingsAddAccountModel.swift */; };
|
||||||
6581C73820CED60100F4AD34 /* SafariExtensionHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6581C73720CED60100F4AD34 /* SafariExtensionHandler.swift */; };
|
6581C73820CED60100F4AD34 /* SafariExtensionHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6581C73720CED60100F4AD34 /* SafariExtensionHandler.swift */; };
|
||||||
|
@ -714,14 +717,12 @@
|
||||||
6581C74020CED60100F4AD34 /* netnewswire-subscribe-to-feed.js in Resources */ = {isa = PBXBuildFile; fileRef = 6581C73F20CED60100F4AD34 /* netnewswire-subscribe-to-feed.js */; };
|
6581C74020CED60100F4AD34 /* netnewswire-subscribe-to-feed.js in Resources */ = {isa = PBXBuildFile; fileRef = 6581C73F20CED60100F4AD34 /* netnewswire-subscribe-to-feed.js */; };
|
||||||
6581C74220CED60100F4AD34 /* ToolbarItemIcon.pdf in Resources */ = {isa = PBXBuildFile; fileRef = 6581C74120CED60100F4AD34 /* ToolbarItemIcon.pdf */; };
|
6581C74220CED60100F4AD34 /* ToolbarItemIcon.pdf in Resources */ = {isa = PBXBuildFile; fileRef = 6581C74120CED60100F4AD34 /* ToolbarItemIcon.pdf */; };
|
||||||
6586A5F724B632F8002BCF4F /* SettingsDetailAccountModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6586A5F624B632F8002BCF4F /* SettingsDetailAccountModel.swift */; };
|
6586A5F724B632F8002BCF4F /* SettingsDetailAccountModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6586A5F624B632F8002BCF4F /* SettingsDetailAccountModel.swift */; };
|
||||||
6591720E24B59C5100B638E8 /* SettingsFeedbinAccountModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6591720D24B59C5100B638E8 /* SettingsFeedbinAccountModel.swift */; };
|
|
||||||
6591723124B5C35400B638E8 /* AccountHeaderImageView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6591723024B5C35400B638E8 /* AccountHeaderImageView.swift */; };
|
6591723124B5C35400B638E8 /* AccountHeaderImageView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6591723024B5C35400B638E8 /* AccountHeaderImageView.swift */; };
|
||||||
6591727F24B5D19500B638E8 /* SettingsDetailAccountView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6591727E24B5D19500B638E8 /* SettingsDetailAccountView.swift */; };
|
6591727F24B5D19500B638E8 /* SettingsDetailAccountView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6591727E24B5D19500B638E8 /* SettingsDetailAccountView.swift */; };
|
||||||
6594CA3B24AF6F2A005C7D7C /* OPMLExporter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8444C8F11FED81840051386C /* OPMLExporter.swift */; };
|
6594CA3B24AF6F2A005C7D7C /* OPMLExporter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8444C8F11FED81840051386C /* OPMLExporter.swift */; };
|
||||||
65ACE48424B4779B003AE06A /* SettingsAddAccountView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 65ACE48324B4779B003AE06A /* SettingsAddAccountView.swift */; };
|
65ACE48424B4779B003AE06A /* SettingsAddAccountView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 65ACE48324B4779B003AE06A /* SettingsAddAccountView.swift */; };
|
||||||
65ACE48624B477C9003AE06A /* SettingsAccountLabelView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 65ACE48524B477C9003AE06A /* SettingsAccountLabelView.swift */; };
|
65ACE48624B477C9003AE06A /* SettingsAccountLabelView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 65ACE48524B477C9003AE06A /* SettingsAccountLabelView.swift */; };
|
||||||
65ACE48824B48020003AE06A /* SettingsLocalAccountView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 65ACE48724B48020003AE06A /* SettingsLocalAccountView.swift */; };
|
65ACE48824B48020003AE06A /* SettingsLocalAccountView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 65ACE48724B48020003AE06A /* SettingsLocalAccountView.swift */; };
|
||||||
65ACE48A24B4C2D8003AE06A /* SettingsFeedbinAccountView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 65ACE48924B4C2D8003AE06A /* SettingsFeedbinAccountView.swift */; };
|
|
||||||
65C2E40124B05D8A000AFDF6 /* FeedsSettingsModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 65C2E40024B05D8A000AFDF6 /* FeedsSettingsModel.swift */; };
|
65C2E40124B05D8A000AFDF6 /* FeedsSettingsModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 65C2E40024B05D8A000AFDF6 /* FeedsSettingsModel.swift */; };
|
||||||
65CBAD5A24AE03C20006DD91 /* ColorPaletteContainerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 65CBAD5924AE03C20006DD91 /* ColorPaletteContainerView.swift */; };
|
65CBAD5A24AE03C20006DD91 /* ColorPaletteContainerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 65CBAD5924AE03C20006DD91 /* ColorPaletteContainerView.swift */; };
|
||||||
65ED3FB7235DEF6C0081F399 /* ArticleArray.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84F204DF1FAACBB30076E152 /* ArticleArray.swift */; };
|
65ED3FB7235DEF6C0081F399 /* ArticleArray.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84F204DF1FAACBB30076E152 /* ArticleArray.swift */; };
|
||||||
|
@ -2147,6 +2148,9 @@
|
||||||
55E15BC1229D65A900D6602A /* AccountsReaderAPI.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = AccountsReaderAPI.xib; sourceTree = "<group>"; };
|
55E15BC1229D65A900D6602A /* AccountsReaderAPI.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = AccountsReaderAPI.xib; sourceTree = "<group>"; };
|
||||||
55E15BCA229D65A900D6602A /* AccountsReaderAPIWindowController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AccountsReaderAPIWindowController.swift; sourceTree = "<group>"; };
|
55E15BCA229D65A900D6602A /* AccountsReaderAPIWindowController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AccountsReaderAPIWindowController.swift; sourceTree = "<group>"; };
|
||||||
5F323808231DF9F000706F6B /* VibrantTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VibrantTableViewCell.swift; sourceTree = "<group>"; };
|
5F323808231DF9F000706F6B /* VibrantTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VibrantTableViewCell.swift; sourceTree = "<group>"; };
|
||||||
|
65082A2E24C72AC8009FA994 /* SettingsCredentialsAccountView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsCredentialsAccountView.swift; sourceTree = "<group>"; };
|
||||||
|
65082A5124C72B88009FA994 /* SettingsCredentialsAccountModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsCredentialsAccountModel.swift; sourceTree = "<group>"; };
|
||||||
|
65082A5324C73D2F009FA994 /* AccountCredentialsError.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccountCredentialsError.swift; sourceTree = "<group>"; };
|
||||||
653A4E7824BCA5BB00EF2D7F /* SettingsCloudKitAccountView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsCloudKitAccountView.swift; sourceTree = "<group>"; };
|
653A4E7824BCA5BB00EF2D7F /* SettingsCloudKitAccountView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsCloudKitAccountView.swift; sourceTree = "<group>"; };
|
||||||
65422D1624B75CD1008A2FA2 /* SettingsAddAccountModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsAddAccountModel.swift; sourceTree = "<group>"; };
|
65422D1624B75CD1008A2FA2 /* SettingsAddAccountModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsAddAccountModel.swift; sourceTree = "<group>"; };
|
||||||
6543108B2322D90900658221 /* common */ = {isa = PBXFileReference; lastKnownFileType = folder; path = common; sourceTree = "<group>"; };
|
6543108B2322D90900658221 /* common */ = {isa = PBXFileReference; lastKnownFileType = folder; path = common; sourceTree = "<group>"; };
|
||||||
|
@ -2160,13 +2164,11 @@
|
||||||
6581C74120CED60100F4AD34 /* ToolbarItemIcon.pdf */ = {isa = PBXFileReference; lastKnownFileType = image.pdf; path = ToolbarItemIcon.pdf; sourceTree = "<group>"; };
|
6581C74120CED60100F4AD34 /* ToolbarItemIcon.pdf */ = {isa = PBXFileReference; lastKnownFileType = image.pdf; path = ToolbarItemIcon.pdf; sourceTree = "<group>"; };
|
||||||
6581C74320CED60100F4AD34 /* Subscribe_to_Feed.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = Subscribe_to_Feed.entitlements; sourceTree = "<group>"; };
|
6581C74320CED60100F4AD34 /* Subscribe_to_Feed.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = Subscribe_to_Feed.entitlements; sourceTree = "<group>"; };
|
||||||
6586A5F624B632F8002BCF4F /* SettingsDetailAccountModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsDetailAccountModel.swift; sourceTree = "<group>"; };
|
6586A5F624B632F8002BCF4F /* SettingsDetailAccountModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsDetailAccountModel.swift; sourceTree = "<group>"; };
|
||||||
6591720D24B59C5100B638E8 /* SettingsFeedbinAccountModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsFeedbinAccountModel.swift; sourceTree = "<group>"; };
|
|
||||||
6591723024B5C35400B638E8 /* AccountHeaderImageView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccountHeaderImageView.swift; sourceTree = "<group>"; };
|
6591723024B5C35400B638E8 /* AccountHeaderImageView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccountHeaderImageView.swift; sourceTree = "<group>"; };
|
||||||
6591727E24B5D19500B638E8 /* SettingsDetailAccountView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsDetailAccountView.swift; sourceTree = "<group>"; };
|
6591727E24B5D19500B638E8 /* SettingsDetailAccountView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsDetailAccountView.swift; sourceTree = "<group>"; };
|
||||||
65ACE48324B4779B003AE06A /* SettingsAddAccountView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsAddAccountView.swift; sourceTree = "<group>"; };
|
65ACE48324B4779B003AE06A /* SettingsAddAccountView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsAddAccountView.swift; sourceTree = "<group>"; };
|
||||||
65ACE48524B477C9003AE06A /* SettingsAccountLabelView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsAccountLabelView.swift; sourceTree = "<group>"; };
|
65ACE48524B477C9003AE06A /* SettingsAccountLabelView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsAccountLabelView.swift; sourceTree = "<group>"; };
|
||||||
65ACE48724B48020003AE06A /* SettingsLocalAccountView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsLocalAccountView.swift; sourceTree = "<group>"; };
|
65ACE48724B48020003AE06A /* SettingsLocalAccountView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsLocalAccountView.swift; sourceTree = "<group>"; };
|
||||||
65ACE48924B4C2D8003AE06A /* SettingsFeedbinAccountView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsFeedbinAccountView.swift; sourceTree = "<group>"; };
|
|
||||||
65C2E40024B05D8A000AFDF6 /* FeedsSettingsModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FeedsSettingsModel.swift; sourceTree = "<group>"; };
|
65C2E40024B05D8A000AFDF6 /* FeedsSettingsModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FeedsSettingsModel.swift; sourceTree = "<group>"; };
|
||||||
65CBAD5924AE03C20006DD91 /* ColorPaletteContainerView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ColorPaletteContainerView.swift; sourceTree = "<group>"; };
|
65CBAD5924AE03C20006DD91 /* ColorPaletteContainerView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ColorPaletteContainerView.swift; sourceTree = "<group>"; };
|
||||||
65ED4083235DEF6C0081F399 /* NetNewsWire.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = NetNewsWire.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
65ED4083235DEF6C0081F399 /* NetNewsWire.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = NetNewsWire.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||||
|
@ -3312,12 +3314,13 @@
|
||||||
65422D1624B75CD1008A2FA2 /* SettingsAddAccountModel.swift */,
|
65422D1624B75CD1008A2FA2 /* SettingsAddAccountModel.swift */,
|
||||||
65ACE48524B477C9003AE06A /* SettingsAccountLabelView.swift */,
|
65ACE48524B477C9003AE06A /* SettingsAccountLabelView.swift */,
|
||||||
65ACE48724B48020003AE06A /* SettingsLocalAccountView.swift */,
|
65ACE48724B48020003AE06A /* SettingsLocalAccountView.swift */,
|
||||||
65ACE48924B4C2D8003AE06A /* SettingsFeedbinAccountView.swift */,
|
|
||||||
6591720D24B59C5100B638E8 /* SettingsFeedbinAccountModel.swift */,
|
|
||||||
6591723024B5C35400B638E8 /* AccountHeaderImageView.swift */,
|
6591723024B5C35400B638E8 /* AccountHeaderImageView.swift */,
|
||||||
6591727E24B5D19500B638E8 /* SettingsDetailAccountView.swift */,
|
6591727E24B5D19500B638E8 /* SettingsDetailAccountView.swift */,
|
||||||
6586A5F624B632F8002BCF4F /* SettingsDetailAccountModel.swift */,
|
6586A5F624B632F8002BCF4F /* SettingsDetailAccountModel.swift */,
|
||||||
653A4E7824BCA5BB00EF2D7F /* SettingsCloudKitAccountView.swift */,
|
653A4E7824BCA5BB00EF2D7F /* SettingsCloudKitAccountView.swift */,
|
||||||
|
65082A2E24C72AC8009FA994 /* SettingsCredentialsAccountView.swift */,
|
||||||
|
65082A5124C72B88009FA994 /* SettingsCredentialsAccountModel.swift */,
|
||||||
|
65082A5324C73D2F009FA994 /* AccountCredentialsError.swift */,
|
||||||
);
|
);
|
||||||
path = Accounts;
|
path = Accounts;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
|
@ -5161,7 +5164,6 @@
|
||||||
5177471824B3812200EB0F74 /* IconView.swift in Sources */,
|
5177471824B3812200EB0F74 /* IconView.swift in Sources */,
|
||||||
51E4995C24A875F300B667CB /* ArticleRenderer.swift in Sources */,
|
51E4995C24A875F300B667CB /* ArticleRenderer.swift in Sources */,
|
||||||
51E4992324A8095700B667CB /* URL-Extensions.swift in Sources */,
|
51E4992324A8095700B667CB /* URL-Extensions.swift in Sources */,
|
||||||
65ACE48A24B4C2D8003AE06A /* SettingsFeedbinAccountView.swift in Sources */,
|
|
||||||
51E4993624A867E800B667CB /* UserInfoKey.swift in Sources */,
|
51E4993624A867E800B667CB /* UserInfoKey.swift in Sources */,
|
||||||
51E4990924A808C500B667CB /* WebFeedIconDownloader.swift in Sources */,
|
51E4990924A808C500B667CB /* WebFeedIconDownloader.swift in Sources */,
|
||||||
51E498F524A8085D00B667CB /* TodayFeedDelegate.swift in Sources */,
|
51E498F524A8085D00B667CB /* TodayFeedDelegate.swift in Sources */,
|
||||||
|
@ -5169,6 +5171,7 @@
|
||||||
172199F124AB716900A31D04 /* SidebarToolbarModifier.swift in Sources */,
|
172199F124AB716900A31D04 /* SidebarToolbarModifier.swift in Sources */,
|
||||||
65CBAD5A24AE03C20006DD91 /* ColorPaletteContainerView.swift in Sources */,
|
65CBAD5A24AE03C20006DD91 /* ColorPaletteContainerView.swift in Sources */,
|
||||||
5177470924B2F87600EB0F74 /* SidebarListStyleModifier.swift in Sources */,
|
5177470924B2F87600EB0F74 /* SidebarListStyleModifier.swift in Sources */,
|
||||||
|
65082A5424C73D2F009FA994 /* AccountCredentialsError.swift in Sources */,
|
||||||
51E4990B24A808C500B667CB /* ImageDownloader.swift in Sources */,
|
51E4990B24A808C500B667CB /* ImageDownloader.swift in Sources */,
|
||||||
51E498F424A8085D00B667CB /* SmartFeedDelegate.swift in Sources */,
|
51E498F424A8085D00B667CB /* SmartFeedDelegate.swift in Sources */,
|
||||||
514E6BFF24AD255D00AC6F6E /* PreviewArticles.swift in Sources */,
|
514E6BFF24AD255D00AC6F6E /* PreviewArticles.swift in Sources */,
|
||||||
|
@ -5192,11 +5195,12 @@
|
||||||
51E49A0324A91FF600B667CB /* SceneNavigationView.swift in Sources */,
|
51E49A0324A91FF600B667CB /* SceneNavigationView.swift in Sources */,
|
||||||
51E4990124A808BB00B667CB /* FaviconURLFinder.swift in Sources */,
|
51E4990124A808BB00B667CB /* FaviconURLFinder.swift in Sources */,
|
||||||
51E4991D24A8092100B667CB /* NSAttributedString+NetNewsWire.swift in Sources */,
|
51E4991D24A8092100B667CB /* NSAttributedString+NetNewsWire.swift in Sources */,
|
||||||
6591720E24B59C5100B638E8 /* SettingsFeedbinAccountModel.swift in Sources */,
|
65082A2F24C72AC8009FA994 /* SettingsCredentialsAccountView.swift in Sources */,
|
||||||
51E499FD24A9137600B667CB /* SidebarModel.swift in Sources */,
|
51E499FD24A9137600B667CB /* SidebarModel.swift in Sources */,
|
||||||
5181C66224B0C326002E0F70 /* SettingsModel.swift in Sources */,
|
5181C66224B0C326002E0F70 /* SettingsModel.swift in Sources */,
|
||||||
51E4995324A8734D00B667CB /* RedditFeedProvider-Extensions.swift in Sources */,
|
51E4995324A8734D00B667CB /* RedditFeedProvider-Extensions.swift in Sources */,
|
||||||
5177471024B3029400EB0F74 /* ArticleViewController.swift in Sources */,
|
5177471024B3029400EB0F74 /* ArticleViewController.swift in Sources */,
|
||||||
|
65082A5224C72B88009FA994 /* SettingsCredentialsAccountModel.swift in Sources */,
|
||||||
172199C924AB228900A31D04 /* SettingsView.swift in Sources */,
|
172199C924AB228900A31D04 /* SettingsView.swift in Sources */,
|
||||||
51B8BCC224C25C3E00360B00 /* SidebarContextMenu.swift in Sources */,
|
51B8BCC224C25C3E00360B00 /* SidebarContextMenu.swift in Sources */,
|
||||||
17D232A824AFF10A0005F075 /* AddWebFeedModel.swift in Sources */,
|
17D232A824AFF10A0005F075 /* AddWebFeedModel.swift in Sources */,
|
||||||
|
|
Loading…
Reference in New Issue