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