< Summary

Class:NFTPromptHUDView
Assembly:NFTPromptHUD
File(s):/tmp/workspace/unity-renderer/unity-renderer/Assets/Scripts/MainScripts/DCL/Controllers/HUD/NFTPromptHUD/NFTPromptHUDView.cs
Covered lines:74
Uncovered lines:136
Coverable lines:210
Total lines:480
Line coverage:35.2% (74 of 210)
Covered branches:0
Total branches:0

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity NPath complexity Sequence coverage
Awake()0%110100%
Dispose()0%220100%
Hide()0%2.012085.71%
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%1321100%
SetNFTImageSize(...)0%6200%
ShortDecimals(...)0%30500%
SetSmartBackgroundColor(...)0%2100%
SetTokenSymbol(...)0%2100%
OpenMarketUrl()0%6200%
OnError(...)0%2100%
OnDestroy()0%110100%
ForgetPromises()0%3.333066.67%
SetupGifPlayer(...)0%6200%
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;
 10
 11internal interface INFTPromptHUDView : IDisposable
 12{
 13    event Action OnOwnerLabelPointerEnter;
 14    event Action OnOwnerLabelPointerExit;
 15    event Action OnOwnersTooltipFocusLost;
 16    event Action OnOwnersTooltipFocus;
 17    event Action OnViewAllPressed;
 18    event Action OnOwnersPopupClosed;
 19    void SetActive(bool active);
 20    bool IsActive();
 21    IOwnersTooltipView GetOwnersTooltip();
 22    IOwnersPopupView GetOwnersPopup();
 23    OwnerInfoElement GetOwnerElementPrefab();
 24    void SetLoading();
 25    void SetNFTInfo(NFTInfoSingleAsset info, string comment);
 26    void OnError(string error);
 27}
 28
 29internal class NFTPromptHUDView : MonoBehaviour, INFTPromptHUDView
 30{
 31    private const string MULTIPLE_OWNERS_FORMAT = "{0} owners";
 32    private const int ADDRESS_MAX_CHARS = 11;
 33
 34    public event Action OnOwnerLabelPointerEnter;
 35    public event Action OnOwnerLabelPointerExit;
 36    public event Action OnOwnersTooltipFocusLost;
 37    public event Action OnOwnersTooltipFocus;
 38    public event Action OnViewAllPressed;
 39    public event Action OnOwnersPopupClosed;
 40
 41    [SerializeField] internal GameObject content;
 42    [SerializeField] internal GameObject nftContent;
 43    [SerializeField] internal GameObject mainErrorFeedbackContent;
 44    [SerializeField] internal GameObject imageErrorFeedbackContent;
 45
 46    [SerializeField] RawImage imageNft;
 47    [SerializeField] Image imageNftBackground;
 48    [SerializeField] TextMeshProUGUI textNftName;
 49    [SerializeField] TextMeshProUGUI textOwner;
 50    [SerializeField] TextMeshProUGUI textMultipleOwner;
 51    [SerializeField] UIHoverCallback multipleOwnersContainer;
 52
 53    [Header("Last Sale")] [SerializeField] TextMeshProUGUI textLastSaleSymbol;
 54    [SerializeField] TextMeshProUGUI textLastSalePrice;
 55    [SerializeField] TextMeshProUGUI textLastSaleNeverSold;
 56
 57    [Header("Price")] [SerializeField] TextMeshProUGUI textPriceSymbol;
 58    [SerializeField] TextMeshProUGUI textPrice;
 59    [SerializeField] TextMeshProUGUI textPriceNotForSale;
 60
 61    [Header("Description & Comment")]
 62    [SerializeField]
 63    TextMeshProUGUI textDescription;
 64
 65    [SerializeField] TextMeshProUGUI textComment;
 66    [SerializeField] GameObject containerDescription;
 67    [SerializeField] GameObject containerComment;
 68
 69    [Header("Spinners")] [SerializeField] GameObject spinnerGeneral;
 70    [SerializeField] GameObject spinnerNftImage;
 71
 72    [Header("Buttons")] [SerializeField] internal Button buttonClose;
 73    [SerializeField] internal Button buttonCancel;
 74    [SerializeField] internal Button buttonOpenMarket;
 75    [SerializeField] TextMeshProUGUI textOpenMarketButton;
 76
 77    [Header("Owners")]
 78    [SerializeField] internal OwnerInfoElement ownerElementPrefab;
 79    [SerializeField] internal OwnersTooltipView ownersTooltip;
 80    [SerializeField] internal OwnersPopupView ownersPopup;
 81
 82    Coroutine fetchNFTImageRoutine = null;
 83
 84    private IPromiseLike_TextureAsset imagePromise = null;
 85    private GifPlayer gifPlayer = null;
 86
 87    private string nftTokenId;
 88    bool backgroundColorSet = false;
 89    string marketUrl = null;
 90
 91    private bool isDestroyed = false;
 92    internal IWrappedTextureHelper wrappedTextureHelper;
 93
 94    private void Awake()
 95    {
 796        wrappedTextureHelper = new WrappedTextureUtils();
 797        name = "_NFTPromptHUD";
 98
 799        buttonClose.onClick.AddListener(Hide);
 7100        buttonCancel.onClick.AddListener(Hide);
 7101        buttonOpenMarket.onClick.AddListener(OpenMarketUrl);
 102
 7103        multipleOwnersContainer.OnPointerEnter += OwnerLabelPointerEnter;
 7104        multipleOwnersContainer.OnPointerExit += OwnerLabelPointerExit;
 7105        ownersTooltip.OnViewAllPressed += OnViewAllOwnersPressed;
 7106        ownersTooltip.OnFocusLost += OnOwnersTooltipLostFocus;
 7107        ownersTooltip.OnFocus += OnOwnersTooltipGainFocus;
 7108        ownersPopup.OnClosePopup += OnOwnersPopupClose;
 7109    }
 110
 111    public void Dispose()
 112    {
 7113        if (!isDestroyed)
 114        {
 7115            Destroy(gameObject);
 116        }
 7117    }
 118
 119    internal void Hide()
 120    {
 1121        content.SetActive(false);
 122
 1123        ForgetPromises();
 124
 1125        if (fetchNFTImageRoutine != null)
 0126            StopCoroutine(fetchNFTImageRoutine);
 127
 1128        fetchNFTImageRoutine = null;
 129
 1130        AudioScriptableObjects.dialogClose.Play(true);
 1131    }
 132
 1133    IOwnersPopupView INFTPromptHUDView.GetOwnersPopup() { return ownersPopup; }
 134
 1135    IOwnersTooltipView INFTPromptHUDView.GetOwnersTooltip() { return ownersTooltip; }
 136
 16137    void INFTPromptHUDView.SetActive(bool active) { content.SetActive(active); }
 138
 1139    bool INFTPromptHUDView.IsActive() { return content.activeSelf; }
 140
 7141    OwnerInfoElement INFTPromptHUDView.GetOwnerElementPrefab() { return ownerElementPrefab; }
 142
 143    void INFTPromptHUDView.SetLoading()
 144    {
 1145        Show();
 146
 1147        if (fetchNFTImageRoutine != null)
 0148            StopCoroutine(fetchNFTImageRoutine);
 149
 1150        imageNftBackground.color = Color.white;
 151
 1152        imageNft.gameObject.SetActive(false);
 1153        textNftName.gameObject.SetActive(false);
 1154        textOwner.gameObject.SetActive(false);
 1155        multipleOwnersContainer.gameObject.SetActive(false);
 1156        textLastSaleSymbol.gameObject.SetActive(false);
 1157        textLastSalePrice.gameObject.SetActive(false);
 1158        textLastSaleNeverSold.gameObject.SetActive(false);
 1159        textPriceSymbol.gameObject.SetActive(false);
 1160        textPrice.gameObject.SetActive(false);
 1161        textPriceNotForSale.gameObject.SetActive(false);
 1162        containerDescription.SetActive(false);
 1163        containerComment.SetActive(false);
 1164        buttonCancel.gameObject.SetActive(false);
 1165        buttonOpenMarket.gameObject.SetActive(false);
 166
 1167        nftContent.SetActive(false);
 1168        ShowImageLoading(false);
 1169        ShowMainLoading(true);
 1170        ShowMainErrorFeedback(false);
 1171    }
 172
 173    void INFTPromptHUDView.SetNFTInfo(NFTInfoSingleAsset info, string comment)
 174    {
 0175        Show();
 176
 0177        ShowMainLoading(false);
 0178        nftContent.SetActive(true);
 179
 0180        nftTokenId = info.tokenId;
 0181        imageNftBackground.color = Color.white;
 0182        backgroundColorSet = info.backgroundColor != null;
 0183        if (backgroundColorSet)
 184        {
 0185            imageNftBackground.color = info.backgroundColor.Value;
 186        }
 187
 0188        textNftName.text = info.name;
 0189        textNftName.gameObject.SetActive(true);
 190
 0191        bool hasMultipleOwners = info.owners.Length > 1;
 0192        if (hasMultipleOwners)
 193        {
 0194            textMultipleOwner.text = string.Format(MULTIPLE_OWNERS_FORMAT, info.owners.Length);
 0195        }
 196        else
 197        {
 0198            textOwner.text = info.owners.Length == 1
 199                ? NFTPromptHUDController.FormatOwnerAddress(info.owners[0].owner, ADDRESS_MAX_CHARS)
 200                : NFTPromptHUDController.FormatOwnerAddress("0x0000000000000000000000000000000000000000", ADDRESS_MAX_CH
 201        }
 0202        textOwner.gameObject.SetActive(!hasMultipleOwners);
 0203        multipleOwnersContainer.gameObject.SetActive(hasMultipleOwners);
 204
 0205        if (!string.IsNullOrEmpty(info.lastSaleAmount))
 206        {
 0207            textLastSalePrice.text = ShortDecimals(info.lastSaleAmount, 4);
 0208            textLastSalePrice.gameObject.SetActive(true);
 0209        }
 210        else
 211        {
 0212            textLastSaleNeverSold.gameObject.SetActive(true);
 213        }
 214
 0215        if (!string.IsNullOrEmpty(info.currentPrice))
 216        {
 0217            textPrice.text = ShortDecimals(info.currentPrice, 4);
 0218            textPrice.gameObject.SetActive(true);
 219
 0220            if (info.currentPriceToken != null)
 221            {
 0222                SetTokenSymbol(textPriceSymbol, info.currentPriceToken.Value.symbol);
 223            }
 0224        }
 225        else
 226        {
 0227            textPriceNotForSale.gameObject.SetActive(true);
 228        }
 229
 0230        if (info.lastSaleToken != null)
 231        {
 0232            SetTokenSymbol(textLastSaleSymbol, info.lastSaleToken.Value.symbol);
 233        }
 234
 0235        if (!string.IsNullOrEmpty(info.description))
 236        {
 0237            textDescription.text = info.description;
 0238            containerDescription.SetActive(true);
 239        }
 240
 0241        if (!string.IsNullOrEmpty(comment))
 242        {
 0243            textComment.text = comment;
 0244            containerComment.SetActive(true);
 245        }
 246
 0247        textOpenMarketButton.text = "VIEW";
 0248        if (info.marketInfo != null)
 249        {
 0250            textOpenMarketButton.text = $"{textOpenMarketButton.text} ON {info.marketInfo.Value.name.ToUpper()}";
 251        }
 252
 0253        marketUrl = null;
 0254        if (!string.IsNullOrEmpty(info.marketLink))
 255        {
 0256            marketUrl = info.marketLink;
 0257        }
 0258        else if (!string.IsNullOrEmpty(info.assetLink))
 259        {
 0260            marketUrl = info.assetLink;
 261        }
 262
 0263        buttonCancel.gameObject.SetActive(true);
 0264        buttonOpenMarket.gameObject.SetActive(true);
 265
 0266        fetchNFTImageRoutine = StartCoroutine(FetchNFTImage(info));
 0267    }
 268
 269    private void Show()
 270    {
 1271        content.SetActive(true);
 1272        Utils.UnlockCursor();
 1273    }
 274
 275    private IEnumerator FetchNFTImage(NFTInfoSingleAsset nftInfo)
 276    {
 0277        ShowImageErrorFeedback(false);
 0278        ShowImageLoading(true);
 279
 0280        bool imageFound = false;
 281
 0282        yield return wrappedTextureHelper.Fetch(nftInfo.previewImageUrl,
 283            promise =>
 284            {
 0285                imagePromise?.Forget();
 0286                imagePromise = promise;
 0287                imageFound = true;
 0288            });
 289
 0290        if (!imageFound)
 291        {
 0292            yield return wrappedTextureHelper.Fetch(nftInfo.originalImageUrl,
 293                promise =>
 294                {
 0295                    imagePromise?.Forget();
 0296                    imagePromise = promise;
 0297                    imageFound = true;
 0298                });
 299        }
 300
 0301        if (imageFound && imagePromise?.asset != null)
 302        {
 0303            Texture2D texture = imagePromise.asset.texture;
 0304            imageNft.texture = texture;
 305
 0306            if ((imagePromise.asset is Asset_Gif gif))
 307            {
 0308                SetupGifPlayer(gif);
 0309            }
 0310            else if (!backgroundColorSet)
 311            {
 0312                SetSmartBackgroundColor(texture);
 313            }
 314
 0315            SetNFTImageSize(texture);
 316
 0317            imageNft.gameObject.SetActive(true);
 0318            ShowImageLoading(false);
 0319        }
 320        else
 321        {
 0322            ShowImageErrorFeedback(true);
 323        }
 0324    }
 325
 326    private void SetNFTImageSize(Texture2D texture)
 327    {
 0328        RectTransform rt = (RectTransform)imageNft.transform.parent;
 329        float h, w;
 0330        if (texture.height > texture.width)
 331        {
 0332            h = rt.rect.height;
 0333            w = h * (texture.width / (float)texture.height);
 0334        }
 335        else
 336        {
 0337            w = rt.rect.width;
 0338            h = w * (texture.height / (float)texture.width);
 339        }
 340
 0341        imageNft.rectTransform.sizeDelta = new Vector2(w, h);
 0342    }
 343
 344    private string ShortDecimals(string value, int decimalCount)
 345    {
 0346        int pointPosition = value.IndexOf('.');
 0347        if (pointPosition <= 0)
 0348            return value;
 349
 0350        string ret = value.Substring(0, pointPosition + Mathf.Min(value.Length - pointPosition, decimalCount + 1));
 351
 0352        for (int i = ret.Length - 1; i >= 0; i--)
 353        {
 0354            if (ret[i] == '.')
 355            {
 0356                return ret.Substring(0, i);
 357            }
 358
 0359            if (ret[i] != '0')
 360            {
 0361                return ret.Substring(0, i + 1);
 362            }
 363        }
 364
 0365        return ret;
 366    }
 367
 0368    private void SetSmartBackgroundColor(Texture2D texture) { imageNftBackground.color = texture.GetPixel(0, 0); }
 369
 370    private void SetTokenSymbol(TextMeshProUGUI textToken, string symbol)
 371    {
 0372        textToken.text = symbol;
 0373        textToken.gameObject.SetActive(true);
 0374    }
 375
 376    private void OpenMarketUrl()
 377    {
 0378        if (!string.IsNullOrEmpty(marketUrl))
 379        {
 0380            WebInterface.OpenURL(marketUrl);
 0381            AnalyticsHelper.SendExternalLinkAnalytic(marketUrl, nftTokenId);
 0382        }
 383        else
 384        {
 0385            Hide();
 386        }
 0387    }
 388
 389    void INFTPromptHUDView.OnError(string error)
 390    {
 0391        Debug.LogError(error);
 0392        ShowMainErrorFeedback(true);
 0393    }
 394
 395    private void OnDestroy()
 396    {
 7397        isDestroyed = true;
 398
 7399        multipleOwnersContainer.OnPointerEnter -= OwnerLabelPointerEnter;
 7400        multipleOwnersContainer.OnPointerExit -= OwnerLabelPointerExit;
 7401        ownersTooltip.OnViewAllPressed -= OnViewAllOwnersPressed;
 7402        ownersTooltip.OnFocusLost -= OnOwnersTooltipLostFocus;
 7403        ownersTooltip.OnFocus -= OnOwnersTooltipGainFocus;
 7404        ownersPopup.OnClosePopup -= OnOwnersPopupClose;
 405
 7406        ForgetPromises();
 7407    }
 408
 409    private void ForgetPromises()
 410    {
 8411        if (imagePromise != null)
 412        {
 0413            imagePromise.Forget();
 0414            imagePromise = null;
 415        }
 8416        gifPlayer?.Dispose();
 8417        gifPlayer = null;
 8418    }
 419
 420    private void SetupGifPlayer(Asset_Gif gif)
 421    {
 0422        if (gifPlayer == null)
 423        {
 0424            gifPlayer = new GifPlayer();
 0425            gifPlayer.OnFrameTextureChanged += (texture) => { imageNft.texture = texture; };
 426        }
 0427        gifPlayer.SetGif(gif);
 0428        gifPlayer.Play(true);
 0429    }
 430
 0431    private void OnViewAllOwnersPressed() { OnViewAllPressed?.Invoke(); }
 432
 0433    private void OnOwnersTooltipGainFocus() { OnOwnersTooltipFocus?.Invoke(); }
 434
 0435    private void OnOwnersTooltipLostFocus() { OnOwnersTooltipFocusLost?.Invoke(); }
 436
 0437    private void OnOwnersPopupClose() { OnOwnersPopupClosed?.Invoke(); }
 438
 0439    private void OwnerLabelPointerEnter() { OnOwnerLabelPointerEnter?.Invoke(); }
 440
 0441    private void OwnerLabelPointerExit() { OnOwnerLabelPointerExit?.Invoke(); }
 442
 443    private void ShowMainLoading(bool isVisible)
 444    {
 1445        if (spinnerGeneral == null)
 0446            return;
 447
 1448        spinnerGeneral.SetActive(isVisible);
 1449    }
 450
 451    private void ShowMainErrorFeedback(bool isVisible)
 452    {
 1453        if (mainErrorFeedbackContent == null)
 0454            return;
 455
 1456        if (isVisible)
 0457            ShowMainLoading(false);
 458
 1459        mainErrorFeedbackContent.SetActive(isVisible);
 1460    }
 461
 462    private void ShowImageLoading(bool isVisible)
 463    {
 1464        if (spinnerNftImage == null)
 0465            return;
 466
 1467        spinnerNftImage.SetActive(isVisible);
 1468    }
 469
 470    private void ShowImageErrorFeedback(bool isVisible)
 471    {
 0472        if (imageErrorFeedbackContent == null)
 0473            return;
 474
 0475        if (isVisible)
 0476            ShowImageLoading(false);
 477
 0478        imageErrorFeedbackContent.SetActive(isVisible);
 0479    }
 480}