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