< Summary

Class:NFTPromptHUDView
Assembly:NFTPromptHUD
File(s):/tmp/workspace/unity-renderer/unity-renderer/Assets/Scripts/MainScripts/DCL/Controllers/HUD/NFTPromptHUD/NFTPromptHUDView.cs
Covered lines:73
Uncovered lines:115
Coverable lines:188
Total lines:458
Line coverage:38.8% (73 of 188)
Covered branches:0
Total branches:0

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity NPath complexity Sequence coverage
Awake()0%110100%
Dispose()0%4.134080%
Hide()0%4.034087.5%
GetOwnersPopup()0%110100%
GetOwnersTooltip()0%110100%
SetActive(...)0%110100%
IsActive()0%110100%
GetOwnerElementPrefab()0%110100%
SetLoading()0%22095.65%
SetNFTInfo(...)0%1821300%
Show()0%110100%
FetchNFTImage()0%30500%
UpdateTexture(...)0%2100%
SetNFTImageSize(...)0%6200%
ShortDecimals(...)0%30500%
SetTransparentBackground()0%110100%
SetTokenSymbol(...)0%2100%
OpenMarketUrl()0%6200%
OnError(...)0%2100%
OnDestroy()0%3.013090%
OnViewAllOwnersPressed()0%6200%
OnOwnersTooltipGainFocus()0%6200%
OnOwnersTooltipLostFocus()0%6200%
OnOwnersPopupClose()0%6200%
OwnerLabelPointerEnter()0%6200%
OwnerLabelPointerExit()0%6200%
ShowMainLoading(...)0%2.062075%
ShowMainErrorFeedback(...)0%3.333066.67%
ShowImageLoading(...)0%2.062075%
ShowImageErrorFeedback(...)0%12300%

File(s)

/tmp/workspace/unity-renderer/unity-renderer/Assets/Scripts/MainScripts/DCL/Controllers/HUD/NFTPromptHUD/NFTPromptHUDView.cs

#LineLine coverage
 1using System;
 2using UnityEngine;
 3using UnityEngine.UI;
 4using TMPro;
 5using DCL;
 6using DCL.Helpers;
 7using DCL.Helpers.NFT;
 8using DCL.Interface;
 9using System.Collections;
 10using NFTShape_Internal;
 11
 12internal interface INFTPromptHUDView : IDisposable
 13{
 14    event Action OnOwnerLabelPointerEnter;
 15    event Action OnOwnerLabelPointerExit;
 16    event Action OnOwnersTooltipFocusLost;
 17    event Action OnOwnersTooltipFocus;
 18    event Action OnViewAllPressed;
 19    event Action OnOwnersPopupClosed;
 20    void SetActive(bool active);
 21    bool IsActive();
 22    IOwnersTooltipView GetOwnersTooltip();
 23    IOwnersPopupView GetOwnersPopup();
 24    OwnerInfoElement GetOwnerElementPrefab();
 25    void SetLoading();
 26    void SetNFTInfo(NFTInfoSingleAsset info, string comment);
 27    void OnError(string error);
 28}
 29
 30internal class NFTPromptHUDView : MonoBehaviour, INFTPromptHUDView
 31{
 32    private const string MULTIPLE_OWNERS_FORMAT = "{0} owners";
 33    private const int ADDRESS_MAX_CHARS = 11;
 34
 35    public event Action OnOwnerLabelPointerEnter;
 36    public event Action OnOwnerLabelPointerExit;
 37    public event Action OnOwnersTooltipFocusLost;
 38    public event Action OnOwnersTooltipFocus;
 39    public event Action OnViewAllPressed;
 40    public event Action OnOwnersPopupClosed;
 41
 42    [SerializeField] internal GameObject content;
 43    [SerializeField] internal GameObject nftContent;
 44    [SerializeField] internal GameObject mainErrorFeedbackContent;
 45    [SerializeField] internal GameObject imageErrorFeedbackContent;
 46
 47    [SerializeField] RawImage imageNft;
 48    [SerializeField] Image imageNftBackground;
 49    [SerializeField] TextMeshProUGUI textNftName;
 50    [SerializeField] TextMeshProUGUI textOwner;
 51    [SerializeField] TextMeshProUGUI textMultipleOwner;
 52    [SerializeField] UIHoverCallback multipleOwnersContainer;
 53
 54    [Header("Last Sale")] [SerializeField] TextMeshProUGUI textLastSaleSymbol;
 55    [SerializeField] TextMeshProUGUI textLastSalePrice;
 56    [SerializeField] TextMeshProUGUI textLastSaleNeverSold;
 57
 58    [Header("Price")] [SerializeField] TextMeshProUGUI textPriceSymbol;
 59    [SerializeField] TextMeshProUGUI textPrice;
 60    [SerializeField] TextMeshProUGUI textPriceNotForSale;
 61
 62    [Header("Description & Comment")]
 63    [SerializeField]
 64    TextMeshProUGUI textDescription;
 65
 66    [SerializeField] TextMeshProUGUI textComment;
 67    [SerializeField] GameObject containerDescription;
 68    [SerializeField] GameObject containerComment;
 69
 70    [Header("Spinners")] [SerializeField] GameObject spinnerGeneral;
 71    [SerializeField] GameObject spinnerNftImage;
 72
 73    [Header("Buttons")] [SerializeField] internal Button buttonClose;
 74    [SerializeField] internal Button buttonCancel;
 75    [SerializeField] internal Button buttonOpenMarket;
 76    [SerializeField] TextMeshProUGUI textOpenMarketButton;
 77
 78    [Header("Owners")]
 79    [SerializeField] internal OwnerInfoElement ownerElementPrefab;
 80    [SerializeField] internal OwnersTooltipView ownersTooltip;
 81    [SerializeField] internal OwnersPopupView ownersPopup;
 82
 83    Coroutine fetchNFTImageRoutine = null;
 84
 85    private string nftTokenId;
 86    bool backgroundColorSet = false;
 87    string marketUrl = null;
 88
 89    private bool isDestroyed = false;
 90    internal INFTAssetRetriever nftAssetRetriever;
 91    private INFTAsset nftAsset;
 92
 93    private void Awake()
 94    {
 795        name = "_NFTPromptHUD";
 96
 797        buttonClose.onClick.AddListener(Hide);
 798        buttonCancel.onClick.AddListener(Hide);
 799        buttonOpenMarket.onClick.AddListener(OpenMarketUrl);
 100
 7101        multipleOwnersContainer.OnPointerEnter += OwnerLabelPointerEnter;
 7102        multipleOwnersContainer.OnPointerExit += OwnerLabelPointerExit;
 7103        ownersTooltip.OnViewAllPressed += OnViewAllOwnersPressed;
 7104        ownersTooltip.OnFocusLost += OnOwnersTooltipLostFocus;
 7105        ownersTooltip.OnFocus += OnOwnersTooltipGainFocus;
 7106        ownersPopup.OnClosePopup += OnOwnersPopupClose;
 7107    }
 108
 109    public void Dispose()
 110    {
 7111        if (!isDestroyed)
 112        {
 7113            Destroy(gameObject);
 114        }
 115
 7116        nftAssetRetriever?.Dispose();
 7117        nftAsset?.Dispose();
 0118    }
 119
 120    internal void Hide()
 121    {
 1122        content.SetActive(false);
 123
 1124        nftAssetRetriever?.Dispose();
 1125        nftAsset?.Dispose();
 126
 1127        if (fetchNFTImageRoutine != null)
 0128            StopCoroutine(fetchNFTImageRoutine);
 129
 1130        fetchNFTImageRoutine = null;
 131
 1132        AudioScriptableObjects.dialogClose.Play(true);
 1133    }
 134
 1135    IOwnersPopupView INFTPromptHUDView.GetOwnersPopup() { return ownersPopup; }
 136
 1137    IOwnersTooltipView INFTPromptHUDView.GetOwnersTooltip() { return ownersTooltip; }
 138
 16139    void INFTPromptHUDView.SetActive(bool active) { content.SetActive(active); }
 140
 1141    bool INFTPromptHUDView.IsActive() { return content.activeSelf; }
 142
 7143    OwnerInfoElement INFTPromptHUDView.GetOwnerElementPrefab() { return ownerElementPrefab; }
 144
 145    void INFTPromptHUDView.SetLoading()
 146    {
 1147        Show();
 148
 1149        if (fetchNFTImageRoutine != null)
 0150            StopCoroutine(fetchNFTImageRoutine);
 151
 1152        SetTransparentBackground();
 153
 1154        imageNft.gameObject.SetActive(false);
 1155        textNftName.gameObject.SetActive(false);
 1156        textOwner.gameObject.SetActive(false);
 1157        multipleOwnersContainer.gameObject.SetActive(false);
 1158        textLastSaleSymbol.gameObject.SetActive(false);
 1159        textLastSalePrice.gameObject.SetActive(false);
 1160        textLastSaleNeverSold.gameObject.SetActive(false);
 1161        textPriceSymbol.gameObject.SetActive(false);
 1162        textPrice.gameObject.SetActive(false);
 1163        textPriceNotForSale.gameObject.SetActive(false);
 1164        containerDescription.SetActive(false);
 1165        containerComment.SetActive(false);
 1166        buttonCancel.gameObject.SetActive(false);
 1167        buttonOpenMarket.gameObject.SetActive(false);
 168
 1169        nftContent.SetActive(false);
 1170        ShowImageLoading(false);
 1171        ShowMainLoading(true);
 1172        ShowMainErrorFeedback(false);
 1173    }
 174
 175    void INFTPromptHUDView.SetNFTInfo(NFTInfoSingleAsset info, string comment)
 176    {
 0177        Show();
 178
 0179        ShowMainLoading(false);
 0180        nftContent.SetActive(true);
 181
 0182        nftTokenId = info.tokenId;
 0183        SetTransparentBackground();
 0184        backgroundColorSet = info.backgroundColor != null;
 0185        if (backgroundColorSet)
 186        {
 0187            imageNftBackground.color = info.backgroundColor.Value;
 188        }
 189
 0190        textNftName.text = info.name;
 0191        textNftName.gameObject.SetActive(true);
 192
 0193        bool hasMultipleOwners = info.owners.Length > 1;
 0194        if (hasMultipleOwners)
 195        {
 0196            textMultipleOwner.text = string.Format(MULTIPLE_OWNERS_FORMAT, info.owners.Length);
 197        }
 198        else
 199        {
 0200            textOwner.text = info.owners.Length == 1
 201                ? NFTPromptHUDController.FormatOwnerAddress(info.owners[0].owner, ADDRESS_MAX_CHARS)
 202                : NFTPromptHUDController.FormatOwnerAddress("0x0000000000000000000000000000000000000000", ADDRESS_MAX_CH
 203        }
 0204        textOwner.gameObject.SetActive(!hasMultipleOwners);
 0205        multipleOwnersContainer.gameObject.SetActive(hasMultipleOwners);
 206
 0207        if (!string.IsNullOrEmpty(info.lastSaleAmount))
 208        {
 0209            textLastSalePrice.text = ShortDecimals(info.lastSaleAmount, 4);
 0210            textLastSalePrice.gameObject.SetActive(true);
 211        }
 212        else
 213        {
 0214            textLastSaleNeverSold.gameObject.SetActive(true);
 215        }
 216
 0217        if (!string.IsNullOrEmpty(info.currentPrice))
 218        {
 0219            textPrice.text = ShortDecimals(info.currentPrice, 4);
 0220            textPrice.gameObject.SetActive(true);
 221
 0222            if (info.currentPriceToken != null)
 223            {
 0224                SetTokenSymbol(textPriceSymbol, info.currentPriceToken.Value.symbol);
 225            }
 226        }
 227        else
 228        {
 0229            textPriceNotForSale.gameObject.SetActive(true);
 230        }
 231
 0232        if (info.lastSaleToken != null)
 233        {
 0234            SetTokenSymbol(textLastSaleSymbol, info.lastSaleToken.Value.symbol);
 235        }
 236
 0237        if (!string.IsNullOrEmpty(info.description))
 238        {
 0239            textDescription.text = info.description;
 0240            containerDescription.SetActive(true);
 241        }
 242
 0243        if (!string.IsNullOrEmpty(comment))
 244        {
 0245            textComment.text = comment;
 0246            containerComment.SetActive(true);
 247        }
 248
 0249        textOpenMarketButton.text = "VIEW";
 0250        if (info.marketInfo != null)
 251        {
 0252            textOpenMarketButton.text = $"{textOpenMarketButton.text} ON {info.marketInfo.Value.name.ToUpper()}";
 253        }
 254
 0255        marketUrl = null;
 0256        if (!string.IsNullOrEmpty(info.marketLink))
 257        {
 0258            marketUrl = info.marketLink;
 259        }
 0260        else if (!string.IsNullOrEmpty(info.assetLink))
 261        {
 0262            marketUrl = info.assetLink;
 263        }
 264
 0265        buttonCancel.gameObject.SetActive(true);
 0266        buttonOpenMarket.gameObject.SetActive(true);
 267
 0268        fetchNFTImageRoutine = StartCoroutine(FetchNFTImage(info));
 0269    }
 270
 271    private void Show()
 272    {
 1273        content.SetActive(true);
 1274        Utils.UnlockCursor();
 1275    }
 276
 277    private IEnumerator FetchNFTImage(NFTInfoSingleAsset nftInfo)
 278    {
 0279        ShowImageErrorFeedback(false);
 0280        ShowImageLoading(true);
 281
 0282        nftAssetRetriever?.Dispose();
 0283        nftAsset?.Dispose();
 284
 0285        nftAssetRetriever = new NFTAssetRetriever();
 0286        yield return nftAssetRetriever.LoadNFTAsset(
 287            nftInfo.previewImageUrl,
 288            OnSuccess: nftAsset =>
 289            {
 0290                this.nftAsset = nftAsset;
 0291                nftAsset.OnTextureUpdate += UpdateTexture;
 292
 0293                if (!(nftAsset is Asset_Gif))
 294                {
 0295                    if (!backgroundColorSet)
 296                    {
 0297                        SetTransparentBackground();
 298                    }
 299                }
 300
 0301                UpdateTexture(nftAsset.previewAsset.texture);
 0302                SetNFTImageSize(nftAsset.previewAsset.texture);
 0303                imageNft.gameObject.SetActive(true);
 0304                ShowImageLoading(false);
 0305            },
 306            OnFail:
 0307            (exc) => { ShowImageErrorFeedback(true); });
 0308    }
 309
 310    private void UpdateTexture(Texture2D texture)
 311    {
 0312        imageNft.texture = texture;
 0313    }
 314
 315    private void SetNFTImageSize(Texture2D texture)
 316    {
 0317        RectTransform rt = (RectTransform)imageNft.transform.parent;
 318
 319        float h, w;
 320
 0321        if (texture.height > texture.width)
 322        {
 0323            h = rt.rect.height;
 0324            w = h * (texture.width / (float)texture.height);
 325        }
 326        else
 327        {
 0328            w = rt.rect.width;
 0329            h = w * (texture.height / (float)texture.width);
 330        }
 331
 0332        imageNft.rectTransform.sizeDelta = new Vector2(w, h);
 0333    }
 334
 335    private string ShortDecimals(string value, int decimalCount)
 336    {
 0337        int pointPosition = value.IndexOf('.');
 338
 0339        if (pointPosition <= 0)
 0340            return value;
 341
 0342        string ret = value.Substring(0, pointPosition + Mathf.Min(value.Length - pointPosition, decimalCount + 1));
 343
 0344        for (int i = ret.Length - 1; i >= 0; i--)
 345        {
 0346            if (ret[i] == '.')
 347            {
 0348                return ret.Substring(0, i);
 349            }
 350
 0351            if (ret[i] != '0')
 352            {
 0353                return ret.Substring(0, i + 1);
 354            }
 355        }
 356
 0357        return ret;
 358    }
 359
 360    private void SetTransparentBackground()
 361    {
 1362        imageNftBackground.color = new Color(
 363            imageNftBackground.color.r,
 364            imageNftBackground.color.g,
 365            imageNftBackground.color.b,
 366            0f);
 1367    }
 368
 369    private void SetTokenSymbol(TextMeshProUGUI textToken, string symbol)
 370    {
 0371        textToken.text = symbol;
 0372        textToken.gameObject.SetActive(true);
 0373    }
 374
 375    private void OpenMarketUrl()
 376    {
 0377        if (!string.IsNullOrEmpty(marketUrl))
 378        {
 0379            WebInterface.OpenURL(marketUrl);
 0380            AnalyticsHelper.SendExternalLinkAnalytic(marketUrl, nftTokenId);
 381        }
 382        else
 383        {
 0384            Hide();
 385        }
 0386    }
 387
 388    void INFTPromptHUDView.OnError(string error)
 389    {
 0390        Debug.LogError(error);
 0391        ShowMainErrorFeedback(true);
 0392    }
 393
 394    private void OnDestroy()
 395    {
 7396        isDestroyed = true;
 397
 7398        multipleOwnersContainer.OnPointerEnter -= OwnerLabelPointerEnter;
 7399        multipleOwnersContainer.OnPointerExit -= OwnerLabelPointerExit;
 7400        ownersTooltip.OnViewAllPressed -= OnViewAllOwnersPressed;
 7401        ownersTooltip.OnFocusLost -= OnOwnersTooltipLostFocus;
 7402        ownersTooltip.OnFocus -= OnOwnersTooltipGainFocus;
 7403        ownersPopup.OnClosePopup -= OnOwnersPopupClose;
 404
 7405        nftAssetRetriever?.Dispose();
 7406        nftAsset?.Dispose();
 0407    }
 408
 0409    private void OnViewAllOwnersPressed() { OnViewAllPressed?.Invoke(); }
 410
 0411    private void OnOwnersTooltipGainFocus() { OnOwnersTooltipFocus?.Invoke(); }
 412
 0413    private void OnOwnersTooltipLostFocus() { OnOwnersTooltipFocusLost?.Invoke(); }
 414
 0415    private void OnOwnersPopupClose() { OnOwnersPopupClosed?.Invoke(); }
 416
 0417    private void OwnerLabelPointerEnter() { OnOwnerLabelPointerEnter?.Invoke(); }
 418
 0419    private void OwnerLabelPointerExit() { OnOwnerLabelPointerExit?.Invoke(); }
 420
 421    private void ShowMainLoading(bool isVisible)
 422    {
 1423        if (spinnerGeneral == null)
 0424            return;
 425
 1426        spinnerGeneral.SetActive(isVisible);
 1427    }
 428
 429    private void ShowMainErrorFeedback(bool isVisible)
 430    {
 1431        if (mainErrorFeedbackContent == null)
 0432            return;
 433
 1434        if (isVisible)
 0435            ShowMainLoading(false);
 436
 1437        mainErrorFeedbackContent.SetActive(isVisible);
 1438    }
 439
 440    private void ShowImageLoading(bool isVisible)
 441    {
 1442        if (spinnerNftImage == null)
 0443            return;
 444
 1445        spinnerNftImage.SetActive(isVisible);
 1446    }
 447
 448    private void ShowImageErrorFeedback(bool isVisible)
 449    {
 0450        if (imageErrorFeedbackContent == null)
 0451            return;
 452
 0453        if (isVisible)
 0454            ShowImageLoading(false);
 455
 0456        imageErrorFeedbackContent.SetActive(isVisible);
 0457    }
 458}