From 5967bd91c6eb3b5eb6716b87e595ed558bd7a52d Mon Sep 17 00:00:00 2001 From: kkostiuk <kateryna.kostiuk@savoirfairelinux.com> Date: Tue, 20 Apr 2021 17:22:51 -0400 Subject: [PATCH] account: show when username available Change-Id: I8300e04446b37c68d4c19b457125410507c09b5c --- Ring/Ring/Constants/Generated/Strings.swift | 2 ++ .../Features/Me/Me/MeViewController.swift | 11 +++----- Ring/Ring/Features/Me/Me/MeViewModel.swift | 4 ++- .../CreateAccountViewController.storyboard | 26 ++++++++++++++----- .../CreateAccountViewController.swift | 10 ++++++- .../CreateAccountViewModel.swift | 21 ++++++++++++--- .../Resources/en.lproj/Localizable.strings | 1 + 7 files changed, 56 insertions(+), 19 deletions(-) diff --git a/Ring/Ring/Constants/Generated/Strings.swift b/Ring/Ring/Constants/Generated/Strings.swift index 32308c53d..caa3c3ae7 100644 --- a/Ring/Ring/Constants/Generated/Strings.swift +++ b/Ring/Ring/Constants/Generated/Strings.swift @@ -370,6 +370,8 @@ internal enum L10n { internal static let usernameNotRegisteredMessage = L10n.tr("Localizable", "createAccount.UsernameNotRegisteredMessage") /// Network error internal static let usernameNotRegisteredTitle = L10n.tr("Localizable", "createAccount.UsernameNotRegisteredTitle") + /// username is available + internal static let usernameValid = L10n.tr("Localizable", "createAccount.usernameValid") /// Adding account internal static let waitCreateAccountTitle = L10n.tr("Localizable", "createAccount.waitCreateAccountTitle") } diff --git a/Ring/Ring/Features/Me/Me/MeViewController.swift b/Ring/Ring/Features/Me/Me/MeViewController.swift index a236c2c61..7fe8cbfc8 100644 --- a/Ring/Ring/Features/Me/Me/MeViewController.swift +++ b/Ring/Ring/Features/Me/Me/MeViewController.swift @@ -979,13 +979,10 @@ class MeViewController: EditProfileViewController, StoryboardBased, ViewModelBas .subscribe(onNext: { [weak controller] (state) in //update name lookup message guard let textFields = controller?.textFields, - textFields.count >= 2 else { return } - if state.isAvailable { - textFields[1].text = "" - } else { - textFields[1].text = state.message - } - }, onError: { (_) in + textFields.count >= 2 else { return } + textFields[1].text = state.message + textFields[1].textColor = state.isAvailable ? UIColor.jamiSuccess : UIColor.jamiFailure + }, onError: { (_) in }) .disposed(by: nameRegistrationBag) guard let textFields = controller.textFields else { diff --git a/Ring/Ring/Features/Me/Me/MeViewModel.swift b/Ring/Ring/Features/Me/Me/MeViewModel.swift index 45de8c5a9..c2c9f5ac5 100644 --- a/Ring/Ring/Features/Me/Me/MeViewModel.swift +++ b/Ring/Ring/Features/Me/Me/MeViewModel.swift @@ -440,8 +440,10 @@ class MeViewModel: ViewModel, Stateable { self?.usernameValidationState.accept(.invalid(message: L10n.CreateAccount.invalidUsername)) case .alreadyTaken: self?.usernameValidationState.accept(.unavailable(message: L10n.CreateAccount.usernameAlreadyTaken)) + case .valid: + self?.usernameValidationState.accept(.available(message: L10n.CreateAccount.usernameValid)) default: - self?.usernameValidationState.accept(.available) + self?.usernameValidationState.accept(.unknown) } }) .disposed(by: disposeBug) diff --git a/Ring/Ring/Features/Walkthrough/CreateAccount/CreateAccountViewController.storyboard b/Ring/Ring/Features/Walkthrough/CreateAccount/CreateAccountViewController.storyboard index 54b444b78..2d8a58194 100644 --- a/Ring/Ring/Features/Walkthrough/CreateAccount/CreateAccountViewController.storyboard +++ b/Ring/Ring/Features/Walkthrough/CreateAccount/CreateAccountViewController.storyboard @@ -1,9 +1,9 @@ <?xml version="1.0" encoding="UTF-8"?> -<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="16096" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES" initialViewController="jUh-Lp-ulu"> +<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="17701" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES" initialViewController="jUh-Lp-ulu"> <device id="retina5_5" orientation="portrait" appearance="light"/> <dependencies> <deployment identifier="iOS"/> - <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="16087"/> + <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="17703"/> <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/> </dependencies> <scenes> @@ -70,8 +70,8 @@ <userDefinedRuntimeAttribute type="boolean" keyPath="roundedCorners" value="YES"/> </userDefinedRuntimeAttributes> </textField> - <label hidden="YES" opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="this username is not available" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="qDW-b2-4NQ"> - <rect key="frame" x="15" y="55" width="179" height="16"/> + <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="qDW-b2-4NQ"> + <rect key="frame" x="15" y="55" width="0.0" height="0.0"/> <fontDescription key="fontDescription" type="system" pointSize="13"/> <color key="textColor" red="0.83137254900000002" green="0.054901960780000002" blue="0.070588235289999995" alpha="0.90000000000000002" colorSpace="custom" customColorSpace="calibratedRGB"/> <nil key="highlightedColor"/> @@ -173,12 +173,12 @@ <color key="onTintColor" red="0.12156862745098039" green="0.28627450980392155" blue="0.44313725490196076" alpha="1" colorSpace="custom" customColorSpace="sRGB"/> </switch> <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Enable notifications" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="v2K-7x-35g" userLabel="Enable Notifications Label"> - <rect key="frame" x="30" y="210.66666666666666" width="151.66666666666666" height="21"/> + <rect key="frame" x="30" y="210.66666666666666" width="152" height="21"/> <fontDescription key="fontDescription" type="system" weight="thin" pointSize="18"/> <color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="0.5" colorSpace="custom" customColorSpace="sRGB"/> <nil key="highlightedColor"/> </label> - <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="05l-0O-Ql0" customClass="DesignableButton" customModule="Ring" customModuleProvider="target"> + <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="05l-0O-Ql0" customClass="DesignableButton" customModule="Ring" customModuleProvider="target"> <rect key="frame" x="20" y="266.66666666666669" width="374" height="50"/> <constraints> <constraint firstAttribute="height" relation="greaterThanOrEqual" constant="50" id="501-bI-E5J"/> @@ -275,4 +275,18 @@ <point key="canvasLocation" x="1944.8" y="563.56821589205401"/> </scene> </scenes> + <designables> + <designable name="05l-0O-Ql0"> + <size key="intrinsicContentSize" width="121" height="34"/> + </designable> + <designable name="E18-Hh-7He"> + <size key="intrinsicContentSize" width="81" height="23.333333333333332"/> + </designable> + <designable name="ODL-4B-fCm"> + <size key="intrinsicContentSize" width="142.33333333333334" height="22"/> + </designable> + <designable name="jhr-UL-eCl"> + <size key="intrinsicContentSize" width="75.333333333333329" height="22"/> + </designable> + </designables> </document> diff --git a/Ring/Ring/Features/Walkthrough/CreateAccount/CreateAccountViewController.swift b/Ring/Ring/Features/Walkthrough/CreateAccount/CreateAccountViewController.swift index 6e15130fa..bb8b01a5a 100644 --- a/Ring/Ring/Features/Walkthrough/CreateAccount/CreateAccountViewController.swift +++ b/Ring/Ring/Features/Walkthrough/CreateAccount/CreateAccountViewController.swift @@ -230,7 +230,7 @@ class CreateAccountViewController: UIViewController, StoryboardBased, ViewModelB // handle registration error self.viewModel.usernameValidationState.asObservable() - .map { $0.isAvailable } + .map { $0.isDefault } .skipUntil(self.usernameTextField.rx.controlEvent(UIControl.Event.editingDidBegin)) .bind(to: self.registerUsernameErrorLabel.rx.isHidden) .disposed(by: self.disposeBag) @@ -239,6 +239,14 @@ class CreateAccountViewController: UIViewController, StoryboardBased, ViewModelB .skipUntil(self.usernameTextField.rx.controlEvent(UIControl.Event.editingDidBegin)) .bind(to: self.registerUsernameErrorLabel.rx.text) .disposed(by: self.disposeBag) + self.viewModel.usernameValidationState.asObservable() + .map { $0.isAvailable } + .skipUntil(self.usernameTextField.rx.controlEvent(UIControl.Event.editingDidBegin)) + .observeOn(MainScheduler.instance) + .subscribe { [weak self] available in + self?.registerUsernameErrorLabel.textColor = available ? UIColor.jamiSuccess : UIColor.jamiFailure + } + .disposed(by: self.disposeBag) // handle creation state self.viewModel.createState diff --git a/Ring/Ring/Features/Walkthrough/CreateAccount/CreateAccountViewModel.swift b/Ring/Ring/Features/Walkthrough/CreateAccount/CreateAccountViewModel.swift index 7ef494f9b..301586fe4 100644 --- a/Ring/Ring/Features/Walkthrough/CreateAccount/CreateAccountViewModel.swift +++ b/Ring/Ring/Features/Walkthrough/CreateAccount/CreateAccountViewModel.swift @@ -48,14 +48,23 @@ enum PasswordValidationState { enum UsernameValidationState { case unknown - case available + case available(message: String) case lookingForAvailibility(message: String) case invalid(message: String) case unavailable(message: String) var isAvailable: Bool { switch self { - case .available, .unknown: + case .available: + return true + default: + return false + } + } + + var isDefault: Bool { + switch self { + case .unknown: return true default: return false @@ -64,8 +73,10 @@ enum UsernameValidationState { var message: String { switch self { - case .available, .unknown: + case .unknown: return "" + case .available(let message): + return message case .lookingForAvailibility(let message): return message case .invalid(let message): @@ -274,8 +285,10 @@ class CreateAccountViewModel: Stateable, ViewModel { self?.usernameValidationState.accept(.invalid(message: L10n.CreateAccount.invalidUsername)) case .alreadyTaken: self?.usernameValidationState.accept(.unavailable(message: L10n.CreateAccount.usernameAlreadyTaken)) + case .valid: + self?.usernameValidationState.accept(.available(message: L10n.CreateAccount.usernameValid)) default: - self?.usernameValidationState.accept(.available) + self?.usernameValidationState.accept(.unknown) } }) .disposed(by: self.disposeBag) diff --git a/Ring/Ring/Resources/en.lproj/Localizable.strings b/Ring/Ring/Resources/en.lproj/Localizable.strings index bace2cca5..c44b4d6a7 100644 --- a/Ring/Ring/Resources/en.lproj/Localizable.strings +++ b/Ring/Ring/Resources/en.lproj/Localizable.strings @@ -83,6 +83,7 @@ "createAccount.lookingForUsernameAvailability" = "looking for availability…"; "createAccount.invalidUsername" = "invalid username"; "createAccount.usernameAlreadyTaken" = "username already taken"; +"createAccount.usernameValid" = "username is available"; "createAccount.loading" = "Loading"; "createAccount.waitCreateAccountTitle" = "Adding account"; "createAccount.RegisterAUsername" = "Register a username"; -- GitLab