< Summary

Class:ProfileHUDView
Assembly:ProfileHUD
File(s):/tmp/workspace/unity-renderer/unity-renderer/Assets/Scripts/MainScripts/DCL/Controllers/HUD/ProfileHUD/ProfileHUDView.cs
Covered lines:99
Uncovered lines:29
Coverable lines:128
Total lines:384
Line coverage:77.3% (99 of 128)
Covered branches:0
Total branches:0

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity NPath complexity Sequence coverage
Awake()0%110100%
SetProfile(...)0%220100%
ToggleMenu()0%330100%
HideMenu()0%330100%
SetVisibility(...)0%5.25080%
HandleProfileSnapshot(...)0%110100%
HandleClaimedProfileName(...)0%110100%
HandleUnverifiedProfileName(...)0%3.033085.71%
SetConnectedWalletSectionActive(...)0%110100%
ForceLayoutToRefreshSize()0%110100%
SetActiveUnverifiedNameGOs(...)0%220100%
HandleProfileAddress(...)0%110100%
SetProfileImage(...)0%2100%
OnDestroy()0%220100%
CopyAddress()0%12300%
ShowCopyToast()0%20400%
OnEnable()0%110100%
OnDisable()0%110100%
SetBackpackButtonVisibility(...)0%550100%
ActivateProfileNameEditionMode(...)0%4.034087.5%
UpdateNameCharLimit(...)0%110100%
SetProfileName(...)0%110100%
SetNameRegex(...)0%2100%
IsValidAvatarName(...)0%6200%
ActivateDescriptionEditionMode(...)0%220100%
SelectComponentOnNextFrame()0%5.673033.33%
SetDescription(...)0%110100%
UpdateDescriptionCharLimit(...)0%110100%
SetDescriptionEnabled(...)0%110100%

File(s)

/tmp/workspace/unity-renderer/unity-renderer/Assets/Scripts/MainScripts/DCL/Controllers/HUD/ProfileHUD/ProfileHUDView.cs

#LineLine coverage
 1using System;
 2using System.Collections;
 3using System.Text.RegularExpressions;
 4using TMPro;
 5using UnityEngine;
 6using UnityEngine.UI;
 7using Environment = DCL.Environment;
 8
 9internal class ProfileHUDView : MonoBehaviour
 10{
 11    private const int ADDRESS_CHUNK_LENGTH = 6;
 12    private const int NAME_POSTFIX_LENGTH = 4;
 13    private const float COPY_TOAST_VISIBLE_TIME = 3;
 14
 15    [SerializeField]
 16    internal ShowHideAnimator mainShowHideAnimator;
 17
 18    [SerializeField]
 19    internal ShowHideAnimator menuShowHideAnimator;
 20
 21    [SerializeField]
 22    private RectTransform mainRootLayout;
 23
 24    [SerializeField]
 25    internal GameObject loadingSpinner;
 26
 27    [SerializeField]
 28    internal ShowHideAnimator copyToast;
 29
 30    [SerializeField]
 31    internal GameObject copyTooltip;
 32
 33    [SerializeField]
 34    internal InputAction_Trigger closeAction;
 35
 36    [Header("Hide GOs on claimed name")]
 37    [SerializeField]
 38    internal GameObject[] hideOnNameClaimed;
 39
 40    [Header("Connected wallet sections")]
 41    [SerializeField]
 42    internal GameObject connectedWalletSection;
 43
 44    [SerializeField]
 45    internal GameObject nonConnectedWalletSection;
 46
 47    [Header("Thumbnail")]
 48    [SerializeField]
 49    internal RawImage imageAvatarThumbnail;
 50
 51    [SerializeField]
 52    internal Button buttonToggleMenu;
 53
 54    [Header("Texts")]
 55    [SerializeField]
 56    internal TextMeshProUGUI textName;
 57
 58    [SerializeField]
 59    internal TextMeshProUGUI textPostfix;
 60
 61    [SerializeField]
 62    internal TextMeshProUGUI textAddress;
 63
 64    [Header("Buttons")]
 65    [SerializeField]
 66    internal Button buttonClaimName;
 67
 68    [SerializeField]
 69    internal Button buttonBackpack;
 70
 71    [SerializeField]
 72    internal Button buttonCopyAddress;
 73
 74    [SerializeField]
 75    internal Button buttonLogOut;
 76
 77    [SerializeField]
 78    internal Button buttonSignUp;
 79
 80    [SerializeField]
 81    internal Button_OnPointerDown buttonTermsOfServiceForConnectedWallets;
 82
 83    [SerializeField]
 84    internal Button_OnPointerDown buttonPrivacyPolicyForConnectedWallets;
 85
 86    [SerializeField]
 87    internal Button_OnPointerDown buttonTermsOfServiceForNonConnectedWallets;
 88
 89    [SerializeField]
 90    internal Button_OnPointerDown buttonPrivacyPolicyForNonConnectedWallets;
 91
 92    [Header("Name Edition")]
 93    [SerializeField]
 94    internal Button_OnPointerDown buttonEditName;
 95
 96    [SerializeField]
 97    internal Button_OnPointerDown buttonEditNamePrefix;
 98
 99    [SerializeField]
 100    internal TMP_InputField inputName;
 101
 102    [SerializeField]
 103    internal TextMeshProUGUI textCharLimit;
 104
 105    [SerializeField]
 106    internal ManaCounterView manaCounterView;
 107
 108    [SerializeField]
 109    internal ManaCounterView polygonManaCounterView;
 110
 111    [Header("Tutorial Config")]
 112    [SerializeField]
 113    internal RectTransform backpackTooltipReference;
 114
 115    [Header("Description")]
 116    [SerializeField]
 117    internal TMP_InputField descriptionPreviewInput;
 118
 119    [SerializeField]
 120    internal TMP_InputField descriptionEditionInput;
 121
 122    [SerializeField]
 123    internal GameObject charLimitDescriptionContainer;
 124
 125    [SerializeField]
 126    internal TextMeshProUGUI textCharLimitDescription;
 127
 128    [SerializeField]
 129    internal GameObject descriptionContainer;
 130
 131    private InputAction_Trigger.Triggered closeActionDelegate;
 132
 133    private Coroutine copyToastRoutine = null;
 134    private UserProfile profile = null;
 135    private Regex nameRegex = null;
 136
 137    internal event Action OnOpen;
 138    internal event Action OnClose;
 139
 140    private void Awake()
 141    {
 19142        closeActionDelegate = (x) => HideMenu();
 143
 19144        buttonToggleMenu.onClick.AddListener(ToggleMenu);
 19145        buttonCopyAddress.onClick.AddListener(CopyAddress);
 19146        buttonEditName.onPointerDown += () => ActivateProfileNameEditionMode(true);
 19147        buttonEditNamePrefix.onPointerDown += () => ActivateProfileNameEditionMode(true);
 19148        inputName.onValueChanged.AddListener(UpdateNameCharLimit);
 19149        inputName.onDeselect.AddListener((x) => ActivateProfileNameEditionMode(false));
 19150        descriptionPreviewInput.onSelect.AddListener(x =>
 151        {
 0152            ActivateDescriptionEditionMode(true);
 0153            UpdateDescriptionCharLimit(descriptionPreviewInput.text);
 0154        });
 19155        descriptionEditionInput.onValueChanged.AddListener(UpdateDescriptionCharLimit);
 19156        descriptionEditionInput.onDeselect.AddListener(x => ActivateDescriptionEditionMode(false));
 19157        copyToast.gameObject.SetActive(false);
 19158    }
 159
 160    internal void SetProfile(UserProfile userProfile)
 161    {
 5162        profile = userProfile;
 5163        if (userProfile.hasClaimedName)
 164        {
 1165            HandleClaimedProfileName(userProfile);
 1166        }
 167        else
 168        {
 4169            HandleUnverifiedProfileName(userProfile);
 170        }
 171
 5172        SetConnectedWalletSectionActive(userProfile.hasConnectedWeb3);
 5173        HandleProfileAddress(userProfile);
 5174        HandleProfileSnapshot(userProfile);
 5175        SetDescription(userProfile.description);
 5176        SetDescriptionEnabled(userProfile.hasConnectedWeb3);
 5177        ForceLayoutToRefreshSize();
 5178    }
 179
 180    internal void ToggleMenu()
 181    {
 2182        if (menuShowHideAnimator.isVisible)
 183        {
 1184            HideMenu();
 1185        }
 186        else
 187        {
 1188            menuShowHideAnimator.Show();
 1189            CommonScriptableObjects.isProfileHUDOpen.Set(true);
 1190            OnOpen?.Invoke();
 191        }
 1192    }
 193
 194    internal void HideMenu()
 195    {
 1196        if (menuShowHideAnimator.isVisible)
 197        {
 1198            menuShowHideAnimator.Hide();
 1199            CommonScriptableObjects.isProfileHUDOpen.Set(false);
 1200            OnClose?.Invoke();
 201        }
 1202    }
 203
 204    internal void SetVisibility(bool visible)
 205    {
 3206        if (visible && !mainShowHideAnimator.isVisible)
 0207            mainShowHideAnimator.Show();
 3208        else if (!visible && mainShowHideAnimator.isVisible)
 1209            mainShowHideAnimator.Hide();
 3210    }
 211
 212    private void HandleProfileSnapshot(UserProfile userProfile)
 213    {
 5214        loadingSpinner.SetActive(true);
 5215        userProfile.snapshotObserver.AddListener(SetProfileImage);
 5216    }
 217
 218    private void HandleClaimedProfileName(UserProfile userProfile)
 219    {
 1220        textName.text = userProfile.userName;
 1221        SetActiveUnverifiedNameGOs(false);
 1222    }
 223
 224    private void HandleUnverifiedProfileName(UserProfile userProfile)
 225    {
 4226        if (!String.IsNullOrEmpty(userProfile.userName) &&
 227            userProfile.userName.Length > NAME_POSTFIX_LENGTH)
 228        {
 4229            textName.text = userProfile.userName.Substring(0, userProfile.userName.Length - NAME_POSTFIX_LENGTH - 1);
 4230        }
 231        else
 232        {
 0233            textName.text = userProfile.userName;
 234        }
 235
 4236        textPostfix.text = $"#{userProfile.userId.Substring(userProfile.userId.Length - NAME_POSTFIX_LENGTH)}";
 4237        SetActiveUnverifiedNameGOs(true);
 4238    }
 239
 240    private void SetConnectedWalletSectionActive(bool active)
 241    {
 5242        connectedWalletSection.SetActive(active);
 5243        nonConnectedWalletSection.SetActive(!active);
 5244    }
 245
 246    private void ForceLayoutToRefreshSize()
 247    {
 5248        LayoutRebuilder.ForceRebuildLayoutImmediate(mainRootLayout);
 5249    }
 250
 251    private void SetActiveUnverifiedNameGOs(bool active)
 252    {
 40253        for (int i = 0; i < hideOnNameClaimed.Length; i++)
 254        {
 15255            hideOnNameClaimed[i].SetActive(active);
 256        }
 5257    }
 258
 259    private void HandleProfileAddress(UserProfile userProfile)
 260    {
 5261        string address = userProfile.userId;
 5262        string start = address.Substring(0, ADDRESS_CHUNK_LENGTH);
 5263        string end = address.Substring(address.Length - ADDRESS_CHUNK_LENGTH);
 5264        textAddress.text = $"{start}...{end}";
 5265    }
 266
 267    private void SetProfileImage(Texture2D texture)
 268    {
 0269        loadingSpinner.SetActive(false);
 0270        imageAvatarThumbnail.texture = texture;
 0271    }
 272
 273    private void OnDestroy()
 274    {
 19275        if (profile)
 4276            profile.snapshotObserver.RemoveListener(SetProfileImage);
 19277    }
 278
 279    private void CopyAddress()
 280    {
 0281        if (!profile)
 282        {
 0283            return;
 284        }
 285
 0286        Environment.i.platform.clipboard.WriteText(profile.userId);
 287
 0288        copyTooltip.gameObject.SetActive(false);
 0289        if (copyToastRoutine != null)
 290        {
 0291            StopCoroutine(copyToastRoutine);
 292        }
 293
 0294        copyToastRoutine = StartCoroutine(ShowCopyToast());
 0295    }
 296
 297    private IEnumerator ShowCopyToast()
 298    {
 0299        if (!copyToast.gameObject.activeSelf)
 300        {
 0301            copyToast.gameObject.SetActive(true);
 302        }
 303
 0304        copyToast.Show();
 0305        yield return new WaitForSeconds(COPY_TOAST_VISIBLE_TIME);
 0306        copyToast.Hide();
 0307    }
 308
 38309    private void OnEnable() { closeAction.OnTriggered += closeActionDelegate; }
 310
 38311    private void OnDisable() { closeAction.OnTriggered -= closeActionDelegate; }
 312
 313    internal void SetBackpackButtonVisibility(bool visible)
 314    {
 23315        if (visible && !buttonBackpack.gameObject.activeSelf)
 2316            buttonBackpack.gameObject.SetActive(true);
 21317        else if (!visible && buttonBackpack.gameObject.activeSelf)
 20318            buttonBackpack.gameObject.SetActive(false);
 21319    }
 320
 321    internal void ActivateProfileNameEditionMode(bool activate)
 322    {
 2323        if (profile != null && profile.hasClaimedName)
 0324            return;
 325
 2326        textName.gameObject.SetActive(!activate);
 2327        inputName.gameObject.SetActive(activate);
 328
 2329        if (activate)
 330        {
 1331            inputName.text = textName.text;
 1332            inputName.Select();
 333        }
 2334    }
 335
 6336    private void UpdateNameCharLimit(string newValue) { textCharLimit.text = $"{newValue.Length}/{inputName.characterLim
 337
 2338    internal void SetProfileName(string newName) { textName.text = newName; }
 339
 0340    internal void SetNameRegex(string namePattern) { nameRegex = new Regex(namePattern); }
 341
 342    internal bool IsValidAvatarName(string name)
 343    {
 0344        if (nameRegex == null)
 0345            return true;
 346
 0347        return nameRegex.IsMatch(name);
 348    }
 349
 350    internal void ActivateDescriptionEditionMode(bool active)
 351    {
 24352        charLimitDescriptionContainer.SetActive(active);
 24353        descriptionEditionInput.gameObject.SetActive(active);
 24354        descriptionPreviewInput.gameObject.SetActive(!active);
 355
 24356        if (active)
 357        {
 3358            descriptionEditionInput.text = descriptionPreviewInput.text;
 3359            StartCoroutine(SelectComponentOnNextFrame(descriptionEditionInput));
 360        }
 24361    }
 362
 363    private IEnumerator SelectComponentOnNextFrame(Selectable selectable)
 364    {
 3365        yield return null;
 0366        selectable.Select();
 0367    }
 368
 369    internal void SetDescription(string description)
 370    {
 7371        descriptionPreviewInput.text = description;
 7372        descriptionEditionInput.text = description;
 7373    }
 374
 375    private void UpdateDescriptionCharLimit(string newValue)
 376    {
 9377        textCharLimitDescription.text = $"{newValue.Length}/{descriptionPreviewInput.characterLimit}";
 9378    }
 379
 380    private void SetDescriptionEnabled(bool enabled)
 381    {
 5382        descriptionContainer.SetActive(enabled);
 5383    }
 384}