From 157bd57c5e78473daaac2c038d177a0258ff17ab Mon Sep 17 00:00:00 2001 From: Maurice Parker Date: Sat, 14 Sep 2019 15:15:13 -0500 Subject: [PATCH] Add FreshRSS add account back into settings --- NetNewsWire.xcodeproj/project.pbxproj | 2 + .../Account/SettingsAddAccountView.swift | 3 + .../Account/SettingsDetailAccountView.swift | 18 ++- .../SettingsReaderAPIAccountView.swift | 119 ++++++++---------- 4 files changed, 73 insertions(+), 69 deletions(-) diff --git a/NetNewsWire.xcodeproj/project.pbxproj b/NetNewsWire.xcodeproj/project.pbxproj index 0f6df4fbc..aa8e3af5d 100644 --- a/NetNewsWire.xcodeproj/project.pbxproj +++ b/NetNewsWire.xcodeproj/project.pbxproj @@ -7,6 +7,7 @@ objects = { /* Begin PBXBuildFile section */ + 510BD15D232D765D002692E4 /* SettingsReaderAPIAccountView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 557EE1A522B6F4E1004206FA /* SettingsReaderAPIAccountView.swift */; }; 51126DA4225FDE2F00722696 /* RSImage-Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51126DA3225FDE2F00722696 /* RSImage-Extensions.swift */; }; 5115CAF42266301400B21BCE /* AddContainerViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51121B5A22661FEF00BC0EC1 /* AddContainerViewController.swift */; }; 511D43CF231FA62200FB1562 /* DetailKeyboardShortcuts.plist in Resources */ = {isa = PBXBuildFile; fileRef = 5127B237222B4849006D641D /* DetailKeyboardShortcuts.plist */; }; @@ -2651,6 +2652,7 @@ 514B7C8323205EFB00BAC947 /* RootSplitViewController.swift in Sources */, 5152E0F923248F6200E5C7AD /* SettingsLocalAccountView.swift in Sources */, FF3ABF162325AF5D0074C542 /* ArticleSorter.swift in Sources */, + 510BD15D232D765D002692E4 /* SettingsReaderAPIAccountView.swift in Sources */, 51C4525C226508DF00C03939 /* String-Extensions.swift in Sources */, 51C452792265091600C03939 /* MasterTimelineTableViewCell.swift in Sources */, 51C452852265093600C03939 /* FlattenedAccountFolderPickerData.swift in Sources */, diff --git a/iOS/Settings/Account/SettingsAddAccountView.swift b/iOS/Settings/Account/SettingsAddAccountView.swift index 2bd52139c..05b0786e7 100644 --- a/iOS/Settings/Account/SettingsAddAccountView.swift +++ b/iOS/Settings/Account/SettingsAddAccountView.swift @@ -20,6 +20,9 @@ struct SettingsAddAccountView : View { NavigationLink(destination: SettingsFeedbinAccountView(viewModel: SettingsFeedbinAccountView.ViewModel())) { SettingsAccountLabelView(accountImage: "accountFeedbin", accountLabel: "Feedbin") } + NavigationLink(destination: SettingsReaderAPIAccountView(viewModel: SettingsReaderAPIAccountView.ViewModel(accountType: .freshRSS))) { + SettingsAccountLabelView(accountImage: "accountFreshRSS", accountLabel: "Fresh RSS") + } } .navigationBarTitle(Text("Add Account"), displayMode: .inline) } diff --git a/iOS/Settings/Account/SettingsDetailAccountView.swift b/iOS/Settings/Account/SettingsDetailAccountView.swift index b785c1b17..c05849549 100644 --- a/iOS/Settings/Account/SettingsDetailAccountView.swift +++ b/iOS/Settings/Account/SettingsDetailAccountView.swift @@ -14,7 +14,7 @@ import RSWeb struct SettingsDetailAccountView : View { @Environment(\.presentationMode) var presentation @ObservedObject var viewModel: ViewModel - @State private var isFeedbinCredentialsPresented = false + @State private var accountType: AccountType = nil @State private var isDeleteAlertPresented = false var body: some View { @@ -32,15 +32,20 @@ struct SettingsDetailAccountView : View { HStack { Spacer() Button(action: { - self.isFeedbinCredentialsPresented.toggle() + self.accountType = self.viewModel.account.type }) { Text("Credentials") } Spacer() } } - .sheet(isPresented: $isFeedbinCredentialsPresented) { - self.settingsFeedbinAccountView + .sheet(item: $accountType) { type in + if type == .feedbin { + self.settingsFeedbinAccountView + } + if type == .freshRSS { + self.settingsReaderAPIAccountView + } } } if viewModel.isDeletable { @@ -74,6 +79,11 @@ struct SettingsDetailAccountView : View { return SettingsFeedbinAccountView(viewModel: feedbinViewModel) } + var settingsReaderAPIAccountView: SettingsReaderAPIAccountView { + let readerAPIModel = SettingsReaderAPIAccountView.ViewModel(account: viewModel.account) + return SettingsReaderAPIAccountView(viewModel: readerAPIModel) + } + class ViewModel: ObservableObject { let objectWillChange = ObservableObjectPublisher() diff --git a/iOS/Settings/Account/SettingsReaderAPIAccountView.swift b/iOS/Settings/Account/SettingsReaderAPIAccountView.swift index 0f4f4f2d5..e37efac63 100644 --- a/iOS/Settings/Account/SettingsReaderAPIAccountView.swift +++ b/iOS/Settings/Account/SettingsReaderAPIAccountView.swift @@ -12,74 +12,61 @@ import Account import RSWeb struct SettingsReaderAPIAccountView : View { - @Environment(\.isPresented) private var isPresented - @ObjectBinding var viewModel: ViewModel + @Environment(\.presentationMode) var presentation + @ObservedObject var viewModel: ViewModel + @State var busy: Bool = false - @State var error: Text = Text("") + @State var error: String = "" var body: some View { - NavigationView { - List { - Section(header: - SettingsAccountLabelView(accountImage: "accountFreshRSS", accountLabel: "FreshRSS").padding() - ) { - HStack { - Text("Email:") - Divider() - TextField($viewModel.email) - .textContentType(.username) - } - HStack { - Text("Password:") - Divider() - SecureField($viewModel.password) - } - HStack { - Text("API URL:") - Divider() - TextField($viewModel.apiURL) - .textContentType(.URL) - } + Form { + Section(header: + HStack { + Spacer() + SettingsAccountLabelView(accountImage: "accountFreshRSS", accountLabel: "FreshRSS") + .padding() + .layoutPriority(1.0) + Spacer() } - Section(footer: - HStack { - Spacer() - error.color(.red) - Spacer() - } - ) { - HStack { - Spacer() - Button(action: { self.addAccount() }) { - if viewModel.isUpdate { - Text("Update Account") - } else { - Text("Add Account") - } + ) { + TextField("Email", text: $viewModel.email).textContentType(.username) + SecureField("Password", text: $viewModel.password) + TextField("API URL:", text: $viewModel.apiURL).textContentType(.URL) + } + + Section(footer: + HStack { + Spacer() + Text(verbatim: error).foregroundColor(.red) + Spacer() + } + ) { + HStack { + Spacer() + Button(action: { self.addAccount() }) { + if viewModel.isUpdate { + Text("Update Account") + } else { + Text("Add Account") } - .disabled(!viewModel.isValid) - Spacer() } + .disabled(!viewModel.isValid) + Spacer() } } - .disabled(busy) - .listStyle(.grouped) - .navigationBarTitle(Text(""), displayMode: .inline) - .navigationBarItems(leading: - Button(action: { self.dismiss() }) { Text("Cancel") } - ) } +// .disabled(busy) } private func addAccount() { busy = true - error = Text("") + error = "" let emailAddress = viewModel.email.trimmingCharacters(in: .whitespaces) let credentials = Credentials.readerAPIBasicLogin(username: emailAddress, password: viewModel.password) guard let apiURL = URL(string: viewModel.apiURL) else { - self.error = Text("Invalide API URL.") + self.error = "Invalid API URL." return } @@ -118,15 +105,15 @@ struct SettingsReaderAPIAccountView : View { self.dismiss() } catch { - self.error = Text("Keychain error while storing credentials.") + self.error = "Keychain error while storing credentials." } } else { - self.error = Text("Invalid email/password combination.") + self.error = "Invalid email/password combination." } case .failure: - self.error = Text("Network error. Try again later.") + self.error = "Network error. Try again later." } } @@ -134,11 +121,12 @@ struct SettingsReaderAPIAccountView : View { } private func dismiss() { - isPresented?.value = false + presentation.wrappedValue.dismiss() } - class ViewModel: BindableObject { - let didChange = PassthroughSubject() + class ViewModel: ObservableObject { + + let objectWillChange = ObservableObjectPublisher() var accountType: AccountType var account: Account? = nil @@ -146,28 +134,29 @@ struct SettingsReaderAPIAccountView : View { self.accountType = accountType } - init(accountType: AccountType, account: Account) { + init(account: Account) { self.account = account - self.accountType = accountType - if case .basic(let username, let password) = try? account.retrieveCredentials() { + self.accountType = account.type + if case .readerAPIBasicLogin(let username, let password) = try? account.retrieveCredentials() { self.email = username self.password = password + self.apiURL = account.endpointURL?.absoluteString ?? "" } } var email: String = "" { - didSet { - didChange.send(self) + willSet { + objectWillChange.send() } } var password: String = "" { - didSet { - didChange.send(self) + willSet { + objectWillChange.send() } } var apiURL: String = "" { - didSet { - didChange.send(self) + willSet { + objectWillChange.send() } } var isUpdate: Bool {