From 83cfbfb09dbc31a4e429f88efc516ba3782023a2 Mon Sep 17 00:00:00 2001 From: Charlie Scheer Date: Tue, 10 Sep 2024 20:14:26 -1000 Subject: [PATCH 1/5] Added convenience function to append attributed strings with color --- Simplenote/NSMutableAttributedString+Simplenote.swift | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/Simplenote/NSMutableAttributedString+Simplenote.swift b/Simplenote/NSMutableAttributedString+Simplenote.swift index 872e0ca99..f9a933f09 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) } From 5b6d89e8a771304e6a81540176751569199b2b13 Mon Sep 17 00:00:00 2001 From: Charlie Scheer Date: Tue, 10 Sep 2024 20:14:55 -1000 Subject: [PATCH 2/5] Added back up link to login with password --- Simplenote/AuthViewController+Swift.swift | 7 +++++ Simplenote/AuthViewController.xib | 2 +- Simplenote/AuthenticationMode.swift | 34 ++++++++++++++++++++--- 3 files changed, 38 insertions(+), 5 deletions(-) diff --git a/Simplenote/AuthViewController+Swift.swift b/Simplenote/AuthViewController+Swift.swift index 14410db44..598af38db 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 @@ -226,6 +228,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 99cfdb123..0ca3b4302 100644 --- a/Simplenote/AuthViewController.xib +++ b/Simplenote/AuthViewController.xib @@ -142,7 +142,7 @@ - + diff --git a/Simplenote/AuthenticationMode.swift b/Simplenote/AuthenticationMode.swift index 988cd9c0f..f871b2933 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: LoginStrings.loginWithEmailEmailHeader, 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 { From 47ed1a888355232e0da25ffda757e88a70a5f99e Mon Sep 17 00:00:00 2001 From: Charlie Scheer Date: Wed, 11 Sep 2024 18:10:05 -1000 Subject: [PATCH 3/5] Make authview update the username field with state on view change --- Simplenote/AuthViewController+Swift.swift | 1 + 1 file changed, 1 insertion(+) diff --git a/Simplenote/AuthViewController+Swift.swift b/Simplenote/AuthViewController+Swift.swift index 598af38db..2bfd99985 100644 --- a/Simplenote/AuthViewController+Swift.swift +++ b/Simplenote/AuthViewController+Swift.swift @@ -169,6 +169,7 @@ extension AuthViewController { codeTextField.isHidden = !inputElements.contains(.code) actionsSeparatorView.isHidden = !inputElements.contains(.actionSeparator) + usernameField.stringValue = state.username } /// Drops any Errors onscreen From 2ffb35e5876a8bdbde7ec205737fb738dc60a5ef Mon Sep 17 00:00:00 2001 From: Charlie Scheer Date: Wed, 11 Sep 2024 18:11:08 -1000 Subject: [PATCH 4/5] Removed header for username/password view --- Simplenote/AuthenticationMode.swift | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Simplenote/AuthenticationMode.swift b/Simplenote/AuthenticationMode.swift index f871b2933..b71f9aedd 100644 --- a/Simplenote/AuthenticationMode.swift +++ b/Simplenote/AuthenticationMode.swift @@ -127,7 +127,7 @@ extension AuthenticationMode { } static var loginWithUsernameAndPassword: AuthenticationMode { - buildLoginWithPasswordMode(header: LoginStrings.loginWithEmailEmailHeader, includeUsername: true) + buildLoginWithPasswordMode(header: nil, includeUsername: true) } /// Auth Mode: Login with Username + Password + Rate Limiting Header @@ -138,7 +138,7 @@ extension AuthenticationMode { /// Builds the loginWithPassword Mode with the specified Header /// - private static func buildLoginWithPasswordMode(header: String, includeUsername: Bool = false) -> AuthenticationMode { + 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, From 7b14cbda99f5bf77a7e9e19eb12e1415869493e8 Mon Sep 17 00:00:00 2001 From: Jorge Leandro Perez Date: Thu, 12 Sep 2024 10:19:54 -0300 Subject: [PATCH 5/5] AuthViewController: Wires nextResponder --- Simplenote/AuthViewController+Swift.swift | 1 + 1 file changed, 1 insertion(+) diff --git a/Simplenote/AuthViewController+Swift.swift b/Simplenote/AuthViewController+Swift.swift index 2bfd99985..01599689a 100644 --- a/Simplenote/AuthViewController+Swift.swift +++ b/Simplenote/AuthViewController+Swift.swift @@ -170,6 +170,7 @@ extension AuthViewController { actionsSeparatorView.isHidden = !inputElements.contains(.actionSeparator) usernameField.stringValue = state.username + usernameField.textField?.nextResponder = passwordField.textField } /// Drops any Errors onscreen