< 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:157
Uncovered lines:34
Coverable lines:191
Total lines:449
Line coverage:82.1% (157 of 191)
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%
ToggleAction_OnTriggered(...)0%6200%
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 toggleAction;
 37
 38    [SerializeField]
 39    internal InputAction_Trigger closeAction;
 40
 41    [SerializeField]
 42    internal Canvas avatarEditorCanvas;
 43
 44    [SerializeField]
 45    internal CanvasGroup avatarEditorCanvasGroup;
 46
 47    [SerializeField]
 48    internal AvatarEditorNavigationInfo[] navigationInfos;
 49
 50    [SerializeField]
 51    internal AvatarEditorWearableFilter[] wearableGridPairs;
 52
 53    [SerializeField]
 54    internal AvatarEditorNavigationInfo collectiblesNavigationInfo;
 55
 56    [SerializeField]
 57    internal ItemSelector collectiblesItemSelector;
 58
 59    [SerializeField]
 60    internal ColorSelector skinColorSelector;
 61
 62    [SerializeField]
 63    internal ColorSelector eyeColorSelector;
 64
 65    [SerializeField]
 66    internal ColorSelector hairColorSelector;
 67
 68    [SerializeField]
 69    internal GameObject characterPreviewPrefab;
 70
 71    [SerializeField]
 72    internal PreviewCameraRotation characterPreviewRotation;
 73
 74    [SerializeField]
 75    internal Button randomizeButton;
 76
 77    [SerializeField]
 78    internal Animator randomizeAnimator;
 79
 80    [SerializeField]
 81    internal Button doneButton;
 82
 83    [SerializeField]
 84    internal Button exitButton;
 85
 86    [SerializeField] internal GameObject loadingSpinnerGameObject;
 87
 88    [Header("Collectibles")]
 89    [SerializeField]
 90    internal GameObject web3Container;
 91
 92    [SerializeField]
 93    internal Button web3GoToMarketplaceButton;
 94
 95    [SerializeField]
 96    internal GameObject noWeb3Container;
 97
 98    [SerializeField]
 99    internal Button noWeb3GoToMarketplaceButton;
 100
 101    internal static CharacterPreviewController characterPreviewController;
 102    private AvatarEditorHUDController controller;
 88103    internal readonly Dictionary<string, ItemSelector> selectorsByCategory = new Dictionary<string, ItemSelector>();
 88104    private readonly HashSet<WearableItem> wearablesWithLoadingSpinner = new HashSet<WearableItem>();
 105
 106    public event System.Action<AvatarModel> OnAvatarAppear;
 107    public event System.Action<bool> OnSetVisibility;
 108    public event System.Action OnRandomize;
 109    public event System.Action OnToggleActionTriggered;
 110    public event System.Action OnCloseActionTriggered;
 111
 112    private void Awake()
 113    {
 44114        toggleAction.OnTriggered += ToggleAction_OnTriggered;
 44115        closeAction.OnTriggered += CloseAction_OnTriggered;
 44116        loadingSpinnerGameObject.SetActive(false);
 44117        doneButton.interactable = false; //the default state of the button should be disable until a profile has been lo
 44118        if (characterPreviewController == null)
 119        {
 44120            characterPreviewController = GameObject.Instantiate(characterPreviewPrefab).GetComponent<CharacterPreviewCon
 44121            characterPreviewController.name = "_CharacterPreviewController";
 122        }
 123
 44124        isOpen = false;
 44125    }
 126
 127    private void OnDestroy()
 128    {
 44129        toggleAction.OnTriggered -= ToggleAction_OnTriggered;
 44130        closeAction.OnTriggered -= CloseAction_OnTriggered;
 44131    }
 132
 0133    private void ToggleAction_OnTriggered(DCLAction_Trigger action) { OnToggleActionTriggered?.Invoke(); }
 134
 0135    private void CloseAction_OnTriggered(DCLAction_Trigger action) { OnCloseActionTriggered?.Invoke(); }
 136
 137    private void Initialize(AvatarEditorHUDController controller)
 138    {
 44139        ItemToggle.getEquippedWearablesReplacedByFunc = controller.GetWearablesReplacedBy;
 44140        this.controller = controller;
 44141        gameObject.name = VIEW_OBJECT_NAME;
 142
 44143        randomizeButton.onClick.AddListener(OnRandomizeButton);
 44144        doneButton.onClick.AddListener(OnDoneButton);
 44145        exitButton.onClick.AddListener(OnExitButton);
 44146        InitializeNavigationEvents();
 44147        InitializeWearableChangeEvents();
 148
 44149        web3GoToMarketplaceButton.onClick.RemoveAllListeners();
 44150        noWeb3GoToMarketplaceButton.onClick.RemoveAllListeners();
 44151        web3GoToMarketplaceButton.onClick.AddListener(controller.GoToMarketplace);
 44152        noWeb3GoToMarketplaceButton.onClick.AddListener(controller.GoToMarketplace);
 153
 44154        characterPreviewController.camera.enabled = false;
 44155    }
 156
 157    public void SetIsWeb3(bool isWeb3User)
 158    {
 95159        web3Container.SetActive(isWeb3User);
 95160        noWeb3Container.SetActive(!isWeb3User);
 95161    }
 162
 163    private void InitializeNavigationEvents()
 164    {
 1672165        for (int i = 0; i < navigationInfos.Length; i++)
 166        {
 792167            InitializeNavigationInfo(navigationInfos[i]);
 168        }
 169
 44170        InitializeNavigationInfo(collectiblesNavigationInfo);
 171
 44172        characterPreviewRotation.OnHorizontalRotation += characterPreviewController.Rotate;
 44173    }
 174
 175    private void InitializeNavigationInfo(AvatarEditorNavigationInfo current)
 176    {
 836177        current.Initialize();
 178
 836179        current.toggle.isOn = current.enabledByDefault;
 180
 836181        current.canvas.gameObject.SetActive(current.enabledByDefault);
 836182        current.toggle.onValueChanged.AddListener((on) =>
 183        {
 0184            current.canvas.gameObject.SetActive(@on);
 0185            characterPreviewController.SetFocus(current.focus);
 0186        });
 836187    }
 188
 189    private void InitializeWearableChangeEvents()
 190    {
 44191        int nPairs = wearableGridPairs.Length;
 1496192        for (int i = 0; i < nPairs; i++)
 193        {
 704194            wearableGridPairs[i].selector.OnItemClicked += controller.WearableClicked;
 704195            wearableGridPairs[i].selector.OnSellClicked += controller.SellCollectible;
 704196            selectorsByCategory.Add(wearableGridPairs[i].categoryFilter, wearableGridPairs[i].selector);
 197        }
 198
 44199        collectiblesItemSelector.OnItemClicked += controller.WearableClicked;
 44200        collectiblesItemSelector.OnSellClicked += controller.SellCollectible;
 44201        collectiblesItemSelector.OnRetryClicked += controller.RetryLoadOwnedWearables;
 202
 44203        skinColorSelector.OnColorChanged += controller.SkinColorClicked;
 44204        eyeColorSelector.OnColorChanged += controller.EyesColorClicked;
 44205        hairColorSelector.OnColorChanged += controller.HairColorClicked;
 44206    }
 207
 208    internal static AvatarEditorHUDView Create(AvatarEditorHUDController controller)
 209    {
 44210        var view = Instantiate(Resources.Load<GameObject>(VIEW_PATH)).GetComponent<AvatarEditorHUDView>();
 44211        view.Initialize(controller);
 44212        return view;
 213    }
 214
 215    public void UpdateSelectedBody(WearableItem bodyShape)
 216    {
 1632217        for (int i = 0; i < wearableGridPairs.Length; i++)
 218        {
 768219            if (wearableGridPairs[i].categoryFilter == WearableLiterals.Categories.BODY_SHAPE)
 220            {
 48221                wearableGridPairs[i].selector.UnselectAll();
 48222                wearableGridPairs[i].selector.Select(bodyShape.id);
 48223            }
 224            else
 225            {
 720226                wearableGridPairs[i].selector.SetBodyShape(bodyShape.id);
 227            }
 228        }
 229
 48230        collectiblesItemSelector.SetBodyShape(bodyShape.id);
 48231    }
 232
 233    public void EquipWearable(WearableItem wearable)
 234    {
 940235        selectorsByCategory[wearable.data.category].Select(wearable.id);
 940236        SetWearableLoadingSpinner(wearable, true);
 940237        collectiblesItemSelector.Select(wearable.id);
 940238    }
 239
 240    public void UnequipWearable(WearableItem wearable)
 241    {
 419242        selectorsByCategory[wearable.data.category].Unselect(wearable.id);
 419243        SetWearableLoadingSpinner(wearable, false);
 419244        collectiblesItemSelector.Unselect(wearable.id);
 419245    }
 246
 247    internal void SetWearableLoadingSpinner(WearableItem wearable, bool isActive)
 248    {
 1359249        selectorsByCategory[wearable.data.category].SetWearableLoadingSpinner(wearable.id, isActive);
 1359250        collectiblesItemSelector.SetWearableLoadingSpinner(wearable.id, isActive);
 1359251        if (isActive)
 940252            wearablesWithLoadingSpinner.Add(wearable);
 253        else
 419254            wearablesWithLoadingSpinner.Remove(wearable);
 419255    }
 256
 257    internal void ClearWearablesLoadingSpinner()
 258    {
 76259        foreach (WearableItem wearable in wearablesWithLoadingSpinner)
 260        {
 18261            selectorsByCategory[wearable.data.category].SetWearableLoadingSpinner(wearable.id, false);
 18262            collectiblesItemSelector.SetWearableLoadingSpinner(wearable.id, false);
 263        }
 264
 20265        wearablesWithLoadingSpinner.Clear();
 20266    }
 267
 200268    public void SelectHairColor(Color hairColor) { hairColorSelector.Select(hairColor); }
 269
 198270    public void SelectSkinColor(Color skinColor) { skinColorSelector.Select(skinColor); }
 271
 200272    public void SelectEyeColor(Color eyesColor) { eyeColorSelector.Select(eyesColor); }
 273
 274    public void SetColors(List<Color> skinColors, List<Color> hairColors, List<Color> eyeColors)
 275    {
 44276        skinColorSelector.Populate(skinColors);
 44277        eyeColorSelector.Populate(eyeColors);
 44278        hairColorSelector.Populate(hairColors);
 44279    }
 280
 281    public void UnselectAllWearables()
 282    {
 3264283        for (int i = 0; i < wearableGridPairs.Length; i++)
 284        {
 1536285            if (wearableGridPairs[i].categoryFilter != WearableLiterals.Categories.BODY_SHAPE)
 286            {
 1440287                wearableGridPairs[i].selector.UnselectAll();
 288            }
 289        }
 290
 96291        collectiblesItemSelector.UnselectAll();
 96292    }
 293
 294    public void UpdateAvatarPreview(AvatarModel avatarModel)
 295    {
 117296        if (avatarModel?.wearables == null)
 0297            return;
 298
 117299        doneButton.interactable = false;
 117300        loadingSpinnerGameObject.SetActive(true);
 117301        characterPreviewController.UpdateModel(avatarModel,
 302            () =>
 303            {
 20304                if (doneButton != null)
 0305                    doneButton.interactable = true;
 306
 20307                loadingSpinnerGameObject?.SetActive(false);
 20308                OnAvatarAppear?.Invoke(avatarModel);
 20309                ClearWearablesLoadingSpinner();
 20310                randomizeAnimator?.SetBool(RANDOMIZE_ANIMATOR_LOADING_BOOL, false);
 0311            });
 117312    }
 313
 314    public void AddWearable(WearableItem wearableItem, int amount)
 315    {
 3880316        if (wearableItem == null)
 0317            return;
 318
 3880319        if (!selectorsByCategory.ContainsKey(wearableItem.data.category))
 320        {
 0321            Debug.LogError($"Category couldn't find selector for category: {wearableItem.data.category} ");
 0322            return;
 323        }
 324
 3880325        selectorsByCategory[wearableItem.data.category].AddItemToggle(wearableItem, amount);
 3880326        if (wearableItem.IsCollectible())
 327        {
 16328            collectiblesItemSelector.AddItemToggle(wearableItem, amount);
 329        }
 3880330    }
 331
 332    public void RemoveWearable(WearableItem wearableItem)
 333    {
 0334        if (wearableItem == null)
 0335            return;
 336
 0337        if (!selectorsByCategory.ContainsKey(wearableItem.data.category))
 338        {
 0339            Debug.LogError($"Category couldn't find selector for category: {wearableItem.data.category} ");
 0340            return;
 341        }
 342
 0343        selectorsByCategory[wearableItem.data.category].RemoveItemToggle(wearableItem.id);
 0344        if (wearableItem.IsCollectible())
 0345            collectiblesItemSelector.RemoveItemToggle(wearableItem.id);
 0346    }
 347
 348    public void RemoveAllWearables()
 349    {
 139350        using (var enumerator = selectorsByCategory.GetEnumerator())
 351        {
 2363352            while (enumerator.MoveNext())
 353            {
 2224354                enumerator.Current.Value.RemoveAllItemToggle();
 355            }
 139356        }
 357
 139358        collectiblesItemSelector.RemoveAllItemToggle();
 139359    }
 360
 361    private void OnRandomizeButton()
 362    {
 0363        OnRandomize?.Invoke();
 0364        controller.RandomizeWearables();
 0365        randomizeAnimator?.SetBool(RANDOMIZE_ANIMATOR_LOADING_BOOL, true);
 0366    }
 367
 368    private void OnDoneButton()
 369    {
 0370        doneButton.interactable = false;
 0371        characterPreviewController.TakeSnapshots(OnSnapshotsReady, OnSnapshotsFailed);
 0372    }
 373
 0374    private void OnExitButton() { OnCloseActionTriggered?.Invoke(); }
 375
 376    private void OnSnapshotsReady(Texture2D face, Texture2D face128, Texture2D face256, Texture2D body)
 377    {
 0378        doneButton.interactable = true;
 0379        controller.SaveAvatar(face, face128, face256, body);
 0380    }
 381
 0382    private void OnSnapshotsFailed() { doneButton.interactable = true; }
 383
 384    public void SetVisibility(bool visible)
 385    {
 40386        characterPreviewController.camera.enabled = visible;
 40387        avatarEditorCanvas.enabled = visible;
 40388        avatarEditorCanvasGroup.blocksRaycasts = visible;
 389
 40390        if (visible && !isOpen)
 391        {
 39392            AudioScriptableObjects.dialogOpen.Play(true);
 39393            OnSetVisibility?.Invoke(visible);
 0394        }
 1395        else if (!visible && isOpen)
 396        {
 1397            AudioScriptableObjects.dialogClose.Play(true);
 1398            OnSetVisibility?.Invoke(visible);
 399        }
 400
 40401        isOpen = visible;
 40402    }
 403
 404    public void CleanUp()
 405    {
 44406        loadingSpinnerGameObject = null;
 44407        randomizeAnimator = null;
 44408        if (wearableGridPairs != null)
 409        {
 44410            int nPairs = wearableGridPairs.Length;
 1496411            for (int i = 0; i < nPairs; i++)
 412            {
 704413                var itemSelector = wearableGridPairs[i].selector;
 704414                if (itemSelector != null)
 415                {
 704416                    itemSelector.OnItemClicked -= controller.WearableClicked;
 704417                    itemSelector.OnSellClicked -= controller.SellCollectible;
 418                }
 419            }
 420        }
 421
 44422        if (collectiblesItemSelector != null)
 423        {
 44424            collectiblesItemSelector.OnItemClicked -= controller.WearableClicked;
 44425            collectiblesItemSelector.OnSellClicked -= controller.SellCollectible;
 44426            collectiblesItemSelector.OnRetryClicked -= controller.RetryLoadOwnedWearables;
 427        }
 428
 44429        if (skinColorSelector != null)
 44430            skinColorSelector.OnColorChanged -= controller.SkinColorClicked;
 44431        if (eyeColorSelector != null)
 44432            eyeColorSelector.OnColorChanged -= controller.EyesColorClicked;
 44433        if (hairColorSelector != null)
 44434            hairColorSelector.OnColorChanged -= controller.HairColorClicked;
 435
 44436        if (this != null)
 44437            Destroy(gameObject);
 438
 44439        if (characterPreviewController != null)
 440        {
 44441            Destroy(characterPreviewController.gameObject);
 44442            characterPreviewController = null;
 443        }
 44444    }
 445
 2446    public void ShowCollectiblesLoadingSpinner(bool isActive) { collectiblesItemSelector.ShowLoading(isActive); }
 447
 2448    public void ShowCollectiblesLoadingRetry(bool isActive) { collectiblesItemSelector.ShowRetryLoading(isActive); }
 449}