< Summary

Class:ProjectCardView
Assembly:BuilderProjectsPanel
File(s):/tmp/workspace/unity-renderer/unity-renderer/Assets/DCLPlugins/BuilderInWorld/HUD/ProjectsPanelHUD/Scripts/Views/ProjectCardView.cs
Covered lines:104
Uncovered lines:24
Coverable lines:128
Total lines:383
Line coverage:81.2% (104 of 128)
Covered branches:0
Total branches:0

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity NPath complexity Sequence coverage
ProjectCardView()0%110100%
ProjectCardView()0%110100%
get_projectData()0%2100%
get_searchInfo()0%110100%
get_contextMenuButtonPosition()0%2100%
Awake()0%110100%
OnDestroy()0%110100%
Dispose()0%220100%
Setup(...)0%110100%
SetScenes(...)0%550100%
ExpandButtonPressed()0%4.254075%
AddRectTransformHeight(...)0%220100%
ScenesVisiblitityChange(...)0%330100%
InstantiateScenesCards()0%220100%
EditorButtonClicked()0%220100%
SetThumbnail(...)0%9.855042.11%
SetThumbnail(...)0%220100%
SetParent(...)0%6200%
SetToDefaultParent()0%110100%
ConfigureDefaultParent(...)0%110100%
SetActive(...)0%110100%
SetSiblingIndex(...)0%2100%
SetName(...)0%110100%
SetSize(...)0%110100%
GetSizeText(...)0%110100%
ChangeHeightAnimation()0%4.024088.89%

File(s)

/tmp/workspace/unity-renderer/unity-renderer/Assets/DCLPlugins/BuilderInWorld/HUD/ProjectsPanelHUD/Scripts/Views/ProjectCardView.cs

#LineLine coverage
 1using System;
 2using System.Collections;
 3using System.Collections.Generic;
 4using System.Configuration;
 5using DCL;
 6using DCL.Builder;
 7using DCL.Configuration;
 8using UnityEngine;
 9using DCL.Helpers;
 10using TMPro;
 11using UnityEngine.UI;
 12
 13internal interface IProjectCardView : IDisposable
 14{
 15    /// <summary>
 16    /// Edit project button pressed
 17    /// </summary>
 18    event Action<ProjectData> OnEditorPressed;
 19
 20    /// <summary>
 21    ///  Setting button pressed
 22    /// </summary>
 23    event Action<ProjectData> OnSettingsPressed;
 24
 25    /// <summary>
 26    /// Expand button pressed
 27    /// </summary>
 28    event Action OnExpandMenuPressed;
 29
 30    /// <summary>
 31    /// Data of the project card
 32    /// </summary>
 33    ProjectData projectData { get; }
 34
 35    /// <summary>
 36    /// Info for the search result
 37    /// </summary>
 38    ISearchInfo searchInfo { get; }
 39
 40    /// <summary>
 41    /// Position of the context menu button
 42    /// </summary>
 43    Vector3 contextMenuButtonPosition { get; }
 44
 45    /// <summary>
 46    /// Set the scenes of the project
 47    /// </summary>
 48    /// <param name="scenes"></param>
 49    void SetScenes(List<Scene> scenes);
 50
 51    /// <summary>
 52    /// This setup the project data
 53    /// </summary>
 54    /// <param name="projectData"></param>
 55    void Setup(ProjectData projectData);
 56
 57    /// <summary>
 58    /// Set Parent of the card
 59    /// </summary>
 60    /// <param name="parent"></param>
 61    void SetParent(Transform parent);
 62
 63    /// <summary>
 64    /// Reset to default parent
 65    /// </summary>
 66    void SetToDefaultParent();
 67
 68    /// <summary>
 69    /// Configure the default parent
 70    /// </summary>
 71    /// <param name="parent">default parent to apply</param>
 72    void ConfigureDefaultParent(Transform parent);
 73
 74    /// <summary>
 75    /// Active the card
 76    /// </summary>
 77    /// <param name="active"></param>
 78    void SetActive(bool active);
 79
 80    /// <summary>
 81    /// This set the order of the card
 82    /// </summary>
 83    /// <param name="index"></param>
 84    void SetSiblingIndex(int index);
 85
 86    void SetName(string name);
 87    void SetSize(int rows, int columns);
 88    void SetThumbnail(string thumbnailUrl, string filename);
 89    void SetThumbnail(Texture2D thumbnailTexture);
 90}
 91
 92internal class ProjectCardView : MonoBehaviour, IProjectCardView
 93{
 194    static readonly Vector3 CONTEXT_MENU_OFFSET = new Vector3(6.24f, 12f, 0);
 95
 96    internal const string NOT_PUBLISHED = "NOT PUBLISHED";
 97    internal const string PUBLISHED_IN = "PUBLISHED IN";
 98
 99    internal const float SCENE_CARD_SIZE = 84;
 100    internal const float SCENE_CARD_ITEM_PADDING = 18;
 101    internal const float SCENE_CARD_TOTAL_PADDING = 36;
 102
 103    public event Action<ProjectData> OnEditorPressed;
 104    public event Action<ProjectData> OnSettingsPressed;
 105    public event Action OnExpandMenuPressed;
 106
 107    [Header("Design Variables")]
 8108    [SerializeField] private  float animationSpeed = 6f;
 109
 110    [Header("Project References")]
 111    [SerializeField] internal Color syncColor;
 112
 113    [SerializeField] internal Color desyncColor;
 114    [SerializeField] private Texture2D defaultThumbnail;
 115    [SerializeField] private GameObject projectSceneCardViewPrefab;
 116
 117
 118    [Header("Prefab references")]
 119    [SerializeField] internal Image syncImage;
 120
 121    [SerializeField] internal Button contextMenuButton;
 122    [SerializeField] internal Button expandButton;
 123    [SerializeField] internal Button editorButton;
 124
 125    [SerializeField] internal RectTransform scenesContainer;
 126    [SerializeField] internal VerticalLayoutGroup layoutGroup;
 127
 128    [SerializeField] private GameObject loadingImgGameObject;
 129    [SerializeField] private GameObject publishedGameObject;
 130    [SerializeField] private RectTransform downButtonTransform;
 131    [SerializeField] internal TextMeshProUGUI projectNameTxt;
 132    [SerializeField] internal TextMeshProUGUI projectSizeTxt;
 133    [SerializeField] internal TextMeshProUGUI projectSyncTxt;
 134
 135    [Space]
 136    [SerializeField] private RawImageFillParent thumbnail;
 137
 0138    ProjectData IProjectCardView.projectData => projectData;
 30139    ISearchInfo IProjectCardView.searchInfo { get; } = new SearchInfo();
 0140    Vector3 IProjectCardView.contextMenuButtonPosition => contextMenuButton.transform.position + CONTEXT_MENU_OFFSET;
 141
 142    private ProjectData projectData;
 143    private ISearchInfo searchInfo;
 144    private Vector3 contextMenuButtonPosition;
 145
 146    private string thumbnailId = null;
 147    private Transform defaultParent;
 148    private AssetPromise_Texture thumbnailPromise;
 149    private bool scenesAreVisible = false;
 150    private bool isDestroyed = false;
 151
 152    private RectTransform rectTransform;
 153
 8154    internal List<Scene> scenesDeployedFromProject = new List<Scene>();
 8155    internal List<IProjectSceneCardView> sceneCardViews = new List<IProjectSceneCardView>();
 156
 157    private Coroutine animationCoroutine;
 158
 159    private void Awake()
 160    {
 7161        editorButton.onClick.AddListener(EditorButtonClicked);
 7162        expandButton.onClick.AddListener(ExpandButtonPressed);
 7163        contextMenuButton.onClick.AddListener(EditorButtonClicked);
 164
 7165        rectTransform = GetComponent<RectTransform>();
 7166    }
 167
 168    private void OnDestroy()
 169    {
 7170        isDestroyed = true;
 7171        Dispose();
 7172    }
 173
 174    public void Dispose()
 175    {
 8176        CoroutineStarter.Stop(animationCoroutine);
 8177        AssetPromiseKeeper_Texture.i.Forget(thumbnailPromise);
 8178        editorButton.onClick.RemoveAllListeners();
 8179        if(!isDestroyed)
 1180            Destroy(gameObject);
 8181    }
 182
 183    public void Setup(ProjectData projectData)
 184    {
 7185        this.projectData = projectData;
 7186        SetName(projectData.title);
 7187        SetSize(projectData.rows, projectData.cols);
 188
 7189        SetThumbnail(projectData.id, projectData.thumbnail);
 190
 7191        ((IProjectCardView)this).searchInfo.SetId(projectData.id);
 7192    }
 193
 194    public void SetScenes(List<Scene> scenes)
 195    {
 4196        scenesDeployedFromProject = scenes;
 4197        publishedGameObject.gameObject.SetActive(true);
 4198        if (scenes.Count == 0)
 199        {
 1200            syncImage.enabled = false;
 1201            projectSyncTxt.text = NOT_PUBLISHED;
 1202            downButtonTransform.gameObject.SetActive(false);
 1203        }
 204        else
 205        {
 3206            downButtonTransform.gameObject.SetActive(true);
 3207            bool isSync = true;
 3208            long projectTimestamp = BIWUtils.ConvertToMilisecondsTimestamp(projectData.updated_at);
 10209            foreach (Scene scene in scenes)
 210            {
 3211                if (scene.deployTimestamp < projectTimestamp)
 212                {
 2213                    isSync = false;
 2214                    break;
 215                }
 216            }
 217
 3218            if (isSync)
 1219                syncImage.color = syncColor;
 220            else
 2221                syncImage.color = desyncColor;
 222
 3223            projectSyncTxt.text = PUBLISHED_IN;
 224        }
 3225    }
 226
 227    internal void ExpandButtonPressed()
 228    {
 1229        if (scenesDeployedFromProject.Count == 0 )
 0230            return;
 231
 1232        downButtonTransform.Rotate(Vector3.forward, 180);
 233
 1234        scenesAreVisible = !scenesAreVisible;
 1235        ScenesVisiblitityChange(scenesAreVisible);
 236
 1237        float amountToIncrease = sceneCardViews.Count * SCENE_CARD_SIZE + SCENE_CARD_TOTAL_PADDING + SCENE_CARD_ITEM_PAD
 238
 1239        if (scenesAreVisible)
 240        {
 1241            layoutGroup.padding.bottom = 18;
 1242            AddRectTransformHeight(rectTransform, amountToIncrease);
 1243            AddRectTransformHeight(scenesContainer, amountToIncrease);
 1244        }
 245        else
 246        {
 0247            layoutGroup.padding.bottom = 0;
 0248            AddRectTransformHeight(rectTransform, -amountToIncrease);
 0249            AddRectTransformHeight(scenesContainer, -amountToIncrease);
 250        }
 251
 1252        OnExpandMenuPressed?.Invoke();
 1253    }
 254
 255
 256    private void AddRectTransformHeight(RectTransform rectTransform, float height)
 257    {
 2258        if(animationCoroutine != null)
 1259            CoroutineStarter.Stop(animationCoroutine);
 260
 2261        animationCoroutine = CoroutineStarter.Start(ChangeHeightAnimation(rectTransform, height));
 2262    }
 263
 264    private void ScenesVisiblitityChange(bool isVisible)
 265    {
 1266        if (sceneCardViews.Count == 0)
 1267            InstantiateScenesCards();
 268
 4269        foreach (IProjectSceneCardView scene in sceneCardViews)
 270        {
 1271            scene.SetActive(isVisible);
 272        }
 1273    }
 274
 275    private void InstantiateScenesCards()
 276    {
 1277        long projectTimestamp = BIWUtils.ConvertToMilisecondsTimestamp(projectData.updated_at);
 4278        foreach (Scene scene in scenesDeployedFromProject)
 279        {
 1280            bool isSync = scene.deployTimestamp < projectTimestamp;
 281
 1282            IProjectSceneCardView cardView = Instantiate(projectSceneCardViewPrefab, scenesContainer).GetComponent<Proje
 1283            cardView.Setup(scene, isSync);
 1284            sceneCardViews.Add(cardView);
 285        }
 1286    }
 287
 288    internal void EditorButtonClicked()
 289    {
 1290        OnEditorPressed?.Invoke(projectData);
 1291    }
 292
 293    public void SetThumbnail(string thumbnailId, string thumbnailEndpoint)
 294    {
 7295        if (this.thumbnailId == thumbnailId)
 0296            return;
 297
 7298        string projectThumbnailUrl = "";
 7299        if (!string.IsNullOrEmpty(thumbnailId))
 300        {
 0301            projectThumbnailUrl = BIWUrlUtils.GetBuilderProjecThumbnailUrl(thumbnailId, thumbnailEndpoint);
 302        }
 303
 7304        this.thumbnailId = thumbnailId;
 305
 7306        if (thumbnailPromise != null)
 307        {
 0308            AssetPromiseKeeper_Texture.i.Forget(thumbnailPromise);
 0309            thumbnailPromise = null;
 310        }
 311
 7312        if (string.IsNullOrEmpty(projectThumbnailUrl))
 313        {
 7314            SetThumbnail((Texture2D) null);
 7315            return;
 316        }
 317
 0318        thumbnailPromise = new AssetPromise_Texture(projectThumbnailUrl);
 0319        thumbnailPromise.OnSuccessEvent += texture => SetThumbnail(texture.texture);
 0320        thumbnailPromise.OnFailEvent += (texture, error) => SetThumbnail(null);
 321
 0322        loadingImgGameObject.SetActive(true);
 0323        thumbnail.enabled = false;
 0324        AssetPromiseKeeper_Texture.i.Keep(thumbnailPromise);
 0325    }
 326
 327    public void SetThumbnail(Texture2D thumbnailTexture)
 328    {
 7329        loadingImgGameObject.SetActive(false);
 7330        thumbnail.texture = thumbnailTexture ?? defaultThumbnail;
 7331        thumbnail.enabled = true;
 7332    }
 333
 334    public void SetParent(Transform parent)
 335    {
 0336        if (transform.parent == parent)
 0337            return;
 338
 0339        transform.SetParent(parent);
 0340        transform.ResetLocalTRS();
 0341    }
 342
 2343    public void SetToDefaultParent() { transform.SetParent(defaultParent); }
 344
 2345    public void ConfigureDefaultParent(Transform parent) { defaultParent = parent; }
 346
 2347    public void SetActive(bool active) { gameObject.SetActive(active); }
 348
 0349    public void SetSiblingIndex(int index) { transform.SetSiblingIndex(index); }
 350
 351    public void SetName(string name)
 352    {
 7353        projectNameTxt.text = name;
 7354        ((IProjectCardView)this).searchInfo.SetName(name);
 7355    }
 356
 357    public void SetSize(int rows, int columns)
 358    {
 7359        projectSizeTxt.text = GetSizeText(rows, columns);
 7360        ((IProjectCardView)this).searchInfo.SetSize(rows * columns);
 7361    }
 362
 363    internal string GetSizeText(int rows, int columns)
 364    {
 8365        return (rows * ParcelSettings.PARCEL_SIZE) + "x" + (columns * ParcelSettings.PARCEL_SIZE)  + "m";
 366    }
 367
 368    IEnumerator ChangeHeightAnimation(RectTransform rectTransform, float height)
 369    {
 2370        float time = 0;
 371
 2372        Vector2 rect2 = rectTransform.sizeDelta;
 2373        float objective  = rect2.y + height;
 374
 2375        while (time < 1)
 376        {
 2377            time += Time.deltaTime * animationSpeed / scenesDeployedFromProject.Count;
 2378            rect2.y = Mathf.Lerp(rect2.y, objective, time);
 2379            rectTransform.sizeDelta = rect2;
 2380            yield return null;
 381        }
 0382    }
 383}