< Summary

Class:ProfileHUDViewV2
Assembly:ProfileHUD
File(s):/tmp/workspace/unity-renderer/unity-renderer/Assets/Scripts/MainScripts/DCL/Controllers/HUD/ProfileHUD/ProfileHUDViewV2.cs
Covered lines:52
Uncovered lines:143
Coverable lines:195
Total lines:442
Line coverage:26.6% (52 of 195)
Covered branches:0
Total branches:0

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity NPath complexity Sequence coverage
HasManaCounterView()0%110100%
HasPolygonManaCounterView()0%2100%
IsDesciptionIsLongerThanMaxCharacters()0%2100%
SetManaBalance(...)0%2100%
SetPolygonBalance(...)0%2100%
SetWalletSectionEnabled(...)0%110100%
SetNonWalletSectionEnabled(...)0%110100%
SetStartMenuButtonActive(...)0%110100%
RefreshControl()0%2100%
SetProfile(...)0%6200%
UpdateLayoutByProfile(...)0%12300%
SetUserId(...)0%2100%
OpenStartMenu()0%12300%
ShowProfileIcon(...)0%2100%
ShowExpanded(...)0%12300%
ActivateProfileNameEditionMode(...)0%20400%
SetDescriptionCharLiitEnabled(...)0%110100%
Awake()0%220100%
OpenPassport()0%6200%
HandleProfileSnapshot(...)0%2100%
HandleClaimedProfileName(...)0%2100%
HandleUnverifiedProfileName(...)0%12300%
SetConnectedWalletSectionActive(...)0%2100%
SetActiveUnverifiedNameGOs(...)0%6200%
HandleProfileAddress(...)0%2100%
SetProfileImage(...)0%2100%
OnDestroy()0%3.143075%
CopyAddress()0%12300%
OnEnable()0%110100%
OnDisable()0%110100%
UpdateNameCharLimit(...)0%2100%
SetDescriptionEnabled(...)0%2100%
SetDescriptionIsEditing(...)0%110100%
UpdateDescriptionCharLimit(...)0%2100%
UpdateLinksInformation(...)0%1821300%
ShowCopyToast()0%20400%
EnableNextFrame()0%12300%

File(s)

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

#LineLine coverage
 1using DCL;
 2using ExploreV2Analytics;
 3using System;
 4using System.Collections;
 5using TMPro;
 6using UnityEngine;
 7using UnityEngine.UI;
 8using Environment = DCL.Environment;
 9
 10public class ProfileHUDViewV2 : BaseComponentView, IProfileHUDView
 11{
 12    private const float COPY_TOAST_VISIBLE_TIME = 3;
 13    private const int ADDRESS_CHUNK_LENGTH = 6;
 14    private const int NAME_POSTFIX_LENGTH = 4;
 15
 16    [SerializeField] private RectTransform mainRootLayout;
 17    [SerializeField] internal GameObject loadingSpinner;
 18    [SerializeField] internal ShowHideAnimator copyToast;
 19    [SerializeField] internal GameObject copyTooltip;
 20    [SerializeField] private GameObject expandedObject;
 21    [SerializeField] private GameObject profilePicObject;
 22    [SerializeField] internal InputAction_Trigger closeAction;
 23    [SerializeField] internal Canvas mainCanvas;
 24    [SerializeField] internal Button viewPassportButton;
 25
 26    [Header("Hide GOs on claimed name")]
 27    [SerializeField]
 28    internal GameObject[] hideOnNameClaimed;
 29
 30    [Header("Connected wallet sections")]
 31    [SerializeField]
 32    internal GameObject connectedWalletSection;
 33
 34    [SerializeField]
 35    internal GameObject nonConnectedWalletSection;
 36
 37    [Header("Thumbnail")]
 38    [SerializeField]
 39    internal RawImage imageAvatarThumbnail;
 40
 41    [SerializeField]
 42    protected internal Button buttonToggleMenu;
 43
 44    [Header("Texts")]
 45    [SerializeField] internal TextMeshProUGUI textName;
 46    [SerializeField] internal TextMeshProUGUI textPostfix;
 47    [SerializeField] internal TextMeshProUGUI textAddress;
 48
 49    [Header("Buttons")]
 50    [SerializeField] protected internal Button buttonClaimName;
 51    [SerializeField] protected internal Button buttonCopyAddress;
 52    [SerializeField] protected internal Button buttonLogOut;
 53    [SerializeField] protected internal Button buttonSignUp;
 54    [SerializeField] protected internal Button_OnPointerDown buttonTermsOfServiceForConnectedWallets;
 55    [SerializeField] protected internal Button_OnPointerDown buttonPrivacyPolicyForConnectedWallets;
 56    [SerializeField] protected internal Button_OnPointerDown buttonTermsOfServiceForNonConnectedWallets;
 57    [SerializeField] protected internal Button_OnPointerDown buttonPrivacyPolicyForNonConnectedWallets;
 58
 59    [Header("Name Edition")]
 60    [SerializeField] protected internal Button_OnPointerDown buttonEditName;
 61    [SerializeField] protected internal Button_OnPointerDown buttonEditNamePrefix;
 62    [SerializeField] internal TMP_InputField inputName;
 63    [SerializeField] internal TextMeshProUGUI textCharLimit;
 64    [SerializeField] internal ManaCounterView manaCounterView;
 65    [SerializeField] internal ManaCounterView polygonManaCounterView;
 66
 67    [Header("Tutorial Config")]
 68    [SerializeField] internal RectTransform tutorialTooltipReference;
 69
 70    [Header("Description")]
 71    [SerializeField] internal GameObject charLimitDescriptionContainer;
 72    [SerializeField] internal GameObject descriptionStartEditingGo;
 73    [SerializeField] internal GameObject descriptionIsEditingGo;
 74    [SerializeField] internal Button descriptionStartEditingButton;
 75    [SerializeField] internal Button descriptionIsEditingButton;
 76    [SerializeField] internal TMP_InputField descriptionInputText;
 77    [SerializeField] internal TextMeshProUGUI textCharLimitDescription;
 78
 79    [SerializeField] internal GameObject descriptionContainer;
 80
 81    private InputAction_Trigger.Triggered closeActionDelegate;
 82
 83    private Coroutine copyToastRoutine = null;
 84    private UserProfile profile = null;
 85    private string description;
 86    private string userId;
 87    private StringVariable currentPlayerId;
 88
 89    public event EventHandler ClaimNamePressed;
 90    public event EventHandler SignedUpPressed;
 91    public event EventHandler LogedOutPressed;
 92    public event EventHandler Opened;
 93    public event EventHandler Closed;
 94    public event EventHandler<string> NameSubmitted;
 95    public event EventHandler<string> DescriptionSubmitted;
 96    public event EventHandler ManaInfoPressed;
 97    public event EventHandler ManaPurchasePressed;
 98    public event EventHandler TermsAndServicesPressed;
 99    public event EventHandler PrivacyPolicyPressed;
 100
 101    internal bool isStartMenuInitialized = false;
 102
 103    private HUDCanvasCameraModeController hudCanvasCameraModeController;
 5104    public GameObject GameObject => gameObject;
 0105    public RectTransform ExpandedMenu => mainRootLayout;
 0106    public RectTransform TutorialReference => tutorialTooltipReference;
 107
 108
 3109    public bool HasManaCounterView() => manaCounterView != null;
 0110    public bool HasPolygonManaCounterView() => polygonManaCounterView != null;
 0111    public bool IsDesciptionIsLongerThanMaxCharacters() => descriptionInputText.characterLimit < descriptionInputText.te
 0112    public void SetManaBalance(string balance) => manaCounterView.SetBalance(balance);
 0113    public void SetPolygonBalance(double balance) => polygonManaCounterView.SetBalance(balance);
 2114    public void SetWalletSectionEnabled(bool isEnabled) => connectedWalletSection.SetActive(isEnabled);
 2115    public void SetNonWalletSectionEnabled(bool isEnabled) => nonConnectedWalletSection.SetActive(isEnabled);
 2116    public void SetStartMenuButtonActive(bool isActive) => isStartMenuInitialized = isActive;
 0117    public override void RefreshControl() { }
 118
 119
 120    public void SetProfile(UserProfile userProfile)
 121    {
 0122        UpdateLayoutByProfile(userProfile);
 0123        if (profile == null)
 124        {
 0125            description = userProfile.description;
 0126            descriptionInputText.text = description;
 0127            UpdateLinksInformation(description);
 128        }
 129
 0130        profile = userProfile;
 0131    }
 132
 133    private void UpdateLayoutByProfile(UserProfile userProfile)
 134    {
 0135        if (userProfile.hasClaimedName)
 0136            HandleClaimedProfileName(userProfile);
 137        else
 0138            HandleUnverifiedProfileName(userProfile);
 139
 0140        SetConnectedWalletSectionActive(userProfile.hasConnectedWeb3);
 0141        HandleProfileAddress(userProfile);
 0142        HandleProfileSnapshot(userProfile);
 0143        SetDescriptionEnabled(userProfile.hasConnectedWeb3);
 0144        SetUserId(userProfile);
 145
 0146        string[] nameSplits = userProfile.userName.Split('#');
 0147        if (nameSplits.Length >= 2)
 148        {
 0149            textName.text = nameSplits[0];
 0150            textPostfix.text = $"#{nameSplits[1]};";
 151        }
 152        else
 153        {
 0154            textName.text = userProfile.userName;
 0155            textPostfix.text = userProfile.userId;
 156        }
 0157    }
 158
 159    private void SetUserId(UserProfile userProfile)
 160    {
 0161        userId = userProfile.userId;
 0162    }
 163
 164    private void OpenStartMenu()
 165    {
 0166        if (isStartMenuInitialized)
 167        {
 0168            if (!DataStore.i.exploreV2.isOpen.Get())
 169            {
 0170                var exploreV2Analytics = new ExploreV2Analytics.ExploreV2Analytics();
 0171                exploreV2Analytics.SendStartMenuVisibility(
 172                    true,
 173                    ExploreUIVisibilityMethod.FromClick);
 174            }
 0175            DataStore.i.exploreV2.isOpen.Set(true);
 176        }
 0177    }
 178
 179    public void ShowProfileIcon(bool show)
 180    {
 0181        profilePicObject.SetActive(show);
 0182    }
 183
 184    public void ShowExpanded(bool show)
 185    {
 0186        expandedObject.SetActive(show);
 0187        if (show && profile)
 0188            UpdateLayoutByProfile(profile);
 0189    }
 190
 191    public void ActivateProfileNameEditionMode(bool activate)
 192    {
 0193        if (profile != null && profile.hasClaimedName)
 0194            return;
 195
 0196        textName.gameObject.SetActive(!activate);
 0197        inputName.gameObject.SetActive(activate);
 198
 0199        if (activate)
 200        {
 0201            inputName.text = textName.text;
 0202            inputName.Select();
 203        }
 0204    }
 205
 206    public void SetDescriptionCharLiitEnabled(bool enabled)
 207    {
 4208        charLimitDescriptionContainer.SetActive(enabled);
 4209    }
 210
 211    private void Awake()
 212    {
 2213        if (currentPlayerId == null)
 2214            currentPlayerId = Resources.Load<StringVariable>("CurrentPlayerInfoCardId");
 215
 2216        buttonLogOut.onClick.AddListener(() => LogedOutPressed?.Invoke(this, EventArgs.Empty));
 2217        buttonSignUp.onClick.AddListener(() => SignedUpPressed?.Invoke(this, EventArgs.Empty));
 2218        buttonClaimName.onClick.AddListener(() => ClaimNamePressed?.Invoke(this, EventArgs.Empty));
 219
 2220        buttonTermsOfServiceForConnectedWallets.onClick.AddListener(() => TermsAndServicesPressed?.Invoke(this, EventArg
 2221        buttonTermsOfServiceForNonConnectedWallets.onClick.AddListener(() => TermsAndServicesPressed?.Invoke(this, Event
 2222        buttonPrivacyPolicyForConnectedWallets.onClick.AddListener(() => PrivacyPolicyPressed?.Invoke(this, EventArgs.Em
 2223        buttonPrivacyPolicyForNonConnectedWallets.onClick.AddListener(() => PrivacyPolicyPressed?.Invoke(this, EventArgs
 224
 2225        manaCounterView.buttonManaInfo.onClick.AddListener(() => ManaInfoPressed?.Invoke(this, EventArgs.Empty));
 2226        polygonManaCounterView.buttonManaInfo.onClick.AddListener(() => ManaInfoPressed?.Invoke(this, EventArgs.Empty));
 2227        manaCounterView.buttonManaPurchase.onClick.AddListener(() => ManaPurchasePressed?.Invoke(this, EventArgs.Empty))
 2228        polygonManaCounterView.buttonManaPurchase.onClick.AddListener(() => ManaPurchasePressed?.Invoke(this, EventArgs.
 229
 2230        closeActionDelegate = (x) => Hide();
 231
 2232        buttonToggleMenu.onClick.AddListener(OpenStartMenu);
 2233        buttonCopyAddress.onClick.AddListener(CopyAddress);
 2234        buttonEditName.onPointerDown += () => ActivateProfileNameEditionMode(true);
 2235        buttonEditNamePrefix.onPointerDown += () => ActivateProfileNameEditionMode(true);
 2236        inputName.onValueChanged.AddListener(UpdateNameCharLimit);
 2237        inputName.onDeselect.AddListener((newName) =>
 238        {
 0239            ActivateProfileNameEditionMode(false);
 0240            NameSubmitted?.Invoke(this, newName);
 0241        });
 242
 2243        buttonClaimName.onClick.AddListener(() => ClaimNamePressed?.Invoke(this, EventArgs.Empty));
 2244        buttonLogOut.onClick.AddListener(() => LogedOutPressed?.Invoke(this, EventArgs.Empty));
 2245        buttonSignUp.onClick.AddListener(() => SignedUpPressed?.Invoke(this, EventArgs.Empty));
 246
 2247        descriptionStartEditingButton.onClick.AddListener(descriptionInputText.Select);
 2248        descriptionIsEditingButton.onClick.AddListener(() => descriptionInputText.OnDeselect(null));
 2249        descriptionInputText.onTextSelection.AddListener((description, x, y) =>
 250        {
 0251            descriptionInputText.text = profile.description;
 0252            SetDescriptionIsEditing(true);
 0253            UpdateDescriptionCharLimit(description);
 0254        });
 2255        descriptionInputText.onSelect.AddListener(x =>
 256        {
 0257            descriptionInputText.text = profile.description;
 0258            SetDescriptionIsEditing(true);
 0259            UpdateDescriptionCharLimit(description);
 0260        });
 2261        descriptionInputText.onValueChanged.AddListener(UpdateDescriptionCharLimit);
 2262        descriptionInputText.onDeselect.AddListener(description =>
 263        {
 0264            this.description = description;
 0265            DescriptionSubmitted?.Invoke(this, description);
 266
 0267            SetDescriptionIsEditing(false);
 0268            UpdateLinksInformation(description);
 0269        });
 2270        SetDescriptionIsEditing(false);
 271
 2272        copyToast.gameObject.SetActive(false);
 2273        hudCanvasCameraModeController = new HUDCanvasCameraModeController(GetComponent<Canvas>(), DataStore.i.camera.hud
 274
 2275        viewPassportButton.onClick.RemoveAllListeners();
 2276        viewPassportButton.onClick.AddListener(OpenPassport);
 2277        Show(false);
 2278    }
 279
 280    private void OpenPassport()
 281    {
 0282        if (string.IsNullOrEmpty(userId))
 0283            return;
 284
 0285        ShowExpanded(false);
 0286        currentPlayerId.Set(userId);
 0287    }
 288
 289    private void HandleProfileSnapshot(UserProfile userProfile)
 290    {
 0291        loadingSpinner.SetActive(true);
 0292        userProfile.snapshotObserver.AddListener(SetProfileImage);
 0293    }
 294
 295    private void HandleClaimedProfileName(UserProfile userProfile)
 296    {
 0297        textName.text = userProfile.userName;
 0298        SetActiveUnverifiedNameGOs(false);
 0299    }
 300
 301    private void HandleUnverifiedProfileName(UserProfile userProfile)
 302    {
 0303        textName.text = string.IsNullOrEmpty(userProfile.userName) || userProfile.userName.Length <= NAME_POSTFIX_LENGTH
 304            ? userProfile.userName
 305            : userProfile.userName.Substring(0, userProfile.userName.Length - NAME_POSTFIX_LENGTH - 1);
 306
 0307        textPostfix.text = $"#{userProfile.userId.Substring(userProfile.userId.Length - NAME_POSTFIX_LENGTH)}";
 0308        SetActiveUnverifiedNameGOs(true);
 0309    }
 310
 311    private void SetConnectedWalletSectionActive(bool active)
 312    {
 0313        connectedWalletSection.SetActive(active);
 0314        nonConnectedWalletSection.SetActive(!active);
 0315        buttonLogOut.gameObject.SetActive(active);
 0316    }
 317
 318    private void SetActiveUnverifiedNameGOs(bool active)
 319    {
 0320        for (int i = 0; i < hideOnNameClaimed.Length; i++)
 0321            hideOnNameClaimed[i].SetActive(active);
 0322    }
 323
 324    private void HandleProfileAddress(UserProfile userProfile)
 325    {
 0326        string address = userProfile.userId;
 0327        string start = address.Substring(0, ADDRESS_CHUNK_LENGTH);
 0328        string end = address.Substring(address.Length - ADDRESS_CHUNK_LENGTH);
 0329        textAddress.text = $"{start}...{end}";
 0330    }
 331
 332    private void SetProfileImage(Texture2D texture)
 333    {
 0334        loadingSpinner.SetActive(false);
 0335        imageAvatarThumbnail.texture = texture;
 0336    }
 337
 338    private void OnDestroy()
 339    {
 2340        hudCanvasCameraModeController?.Dispose();
 2341        if (profile)
 0342            profile.snapshotObserver.RemoveListener(SetProfileImage);
 2343    }
 344
 345    private void CopyAddress()
 346    {
 0347        if (!profile)
 0348            return;
 349
 0350        Environment.i.platform.clipboard.WriteText(profile.userId);
 351
 0352        copyTooltip.gameObject.SetActive(false);
 0353        if (copyToastRoutine != null)
 0354            StopCoroutine(copyToastRoutine);
 355
 0356        copyToastRoutine = StartCoroutine(ShowCopyToast());
 0357    }
 358
 4359    private void OnEnable() { closeAction.OnTriggered += closeActionDelegate; }
 360
 4361    private void OnDisable() { closeAction.OnTriggered -= closeActionDelegate; }
 362
 0363    private void UpdateNameCharLimit(string newValue) { textCharLimit.text = $"{newValue.Length}/{inputName.characterLim
 364
 365    private void SetDescriptionEnabled(bool enabled)
 366    {
 0367        descriptionContainer.SetActive(enabled);
 0368    }
 369
 370    public void SetDescriptionIsEditing(bool isEditing)
 371    {
 4372        SetDescriptionCharLiitEnabled(isEditing);
 4373        descriptionStartEditingGo.SetActive(!isEditing);
 4374        descriptionIsEditingGo.SetActive(isEditing);
 4375    }
 376
 377    private void UpdateDescriptionCharLimit(string description) =>
 0378        textCharLimitDescription.text = $"{description.Length}/{descriptionInputText.characterLimit}";
 379
 380    private void UpdateLinksInformation(string description)
 381    {
 0382        string[] words = description.Split(' ', StringSplitOptions.RemoveEmptyEntries);
 0383        bool[] areLinks = new bool[words.Length];
 0384        bool linksFound = false;
 385
 0386        for (int i = 0; i < words.Length; i++)
 387        {
 0388            if (words[i].StartsWith("[") && words[i].Contains("]") && words[i].Contains("(") && words[i].EndsWith(")"))
 389            {
 0390                string link = words[i].Split("(")[0].Replace("[", "").Replace("]", "");
 0391                string id = words[i].Split("]")[1].Replace("(", "").Replace(")", "");
 0392                string[] elements = words[i].Split('.');
 0393                if (elements.Length >= 2)
 394                {
 0395                    words[i] = $"<color=\"blue\"><link=\"{id}\">{link}</link></color>";
 0396                    areLinks[i] = true;
 0397                    linksFound = true;
 398                }
 399            }
 400        }
 401
 0402        if (linksFound)
 403        {
 0404            bool foundLinksAtTheEnd = false;
 0405            for (int i = words.Length - 1; i >= 0; i--)
 406            {
 0407                if (string.IsNullOrEmpty(words[i]))
 408                    continue;
 409
 0410                if (!foundLinksAtTheEnd && !areLinks[i])
 411                    break;
 412
 0413                if (areLinks[i])
 414                {
 0415                    foundLinksAtTheEnd = true;
 0416                    continue;
 417                }
 418
 0419                words[i] += "\n\n";
 0420                break;
 421            }
 0422            descriptionInputText.text = string.Join(" ", words);
 423        }
 0424    }
 425
 426
 427    private IEnumerator ShowCopyToast()
 428    {
 0429        if (!copyToast.gameObject.activeSelf)
 0430            copyToast.gameObject.SetActive(true);
 431
 0432        copyToast.Show();
 0433        yield return new WaitForSeconds(COPY_TOAST_VISIBLE_TIME);
 0434        copyToast.Hide();
 0435    }
 436
 437    private IEnumerator EnableNextFrame(GameObject go, bool shouldEnable)
 438    {
 0439        yield return null;
 0440        go.SetActive(shouldEnable);
 0441    }
 442}