< Summary

Class:ProfileHUDViewV2
Assembly:ProfileHUD
File(s):/tmp/workspace/unity-renderer/unity-renderer/Assets/Scripts/MainScripts/DCL/Controllers/HUD/ProfileHUD/ProfileHUDViewV2.cs
Covered lines:49
Uncovered lines:147
Coverable lines:196
Total lines:448
Line coverage:25% (49 of 196)
Covered branches:0
Total branches:0
Covered methods:12
Total methods:42
Method coverage:28.5% (12 of 42)

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity NPath complexity Sequence coverage
Awake()0%110100%
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%
ShowProfileIcon(...)0%2100%
ShowExpanded(...)0%42600%
SetDescriptionIsEditing(...)0%110100%
UpdateLayoutByProfile(...)0%12300%
SetUserId(...)0%2100%
OpenStartMenu()0%12300%
ActivateProfileNameEditionMode(...)0%20400%
SetDescriptionCharLimitEnabled(...)0%110100%
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%
UpdateDescriptionCharLimit(...)0%2100%
UpdateLinksInformation(...)0%1821300%
ShowCopyToast()0%20400%

File(s)

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

#LineLine coverage
 1using DCL;
 2using DCL.MyAccount;
 3using ExploreV2Analytics;
 4using System;
 5using System.Collections;
 6using TMPro;
 7using UnityEngine;
 8using UnityEngine.UI;
 9using Environment = DCL.Environment;
 10
 11public class ProfileHUDViewV2 : BaseComponentView, IProfileHUDView
 12{
 13    private const float COPY_TOAST_VISIBLE_TIME = 3;
 14    private const int ADDRESS_CHUNK_LENGTH = 6;
 15    private const int NAME_POSTFIX_LENGTH = 4;
 16    private const string OPEN_PASSPORT_SOURCE = "ProfileHUD";
 17
 18    [SerializeField] private MyAccountCardComponentView myAccountCardView;
 19    [SerializeField] private RectTransform myAccountCardLayout;
 20    [SerializeField] private RectTransform mainRootLayout;
 21    [SerializeField] internal GameObject loadingSpinner;
 22    [SerializeField] internal ShowHideAnimator copyToast;
 23    [SerializeField] internal GameObject copyTooltip;
 24    [SerializeField] private GameObject expandedObject;
 25    [SerializeField] private GameObject profilePicObject;
 26    [SerializeField] internal InputAction_Trigger closeAction;
 27    [SerializeField] internal Canvas mainCanvas;
 28    [SerializeField] internal Button viewPassportButton;
 29
 30    [Header("Hide GOs on claimed name")]
 31    [SerializeField]
 32    internal GameObject[] hideOnNameClaimed;
 33
 34    [Header("Connected wallet sections")]
 35    [SerializeField]
 36    internal GameObject connectedWalletSection;
 37
 38    [SerializeField]
 39    internal GameObject nonConnectedWalletSection;
 40
 41    [Header("Thumbnail")]
 42    [SerializeField]
 43    internal RawImage imageAvatarThumbnail;
 44
 45    [SerializeField]
 46    protected internal Button buttonToggleMenu;
 47
 48    [Header("Texts")]
 49    [SerializeField] internal TextMeshProUGUI textName;
 50    [SerializeField] internal TextMeshProUGUI textPostfix;
 51    [SerializeField] internal TextMeshProUGUI textAddress;
 52
 53    [Header("Buttons")]
 54    [SerializeField] protected internal Button buttonClaimName;
 55    [SerializeField] protected internal Button buttonCopyAddress;
 56    [SerializeField] protected internal Button buttonLogOut;
 57    [SerializeField] protected internal Button buttonSignUp;
 58    [SerializeField] protected internal Button_OnPointerDown buttonTermsOfServiceForConnectedWallets;
 59    [SerializeField] protected internal Button_OnPointerDown buttonPrivacyPolicyForConnectedWallets;
 60    [SerializeField] protected internal Button_OnPointerDown buttonTermsOfServiceForNonConnectedWallets;
 61    [SerializeField] protected internal Button_OnPointerDown buttonPrivacyPolicyForNonConnectedWallets;
 62
 63    [Header("Name Edition")]
 64    [SerializeField] protected internal Button_OnPointerDown buttonEditName;
 65    [SerializeField] protected internal Button_OnPointerDown buttonEditNamePrefix;
 66    [SerializeField] internal TMP_InputField inputName;
 67    [SerializeField] internal TextMeshProUGUI textCharLimit;
 68    [SerializeField] internal ManaCounterView manaCounterView;
 69    [SerializeField] internal ManaCounterView polygonManaCounterView;
 70
 71    [Header("Tutorial Config")]
 72    [SerializeField] internal RectTransform tutorialTooltipReference;
 73
 74    [Header("Description")]
 75    [SerializeField] internal GameObject charLimitDescriptionContainer;
 76    [SerializeField] internal GameObject descriptionStartEditingGo;
 77    [SerializeField] internal GameObject descriptionIsEditingGo;
 78    [SerializeField] internal Button descriptionStartEditingButton;
 79    [SerializeField] internal Button descriptionIsEditingButton;
 80    [SerializeField] internal TMP_InputField descriptionInputText;
 81    [SerializeField] internal TextMeshProUGUI textCharLimitDescription;
 82
 83    [SerializeField] internal GameObject descriptionContainer;
 84
 85    private InputAction_Trigger.Triggered closeActionDelegate;
 86
 87    private Coroutine copyToastRoutine;
 88    private UserProfile profile;
 89    private string description;
 90    private string userId;
 91    private BaseVariable<(string playerId, string source)> currentPlayerId;
 92
 93    public event EventHandler ClaimNamePressed;
 94    public event EventHandler SignedUpPressed;
 95    public event EventHandler LogedOutPressed;
 96    public event EventHandler Opened;
 97    public event EventHandler Closed;
 98    public event EventHandler<string> NameSubmitted;
 99    public event EventHandler<string> DescriptionSubmitted;
 100    public event EventHandler ManaInfoPressed;
 101    public event EventHandler ManaPurchasePressed;
 102    public event EventHandler TermsAndServicesPressed;
 103    public event EventHandler PrivacyPolicyPressed;
 104
 105    internal bool isStartMenuInitialized = false;
 106
 107    private HUDCanvasCameraModeController hudCanvasCameraModeController;
 2108    public GameObject GameObject => gameObject;
 0109    public RectTransform ExpandedMenu => mainRootLayout;
 0110    public RectTransform MyAccountCardLayout => myAccountCardLayout;
 0111    public RectTransform MyAccountCardMenu => (RectTransform)myAccountCardView.transform;
 1112    public MyAccountCardComponentView MyAccountCardView => myAccountCardView;
 0113    public RectTransform TutorialReference => tutorialTooltipReference;
 114
 115    public override void Awake()
 116    {
 1117        currentPlayerId = DataStore.i.HUDs.currentPlayerId;
 118
 1119        buttonLogOut.onClick.AddListener(() => LogedOutPressed?.Invoke(this, EventArgs.Empty));
 1120        buttonSignUp.onClick.AddListener(() => SignedUpPressed?.Invoke(this, EventArgs.Empty));
 1121        buttonClaimName.onClick.AddListener(() => ClaimNamePressed?.Invoke(this, EventArgs.Empty));
 122
 1123        buttonTermsOfServiceForConnectedWallets.onClick.AddListener(() => TermsAndServicesPressed?.Invoke(this, EventArg
 1124        buttonTermsOfServiceForNonConnectedWallets.onClick.AddListener(() => TermsAndServicesPressed?.Invoke(this, Event
 1125        buttonPrivacyPolicyForConnectedWallets.onClick.AddListener(() => PrivacyPolicyPressed?.Invoke(this, EventArgs.Em
 1126        buttonPrivacyPolicyForNonConnectedWallets.onClick.AddListener(() => PrivacyPolicyPressed?.Invoke(this, EventArgs
 127
 1128        manaCounterView.buttonManaInfo.onClick.AddListener(() => ManaInfoPressed?.Invoke(this, EventArgs.Empty));
 1129        polygonManaCounterView.buttonManaInfo.onClick.AddListener(() => ManaInfoPressed?.Invoke(this, EventArgs.Empty));
 1130        manaCounterView.buttonManaPurchase.onClick.AddListener(() => ManaPurchasePressed?.Invoke(this, EventArgs.Empty))
 1131        polygonManaCounterView.buttonManaPurchase.onClick.AddListener(() => ManaPurchasePressed?.Invoke(this, EventArgs.
 132
 1133        closeActionDelegate = (x) => Hide();
 134
 1135        buttonToggleMenu.onClick.AddListener(OpenStartMenu);
 1136        buttonCopyAddress.onClick.AddListener(CopyAddress);
 1137        buttonEditName.onPointerDown += () => ActivateProfileNameEditionMode(true);
 1138        buttonEditNamePrefix.onPointerDown += () => ActivateProfileNameEditionMode(true);
 1139        inputName.onValueChanged.AddListener(UpdateNameCharLimit);
 1140        inputName.onDeselect.AddListener((newName) =>
 141        {
 0142            ActivateProfileNameEditionMode(false);
 0143            NameSubmitted?.Invoke(this, newName);
 0144        });
 145
 1146        descriptionStartEditingButton.onClick.AddListener(descriptionInputText.Select);
 1147        descriptionIsEditingButton.onClick.AddListener(() => descriptionInputText.OnDeselect(null));
 1148        descriptionInputText.onTextSelection.AddListener((description, x, y) =>
 149        {
 0150            descriptionInputText.text = profile.description;
 0151            SetDescriptionIsEditing(true);
 0152            UpdateDescriptionCharLimit(description);
 0153        });
 1154        descriptionInputText.onSelect.AddListener(x =>
 155        {
 0156            descriptionInputText.text = profile.description;
 0157            SetDescriptionIsEditing(true);
 0158            UpdateDescriptionCharLimit(description);
 0159        });
 1160        descriptionInputText.onValueChanged.AddListener(UpdateDescriptionCharLimit);
 1161        descriptionInputText.onDeselect.AddListener(description =>
 162        {
 0163            this.description = description;
 0164            DescriptionSubmitted?.Invoke(this, description);
 165
 0166            SetDescriptionIsEditing(false);
 0167            UpdateLinksInformation(description);
 0168        });
 1169        SetDescriptionIsEditing(false);
 170
 1171        copyToast.gameObject.SetActive(false);
 1172        hudCanvasCameraModeController = new HUDCanvasCameraModeController(GetComponent<Canvas>(), DataStore.i.camera.hud
 173
 1174        viewPassportButton.onClick.RemoveAllListeners();
 1175        viewPassportButton.onClick.AddListener(OpenPassport);
 1176        Show(false);
 1177    }
 178
 1179    public bool HasManaCounterView() => manaCounterView != null;
 0180    public bool HasPolygonManaCounterView() => polygonManaCounterView != null;
 0181    public bool IsDesciptionIsLongerThanMaxCharacters() => descriptionInputText.characterLimit < descriptionInputText.te
 0182    public void SetManaBalance(string balance) => manaCounterView.SetBalance(balance);
 0183    public void SetPolygonBalance(double balance) => polygonManaCounterView.SetBalance(balance);
 1184    public void SetWalletSectionEnabled(bool isEnabled) => connectedWalletSection.SetActive(isEnabled);
 1185    public void SetNonWalletSectionEnabled(bool isEnabled) => nonConnectedWalletSection.SetActive(isEnabled);
 1186    public void SetStartMenuButtonActive(bool isActive) => isStartMenuInitialized = isActive;
 0187    public override void RefreshControl() { }
 188
 189    public void SetProfile(UserProfile userProfile)
 190    {
 0191        UpdateLayoutByProfile(userProfile);
 0192        if (profile == null)
 193        {
 0194            description = userProfile.description;
 0195            descriptionInputText.text = description;
 0196            UpdateLinksInformation(description);
 197        }
 198
 0199        profile = userProfile;
 0200    }
 201
 202    public void ShowProfileIcon(bool show)
 203    {
 0204        profilePicObject.SetActive(show);
 0205    }
 206
 207    public void ShowExpanded(bool show, bool showMyAccountVersion = false)
 208    {
 0209        if (!show)
 210        {
 0211            expandedObject.SetActive(false);
 0212            myAccountCardView.Hide();
 213        }
 214        else
 215        {
 0216            if (!showMyAccountVersion)
 0217                expandedObject.SetActive(true);
 218            else
 0219                myAccountCardView.Show();
 220        }
 221
 0222        if (show && profile && !showMyAccountVersion)
 0223            UpdateLayoutByProfile(profile);
 0224    }
 225
 226    public void SetDescriptionIsEditing(bool isEditing)
 227    {
 2228        SetDescriptionCharLimitEnabled(isEditing);
 2229        descriptionStartEditingGo.SetActive(!isEditing);
 2230        descriptionIsEditingGo.SetActive(isEditing);
 2231    }
 232
 233    private void UpdateLayoutByProfile(UserProfile userProfile)
 234    {
 0235        if (userProfile.hasClaimedName)
 0236            HandleClaimedProfileName(userProfile);
 237        else
 0238            HandleUnverifiedProfileName(userProfile);
 239
 0240        SetConnectedWalletSectionActive(userProfile.hasConnectedWeb3);
 0241        HandleProfileAddress(userProfile);
 0242        HandleProfileSnapshot(userProfile);
 0243        SetDescriptionEnabled(userProfile.hasConnectedWeb3);
 0244        SetUserId(userProfile);
 245
 0246        string[] nameSplits = userProfile.userName.Split('#');
 0247        if (nameSplits.Length >= 2)
 248        {
 0249            textName.text = nameSplits[0];
 0250            textPostfix.text = $"#{nameSplits[1]};";
 251        }
 252        else
 253        {
 0254            textName.text = userProfile.userName;
 0255            textPostfix.text = userProfile.userId;
 256        }
 0257    }
 258
 259    private void SetUserId(UserProfile userProfile)
 260    {
 0261        userId = userProfile.userId;
 0262    }
 263
 264    private void OpenStartMenu()
 265    {
 0266        if (isStartMenuInitialized)
 267        {
 0268            if (!DataStore.i.exploreV2.isOpen.Get())
 269            {
 0270                var exploreV2Analytics = new ExploreV2Analytics.ExploreV2Analytics();
 0271                exploreV2Analytics.SendStartMenuVisibility(
 272                    true,
 273                    ExploreUIVisibilityMethod.FromClick);
 274            }
 0275            DataStore.i.exploreV2.isOpen.Set(true);
 276        }
 0277    }
 278
 279    private void ActivateProfileNameEditionMode(bool activate)
 280    {
 0281        if (profile != null && profile.hasClaimedName)
 0282            return;
 283
 0284        textName.gameObject.SetActive(!activate);
 0285        inputName.gameObject.SetActive(activate);
 286
 0287        if (activate)
 288        {
 0289            inputName.text = textName.text;
 0290            inputName.Select();
 291        }
 0292    }
 293
 294    private void SetDescriptionCharLimitEnabled(bool enabled)
 295    {
 2296        charLimitDescriptionContainer.SetActive(enabled);
 2297    }
 298
 299    private void OpenPassport()
 300    {
 0301        if (string.IsNullOrEmpty(userId))
 0302            return;
 303
 0304        ShowExpanded(false);
 0305        currentPlayerId.Set((userId, OPEN_PASSPORT_SOURCE));
 0306    }
 307
 308    private void HandleProfileSnapshot(UserProfile userProfile)
 309    {
 0310        loadingSpinner.SetActive(true);
 0311        userProfile.snapshotObserver.AddListener(SetProfileImage);
 0312    }
 313
 314    private void HandleClaimedProfileName(UserProfile userProfile)
 315    {
 0316        textName.text = userProfile.userName;
 0317        SetActiveUnverifiedNameGOs(false);
 0318    }
 319
 320    private void HandleUnverifiedProfileName(UserProfile userProfile)
 321    {
 0322        textName.text = string.IsNullOrEmpty(userProfile.userName) || userProfile.userName.Length <= NAME_POSTFIX_LENGTH
 323            ? userProfile.userName
 324            : userProfile.userName[..(userProfile.userName.Length - NAME_POSTFIX_LENGTH - 1)];
 325
 0326        textPostfix.text = $"#{userProfile.userId[^NAME_POSTFIX_LENGTH..]}";
 0327        SetActiveUnverifiedNameGOs(true);
 0328    }
 329
 330    private void SetConnectedWalletSectionActive(bool active)
 331    {
 0332        connectedWalletSection.SetActive(active);
 0333        nonConnectedWalletSection.SetActive(!active);
 0334        buttonLogOut.gameObject.SetActive(active);
 0335    }
 336
 337    private void SetActiveUnverifiedNameGOs(bool active)
 338    {
 0339        for (int i = 0; i < hideOnNameClaimed.Length; i++)
 0340            hideOnNameClaimed[i].SetActive(active);
 0341    }
 342
 343    private void HandleProfileAddress(UserProfile userProfile)
 344    {
 0345        string address = userProfile.userId;
 0346        string start = address.Substring(0, ADDRESS_CHUNK_LENGTH);
 0347        string end = address.Substring(address.Length - ADDRESS_CHUNK_LENGTH);
 0348        textAddress.text = $"{start}...{end}";
 0349    }
 350
 351    private void SetProfileImage(Texture2D texture)
 352    {
 0353        loadingSpinner.SetActive(false);
 0354        imageAvatarThumbnail.texture = texture;
 0355    }
 356
 357    private void OnDestroy()
 358    {
 1359        hudCanvasCameraModeController?.Dispose();
 1360        if (profile)
 0361            profile.snapshotObserver.RemoveListener(SetProfileImage);
 1362    }
 363
 364    private void CopyAddress()
 365    {
 0366        if (!profile)
 0367            return;
 368
 0369        Environment.i.platform.clipboard.WriteText(profile.userId);
 370
 0371        copyTooltip.gameObject.SetActive(false);
 0372        if (copyToastRoutine != null)
 0373            StopCoroutine(copyToastRoutine);
 374
 0375        copyToastRoutine = StartCoroutine(ShowCopyToast());
 0376    }
 377
 2378    private void OnEnable() { closeAction.OnTriggered += closeActionDelegate; }
 379
 2380    private void OnDisable() { closeAction.OnTriggered -= closeActionDelegate; }
 381
 0382    private void UpdateNameCharLimit(string newValue) { textCharLimit.text = $"{newValue.Length}/{inputName.characterLim
 383
 384    private void SetDescriptionEnabled(bool enabled)
 385    {
 0386        descriptionContainer.SetActive(enabled);
 0387    }
 388
 389    private void UpdateDescriptionCharLimit(string description) =>
 0390        textCharLimitDescription.text = $"{description.Length}/{descriptionInputText.characterLimit}";
 391
 392    private void UpdateLinksInformation(string description)
 393    {
 0394        string[] words = description.Split(' ', StringSplitOptions.RemoveEmptyEntries);
 0395        bool[] areLinks = new bool[words.Length];
 0396        bool linksFound = false;
 397
 0398        for (int i = 0; i < words.Length; i++)
 399        {
 0400            if (words[i].StartsWith("[") && words[i].Contains("]") && words[i].Contains("(") && words[i].EndsWith(")"))
 401            {
 0402                string link = words[i].Split("(")[0].Replace("[", "").Replace("]", "");
 0403                string id = words[i].Split("]")[1].Replace("(", "").Replace(")", "");
 0404                string[] elements = words[i].Split('.');
 0405                if (elements.Length >= 2)
 406                {
 0407                    words[i] = $"<color=\"blue\"><link=\"{id}\">{link}</link></color>";
 0408                    areLinks[i] = true;
 0409                    linksFound = true;
 410                }
 411            }
 412        }
 413
 0414        if (linksFound)
 415        {
 0416            bool foundLinksAtTheEnd = false;
 0417            for (int i = words.Length - 1; i >= 0; i--)
 418            {
 0419                if (string.IsNullOrEmpty(words[i]))
 420                    continue;
 421
 0422                if (!foundLinksAtTheEnd && !areLinks[i])
 423                    break;
 424
 0425                if (areLinks[i])
 426                {
 0427                    foundLinksAtTheEnd = true;
 0428                    continue;
 429                }
 430
 0431                words[i] += "\n\n";
 0432                break;
 433            }
 0434            descriptionInputText.text = string.Join(" ", words);
 435        }
 0436    }
 437
 438
 439    private IEnumerator ShowCopyToast()
 440    {
 0441        if (!copyToast.gameObject.activeSelf)
 0442            copyToast.gameObject.SetActive(true);
 443
 0444        copyToast.Show();
 0445        yield return new WaitForSeconds(COPY_TOAST_VISIBLE_TIME);
 0446        copyToast.Hide();
 0447    }
 448}