< Summary

Class:AvatarEditorHUDView
Assembly:AvatarEditorHUD
File(s):/tmp/workspace/unity-renderer/unity-renderer/Assets/Scripts/MainScripts/DCL/Controllers/HUD/AvatarEditorHUD/Scripts/AvatarEditorHUDView.cs
Covered lines:154
Uncovered lines:33
Coverable lines:187
Total lines:438
Line coverage:82.3% (154 of 187)
Covered branches:0
Total branches:0

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity NPath complexity Sequence coverage
AvatarEditorHUDView()0%110100%
Initialize()0%110100%
AvatarEditorHUDView()0%110100%
Awake()0%220100%
OnDestroy()0%110100%
CloseAction_OnTriggered(...)0%6200%
Initialize(...)0%110100%
SetIsWeb3(...)0%110100%
InitializeNavigationEvents()0%220100%
InitializeNavigationInfo(...)0%110100%
InitializeWearableChangeEvents()0%220100%
Create(...)0%110100%
UpdateSelectedBody(...)0%330100%
EquipWearable(...)0%110100%
UnequipWearable(...)0%110100%
SetWearableLoadingSpinner(...)0%220100%
ClearWearablesLoadingSpinner()0%220100%
SelectHairColor(...)0%110100%
SelectSkinColor(...)0%110100%
SelectEyeColor(...)0%110100%
SetColors(...)0%110100%
UnselectAllWearables()0%330100%
UpdateAvatarPreview(...)0%4.074083.33%
AddWearable(...)0%4.594066.67%
RemoveWearable(...)0%20400%
RemoveAllWearables()0%220100%
OnRandomizeButton()0%12300%
OnDoneButton()0%2100%
OnExitButton()0%6200%
OnSnapshotsReady(...)0%2100%
OnSnapshotsFailed()0%2100%
SetVisibility(...)0%7.037091.67%
CleanUp()0%10100100%
ShowCollectiblesLoadingSpinner(...)0%110100%
ShowCollectiblesLoadingRetry(...)0%110100%

File(s)

/tmp/workspace/unity-renderer/unity-renderer/Assets/Scripts/MainScripts/DCL/Controllers/HUD/AvatarEditorHUD/Scripts/AvatarEditorHUDView.cs

#LineLine coverage
 1using System.Collections.Generic;
 2using System.Runtime.CompilerServices;
 3using UnityEngine;
 4using UnityEngine.UI;
 5
 6[assembly: InternalsVisibleTo("AvatarEditorHUDTests")]
 7
 8public class AvatarEditorHUDView : MonoBehaviour
 9{
 110    private static readonly int RANDOMIZE_ANIMATOR_LOADING_BOOL = Animator.StringToHash("Loading");
 11    private const string VIEW_PATH = "AvatarEditorHUD";
 12    private const string VIEW_OBJECT_NAME = "_AvatarEditorHUD";
 13
 014    public bool isOpen { get; private set; }
 15
 16    [System.Serializable]
 17    public class AvatarEditorNavigationInfo
 18    {
 19        public Toggle toggle;
 20        public Canvas canvas;
 21        public bool enabledByDefault;
 22        public CharacterPreviewController.CameraFocus focus = CharacterPreviewController.CameraFocus.DefaultEditing;
 23
 24        //To remove when we refactor this to avoid ToggleGroup issues when quitting application
 167225        public void Initialize() { Application.quitting += () => toggle.onValueChanged.RemoveAllListeners(); }
 26    }
 27
 28    [System.Serializable]
 29    public class AvatarEditorWearableFilter
 30    {
 31        public string categoryFilter;
 32        public ItemSelector selector;
 33    }
 34
 35    [SerializeField]
 36    internal InputAction_Trigger closeAction;
 37
 38    [SerializeField]
 39    internal Canvas avatarEditorCanvas;
 40
 41    [SerializeField]
 42    internal CanvasGroup avatarEditorCanvasGroup;
 43
 44    [SerializeField]
 45    internal AvatarEditorNavigationInfo[] navigationInfos;
 46
 47    [SerializeField]
 48    internal AvatarEditorWearableFilter[] wearableGridPairs;
 49
 50    [SerializeField]
 51    internal AvatarEditorNavigationInfo collectiblesNavigationInfo;
 52
 53    [SerializeField]
 54    internal ItemSelector collectiblesItemSelector;
 55
 56    [SerializeField]
 57    internal ColorSelector skinColorSelector;
 58
 59    [SerializeField]
 60    internal ColorSelector eyeColorSelector;
 61
 62    [SerializeField]
 63    internal ColorSelector hairColorSelector;
 64
 65    [SerializeField]
 66    internal GameObject characterPreviewPrefab;
 67
 68    [SerializeField]
 69    internal PreviewCameraRotation characterPreviewRotation;
 70
 71    [SerializeField]
 72    internal Button randomizeButton;
 73
 74    [SerializeField]
 75    internal Animator randomizeAnimator;
 76
 77    [SerializeField]
 78    internal Button doneButton;
 79
 80    [SerializeField]
 81    internal Button exitButton;
 82
 83    [SerializeField] internal GameObject loadingSpinnerGameObject;
 84
 85    [Header("Collectibles")]
 86    [SerializeField]
 87    internal GameObject web3Container;
 88
 89    [SerializeField]
 90    internal Button web3GoToMarketplaceButton;
 91
 92    [SerializeField]
 93    internal GameObject noWeb3Container;
 94
 95    [SerializeField]
 96    internal Button noWeb3GoToMarketplaceButton;
 97
 98    internal static CharacterPreviewController characterPreviewController;
 99    private AvatarEditorHUDController controller;
 88100    internal readonly Dictionary<string, ItemSelector> selectorsByCategory = new Dictionary<string, ItemSelector>();
 88101    private readonly HashSet<WearableItem> wearablesWithLoadingSpinner = new HashSet<WearableItem>();
 102
 103    public event System.Action<AvatarModel> OnAvatarAppear;
 104    public event System.Action<bool> OnSetVisibility;
 105    public event System.Action OnRandomize;
 106    public event System.Action OnCloseActionTriggered;
 107
 108    private void Awake()
 109    {
 44110        closeAction.OnTriggered += CloseAction_OnTriggered;
 44111        loadingSpinnerGameObject.SetActive(false);
 44112        doneButton.interactable = false; //the default state of the button should be disable until a profile has been lo
 44113        if (characterPreviewController == null)
 114        {
 44115            characterPreviewController = GameObject.Instantiate(characterPreviewPrefab).GetComponent<CharacterPreviewCon
 44116            characterPreviewController.name = "_CharacterPreviewController";
 117        }
 118
 44119        isOpen = false;
 44120    }
 121
 88122    private void OnDestroy() { closeAction.OnTriggered -= CloseAction_OnTriggered; }
 123
 0124    private void CloseAction_OnTriggered(DCLAction_Trigger action) { OnCloseActionTriggered?.Invoke(); }
 125
 126    private void Initialize(AvatarEditorHUDController controller)
 127    {
 44128        ItemToggle.getEquippedWearablesReplacedByFunc = controller.GetWearablesReplacedBy;
 44129        this.controller = controller;
 44130        gameObject.name = VIEW_OBJECT_NAME;
 131
 44132        randomizeButton.onClick.AddListener(OnRandomizeButton);
 44133        doneButton.onClick.AddListener(OnDoneButton);
 44134        exitButton.onClick.AddListener(OnExitButton);
 44135        InitializeNavigationEvents();
 44136        InitializeWearableChangeEvents();
 137
 44138        web3GoToMarketplaceButton.onClick.RemoveAllListeners();
 44139        noWeb3GoToMarketplaceButton.onClick.RemoveAllListeners();
 44140        web3GoToMarketplaceButton.onClick.AddListener(controller.GoToMarketplace);
 44141        noWeb3GoToMarketplaceButton.onClick.AddListener(controller.GoToMarketplace);
 142
 44143        characterPreviewController.camera.enabled = false;
 44144    }
 145
 146    public void SetIsWeb3(bool isWeb3User)
 147    {
 95148        web3Container.SetActive(isWeb3User);
 95149        noWeb3Container.SetActive(!isWeb3User);
 95150    }
 151
 152    private void InitializeNavigationEvents()
 153    {
 1672154        for (int i = 0; i < navigationInfos.Length; i++)
 155        {
 792156            InitializeNavigationInfo(navigationInfos[i]);
 157        }
 158
 44159        InitializeNavigationInfo(collectiblesNavigationInfo);
 160
 44161        characterPreviewRotation.OnHorizontalRotation += characterPreviewController.Rotate;
 44162    }
 163
 164    private void InitializeNavigationInfo(AvatarEditorNavigationInfo current)
 165    {
 836166        current.Initialize();
 167
 836168        current.toggle.isOn = current.enabledByDefault;
 169
 836170        current.canvas.gameObject.SetActive(current.enabledByDefault);
 836171        current.toggle.onValueChanged.AddListener((on) =>
 172        {
 0173            current.canvas.gameObject.SetActive(@on);
 0174            characterPreviewController.SetFocus(current.focus);
 0175        });
 836176    }
 177
 178    private void InitializeWearableChangeEvents()
 179    {
 44180        int nPairs = wearableGridPairs.Length;
 1496181        for (int i = 0; i < nPairs; i++)
 182        {
 704183            wearableGridPairs[i].selector.OnItemClicked += controller.WearableClicked;
 704184            wearableGridPairs[i].selector.OnSellClicked += controller.SellCollectible;
 704185            selectorsByCategory.Add(wearableGridPairs[i].categoryFilter, wearableGridPairs[i].selector);
 186        }
 187
 44188        collectiblesItemSelector.OnItemClicked += controller.WearableClicked;
 44189        collectiblesItemSelector.OnSellClicked += controller.SellCollectible;
 44190        collectiblesItemSelector.OnRetryClicked += controller.RetryLoadOwnedWearables;
 191
 44192        skinColorSelector.OnColorChanged += controller.SkinColorClicked;
 44193        eyeColorSelector.OnColorChanged += controller.EyesColorClicked;
 44194        hairColorSelector.OnColorChanged += controller.HairColorClicked;
 44195    }
 196
 197    internal static AvatarEditorHUDView Create(AvatarEditorHUDController controller)
 198    {
 44199        var view = Instantiate(Resources.Load<GameObject>(VIEW_PATH)).GetComponent<AvatarEditorHUDView>();
 44200        view.Initialize(controller);
 44201        return view;
 202    }
 203
 204    public void UpdateSelectedBody(WearableItem bodyShape)
 205    {
 1632206        for (int i = 0; i < wearableGridPairs.Length; i++)
 207        {
 768208            if (wearableGridPairs[i].categoryFilter == WearableLiterals.Categories.BODY_SHAPE)
 209            {
 48210                wearableGridPairs[i].selector.UnselectAll();
 48211                wearableGridPairs[i].selector.Select(bodyShape.id);
 48212            }
 213            else
 214            {
 720215                wearableGridPairs[i].selector.SetBodyShape(bodyShape.id);
 216            }
 217        }
 218
 48219        collectiblesItemSelector.SetBodyShape(bodyShape.id);
 48220    }
 221
 222    public void EquipWearable(WearableItem wearable)
 223    {
 940224        selectorsByCategory[wearable.data.category].Select(wearable.id);
 940225        SetWearableLoadingSpinner(wearable, true);
 940226        collectiblesItemSelector.Select(wearable.id);
 940227    }
 228
 229    public void UnequipWearable(WearableItem wearable)
 230    {
 419231        selectorsByCategory[wearable.data.category].Unselect(wearable.id);
 419232        SetWearableLoadingSpinner(wearable, false);
 419233        collectiblesItemSelector.Unselect(wearable.id);
 419234    }
 235
 236    internal void SetWearableLoadingSpinner(WearableItem wearable, bool isActive)
 237    {
 1359238        selectorsByCategory[wearable.data.category].SetWearableLoadingSpinner(wearable.id, isActive);
 1359239        collectiblesItemSelector.SetWearableLoadingSpinner(wearable.id, isActive);
 1359240        if (isActive)
 940241            wearablesWithLoadingSpinner.Add(wearable);
 242        else
 419243            wearablesWithLoadingSpinner.Remove(wearable);
 419244    }
 245
 246    internal void ClearWearablesLoadingSpinner()
 247    {
 74248        foreach (WearableItem wearable in wearablesWithLoadingSpinner)
 249        {
 17250            selectorsByCategory[wearable.data.category].SetWearableLoadingSpinner(wearable.id, false);
 17251            collectiblesItemSelector.SetWearableLoadingSpinner(wearable.id, false);
 252        }
 253
 20254        wearablesWithLoadingSpinner.Clear();
 20255    }
 256
 200257    public void SelectHairColor(Color hairColor) { hairColorSelector.Select(hairColor); }
 258
 198259    public void SelectSkinColor(Color skinColor) { skinColorSelector.Select(skinColor); }
 260
 200261    public void SelectEyeColor(Color eyesColor) { eyeColorSelector.Select(eyesColor); }
 262
 263    public void SetColors(List<Color> skinColors, List<Color> hairColors, List<Color> eyeColors)
 264    {
 44265        skinColorSelector.Populate(skinColors);
 44266        eyeColorSelector.Populate(eyeColors);
 44267        hairColorSelector.Populate(hairColors);
 44268    }
 269
 270    public void UnselectAllWearables()
 271    {
 3264272        for (int i = 0; i < wearableGridPairs.Length; i++)
 273        {
 1536274            if (wearableGridPairs[i].categoryFilter != WearableLiterals.Categories.BODY_SHAPE)
 275            {
 1440276                wearableGridPairs[i].selector.UnselectAll();
 277            }
 278        }
 279
 96280        collectiblesItemSelector.UnselectAll();
 96281    }
 282
 283    public void UpdateAvatarPreview(AvatarModel avatarModel)
 284    {
 117285        if (avatarModel?.wearables == null)
 0286            return;
 287
 117288        doneButton.interactable = false;
 117289        loadingSpinnerGameObject.SetActive(true);
 117290        characterPreviewController.UpdateModel(avatarModel,
 291            () =>
 292            {
 20293                if (doneButton != null)
 0294                    doneButton.interactable = true;
 295
 20296                loadingSpinnerGameObject?.SetActive(false);
 20297                OnAvatarAppear?.Invoke(avatarModel);
 20298                ClearWearablesLoadingSpinner();
 20299                randomizeAnimator?.SetBool(RANDOMIZE_ANIMATOR_LOADING_BOOL, false);
 0300            });
 117301    }
 302
 303    public void AddWearable(WearableItem wearableItem, int amount)
 304    {
 3880305        if (wearableItem == null)
 0306            return;
 307
 3880308        if (!selectorsByCategory.ContainsKey(wearableItem.data.category))
 309        {
 0310            Debug.LogError($"Category couldn't find selector for category: {wearableItem.data.category} ");
 0311            return;
 312        }
 313
 3880314        selectorsByCategory[wearableItem.data.category].AddItemToggle(wearableItem, amount);
 3880315        if (wearableItem.IsCollectible())
 316        {
 16317            collectiblesItemSelector.AddItemToggle(wearableItem, amount);
 318        }
 3880319    }
 320
 321    public void RemoveWearable(WearableItem wearableItem)
 322    {
 0323        if (wearableItem == null)
 0324            return;
 325
 0326        if (!selectorsByCategory.ContainsKey(wearableItem.data.category))
 327        {
 0328            Debug.LogError($"Category couldn't find selector for category: {wearableItem.data.category} ");
 0329            return;
 330        }
 331
 0332        selectorsByCategory[wearableItem.data.category].RemoveItemToggle(wearableItem.id);
 0333        if (wearableItem.IsCollectible())
 0334            collectiblesItemSelector.RemoveItemToggle(wearableItem.id);
 0335    }
 336
 337    public void RemoveAllWearables()
 338    {
 139339        using (var enumerator = selectorsByCategory.GetEnumerator())
 340        {
 2363341            while (enumerator.MoveNext())
 342            {
 2224343                enumerator.Current.Value.RemoveAllItemToggle();
 344            }
 139345        }
 346
 139347        collectiblesItemSelector.RemoveAllItemToggle();
 139348    }
 349
 350    private void OnRandomizeButton()
 351    {
 0352        OnRandomize?.Invoke();
 0353        controller.RandomizeWearables();
 0354        randomizeAnimator?.SetBool(RANDOMIZE_ANIMATOR_LOADING_BOOL, true);
 0355    }
 356
 357    private void OnDoneButton()
 358    {
 0359        doneButton.interactable = false;
 0360        characterPreviewController.TakeSnapshots(OnSnapshotsReady, OnSnapshotsFailed);
 0361    }
 362
 0363    private void OnExitButton() { OnCloseActionTriggered?.Invoke(); }
 364
 365    private void OnSnapshotsReady(Texture2D face, Texture2D face128, Texture2D face256, Texture2D body)
 366    {
 0367        doneButton.interactable = true;
 0368        controller.SaveAvatar(face, face128, face256, body);
 0369    }
 370
 0371    private void OnSnapshotsFailed() { doneButton.interactable = true; }
 372
 373    public void SetVisibility(bool visible)
 374    {
 84375        characterPreviewController.camera.enabled = visible;
 84376        avatarEditorCanvas.enabled = visible;
 84377        avatarEditorCanvasGroup.blocksRaycasts = visible;
 378
 84379        if (visible && !isOpen)
 380        {
 39381            AudioScriptableObjects.dialogOpen.Play(true);
 39382            OnSetVisibility?.Invoke(visible);
 0383        }
 45384        else if (!visible && isOpen)
 385        {
 1386            AudioScriptableObjects.dialogClose.Play(true);
 1387            OnSetVisibility?.Invoke(visible);
 388        }
 389
 84390        isOpen = visible;
 84391    }
 392
 393    public void CleanUp()
 394    {
 44395        loadingSpinnerGameObject = null;
 44396        randomizeAnimator = null;
 44397        if (wearableGridPairs != null)
 398        {
 44399            int nPairs = wearableGridPairs.Length;
 1496400            for (int i = 0; i < nPairs; i++)
 401            {
 704402                var itemSelector = wearableGridPairs[i].selector;
 704403                if (itemSelector != null)
 404                {
 704405                    itemSelector.OnItemClicked -= controller.WearableClicked;
 704406                    itemSelector.OnSellClicked -= controller.SellCollectible;
 407                }
 408            }
 409        }
 410
 44411        if (collectiblesItemSelector != null)
 412        {
 44413            collectiblesItemSelector.OnItemClicked -= controller.WearableClicked;
 44414            collectiblesItemSelector.OnSellClicked -= controller.SellCollectible;
 44415            collectiblesItemSelector.OnRetryClicked -= controller.RetryLoadOwnedWearables;
 416        }
 417
 44418        if (skinColorSelector != null)
 44419            skinColorSelector.OnColorChanged -= controller.SkinColorClicked;
 44420        if (eyeColorSelector != null)
 44421            eyeColorSelector.OnColorChanged -= controller.EyesColorClicked;
 44422        if (hairColorSelector != null)
 44423            hairColorSelector.OnColorChanged -= controller.HairColorClicked;
 424
 44425        if (this != null)
 44426            Destroy(gameObject);
 427
 44428        if (characterPreviewController != null)
 429        {
 44430            Destroy(characterPreviewController.gameObject);
 44431            characterPreviewController = null;
 432        }
 44433    }
 434
 2435    public void ShowCollectiblesLoadingSpinner(bool isActive) { collectiblesItemSelector.ShowLoading(isActive); }
 436
 2437    public void ShowCollectiblesLoadingRetry(bool isActive) { collectiblesItemSelector.ShowRetryLoading(isActive); }
 438}