diff --git a/Simplenote/AuthViewController+Swift.swift b/Simplenote/AuthViewController+Swift.swift
index 14410db4..01599689 100644
--- a/Simplenote/AuthViewController+Swift.swift
+++ b/Simplenote/AuthViewController+Swift.swift
@@ -150,6 +150,8 @@ extension AuthViewController {
if let title = descriptor.text {
actionView.title = title
+ } else if let attributedTitle = descriptor.attributedText {
+ actionView.attributedTitle = attributedTitle
}
actionView.action = descriptor.selector
@@ -167,6 +169,8 @@ extension AuthViewController {
codeTextField.isHidden = !inputElements.contains(.code)
actionsSeparatorView.isHidden = !inputElements.contains(.actionSeparator)
+ usernameField.stringValue = state.username
+ usernameField.textField?.nextResponder = passwordField.textField
}
/// Drops any Errors onscreen
@@ -226,6 +230,11 @@ extension AuthViewController {
func pushCodeLoginView() {
pushNewAuthViewController(with: .loginWithCode, state: state)
}
+
+ @objc
+ func pushUsernameAndPasswordView() {
+ pushNewAuthViewController(with: .loginWithUsernameAndPassword, state: state)
+ }
}
diff --git a/Simplenote/AuthViewController.xib b/Simplenote/AuthViewController.xib
index 99cfdb12..0ca3b430 100644
--- a/Simplenote/AuthViewController.xib
+++ b/Simplenote/AuthViewController.xib
@@ -142,7 +142,7 @@
-
+
diff --git a/Simplenote/AuthenticationMode.swift b/Simplenote/AuthenticationMode.swift
index 988cd9c0..b71f9aed 100644
--- a/Simplenote/AuthenticationMode.swift
+++ b/Simplenote/AuthenticationMode.swift
@@ -125,7 +125,11 @@ extension AuthenticationMode {
static var loginWithPassword: AuthenticationMode {
buildLoginWithPasswordMode(header: LoginStrings.loginWithEmailEmailHeader)
}
-
+
+ static var loginWithUsernameAndPassword: AuthenticationMode {
+ buildLoginWithPasswordMode(header: nil, includeUsername: true)
+ }
+
/// Auth Mode: Login with Username + Password + Rate Limiting Header
///
static var loginWithPasswordRateLimited: AuthenticationMode {
@@ -134,10 +138,11 @@ extension AuthenticationMode {
/// Builds the loginWithPassword Mode with the specified Header
///
- private static func buildLoginWithPasswordMode(header: String) -> AuthenticationMode {
- AuthenticationMode(title: NSLocalizedString("Log In with Password", comment: "LogIn Interface Title"),
+ private static func buildLoginWithPasswordMode(header: String?, includeUsername: Bool = false) -> AuthenticationMode {
+ let inputElements: AuthenticationInputElements = includeUsername ? [.username, .password] : [.password]
+ return AuthenticationMode(title: NSLocalizedString("Log In with Password", comment: "LogIn Interface Title"),
header: header,
- inputElements: [.password],
+ inputElements: inputElements,
actions: [
AuthenticationActionDescriptor(name: .primary,
selector: #selector(AuthViewController.pressedLogInWithPassword),
@@ -160,6 +165,10 @@ extension AuthenticationMode {
AuthenticationActionDescriptor(name: .primary,
selector: #selector(AuthViewController.pressedLoginWithMagicLink),
text: MagicLinkStrings.primaryAction),
+ AuthenticationActionDescriptor(name: .secondary,
+ selector: #selector(AuthViewController.pushUsernameAndPasswordView),
+ text: nil,
+ attributedText: LoginStrings.usernameAndPasswordOption),
AuthenticationActionDescriptor(name: .tertiary,
selector: #selector(AuthViewController.wordpressSSOAction),
text: LoginStrings.wordpressAction)
@@ -214,6 +223,23 @@ private enum LoginStrings {
static let loginWithEmailEmailHeader = NSLocalizedString("Enter the password for the account {{EMAIL}}", comment: "Header for Login With Password. Please preserve the {{EMAIL}} substring")
static let loginWithEmailLimitHeader = NSLocalizedString("Log in with email failed, please enter the password for {{EMAIL}}", comment: "Header for Enter Password UI, when the user performed too many requests")
+ /// Returns a formatted Secondary Action String for Optional Username and password login
+ ///
+ static var usernameAndPasswordOption: NSAttributedString {
+ let output = NSMutableAttributedString(string: String(), attributes: [
+ .font: NSFont.preferredFont(forTextStyle: .subheadline)
+ ])
+
+ let prefix = NSLocalizedString("We'll email you a code to log in, \nor you can", comment: "Option to login with username and password *PREFIX*: printed in dark color")
+ let suffix = NSLocalizedString("log in manually.", comment: "Option to login with username and password *SUFFIX*: Concatenated with a space, after the PREFIX, and printed in blue")
+
+ output.append(string: prefix, foregroundColor: NSColor(studioColor: ColorStudio.gray60))
+ output.append(string: " ")
+ output.append(string: suffix, foregroundColor: NSColor(studioColor: ColorStudio.spBlue60))
+
+ return output
+ }
+
}
private enum MagicLinkStrings {
diff --git a/Simplenote/NSMutableAttributedString+Simplenote.swift b/Simplenote/NSMutableAttributedString+Simplenote.swift
index 872e0ca9..f9a933f0 100644
--- a/Simplenote/NSMutableAttributedString+Simplenote.swift
+++ b/Simplenote/NSMutableAttributedString+Simplenote.swift
@@ -21,8 +21,13 @@ extension NSMutableAttributedString {
/// Appends the specified String
///
- func append(string: String) {
- let string = NSAttributedString(string: string)
+ func append(string: String, foregroundColor: NSColor? = nil) {
+ var attributes = [NSAttributedString.Key: Any]()
+ if let foregroundColor = foregroundColor {
+ attributes[.foregroundColor] = foregroundColor
+ }
+
+ let string = NSAttributedString(string: string, attributes: attributes)
append(string)
}