Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Magic links: Tweaks and updates #1198

Merged
merged 8 commits into from
Jul 26, 2024
4 changes: 4 additions & 0 deletions Simplenote.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -338,6 +338,7 @@
BACA687C2C0A764C005409C1 /* KeychainPasswordItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = BACA687A2C0A7634005409C1 /* KeychainPasswordItem.swift */; };
BAD4ECC026E6FC0A00881CC4 /* markdown-light.css in Resources */ = {isa = PBXBuildFile; fileRef = BAF8D5DB26AE3BE800CA9383 /* markdown-light.css */; };
BAE66CAA26AF647500398FF3 /* Remote.swift in Sources */ = {isa = PBXBuildFile; fileRef = BA938CEB26ACFF4A00BE5A1D /* Remote.swift */; };
BAEBDD4A2C52C14500335700 /* SPAuthenticationTextField+Simplenote.swift in Sources */ = {isa = PBXBuildFile; fileRef = BAEBDD492C52C14500335700 /* SPAuthenticationTextField+Simplenote.swift */; };
BAF1B0C32BC9B1C500B55F73 /* NoteWindow.swift in Sources */ = {isa = PBXBuildFile; fileRef = BAF1B0C12BC9B1C500B55F73 /* NoteWindow.swift */; };
BAF1B0C92BCEDFD400B55F73 /* NoteWindowControllersManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = BAF1B0C72BCDDA9600B55F73 /* NoteWindowControllersManager.swift */; };
BAF4E5DE2C49C08A009B891F /* SPNavigationController.swift in Sources */ = {isa = PBXBuildFile; fileRef = BAF4E5DD2C49C08A009B891F /* SPNavigationController.swift */; };
Expand Down Expand Up @@ -807,6 +808,7 @@
BACA68752C0A72F3005409C1 /* NSString+Intents.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "NSString+Intents.swift"; sourceTree = "<group>"; };
BACA68772C0A7537005409C1 /* KeychainManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KeychainManager.swift; sourceTree = "<group>"; };
BACA687A2C0A7634005409C1 /* KeychainPasswordItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KeychainPasswordItem.swift; sourceTree = "<group>"; };
BAEBDD492C52C14500335700 /* SPAuthenticationTextField+Simplenote.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "SPAuthenticationTextField+Simplenote.swift"; sourceTree = "<group>"; };
BAF1B0C12BC9B1C500B55F73 /* NoteWindow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NoteWindow.swift; sourceTree = "<group>"; };
BAF1B0C72BCDDA9600B55F73 /* NoteWindowControllersManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NoteWindowControllersManager.swift; sourceTree = "<group>"; };
BAF4E5DD2C49C08A009B891F /* SPNavigationController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SPNavigationController.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -1244,6 +1246,7 @@
BA2C65CA26FE996100FA84E1 /* NSButton+Extensions.swift */,
BA52005C2BC88397003F1B75 /* NSManagedObjectContext+Simplenote.swift */,
BAF4E5DF2C49C17A009B891F /* NSViewController+Simplenote.swift */,
BAEBDD492C52C14500335700 /* SPAuthenticationTextField+Simplenote.swift */,
);
name = Extensions;
sourceTree = "<group>";
Expand Down Expand Up @@ -2243,6 +2246,7 @@
B5ACE42F24785D8C00AB02C7 /* BackgroundView.swift in Sources */,
B5F5415525F0137100CAF52C /* MagicLinkAuthenticator.swift in Sources */,
B58A71BF258422CC00601641 /* NSBezierPath+Simplenote.swift in Sources */,
BAEBDD4A2C52C14500335700 /* SPAuthenticationTextField+Simplenote.swift in Sources */,
B587D7EE2C2217B1006645CF /* LoginRemoteProtocol.swift in Sources */,
BAF4E5DE2C49C08A009B891F /* SPNavigationController.swift in Sources */,
B5DD0F922476309000C8DD41 /* NoteTableCellView.swift in Sources */,
Expand Down
28 changes: 12 additions & 16 deletions Simplenote/AuthViewController+Swift.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,6 @@ extension AuthViewController {

@objc
func setupInterface() {
if state == nil {
state = AuthenticationState()
}

simplenoteTitleView.stringValue = "Simplenote"
simplenoteSubTitleView.textColor = .simplenoteGray50Color
simplenoteSubTitleView.stringValue = NSLocalizedString("The simplest way to keep notes.", comment: "Simplenote subtitle")
Expand Down Expand Up @@ -184,7 +180,7 @@ extension AuthViewController {
///
@objc
func ensureFirstTextFieldIsFirstResponder() {
firstVisibleTextField?.textField.becomeFirstResponder()
firstVisibleTextField?.becomeFirstResponder()
view.needsDisplay = true
}
}
Expand All @@ -203,32 +199,32 @@ extension AuthViewController {
ensureFirstTextFieldIsFirstResponder()
}

private func authViewController(with mode: AuthenticationMode, state: AuthenticationState) -> AuthViewController {
let vc = AuthViewController()
vc.authenticator = authenticator
vc.state = state
vc.mode = mode
private func pushNewAuthViewController(with mode: AuthenticationMode, state: AuthenticationState) {
guard let authVC = AuthViewController(mode: mode, state: state) else {
return
}
authVC.authenticator = authenticator

return vc
containingNavigationController?.push(authVC)
}

@objc
func pushEmailLoginView() {
containingNavigationController?.push(authViewController(with: .requestLoginCode, state: state))
pushNewAuthViewController(with: .requestLoginCode, state: state)
}

@objc
func pushSignupView() {
containingNavigationController?.push(authViewController(with: .signup, state: state))
pushNewAuthViewController(with: .signup, state: state)
}

@objc
func pushPasswordView() {
containingNavigationController?.push(authViewController(with: .loginWithPassword(), state: state))
pushNewAuthViewController(with: .loginWithPassword, state: state)
}

func pushCodeLoginView() {
containingNavigationController?.push(authViewController(with: .loginWithCode, state: state))
pushNewAuthViewController(with: .loginWithCode, state: state)
}
}

Expand All @@ -239,7 +235,7 @@ extension AuthViewController {

@IBAction
func switchToPasswordAuth(_ sender: Any) {
mode = AuthenticationMode.loginWithPassword(header: nil)
mode = AuthenticationMode.loginWithPassword
}

@objc
Expand Down
1 change: 1 addition & 0 deletions Simplenote/AuthViewController.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
@property (nonatomic, strong) AuthenticationMode *mode;
@property (nonatomic, strong) AuthenticationState *state;

- (instancetype)initWithMode:(AuthenticationMode*)mode state:(AuthenticationState*)state;
- (void)pressedLogInWithPassword;
- (void)pressedLoginWithMagicLink;
- (void)pressedSignUp;
Expand Down
12 changes: 12 additions & 0 deletions Simplenote/AuthViewController.m
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,23 @@ - (void)dealloc
[[NSNotificationCenter defaultCenter] removeObserver: self];
}

- (instancetype)initWithMode:(AuthenticationMode*)mode state:(AuthenticationState*)state;
{
if (self = [super init]) {
self.validator = [SPAuthenticationValidator new];
self.mode = mode;
self.state = state;
}

return self;
}

- (instancetype)init
{
if (self = [super init]) {
self.validator = [SPAuthenticationValidator new];
self.mode = [AuthenticationMode onboarding];
self.state = [AuthenticationState new];
}

return self;
Expand Down
2 changes: 1 addition & 1 deletion Simplenote/AuthViewController.xib
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@
<constraint firstAttribute="height" constant="40" id="hpG-uZ-e1S"/>
</constraints>
<userDefinedRuntimeAttributes>
<userDefinedRuntimeAttribute type="boolean" keyPath="secure" value="YES"/>
<userDefinedRuntimeAttribute type="boolean" keyPath="secure" value="NO"/>
</userDefinedRuntimeAttributes>
</customView>
<customView translatesAutoresizingMaskIntoConstraints="NO" id="Epn-oY-sfo" userLabel="Action View">
Expand Down
5 changes: 3 additions & 2 deletions Simplenote/AuthWindowController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ class AuthWindowController: NSWindowController, SPAuthenticationInterface {
}

init() {
self.authViewController = AuthViewController()
self.authViewController = AuthViewController(mode: .onboarding, state: AuthenticationState())
let navigationController = SPNavigationController(initialViewController: authViewController)
let window = NSWindow(contentViewController: navigationController)
window.styleMask = [.borderless, .closable, .titled, .fullSizeContentView]
Expand Down Expand Up @@ -78,8 +78,9 @@ extension AuthWindowController {
}

let authViewController = AuthViewController()
let navigationController = SPNavigationController(initialViewController: authViewController)
authViewController.authenticator = authenticator
window.transition(to: authViewController)
window.transition(to: navigationController)
}

func switchToMagicLinkRequestedUI(email: String) {
Expand Down
7 changes: 4 additions & 3 deletions Simplenote/AuthenticationMode.swift
Original file line number Diff line number Diff line change
Expand Up @@ -120,9 +120,9 @@ extension AuthenticationMode {

/// Auth Mode: Login with Username + Password
///
static func loginWithPassword(header: String? = nil) -> AuthenticationMode {
static var loginWithPassword: AuthenticationMode {
AuthenticationMode(title: NSLocalizedString("Log In with Password", comment: "LogIn Interface Title"),
header: header,
header: LoginStrings.loginWithEmailEmailHeader,
inputElements: [.password],
actions: [
AuthenticationActionDescriptor(name: .primary,
Expand Down Expand Up @@ -195,10 +195,11 @@ private enum LoginStrings {
static let switchAction = NSLocalizedString("Sign Up", comment: "Title of button for signing up")
static let switchTip = NSLocalizedString("Need an account?", comment: "Link to create an account")
static let wordpressAction = NSLocalizedString("Log in with WordPress.com", comment: "Title to use wordpress login instead of email")
static let loginWithEmailEmailHeader = NSLocalizedString("Enter the password for the account {{EMAIL}}", comment: "Header for Login With Password. Please preserve the {{EMAIL}} substring")
}

private enum MagicLinkStrings {
static let primaryAction = NSLocalizedString("Instantly Log In with Email", comment: "Title of button for logging in")
static let primaryAction = NSLocalizedString("Log in with email", comment: "Title of button for logging in")
static let primaryAnimationText = NSLocalizedString("Requesting Email...", comment: "Title of button for logging in")
static let secondaryAction = NSLocalizedString("Continue with Password", comment: "Continue with Password Action")
static let switchAction = NSLocalizedString("Sign Up", comment: "Title of button for signing up")
Expand Down
13 changes: 13 additions & 0 deletions Simplenote/SPAuthenticationTextField+Simplenote.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import Simperium_OSX

extension SPAuthenticationTextField {
@discardableResult
override open func becomeFirstResponder() -> Bool {
let responderStatus = textField.becomeFirstResponder()

let selectedRange = textField.currentEditor()?.selectedRange
textField.currentEditor()?.selectedRange = NSMakeRange(selectedRange?.length ?? .zero, .zero)

return responderStatus
}
}
18 changes: 18 additions & 0 deletions Simplenote/SPNavigationController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,12 @@ class SPNavigationController: NSViewController {
backButton = button
backButton.isHidden = hideBackButton
button.bezelStyle = .accessoryBarAction
button.cell?.isBordered = false
button.contentTintColor = .darkGray
button.wantsLayer = true
button.layer?.cornerRadius = 5
let trackingArea = NSTrackingArea(rect: backButton.bounds, options: [.mouseEnteredAndExited, .activeAlways], owner: self)
button.addTrackingArea(trackingArea)

view.addSubview(backButton)
NSLayoutConstraint.activate([
Expand Down Expand Up @@ -192,3 +198,15 @@ class SPNavigationController: NSViewController {
}
}
}

// MARK: - Button Hover Color Animation
//
extension SPNavigationController {
override func mouseEntered(with event: NSEvent) {
backButton.layer?.backgroundColor = NSColor.lightGray.withAlphaComponent(0.1).cgColor
}

override func mouseExited(with event: NSEvent) {
backButton.layer?.backgroundColor = .clear
}
}