Models now handle sign up presentations

This commit is contained in:
Stuart Breckenridge 2020-12-06 07:58:20 +08:00
parent 56f26c0c3d
commit 32506b25ae
No known key found for this signature in database
GPG Key ID: 1F11FD62007DC331
12 changed files with 123 additions and 49 deletions

View File

@ -0,0 +1,68 @@
//
// AddAccountSignUp.swift
// NetNewsWire
//
// Created by Stuart Breckenridge on 06/12/2020.
// Copyright © 2020 Ranchero Software. All rights reserved.
//
import Foundation
import Account
#if os(iOS)
import UIKit
#endif
/// Helper functions common to most account services.
protocol AddAccountSignUp {
func presentSignUpOption(_ accountType: AccountType)
}
extension AddAccountSignUp {
func presentSignUpOption(_ accountType: AccountType) {
#if os(macOS)
switch accountType {
case .bazQux:
NSWorkspace.shared.open(URL(string: "https://bazqux.com")!)
case .feedbin:
NSWorkspace.shared.open(URL(string: "https://feedbin.com/signup")!)
case .feedly:
NSWorkspace.shared.open(URL(string: "https://feedly.com")!)
case .feedWrangler:
NSWorkspace.shared.open(URL(string: "https://feedwrangler.net/users/new")!)
case .freshRSS:
NSWorkspace.shared.open(URL(string: "https://freshrss.org")!)
case .inoreader:
NSWorkspace.shared.open(URL(string: "https://www.inoreader.com")!)
case .newsBlur:
NSWorkspace.shared.open(URL(string: "https://newsblur.com")!)
case .theOldReader:
NSWorkspace.shared.open(URL(string: "https://theoldreader.com")!)
default:
return
}
#else
switch accountType {
case .bazQux:
UIApplication.shared.open(URL(string: "https://bazqux.com")!, options: [UIApplication.OpenExternalURLOptionsKey.universalLinksOnly : false], completionHandler: nil)
case .feedbin:
UIApplication.shared.open(URL(string: "https://feedbin.com/signup")!, options: [:], completionHandler: nil)
case .feedly:
UIApplication.shared.open(URL(string: "https://feedwrangler.net/users/new")!, options: [UIApplication.OpenExternalURLOptionsKey.universalLinksOnly : false], completionHandler: nil)
case .feedWrangler:
UIApplication.shared.open(URL(string: "https://freshrss.org")!, options: [UIApplication.OpenExternalURLOptionsKey.universalLinksOnly : false], completionHandler: nil)
case .freshRSS:
UIApplication.shared.open(URL(string: "https://www.inoreader.com")!, options: [UIApplication.OpenExternalURLOptionsKey.universalLinksOnly : false], completionHandler: nil)
case .inoreader:
UIApplication.shared.open(URL(string: "https://www.inoreader.com")!, options: [UIApplication.OpenExternalURLOptionsKey.universalLinksOnly : false], completionHandler: nil)
case .newsBlur:
UIApplication.shared.open(URL(string: "https://newsblur.com")!, options: [UIApplication.OpenExternalURLOptionsKey.universalLinksOnly : false], completionHandler: nil)
case .theOldReader:
UIApplication.shared.open(URL(string: "https://theoldreader.com")!, options: [UIApplication.OpenExternalURLOptionsKey.universalLinksOnly : false], completionHandler: nil)
default:
return
}
#endif
}
}

View File

@ -12,13 +12,14 @@ import RSCore
import RSWeb import RSWeb
import Secrets import Secrets
class AddFeedWranglerViewModel: ObservableObject { class AddFeedWranglerViewModel: ObservableObject, AddAccountSignUp {
@Published var isAuthenticating: Bool = false @Published var isAuthenticating: Bool = false
@Published var accountUpdateError: AccountUpdateErrors = .none @Published var accountUpdateError: AccountUpdateErrors = .none
@Published var showError: Bool = false @Published var showError: Bool = false
@Published var username: String = "" @Published var username: String = ""
@Published var password: String = "" @Published var password: String = ""
@Published var canDismiss: Bool = false @Published var canDismiss: Bool = false
@Published var showPassword: Bool = false
func authenticateFeedWrangler() { func authenticateFeedWrangler() {

View File

@ -12,13 +12,14 @@ import RSCore
import RSWeb import RSWeb
import Secrets import Secrets
class AddFeedbinViewModel: ObservableObject { class AddFeedbinViewModel: ObservableObject, AddAccountSignUp {
@Published var isAuthenticating: Bool = false @Published var isAuthenticating: Bool = false
@Published var accountUpdateError: AccountUpdateErrors = .none @Published var accountUpdateError: AccountUpdateErrors = .none
@Published var showError: Bool = false @Published var showError: Bool = false
@Published var username: String = "" @Published var username: String = ""
@Published var password: String = "" @Published var password: String = ""
@Published var canDismiss: Bool = false @Published var canDismiss: Bool = false
@Published var showPassword: Bool = false
func authenticateFeedbin() { func authenticateFeedbin() {
isAuthenticating = true isAuthenticating = true

View File

@ -12,12 +12,13 @@ import RSCore
import RSWeb import RSWeb
import Secrets import Secrets
class AddFeedlyViewModel: ObservableObject, OAuthAccountAuthorizationOperationDelegate { class AddFeedlyViewModel: ObservableObject, OAuthAccountAuthorizationOperationDelegate, AddAccountSignUp {
@Published var isAuthenticating: Bool = false @Published var isAuthenticating: Bool = false
@Published var accountUpdateError: AccountUpdateErrors = .none @Published var accountUpdateError: AccountUpdateErrors = .none
@Published var showError: Bool = false @Published var showError: Bool = false
@Published var username: String = "" @Published var username: String = ""
@Published var password: String = "" @Published var password: String = ""
@Published var showPassword: Bool = false
func authenticateFeedly() { func authenticateFeedly() {
isAuthenticating = true isAuthenticating = true

View File

@ -12,7 +12,7 @@ import RSCore
import RSWeb import RSWeb
import Secrets import Secrets
class AddNewsBlurViewModel: ObservableObject { class AddNewsBlurViewModel: ObservableObject, AddAccountSignUp {
@Published var isAuthenticating: Bool = false @Published var isAuthenticating: Bool = false
@Published var accountUpdateError: AccountUpdateErrors = .none @Published var accountUpdateError: AccountUpdateErrors = .none
@Published var showError: Bool = false @Published var showError: Bool = false

View File

@ -12,7 +12,7 @@ import RSCore
import RSWeb import RSWeb
import Secrets import Secrets
class AddReaderAPIViewModel: ObservableObject { class AddReaderAPIViewModel: ObservableObject, AddAccountSignUp {
@Published var isAuthenticating: Bool = false @Published var isAuthenticating: Bool = false
@Published var accountUpdateError: AccountUpdateErrors = .none @Published var accountUpdateError: AccountUpdateErrors = .none
@Published var showError: Bool = false @Published var showError: Bool = false
@ -20,6 +20,7 @@ class AddReaderAPIViewModel: ObservableObject {
@Published var password: String = "" @Published var password: String = ""
@Published var apiUrl: String = "" @Published var apiUrl: String = ""
@Published var canDismiss: Bool = false @Published var canDismiss: Bool = false
@Published var showPassword: Bool = false
func authenticateReaderAccount(_ accountType: AccountType) { func authenticateReaderAccount(_ accountType: AccountType) {
isAuthenticating = true isAuthenticating = true

View File

@ -69,7 +69,7 @@ struct AddFeedWranglerAccountView: View {
Text("Don't have a Feed Wrangler account?") Text("Don't have a Feed Wrangler account?")
.font(.callout) .font(.callout)
Button(action: { Button(action: {
NSWorkspace.shared.open(URL(string: "https://feedwrangler.net/users/new")!) model.presentSignUpOption(.feedWrangler)
}, label: { }, label: {
Text("Sign up here.").font(.callout) Text("Sign up here.").font(.callout)
}).buttonStyle(LinkButtonStyle()) }).buttonStyle(LinkButtonStyle())
@ -137,7 +137,7 @@ struct AddFeedWranglerAccountView: View {
AccountType.newsBlur.image() AccountType.newsBlur.image()
.resizable() .resizable()
.frame(width: 50, height: 50) .frame(width: 50, height: 50)
Text("Sign in to your NewsBlur account.") Text("Sign in to your Feed Wrangler account.")
.font(.headline) .font(.headline)
Text("This account syncs across your subscriptions across devices.") Text("This account syncs across your subscriptions across devices.")

View File

@ -30,10 +30,35 @@ struct AddFeedbinAccountView: View {
#if os(iOS) #if os(iOS)
var iosBody: some View { var iosBody: some View {
List { List {
Section(header: formHeader, footer: ProgressView() Section(header: formHeader, content: {
.hidden(!model.isAuthenticating) , content: {
TextField("Email", text: $model.username) TextField("Email", text: $model.username)
SecureField("Password", text: $model.password) if model.showPassword == false {
ZStack {
HStack {
SecureField("Password", text: $model.password)
Spacer()
Image(systemName: "eye.fill")
.foregroundColor(.accentColor)
.onTapGesture {
model.showPassword = true
}
}
}
}
else {
ZStack {
HStack {
TextField("Password", text: $model.password)
Spacer()
Image(systemName: "eye.slash.fill")
.foregroundColor(.accentColor)
.onTapGesture {
model.showPassword = false
}
}
}
}
}) })
Section(footer: formFooter, content: { Section(footer: formFooter, content: {
@ -81,7 +106,7 @@ struct AddFeedbinAccountView: View {
Text("Don't have a Feedbin account?") Text("Don't have a Feedbin account?")
.font(.callout) .font(.callout)
Button(action: { Button(action: {
NSWorkspace.shared.open(URL(string: "https://feedbin.com/signup")!) model.presentSignUpOption(.feedbin)
}, label: { }, label: {
Text("Sign up here.").font(.callout) Text("Sign up here.").font(.callout)
}).buttonStyle(LinkButtonStyle()) }).buttonStyle(LinkButtonStyle())
@ -161,9 +186,12 @@ struct AddFeedbinAccountView: View {
VStack(spacing: 8) { VStack(spacing: 8) {
Text("Sign in to your Feedbin account and sync your subscriptions across your devices. Your username and password and password will be encrypted and stored in Keychain.").foregroundColor(.secondary) Text("Sign in to your Feedbin account and sync your subscriptions across your devices. Your username and password and password will be encrypted and stored in Keychain.").foregroundColor(.secondary)
Text("Don't have a Feedbin account?").foregroundColor(.secondary) Text("Don't have a Feedbin account?").foregroundColor(.secondary)
Button(action: {}, label: { Button(action: {
model.presentSignUpOption(.feedbin)
}, label: {
Text("Sign Up Here").foregroundColor(.blue).multilineTextAlignment(.center) Text("Sign Up Here").foregroundColor(.blue).multilineTextAlignment(.center)
}).disabled(model.username.isEmpty || model.password.isEmpty) })
ProgressView().hidden(!model.isAuthenticating)
} }
.multilineTextAlignment(.center) .multilineTextAlignment(.center)
.font(.caption2) .font(.caption2)

View File

@ -53,7 +53,7 @@ struct AddFeedlyAccountView: View {
Text("Don't have a Feedly account?") Text("Don't have a Feedly account?")
.font(.callout) .font(.callout)
Button(action: { Button(action: {
NSWorkspace.shared.open(URL(string: "https://feedly.com")!) model.presentSignUpOption(.feedly)
}, label: { }, label: {
Text("Sign up here.").font(.callout) Text("Sign up here.").font(.callout)
}).buttonStyle(LinkButtonStyle()) }).buttonStyle(LinkButtonStyle())
@ -70,7 +70,7 @@ struct AddFeedlyAccountView: View {
}).keyboardShortcut(.cancelAction) }).keyboardShortcut(.cancelAction)
Button(action: { Button(action: {
authenticateFeedly() model.authenticateFeedly()
presentationMode.wrappedValue.dismiss() presentationMode.wrappedValue.dismiss()
}, label: { }, label: {
Text("Sign In") Text("Sign In")

View File

@ -66,7 +66,7 @@ struct AddNewsBlurAccountView: View {
Text("Don't have a NewsBlur account?") Text("Don't have a NewsBlur account?")
.font(.callout) .font(.callout)
Button(action: { Button(action: {
NSWorkspace.shared.open(URL(string: "https://newsblur.com")!) model.presentSignUpOption(.newsBlur)
}, label: { }, label: {
Text("Sign up here.").font(.callout) Text("Sign up here.").font(.callout)
}).buttonStyle(LinkButtonStyle()) }).buttonStyle(LinkButtonStyle())

View File

@ -53,10 +53,8 @@ struct AddReaderAPIAccountView: View {
Text("Don't have an \(accountType.localizedAccountName()) account?") Text("Don't have an \(accountType.localizedAccountName()) account?")
.font(.callout) .font(.callout)
} }
Button(action: { Button(action: {
signUp() model.presentSignUpOption(accountType)
}, label: { }, label: {
Text(accountType == .freshRSS ? "Find out more." : "Sign up here.").font(.callout) Text(accountType == .freshRSS ? "Find out more." : "Sign up here.").font(.callout)
}).buttonStyle(LinkButtonStyle()) }).buttonStyle(LinkButtonStyle())
@ -140,36 +138,6 @@ struct AddReaderAPIAccountView: View {
} }
return 230 return 230
} }
private func signUp() {
switch accountType {
case .freshRSS:
#if os(macOS)
NSWorkspace.shared.open(URL(string: "https://freshrss.org")!)
#endif
case .inoreader:
#if os(macOS)
NSWorkspace.shared.open(URL(string: "https://www.inoreader.com")!)
#endif
case .bazQux:
#if os(macOS)
NSWorkspace.shared.open(URL(string: "https://bazqux.com")!)
#endif
case .theOldReader:
#if os(macOS)
NSWorkspace.shared.open(URL(string: "https://theoldreader.com")!)
#endif
default:
return
}
}
} }
struct AddReaderAPIAccountView_Previews: PreviewProvider { struct AddReaderAPIAccountView_Previews: PreviewProvider {

View File

@ -127,6 +127,8 @@
17D0682C2564F47E00C0B37E /* Localizable.stringsdict in Resources */ = {isa = PBXBuildFile; fileRef = 17D0682B2564F47E00C0B37E /* Localizable.stringsdict */; }; 17D0682C2564F47E00C0B37E /* Localizable.stringsdict in Resources */ = {isa = PBXBuildFile; fileRef = 17D0682B2564F47E00C0B37E /* Localizable.stringsdict */; };
17D232A824AFF10A0005F075 /* AddWebFeedModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 17D232A724AFF10A0005F075 /* AddWebFeedModel.swift */; }; 17D232A824AFF10A0005F075 /* AddWebFeedModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 17D232A724AFF10A0005F075 /* AddWebFeedModel.swift */; };
17D232A924AFF10A0005F075 /* AddWebFeedModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 17D232A724AFF10A0005F075 /* AddWebFeedModel.swift */; }; 17D232A924AFF10A0005F075 /* AddWebFeedModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 17D232A724AFF10A0005F075 /* AddWebFeedModel.swift */; };
17D3CEE3257C4D2300E74939 /* AddAccountSignUp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 17D3CEE2257C4D2300E74939 /* AddAccountSignUp.swift */; };
17D3CEE4257C4D2300E74939 /* AddAccountSignUp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 17D3CEE2257C4D2300E74939 /* AddAccountSignUp.swift */; };
17D5F17124B0BC6700375168 /* SidebarToolbarModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 17D5F17024B0BC6700375168 /* SidebarToolbarModel.swift */; }; 17D5F17124B0BC6700375168 /* SidebarToolbarModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 17D5F17024B0BC6700375168 /* SidebarToolbarModel.swift */; };
17D5F17224B0BC6700375168 /* SidebarToolbarModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 17D5F17024B0BC6700375168 /* SidebarToolbarModel.swift */; }; 17D5F17224B0BC6700375168 /* SidebarToolbarModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 17D5F17024B0BC6700375168 /* SidebarToolbarModel.swift */; };
17D5F19524B0C1DD00375168 /* SidebarToolbarModifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = 172199F024AB716900A31D04 /* SidebarToolbarModifier.swift */; }; 17D5F19524B0C1DD00375168 /* SidebarToolbarModifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = 172199F024AB716900A31D04 /* SidebarToolbarModifier.swift */; };
@ -1422,6 +1424,7 @@
17B223DB24AC24D2001E4592 /* TimelineLayoutView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TimelineLayoutView.swift; sourceTree = "<group>"; }; 17B223DB24AC24D2001E4592 /* TimelineLayoutView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TimelineLayoutView.swift; sourceTree = "<group>"; };
17D0682B2564F47E00C0B37E /* Localizable.stringsdict */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; path = Localizable.stringsdict; sourceTree = "<group>"; }; 17D0682B2564F47E00C0B37E /* Localizable.stringsdict */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; path = Localizable.stringsdict; sourceTree = "<group>"; };
17D232A724AFF10A0005F075 /* AddWebFeedModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AddWebFeedModel.swift; sourceTree = "<group>"; }; 17D232A724AFF10A0005F075 /* AddWebFeedModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AddWebFeedModel.swift; sourceTree = "<group>"; };
17D3CEE2257C4D2300E74939 /* AddAccountSignUp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AddAccountSignUp.swift; sourceTree = "<group>"; };
17D5F17024B0BC6700375168 /* SidebarToolbarModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SidebarToolbarModel.swift; sourceTree = "<group>"; }; 17D5F17024B0BC6700375168 /* SidebarToolbarModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SidebarToolbarModel.swift; sourceTree = "<group>"; };
17E4DBD524BFC53E00FE462A /* AdvancedPreferencesModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AdvancedPreferencesModel.swift; sourceTree = "<group>"; }; 17E4DBD524BFC53E00FE462A /* AdvancedPreferencesModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AdvancedPreferencesModel.swift; sourceTree = "<group>"; };
3B3A328B238B820900314204 /* FeedWranglerAccountViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FeedWranglerAccountViewController.swift; sourceTree = "<group>"; }; 3B3A328B238B820900314204 /* FeedWranglerAccountViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FeedWranglerAccountViewController.swift; sourceTree = "<group>"; };
@ -2139,6 +2142,7 @@
1724127F257BBF3E00ACCEBC /* AddFeedWranglerViewModel.swift */, 1724127F257BBF3E00ACCEBC /* AddFeedWranglerViewModel.swift */,
17241287257BBF7000ACCEBC /* AddNewsBlurViewModel.swift */, 17241287257BBF7000ACCEBC /* AddNewsBlurViewModel.swift */,
1724128F257BBFAD00ACCEBC /* AddReaderAPIViewModel.swift */, 1724128F257BBFAD00ACCEBC /* AddReaderAPIViewModel.swift */,
17D3CEE2257C4D2300E74939 /* AddAccountSignUp.swift */,
); );
path = "Add Account Models"; path = "Add Account Models";
sourceTree = "<group>"; sourceTree = "<group>";
@ -4553,6 +4557,7 @@
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 */,
17D3CEE3257C4D2300E74939 /* AddAccountSignUp.swift in Sources */,
65082A5224C72B88009FA994 /* SettingsCredentialsAccountModel.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 */,
@ -4795,6 +4800,7 @@
17241249257B8A8A00ACCEBC /* AddFeedlyAccountView.swift in Sources */, 17241249257B8A8A00ACCEBC /* AddFeedlyAccountView.swift in Sources */,
51E4992D24A8676300B667CB /* FetchRequestOperation.swift in Sources */, 51E4992D24A8676300B667CB /* FetchRequestOperation.swift in Sources */,
51E4992424A8098400B667CB /* SmartFeedPasteboardWriter.swift in Sources */, 51E4992424A8098400B667CB /* SmartFeedPasteboardWriter.swift in Sources */,
17D3CEE4257C4D2300E74939 /* AddAccountSignUp.swift in Sources */,
51E4991424A808FF00B667CB /* ArticleStringFormatter.swift in Sources */, 51E4991424A808FF00B667CB /* ArticleStringFormatter.swift in Sources */,
51B54A6624B549CB0014348B /* PreloadedWebView.swift in Sources */, 51B54A6624B549CB0014348B /* PreloadedWebView.swift in Sources */,
51E4991024A808DE00B667CB /* SmallIconProvider.swift in Sources */, 51E4991024A808DE00B667CB /* SmallIconProvider.swift in Sources */,