Improve Account section for providers

This commit is contained in:
Davide De Rosa 2019-04-05 16:17:34 +02:00
parent 00a4fe9a74
commit bc457270cc
4 changed files with 166 additions and 82 deletions

View File

@ -329,6 +329,30 @@
</subviews>
</tableViewCellContentView>
</tableViewCell>
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="default" indentationWidth="10" reuseIdentifier="SettingTableViewCell" textLabel="fgS-Wv-Ps8" detailTextLabel="5Qq-6l-gb9" style="IBUITableViewCellStyleValue1" id="WlQ-JJ-3z3" customClass="SettingTableViewCell" customModule="Passepartout" customModuleProvider="target">
<rect key="frame" x="0.0" y="99.5" width="375" height="44"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="WlQ-JJ-3z3" id="2P7-8h-6AC">
<rect key="frame" x="0.0" y="0.0" width="375" height="43.5"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" insetsLayoutMarginsFromSafeArea="NO" text="Title" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="fgS-Wv-Ps8">
<rect key="frame" x="15" y="12" width="33.5" height="20.5"/>
<autoresizingMask key="autoresizingMask"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" insetsLayoutMarginsFromSafeArea="NO" text="Detail" textAlignment="right" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="5Qq-6l-gb9">
<rect key="frame" x="316" y="12" width="44" height="20.5"/>
<autoresizingMask key="autoresizingMask"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
</subviews>
</tableViewCellContentView>
</tableViewCell>
</prototypes>
<connections>
<outlet property="dataSource" destination="eIk-8Z-CLS" id="GbK-wM-Fhp"/>

View File

@ -56,6 +56,26 @@ class AccountViewController: UIViewController, TableModelHost {
return Credentials(username, password).trimmed()
}
private var guidanceString: String? {
guard let name = infrastructureName else {
return nil
}
let V = L10n.Account.Sections.Guidance.Footer.Infrastructure.self
switch name {
case .mullvad:
return V.mullvad(name.rawValue)
case .pia:
return V.pia(name.rawValue)
case .tunnelBear:
return V.tunnelbear(name.rawValue)
case .windscribe:
return V.windscribe(name.rawValue)
}
}
private var guidanceURL: String? {
guard let name = infrastructureName else {
return nil
@ -80,41 +100,24 @@ class AccountViewController: UIViewController, TableModelHost {
model.clear()
model.add(.credentials)
model.setHeader("", for: .credentials)
model.setHeader(L10n.Account.Sections.Credentials.header, for: .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
case .windscribe:
guidance = V.Infrastructure.windscribe
}
model.add(.noAccount)
model.set([], in: .noAccount)
if guidance != nil {
let footer: String
if let guidanceString = guidanceString {
if let _ = guidanceURL {
footer = "\(guidance!) \(V.guidanceLink)"
model.add(.guidance)
model.setFooter(guidanceString, for: .guidance)
model.set([.openGuide], in: .guidance)
} else {
footer = guidance!
model.setFooter(guidanceString, for: .credentials)
}
model.setFooter(footer, for: .credentials)
model.setHeader("", for: .registration)
}
if let _ = referralURL {
model.setFooter(V.referral, for: .noAccount)
model.add(.registration)
model.setFooter(L10n.Account.Sections.Registration.footer(name.rawValue), for: .registration)
model.set([.signUp], in: .registration)
}
}
}
@ -154,6 +157,20 @@ class AccountViewController: UIViewController, TableModelHost {
delegate?.accountController(self, didEnterCredentials: newCredentials)
}
private func openGuidanceURL() {
guard let urlString = guidanceURL else {
return
}
UIApplication.shared.open(URL(string: urlString)!, options: [:], completionHandler: nil)
}
private func openReferralURL() {
guard let urlString = referralURL else {
return
}
UIApplication.shared.open(URL(string: urlString)!, options: [:], completionHandler: nil)
}
@IBAction private func done() {
view.endEditing(true)
delegate?.accountControllerDidComplete(self)
@ -166,13 +183,19 @@ extension AccountViewController: UITableViewDataSource, UITableViewDelegate, Fie
enum SectionType: Int {
case credentials
case noAccount
case guidance
case registration
}
enum RowType: Int {
case username
case password
case openGuide
case signUp
}
private static let footerButtonTag = 1000
@ -181,6 +204,10 @@ extension AccountViewController: UITableViewDataSource, UITableViewDelegate, Fie
return model.count
}
func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
return model.header(for: section)
}
func tableView(_ tableView: UITableView, titleForFooterInSection section: Int) -> String? {
return model.footer(for: section)
}
@ -189,26 +216,14 @@ extension AccountViewController: UITableViewDataSource, UITableViewDelegate, Fie
return model.headerHeight(for: section)
}
func tableView(_ tableView: UITableView, willDisplayFooterView view: UIView, forSection section: Int) {
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)
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return model.count(for: section)
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = Cells.field.dequeue(from: tableView, for: indexPath)
switch model.row(at: indexPath) {
case .username:
let cell = Cells.field.dequeue(from: tableView, for: indexPath)
cellUsername = cell
cell.caption = L10n.Account.Cells.Username.caption
cell.field.placeholder = usernamePlaceholder ?? L10n.Account.Cells.Username.placeholder
@ -218,8 +233,12 @@ extension AccountViewController: UITableViewDataSource, UITableViewDelegate, Fie
cell.field.keyboardType = .emailAddress
cell.field.returnKeyType = .next
cell.field.textContentType = .username
cell.captionWidth = 120.0
cell.delegate = self
return cell
case .password:
let cell = Cells.field.dequeue(from: tableView, for: indexPath)
cellPassword = cell
cell.caption = L10n.Account.Cells.Password.caption
cell.field.placeholder = L10n.Account.Cells.Password.placeholder
@ -228,10 +247,39 @@ extension AccountViewController: UITableViewDataSource, UITableViewDelegate, Fie
cell.field.text = currentCredentials?.password
cell.field.returnKeyType = .done
cell.field.textContentType = .password
cell.captionWidth = 120.0
cell.delegate = self
return cell
case .openGuide:
let cell = Cells.setting.dequeue(from: tableView, for: indexPath)
cell.leftText = L10n.Account.Cells.OpenGuide.caption
cell.applyAction(Theme.current)
return cell
case .signUp:
guard let name = infrastructureName else {
fatalError("Sign-up shown when not a provider profile")
}
let cell = Cells.setting.dequeue(from: tableView, for: indexPath)
cell.leftText = L10n.Account.Cells.Signup.caption(name.rawValue)
cell.applyAction(Theme.current)
return cell
}
cell.captionWidth = 120.0
cell.delegate = self
return cell
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
switch model.row(at: indexPath) {
case .openGuide:
openGuidanceURL()
case .signUp:
openReferralURL()
default:
break
}
tableView.deselectRow(at: indexPath, animated: true)
}
func fieldCellDidEdit(_: FieldTableViewCell) {
@ -251,22 +299,4 @@ 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)
}
}

View File

@ -129,18 +129,20 @@
"service.alerts.masks_private_data.messages.must_reconnect" = "In order to safely reset the current debug log and apply the new masking preference, you must reconnect to the VPN now.";
"service.alerts.buttons.reconnect" = "Reconnect";
"account.sections.credentials.header" = "Credentials";
"account.sections.guidance.footer.infrastructure.mullvad" = "Use your %@ website account number and password \"m\".";
"account.sections.guidance.footer.infrastructure.pia" = "Use your %@ website credentials. Your username is usually numeric with a \"p\" prefix.";
"account.sections.guidance.footer.infrastructure.tunnelbear" = "Use your %@ website credentials. Your username is usually your email.";
"account.sections.guidance.footer.infrastructure.windscribe" = "Find your credentials in the OpenVPN Config Generator on the %@ website.";
"account.sections.registration.footer" = "Go get an account on the %@ website.";
"account.cells.username.caption" = "Username";
"account.cells.username.placeholder" = "username";
"account.cells.password.caption" = "Password";
"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.windscribe" = "Find your credentials in the OpenVPN Config Generator on the website.";
"account.suggestion_footer.guidance_link" = "Tap to open web page.";
"account.suggestion_footer.referral" = "Don't have an account? Tap here to get one.";
"account.cells.open_guide.caption" = "See your credentials";
"account.cells.signup.caption" = "Register with %@";
"endpoint.sections.location_addresses.header" = "Addresses";
"endpoint.sections.location_protocols.header" = "Protocols";

View File

@ -67,12 +67,22 @@ public enum L10n {
public enum Account {
public enum Cells {
public enum OpenGuide {
/// Find your credentials
public static let caption = L10n.tr("Localizable", "account.cells.open_guide.caption")
}
public enum Password {
/// Password
public static let caption = L10n.tr("Localizable", "account.cells.password.caption")
/// secret
public static let placeholder = L10n.tr("Localizable", "account.cells.password.placeholder")
}
public enum Signup {
/// Register with %@
public static func caption(_ p1: String) -> String {
return L10n.tr("Localizable", "account.cells.signup.caption", p1)
}
}
public enum Username {
/// Username
public static let caption = L10n.tr("Localizable", "account.cells.username.caption")
@ -80,20 +90,38 @@ public enum L10n {
public static let placeholder = L10n.tr("Localizable", "account.cells.username.placeholder")
}
}
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 {
/// Use your website account number and password "m".
public static let mullvad = L10n.tr("Localizable", "account.suggestion_footer.infrastructure.mullvad")
/// Use your website credentials. Your username is usually numeric with a "p" prefix.
public static let pia = L10n.tr("Localizable", "account.suggestion_footer.infrastructure.pia")
/// Use your website credentials. Your username is usually your email.
public static let tunnelbear = L10n.tr("Localizable", "account.suggestion_footer.infrastructure.tunnelbear")
/// Find your credentials in the OpenVPN Config Generator on the website.
public static let windscribe = L10n.tr("Localizable", "account.suggestion_footer.infrastructure.windscribe")
public enum Sections {
public enum Credentials {
/// Credentials
public static let header = L10n.tr("Localizable", "account.sections.credentials.header")
}
public enum Guidance {
public enum Footer {
public enum Infrastructure {
/// Use your %@ website account number and password "m".
public static func mullvad(_ p1: String) -> String {
return L10n.tr("Localizable", "account.sections.guidance.footer.infrastructure.mullvad", p1)
}
/// Use your %@ website credentials. Your username is usually numeric with a "p" prefix.
public static func pia(_ p1: String) -> String {
return L10n.tr("Localizable", "account.sections.guidance.footer.infrastructure.pia", p1)
}
/// Use your %@ website credentials. Your username is usually your email.
public static func tunnelbear(_ p1: String) -> String {
return L10n.tr("Localizable", "account.sections.guidance.footer.infrastructure.tunnelbear", p1)
}
/// Find your credentials in the OpenVPN Config Generator on the %@ website.
public static func windscribe(_ p1: String) -> String {
return L10n.tr("Localizable", "account.sections.guidance.footer.infrastructure.windscribe", p1)
}
}
}
}
public enum Registration {
/// Go get an account on the %@ website.
public static func footer(_ p1: String) -> String {
return L10n.tr("Localizable", "account.sections.registration.footer", p1)
}
}
}
}