diff --git a/Passepartout-iOS/Scenes/AccountViewController.swift b/Passepartout-iOS/Scenes/AccountViewController.swift index c9b1e95c..47e83302 100644 --- a/Passepartout-iOS/Scenes/AccountViewController.swift +++ b/Passepartout-iOS/Scenes/AccountViewController.swift @@ -45,35 +45,8 @@ class AccountViewController: UIViewController, TableModelHost { var infrastructureName: Infrastructure.Name? { didSet { - guard let name = infrastructureName else { - model.removeFooter(for: .credentials) - return - } - - let V = L10n.Account.SuggestionFooter.self - - var guidance: String? - switch name { - case .pia: - guidance = V.Infrastructure.pia - - case .tunnelBear: - guidance = V.Infrastructure.tunnelbear - - case .mullvad: - guidance = V.Infrastructure.mullvad - } - - if guidance != nil { - let footer: String - if let _ = referralURL { - footer = "\(guidance!)\n\n\(V.referral)" - } else { - footer = guidance! - } - model.setFooter(footer, for: .credentials) - tableView?.reloadData() - } + reloadModel() + tableView?.reloadData() } } @@ -83,6 +56,13 @@ class AccountViewController: UIViewController, TableModelHost { return Credentials(username, password).trimmed() } + private var guidanceURL: String? { + guard let name = infrastructureName else { + return nil + } + return AppConstants.URLs.guidances[name] + } + private var referralURL: String? { guard let name = infrastructureName else { return nil @@ -94,14 +74,45 @@ class AccountViewController: UIViewController, TableModelHost { // MARK: TableModelHost - let model: TableModel = { - let model: TableModel = TableModel() - model.add(.credentials) - model.set([.username, .password], in: .credentials) - return model - }() + var model: TableModel = TableModel() func reloadModel() { + model.clear() + + model.add(.credentials) + model.set([.username, .password], in: .credentials) + + if let name = infrastructureName { + let V = L10n.Account.SuggestionFooter.self + + var guidance: String? + switch name { + case .mullvad: + guidance = V.Infrastructure.mullvad + + case .pia: + guidance = V.Infrastructure.pia + + case .tunnelBear: + guidance = V.Infrastructure.tunnelbear + } + + model.add(.noAccount) + model.set([], in: .noAccount) + + if guidance != nil { + let footer: String + if let _ = guidanceURL { + footer = "\(guidance!) \(V.guidanceLink)" + } else { + footer = guidance! + } + model.setFooter(footer, for: .credentials) + } + if let _ = referralURL { + model.setFooter(V.referral, for: .noAccount) + } + } } // MARK: UIViewController @@ -118,6 +129,8 @@ class AccountViewController: UIViewController, TableModelHost { title = L10n.Service.Cells.Account.caption cellUsername?.field.text = currentCredentials?.username cellPassword?.field.text = currentCredentials?.password + + reloadModel() } override func viewDidAppear(_ animated: Bool) { @@ -141,13 +154,6 @@ class AccountViewController: UIViewController, TableModelHost { view.endEditing(true) delegate?.accountControllerDidComplete(self) } - - @objc private func footerTapped() { - guard let url = referralURL else { - return - } - UIApplication.shared.open(URL(string: url)!, options: [:], completionHandler: nil) - } } // MARK: - @@ -155,6 +161,8 @@ class AccountViewController: UIViewController, TableModelHost { extension AccountViewController: UITableViewDataSource, UITableViewDelegate, FieldTableViewCellDelegate { enum SectionType: Int { case credentials + + case noAccount } enum RowType: Int { @@ -165,19 +173,24 @@ extension AccountViewController: UITableViewDataSource, UITableViewDelegate, Fie private static let footerButtonTag = 1000 + func numberOfSections(in tableView: UITableView) -> Int { + return model.count + } + func tableView(_ tableView: UITableView, titleForFooterInSection section: Int) -> String? { - return model.footer(for: .credentials) + return model.footer(for: section) } func tableView(_ tableView: UITableView, willDisplayFooterView view: UIView, forSection section: Int) { - var optButton = view.viewWithTag(AccountViewController.footerButtonTag) as? UIButton + var optButton = view.viewWithTag(AccountViewController.footerButtonTag + section) as? UIButton if optButton == nil { let button = UIButton() button.frame = view.bounds + button.tag = AccountViewController.footerButtonTag + section view.addSubview(button) optButton = button } - optButton?.addTarget(self, action: #selector(footerTapped), for: .touchUpInside) + optButton?.addTarget(self, action: #selector(footerTapped(_:)), for: .touchUpInside) } func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { @@ -230,4 +243,22 @@ extension AccountViewController: UITableViewDataSource, UITableViewDelegate, Fie break } } + + @objc private func footerTapped(_ sender: Any?) { + guard let button = sender as? UIButton, let section = SectionType(rawValue: button.tag - AccountViewController.footerButtonTag) else { + return + } + var urlString: String? + switch section { + case .credentials: + urlString = guidanceURL + + case .noAccount: + urlString = referralURL + } + guard let url = urlString else { + return + } + UIApplication.shared.open(URL(string: url)!, options: [:], completionHandler: nil) + } } diff --git a/Passepartout/Resources/en.lproj/Localizable.strings b/Passepartout/Resources/en.lproj/Localizable.strings index c8f74c99..3cdafa1d 100644 --- a/Passepartout/Resources/en.lproj/Localizable.strings +++ b/Passepartout/Resources/en.lproj/Localizable.strings @@ -130,9 +130,10 @@ "account.cells.password.placeholder" = "secret"; //"account.cells.password_confirm.caption" = "Confirm"; //"account.cells.password_confirm.mismatch" = "Passwords don't match!"; +"account.suggestion_footer.infrastructure.mullvad" = "Use your website account number and password \"m\"."; "account.suggestion_footer.infrastructure.pia" = "Use your website credentials. Your username is usually numeric with a \"p\" prefix."; "account.suggestion_footer.infrastructure.tunnelbear" = "Use your website credentials. Your username is usually your email."; -"account.suggestion_footer.infrastructure.mullvad" = "Use your website account number and password \"m\"."; +"account.suggestion_footer.guidance_link" = "Tap to open web page."; "account.suggestion_footer.referral" = "Don't have an account? Tap here to get one."; "endpoint.sections.location_addresses.header" = "Addresses"; diff --git a/Passepartout/Sources/AppConstants.swift b/Passepartout/Sources/AppConstants.swift index 0eadb232..62d86c0e 100644 --- a/Passepartout/Sources/AppConstants.swift +++ b/Passepartout/Sources/AppConstants.swift @@ -164,10 +164,12 @@ public class AppConstants { return URL(string: "https://itunes.apple.com/app/id\(id)?action=write-review")! } + public static let guidances: [Infrastructure.Name: String] = [:] + public static let referrals: [Infrastructure.Name: String] = [ + .mullvad: "https://mullvad.net/en/account/create/", .pia: "https://www.privateinternetaccess.com/pages/buy-vpn/", .tunnelBear: "https://click.tunnelbear.com/aff_c?offer_id=2&aff_id=7464", - .mullvad: "https://mullvad.net/en/account/create/" ] } diff --git a/Passepartout/Sources/Services/Infrastructure.swift b/Passepartout/Sources/Services/Infrastructure.swift index 4c609610..8b93246a 100644 --- a/Passepartout/Sources/Services/Infrastructure.swift +++ b/Passepartout/Sources/Services/Infrastructure.swift @@ -28,12 +28,12 @@ import TunnelKit public struct Infrastructure: Codable { public enum Name: String, Codable, Comparable { + case mullvad = "Mullvad" + case pia = "PIA" case tunnelBear = "TunnelBear" - case mullvad = "Mullvad" - public var webName: String { return rawValue.lowercased() } diff --git a/Passepartout/Sources/SwiftGen+Strings.swift b/Passepartout/Sources/SwiftGen+Strings.swift index 93060e80..801f9fe5 100644 --- a/Passepartout/Sources/SwiftGen+Strings.swift +++ b/Passepartout/Sources/SwiftGen+Strings.swift @@ -81,6 +81,8 @@ public enum L10n { } } public enum SuggestionFooter { + /// Tap to open web page. + public static let guidanceLink = L10n.tr("Localizable", "account.suggestion_footer.guidance_link") /// Don't have an account? Tap here to get one. public static let referral = L10n.tr("Localizable", "account.suggestion_footer.referral") public enum Infrastructure {