Merge pull request #2229 from rizwankce/add-feedbin-account
Add Feedbin account addition implementation
This commit is contained in:
commit
9a054a320c
|
@ -40,7 +40,7 @@ struct SettingsAddAccountView: View {
|
||||||
SettingsLocalAccountView()
|
SettingsLocalAccountView()
|
||||||
}
|
}
|
||||||
if selectedAccountType == .feedbin {
|
if selectedAccountType == .feedbin {
|
||||||
//SettingsFeedbinAccountView(viewModel: SettingsFeedbinAccountView.ViewModel())
|
SettingsFeedbinAccountView()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.navigationBarTitle(Text("Add Account"), displayMode: .inline)
|
.navigationBarTitle(Text("Add Account"), displayMode: .inline)
|
||||||
|
|
|
@ -0,0 +1,111 @@
|
||||||
|
//
|
||||||
|
// 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
|
||||||
|
|
||||||
|
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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,91 @@
|
||||||
|
//
|
||||||
|
// SettingsFeedbinAccountView.swift
|
||||||
|
// Multiplatform iOS
|
||||||
|
//
|
||||||
|
// Created by Rizwan on 07/07/20.
|
||||||
|
// Copyright © 2020 Ranchero Software. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import SwiftUI
|
||||||
|
import Account
|
||||||
|
import Combine
|
||||||
|
import RSWeb
|
||||||
|
import Secrets
|
||||||
|
|
||||||
|
struct SettingsFeedbinAccountView: View {
|
||||||
|
@Environment(\.presentationMode) var presentationMode
|
||||||
|
@StateObject var settingsModel = SettingsFeedbinAccountModel()
|
||||||
|
|
||||||
|
var body: some View {
|
||||||
|
NavigationView {
|
||||||
|
List {
|
||||||
|
Section {
|
||||||
|
imageView
|
||||||
|
TextField("Email", text: $settingsModel.email).textContentType(.emailAddress)
|
||||||
|
SecureField("Password", text: $settingsModel.password)
|
||||||
|
}
|
||||||
|
Section(footer: errorFooter) {
|
||||||
|
HStack {
|
||||||
|
Spacer()
|
||||||
|
Button(action: { settingsModel.addAccount() }) {
|
||||||
|
if settingsModel.isUpdate {
|
||||||
|
Text("Update Account")
|
||||||
|
} else {
|
||||||
|
Text("Add Account")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.disabled(!settingsModel.isValid)
|
||||||
|
Spacer()
|
||||||
|
if settingsModel.busy {
|
||||||
|
ProgressView()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.onReceive(settingsModel.$shouldDismiss, perform: { dismiss in
|
||||||
|
if dismiss == true {
|
||||||
|
presentationMode.wrappedValue.dismiss()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.listStyle(InsetGroupedListStyle())
|
||||||
|
.disabled(settingsModel.busy)
|
||||||
|
.navigationBarTitle(Text(verbatim: "Feedbin"), displayMode: .inline)
|
||||||
|
.navigationBarItems(leading:
|
||||||
|
Button(action: { self.dismiss() }) { Text("Cancel") }
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var imageView: some View {
|
||||||
|
HStack {
|
||||||
|
Spacer()
|
||||||
|
Image(rsImage: AppAssets.image(for: .feedbin)!)
|
||||||
|
.resizable()
|
||||||
|
.aspectRatio(1, contentMode: .fit)
|
||||||
|
.frame(height: 48, alignment: .center)
|
||||||
|
.padding()
|
||||||
|
Spacer()
|
||||||
|
}
|
||||||
|
.listRowBackground(Color.clear)
|
||||||
|
}
|
||||||
|
|
||||||
|
var errorFooter: some View {
|
||||||
|
HStack {
|
||||||
|
Spacer()
|
||||||
|
if settingsModel.showError {
|
||||||
|
Text(verbatim: settingsModel.feedbinAccountError!.localizedDescription).foregroundColor(.red)
|
||||||
|
}
|
||||||
|
Spacer()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private func dismiss() {
|
||||||
|
presentationMode.wrappedValue.dismiss()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct SettingsFeedbinAccountView_Previews: PreviewProvider {
|
||||||
|
static var previews: some View {
|
||||||
|
SettingsFeedbinAccountView()
|
||||||
|
}
|
||||||
|
}
|
|
@ -669,10 +669,12 @@
|
||||||
6581C73D20CED60100F4AD34 /* SafariExtensionViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 6581C73B20CED60100F4AD34 /* SafariExtensionViewController.xib */; };
|
6581C73D20CED60100F4AD34 /* SafariExtensionViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 6581C73B20CED60100F4AD34 /* SafariExtensionViewController.xib */; };
|
||||||
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 */; };
|
||||||
|
6591720E24B59C5100B638E8 /* SettingsFeedbinAccountModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6591720D24B59C5100B638E8 /* SettingsFeedbinAccountModel.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 */; };
|
||||||
|
@ -2082,9 +2084,11 @@
|
||||||
6581C73F20CED60100F4AD34 /* netnewswire-subscribe-to-feed.js */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.javascript; path = "netnewswire-subscribe-to-feed.js"; sourceTree = "<group>"; };
|
6581C73F20CED60100F4AD34 /* netnewswire-subscribe-to-feed.js */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.javascript; path = "netnewswire-subscribe-to-feed.js"; sourceTree = "<group>"; };
|
||||||
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>"; };
|
||||||
|
6591720D24B59C5100B638E8 /* SettingsFeedbinAccountModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsFeedbinAccountModel.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; };
|
||||||
|
@ -3139,6 +3143,8 @@
|
||||||
65ACE48324B4779B003AE06A /* SettingsAddAccountView.swift */,
|
65ACE48324B4779B003AE06A /* SettingsAddAccountView.swift */,
|
||||||
65ACE48524B477C9003AE06A /* SettingsAccountLabelView.swift */,
|
65ACE48524B477C9003AE06A /* SettingsAccountLabelView.swift */,
|
||||||
65ACE48724B48020003AE06A /* SettingsLocalAccountView.swift */,
|
65ACE48724B48020003AE06A /* SettingsLocalAccountView.swift */,
|
||||||
|
65ACE48924B4C2D8003AE06A /* SettingsFeedbinAccountView.swift */,
|
||||||
|
6591720D24B59C5100B638E8 /* SettingsFeedbinAccountModel.swift */,
|
||||||
);
|
);
|
||||||
path = Accounts;
|
path = Accounts;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
|
@ -4979,6 +4985,7 @@
|
||||||
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 */,
|
||||||
|
@ -5009,6 +5016,7 @@
|
||||||
51E4990124A808BB00B667CB /* FaviconURLFinder.swift in Sources */,
|
51E4990124A808BB00B667CB /* FaviconURLFinder.swift in Sources */,
|
||||||
51E4991D24A8092100B667CB /* NSAttributedString+NetNewsWire.swift in Sources */,
|
51E4991D24A8092100B667CB /* NSAttributedString+NetNewsWire.swift in Sources */,
|
||||||
FF64D0E924AF53EE0084080A /* RefreshProgressView.swift in Sources */,
|
FF64D0E924AF53EE0084080A /* RefreshProgressView.swift in Sources */,
|
||||||
|
6591720E24B59C5100B638E8 /* SettingsFeedbinAccountModel.swift in Sources */,
|
||||||
51E499FD24A9137600B667CB /* SidebarModel.swift in Sources */,
|
51E499FD24A9137600B667CB /* SidebarModel.swift in Sources */,
|
||||||
517B2EEB24B40E09001AC46C /* TimelineTitleModifier.swift in Sources */,
|
517B2EEB24B40E09001AC46C /* TimelineTitleModifier.swift in Sources */,
|
||||||
5181C66224B0C326002E0F70 /* SettingsModel.swift in Sources */,
|
5181C66224B0C326002E0F70 /* SettingsModel.swift in Sources */,
|
||||||
|
|
Loading…
Reference in New Issue