| | 1 | | using System; |
| | 2 | | using System.Net.Mail; |
| | 3 | | using System.Text.RegularExpressions; |
| | 4 | | using DCL.Helpers; |
| | 5 | | using TMPro; |
| | 6 | | using UnityEngine; |
| | 7 | | using UnityEngine.UI; |
| | 8 | |
|
| | 9 | | namespace SignupHUD |
| | 10 | | { |
| | 11 | | public interface ISignupHUDView : IDisposable |
| | 12 | | { |
| | 13 | | delegate void NameScreenDone(string newName, string newEmail); |
| | 14 | |
|
| | 15 | | event NameScreenDone OnNameScreenNext; |
| | 16 | | event Action OnEditAvatar; |
| | 17 | | event Action OnTermsOfServiceAgreed; |
| | 18 | | event Action OnTermsOfServiceBack; |
| | 19 | | event Action<string> OnLinkClicked; |
| | 20 | |
|
| | 21 | | void SetVisibility(bool visible); |
| | 22 | | void ShowNameScreen(); |
| | 23 | | void ShowTermsOfServiceScreen(); |
| | 24 | | } |
| | 25 | |
|
| | 26 | | public class SignupHUDView : MonoBehaviour, ISignupHUDView |
| | 27 | | { |
| | 28 | | private const int MIN_NAME_LENGTH = 1; |
| | 29 | | private const int MAX_NAME_LENGTH = 15; |
| | 30 | |
|
| | 31 | | public event ISignupHUDView.NameScreenDone OnNameScreenNext; |
| | 32 | | public event Action OnEditAvatar; |
| | 33 | | public event Action OnTermsOfServiceAgreed; |
| | 34 | | public event Action OnTermsOfServiceBack; |
| | 35 | | public event Action<string> OnLinkClicked; |
| | 36 | |
|
| | 37 | | [Header("Name and Email Screen")] |
| | 38 | | [SerializeField] internal RectTransform nameAndEmailPanel; |
| | 39 | |
|
| | 40 | | [SerializeField] internal Button nameAndEmailNextButton; |
| | 41 | | [SerializeField] internal TMP_InputField nameInputField; |
| | 42 | | [SerializeField] internal GameObject nameInputFieldFullOrInvalid; |
| | 43 | | [SerializeField] internal GameObject nameInputInvalidLabel; |
| | 44 | | [SerializeField] internal TextMeshProUGUI nameCurrentCharacters; |
| | 45 | | [SerializeField] internal GameObject emailInputFieldInvalid; |
| | 46 | | [SerializeField] internal TMP_InputField emailInputField; |
| | 47 | | [SerializeField] internal GameObject emailInputInvalidLabel; |
| | 48 | | [SerializeField] internal Color colorForCharLimit; |
| | 49 | |
|
| | 50 | | [Header("Terms of Service Screen")] |
| | 51 | | [SerializeField] internal RectTransform termsOfServicePanel; |
| | 52 | |
|
| | 53 | | [SerializeField] internal Button editAvatarButton; |
| | 54 | | [SerializeField] internal ScrollRect termsOfServiceScrollView; |
| | 55 | | [SerializeField] internal Button termsOfServiceBackButton; |
| | 56 | | [SerializeField] internal Button termsOfServiceAgreeButton; |
| | 57 | | [SerializeField] internal RawImage avatarPic; |
| | 58 | |
|
| | 59 | | private ILazyTextureObserver snapshotTextureObserver; |
| | 60 | |
|
| | 61 | | private void Awake() |
| | 62 | | { |
| 9 | 63 | | InitNameAndEmailScreen(); |
| 9 | 64 | | InitTermsOfServicesScreen(); |
| 9 | 65 | | } |
| | 66 | |
|
| | 67 | | private void InitNameAndEmailScreen() |
| | 68 | | { |
| 9 | 69 | | UserProfile userProfile = UserProfile.GetOwnUserProfile(); |
| 9 | 70 | | snapshotTextureObserver = userProfile.snapshotObserver; |
| 9 | 71 | | snapshotTextureObserver.AddListener(OnFaceSnapshotReady); |
| | 72 | |
|
| 9 | 73 | | nameAndEmailNextButton.interactable = false; |
| 9 | 74 | | nameCurrentCharacters.text = $"{0}/{MAX_NAME_LENGTH}"; |
| 9 | 75 | | nameInputField.characterLimit = MAX_NAME_LENGTH; |
| 9 | 76 | | nameInputInvalidLabel.SetActive(false); |
| 9 | 77 | | nameInputFieldFullOrInvalid.SetActive(false); |
| 9 | 78 | | emailInputFieldInvalid.SetActive(false); |
| 9 | 79 | | emailInputInvalidLabel.SetActive(false); |
| | 80 | |
|
| 9 | 81 | | nameInputField.onValueChanged.AddListener((text) => |
| | 82 | | { |
| 3 | 83 | | UpdateNameAndEmailNextButton(); |
| 3 | 84 | | nameCurrentCharacters.text = $"{text.Length} / {MAX_NAME_LENGTH}"; |
| 3 | 85 | | nameCurrentCharacters.color = text.Length < MAX_NAME_LENGTH ? Color.black : colorForCharLimit; |
| 3 | 86 | | nameInputInvalidLabel.SetActive(!IsValidName(text)); |
| 3 | 87 | | nameInputFieldFullOrInvalid.SetActive(text.Length >= MAX_NAME_LENGTH || !IsValidName(text)); |
| 3 | 88 | | }); |
| | 89 | |
|
| 9 | 90 | | emailInputField.onValueChanged.AddListener((text) => |
| | 91 | | { |
| 2 | 92 | | emailInputFieldInvalid.SetActive(!IsValidEmail(text)); |
| 2 | 93 | | emailInputInvalidLabel.SetActive(!IsValidEmail(text)); |
| 2 | 94 | | UpdateNameAndEmailNextButton(); |
| 2 | 95 | | }); |
| | 96 | |
|
| 9 | 97 | | nameAndEmailNextButton.onClick.AddListener(() => OnNameScreenNext?.Invoke(nameInputField.text, emailInputFie |
| 9 | 98 | | editAvatarButton.onClick.AddListener(() => OnEditAvatar?.Invoke()); |
| 9 | 99 | | } |
| | 100 | |
|
| | 101 | | private void InitTermsOfServicesScreen() |
| | 102 | | { |
| 9 | 103 | | termsOfServiceScrollView.onValueChanged.AddListener(pos => |
| | 104 | | { |
| 0 | 105 | | if (pos.y <= 0.1f) |
| 0 | 106 | | termsOfServiceAgreeButton.interactable = true; |
| 0 | 107 | | }); |
| | 108 | |
|
| 9 | 109 | | termsOfServiceAgreeButton.interactable = false; |
| 9 | 110 | | termsOfServiceBackButton.onClick.AddListener(() => OnTermsOfServiceBack?.Invoke()); |
| 9 | 111 | | termsOfServiceAgreeButton.onClick.AddListener(() => OnTermsOfServiceAgreed?.Invoke()); |
| 9 | 112 | | } |
| | 113 | |
|
| 0 | 114 | | private void OnFaceSnapshotReady(Texture2D texture) { avatarPic.texture = texture; } |
| | 115 | |
|
| 4 | 116 | | public void SetVisibility(bool visible) { gameObject.SetActive(visible); } |
| | 117 | |
|
| | 118 | | public void ShowNameScreen() |
| | 119 | | { |
| 1 | 120 | | nameAndEmailPanel.gameObject.SetActive(true); |
| 1 | 121 | | termsOfServicePanel.gameObject.SetActive(false); |
| 1 | 122 | | } |
| | 123 | |
|
| | 124 | | public void ShowTermsOfServiceScreen() |
| | 125 | | { |
| 1 | 126 | | nameAndEmailPanel.gameObject.SetActive(false); |
| 1 | 127 | | termsOfServicePanel.gameObject.SetActive(true); |
| 1 | 128 | | } |
| | 129 | |
|
| | 130 | | public void Dispose() |
| | 131 | | { |
| 0 | 132 | | snapshotTextureObserver.RemoveListener(OnFaceSnapshotReady); |
| | 133 | |
|
| 0 | 134 | | if (this != null) |
| 0 | 135 | | Destroy(gameObject); |
| 0 | 136 | | } |
| | 137 | |
|
| | 138 | | internal void UpdateNameAndEmailNextButton() |
| | 139 | | { |
| 9 | 140 | | string name = nameInputField.text; |
| 9 | 141 | | string email = emailInputField.text; |
| | 142 | |
|
| 9 | 143 | | nameAndEmailNextButton.interactable = name.Length >= MIN_NAME_LENGTH && IsValidName(name) && IsValidEmail(em |
| 9 | 144 | | } |
| | 145 | |
|
| | 146 | | private bool IsValidEmail(string email) |
| | 147 | | { |
| 12 | 148 | | if (email.Length == 0) |
| 4 | 149 | | return true; |
| | 150 | |
|
| | 151 | | try |
| | 152 | | { |
| 8 | 153 | | MailAddress mailAddress = new MailAddress(email); |
| 4 | 154 | | return mailAddress.Address == email; |
| | 155 | | } |
| 4 | 156 | | catch |
| | 157 | | { |
| 4 | 158 | | return false; |
| | 159 | | } |
| 8 | 160 | | } |
| | 161 | |
|
| 14 | 162 | | private bool IsValidName(string name) { return Regex.IsMatch(name, "^[a-zA-Z0-9]*$"); } |
| | 163 | | } |
| | 164 | | } |