< 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:212
Uncovered lines:105
Coverable lines:317
Total lines:757
Line coverage:66.8% (212 of 317)
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%110100%
Initialize(...)0%440100%
Update()0%110100%
SetIsWeb3(...)0%110100%
InitializeNavigationEvents(...)0%330100%
OnCharacterPreviewRotation(...)0%2100%
InitializeNavigationInfo(...)0%550100%
InitializeNavigationInfo(...)0%110100%
InitializeWearableChangeEvents()0%220100%
Create(...)0%110100%
UpdateSelectedBody(...)0%330100%
EquipWearable(...)0%110100%
UnequipWearable(...)0%110100%
SetWearableLoadingSpinner(...)0%220100%
ClearWearablesLoadingSpinner()0%6200%
SelectHairColor(...)0%110100%
GetRandomColor()0%110100%
SelectSkinColor(...)0%110100%
SelectEyeColor(...)0%110100%
SetColors(...)0%110100%
UnselectAllWearables()0%330100%
UpdateAvatarPreview(...)0%4.054085.71%
AddFeedbackOnAppear()0%110100%
AddWearable(...)0%5.685070%
RefreshSelectorsSize()0%220100%
GetWearableCollectionName(...)0%4.123050%
RemoveWearable(...)0%30500%
RemoveAllWearables()0%220100%
OnRandomizeButton()0%12300%
OnDoneButton()0%2100%
OnWearablesSelectorsClicked(...)0%6200%
TakeSnapshotsAfterStopPreviewAnimation()0%12300%
OnSnapshotsReady(...)0%2100%
OnSnapshotsFailed()0%2100%
SetVisibility(...)0%770100%
Dispose()0%11110100%
SetAsFullScreenMenuMode(...)0%4.312016.67%
OnPointerDown(...)0%30500%
LoadCollectionsDropdown(...)0%6200%
BlockCollectionsDropdown(...)0%110100%
ShowSkinPopulatedList(...)0%110100%
ShowCollectiblesPopulatedList(...)0%110100%
SetThirdPartyCollectionsVisibility(...)0%110100%
ConfigureSectionSelector()0%110100%
SetSectionActive(...)0%220100%
PlayPreviewEmote(...)0%110100%
ResetPreviewEmote()0%110100%
ToggleThirdPartyCollection(...)0%12300%
ShowNoItemOfWearableCollectionWarning()0%2100%
ClickBlockerClicked()0%2100%
UpdateAvatarModelWhenNeeded()0%2.52050%
<UpdateAvatarModelWhenNeeded()0%72800%

File(s)

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

#LineLine coverage
 1using Cysharp.Threading.Tasks;
 2using DCL;
 3using MainScripts.DCL.Controllers.HUD.CharacterPreview;
 4using System;
 5using System.Collections;
 6using System.Collections.Generic;
 7using System.Linq;
 8using System.Runtime.CompilerServices;
 9using TMPro;
 10using UnityEngine;
 11using UnityEngine.EventSystems;
 12using UnityEngine.UI;
 13using static WearableCollectionsAPIData;
 14using Random = System.Random;
 15
 16[assembly: InternalsVisibleTo("AvatarEditorHUDTests")]
 17
 18public class AvatarEditorHUDView : MonoBehaviour, IAvatarEditorHUDView, IPointerDownHandler
 19{
 120    private static readonly int RANDOMIZE_ANIMATOR_LOADING_BOOL = Animator.StringToHash("Loading");
 21    private const string VIEW_PATH = "AvatarEditorHUD";
 22    private const string VIEW_OBJECT_NAME = "_AvatarEditorHUD";
 23    internal const int AVATAR_SECTION_INDEX = 0;
 24    internal const string AVATAR_SECTION_TITLE = "Avatar";
 25    internal const int EMOTES_SECTION_INDEX = 1;
 26    internal const string EMOTES_SECTION_TITLE = "Emotes";
 27    private const string RESET_PREVIEW_ANIMATION = "Idle";
 28    private const float TIME_TO_RESET_PREVIEW_ANIMATION = 0.2f;
 29
 40930    public bool isOpen { get; private set; }
 031    internal DataStore_EmotesCustomization emotesCustomizationDataStore => DataStore.i.emotesCustomization;
 32
 33    internal bool arePanelsInitialized = false;
 34
 35    [Serializable]
 36    public class AvatarEditorNavigationInfo
 37    {
 38        public Toggle toggle;
 39        public Canvas canvas;
 40        public bool enabledByDefault;
 41        public CharacterPreviewController.CameraFocus focus = CharacterPreviewController.CameraFocus.DefaultEditing;
 42
 43        //To remove when we refactor this to avoid ToggleGroup issues when quitting application
 188044        public void Initialize() { Application.quitting += () => toggle.onValueChanged.RemoveAllListeners(); }
 45    }
 46
 47    [Serializable]
 48    public class AvatarEditorWearableFilter
 49    {
 50        public string categoryFilter;
 51        public ItemSelector selector;
 52    }
 53
 54    [SerializeField]
 55    internal Canvas avatarEditorCanvas;
 56
 57    [SerializeField]
 58    internal CanvasGroup avatarEditorCanvasGroup;
 59
 60    [SerializeField]
 61    internal AvatarEditorNavigationInfo[] navigationInfos;
 62
 63    [SerializeField]
 64    internal AvatarEditorWearableFilter[] wearableGridPairs;
 65
 66    [SerializeField]
 67    internal AvatarEditorNavigationInfo collectiblesNavigationInfo;
 68
 69    [SerializeField]
 70    internal ItemSelector collectiblesItemSelector;
 71
 72    [SerializeField]
 73    internal ColorSelector skinColorSelector;
 74
 75    [SerializeField]
 76    internal ColorPickerComponentView eyeColorPickerComponent;
 77
 78    [SerializeField]
 79    internal ColorPickerComponentView hairColorPickerComponent;
 80
 81    [SerializeField]
 82    internal ColorPickerComponentView facialHairColorPickerComponent;
 83
 84    [SerializeField]
 85    internal ColorPickerComponentView eyeBrowsColorPickerComponent;
 86
 87    [SerializeField]
 88    internal PreviewCameraRotation characterPreviewRotation;
 89
 90    [SerializeField]
 91    internal RawImage characterPreviewImage;
 92
 93    [SerializeField]
 94    internal Button randomizeButton;
 95
 96    [SerializeField]
 97    internal Animator randomizeAnimator;
 98
 99    [SerializeField]
 100    internal Button doneButton;
 101
 102    [SerializeField] internal Button[] goToMarketplaceButtons;
 103
 104    [SerializeField] internal GameObject loadingSpinnerGameObject;
 105
 106    [Header("Collectibles")]
 107    [SerializeField] internal GameObject web3Container;
 108    [SerializeField] internal GameObject noWeb3Container;
 109    [SerializeField] private GameObject collectiblesEmptyListContainer;
 110
 111    [Header("Skins")]
 112
 113    [SerializeField] internal GameObject skinsFeatureContainer;
 114
 115    [SerializeField] internal GameObject skinsWeb3Container;
 116
 117    [SerializeField] internal GameObject skinsMissingWeb3Container;
 118
 119    [SerializeField] internal GameObject skinsConnectWalletButtonContainer;
 120
 121    [SerializeField] private GameObject skinsPopulatedListContainer;
 122    [SerializeField] private GameObject skinsEmptyListContainer;
 123
 124    [SerializeField]
 125    internal DropdownComponentView collectionsDropdown;
 126
 127    [Header("Section Selector")]
 128    [SerializeField] internal SectionSelectorComponentView sectionSelector;
 129    [SerializeField] internal TMP_Text sectionTitle;
 130    [SerializeField] internal GameObject avatarSection;
 131    [SerializeField] internal GameObject emotesSection;
 132
 133    [SerializeField] internal UIHelper_ClickBlocker clickBlocker;
 134    [SerializeField] internal Notification noItemInCollectionWarning;
 135
 136    private Service<ICharacterPreviewFactory> characterPreviewFactory;
 137
 138    private AvatarEditorHUDController controller;
 50139    internal readonly Dictionary<string, ItemSelector> selectorsByCategory = new Dictionary<string, ItemSelector>();
 50140    private readonly HashSet<WearableItem> wearablesWithLoadingSpinner = new HashSet<WearableItem>();
 50141    private readonly Dictionary<string, ToggleComponentModel> loadedCollectionModels = new Dictionary<string, ToggleComp
 142    private bool isAvatarDirty;
 143    private AvatarModel avatarModelToUpdate;
 144
 145    private bool doAvatarFeedback;
 146
 236147    public ICharacterPreviewController CharacterPreview { get; private set; }
 148
 149    public event Action<AvatarModel> OnAvatarAppearFeedback;
 150    public event Action<bool> OnSetVisibility;
 151    public event Action OnRandomize;
 152    public event Action<string> WearableSelectorClicked;
 153
 154    private void Awake()
 155    {
 48156        loadingSpinnerGameObject.SetActive(false);
 48157        doneButton.interactable = false; //the default state of the button should be disable until a profile has been lo
 48158        isOpen = false;
 48159        arePanelsInitialized = false;
 48160    }
 161
 162    private void Initialize(AvatarEditorHUDController controller)
 163    {
 48164        this.controller = controller;
 48165        gameObject.name = VIEW_OBJECT_NAME;
 166
 48167        randomizeButton.onClick.AddListener(OnRandomizeButton);
 48168        doneButton.onClick.AddListener(OnDoneButton);
 48169        InitializeWearableChangeEvents();
 170
 576171        foreach (var button in goToMarketplaceButtons)
 240172            button.onClick.RemoveAllListeners();
 576173        foreach (var button in goToMarketplaceButtons)
 240174            button.onClick.AddListener(controller.GoToMarketplaceOrConnectWallet);
 175
 48176        CharacterPreview = characterPreviewFactory.Ref.Create(CharacterPreviewMode.WithoutHologram, (RenderTexture) char
 177
 48178        collectionsDropdown.OnOptionSelectionChanged -= controller.ToggleThirdPartyCollection;
 48179        collectionsDropdown.OnOptionSelectionChanged += controller.ToggleThirdPartyCollection;
 180
 48181        clickBlocker.OnClicked += ClickBlockerClicked;
 182
 1728183        for (int i = 0; i < wearableGridPairs.Length; i++)
 184        {
 816185            wearableGridPairs[i].selector.OnItemClicked += OnWearablesSelectorsClicked;
 186        }
 48187        collectiblesItemSelector.OnItemClicked += OnWearablesSelectorsClicked;
 188
 48189        ConfigureSectionSelector();
 48190    }
 191
 192    private void Update()
 193    {
 1194        UpdateAvatarModelWhenNeeded();
 1195    }
 196
 197    public void SetIsWeb3(bool isWeb3User)
 198    {
 82199        web3Container.SetActive(isWeb3User);
 82200        noWeb3Container.SetActive(!isWeb3User);
 82201        skinsWeb3Container.SetActive(isWeb3User);
 82202        skinsMissingWeb3Container.SetActive(!isWeb3User);
 82203    }
 204
 205    internal void InitializeNavigationEvents(bool isGuest)
 206    {
 82207        if (arePanelsInitialized)
 35208            return;
 209
 1880210        for (int i = 0; i < navigationInfos.Length; i++)
 211        {
 893212            InitializeNavigationInfo(navigationInfos[i]);
 213        }
 47214        InitializeNavigationInfo(collectiblesNavigationInfo, !isGuest);
 215
 47216        characterPreviewRotation.OnHorizontalRotation += OnCharacterPreviewRotation;
 47217        arePanelsInitialized = true;
 47218    }
 219
 220    private void OnCharacterPreviewRotation(float angularVelocity)
 221    {
 0222        CharacterPreview.Rotate(angularVelocity);
 0223    }
 224
 225    private void InitializeNavigationInfo(AvatarEditorNavigationInfo current, bool isActive)
 226    {
 940227        current.Initialize();
 228
 940229        current.toggle.isOn = isActive ? current.enabledByDefault : false;
 940230        current.canvas.gameObject.SetActive(isActive ? current.enabledByDefault : false);
 231
 940232        current.toggle.onValueChanged.AddListener((on) =>
 233        {
 47234            current.canvas.gameObject.SetActive(@on);
 47235            CharacterPreview.SetFocus(current.focus);
 47236        });
 940237    }
 238
 239    private void InitializeNavigationInfo(AvatarEditorNavigationInfo current)
 240    {
 893241        InitializeNavigationInfo(current, true);
 893242    }
 243
 244    private void InitializeWearableChangeEvents()
 245    {
 48246        int nPairs = wearableGridPairs.Length;
 1728247        for (int i = 0; i < nPairs; i++)
 248        {
 816249            wearableGridPairs[i].selector.OnItemClicked += controller.WearableClicked;
 816250            wearableGridPairs[i].selector.OnSellClicked += controller.SellCollectible;
 816251            selectorsByCategory.Add(wearableGridPairs[i].categoryFilter, wearableGridPairs[i].selector);
 252        }
 253
 48254        collectiblesItemSelector.OnItemClicked += controller.WearableClicked;
 48255        collectiblesItemSelector.OnSellClicked += controller.SellCollectible;
 256
 48257        skinColorSelector.OnColorSelectorChange += controller.SkinColorClicked;
 48258        eyeColorPickerComponent.OnColorChanged += controller.EyesColorClicked;
 48259        hairColorPickerComponent.OnColorChanged += controller.HairColorClicked;
 48260        facialHairColorPickerComponent.OnColorChanged += controller.HairColorClicked;
 48261        eyeBrowsColorPickerComponent.OnColorChanged += controller.HairColorClicked;
 48262    }
 263
 264    internal static AvatarEditorHUDView Create(AvatarEditorHUDController controller)
 265    {
 48266        var view = Instantiate(Resources.Load<GameObject>(VIEW_PATH)).GetComponent<AvatarEditorHUDView>();
 48267        view.Initialize(controller);
 48268        return view;
 269    }
 270
 271    public void UpdateSelectedBody(WearableItem bodyShape)
 272    {
 2232273        for (int i = 0; i < wearableGridPairs.Length; i++)
 274        {
 1054275            if (wearableGridPairs[i].categoryFilter == WearableLiterals.Categories.BODY_SHAPE)
 276            {
 62277                wearableGridPairs[i].selector.UnselectAll();
 62278                wearableGridPairs[i].selector.Select(bodyShape.id);
 279            }
 280            else
 281            {
 992282                wearableGridPairs[i].selector.SetBodyShape(bodyShape.id);
 283            }
 284        }
 285
 62286        collectiblesItemSelector.SetBodyShape(bodyShape.id);
 62287    }
 288
 289    public void EquipWearable(WearableItem wearable)
 290    {
 964291        selectorsByCategory[wearable.data.category].Select(wearable.id);
 964292        SetWearableLoadingSpinner(wearable, true);
 964293        collectiblesItemSelector.Select(wearable.id);
 964294    }
 295
 296    public void UnequipWearable(WearableItem wearable)
 297    {
 404298        selectorsByCategory[wearable.data.category].Unselect(wearable.id);
 404299        SetWearableLoadingSpinner(wearable, false);
 404300        collectiblesItemSelector.Unselect(wearable.id);
 404301    }
 302
 303    internal void SetWearableLoadingSpinner(WearableItem wearable, bool isActive)
 304    {
 1368305        selectorsByCategory[wearable.data.category].SetWearableLoadingSpinner(wearable.id, isActive);
 1368306        collectiblesItemSelector.SetWearableLoadingSpinner(wearable.id, isActive);
 1368307        if (isActive)
 964308            wearablesWithLoadingSpinner.Add(wearable);
 309        else
 404310            wearablesWithLoadingSpinner.Remove(wearable);
 404311    }
 312
 313    internal void ClearWearablesLoadingSpinner()
 314    {
 0315        foreach (WearableItem wearable in wearablesWithLoadingSpinner)
 316        {
 0317            selectorsByCategory[wearable.data.category].SetWearableLoadingSpinner(wearable.id, false);
 0318            collectiblesItemSelector.SetWearableLoadingSpinner(wearable.id, false);
 319        }
 320
 0321        wearablesWithLoadingSpinner.Clear();
 0322    }
 323
 324    public void SelectHairColor(Color hairColor)
 325    {
 86326        hairColorPickerComponent.SetColorSelector(hairColor);
 86327        hairColorPickerComponent.UpdateSliderValues(hairColor);
 86328        eyeBrowsColorPickerComponent.SetColorSelector(hairColor);
 86329        eyeBrowsColorPickerComponent.UpdateSliderValues(hairColor);
 86330        facialHairColorPickerComponent.SetColorSelector(hairColor);
 86331        facialHairColorPickerComponent.UpdateSliderValues(hairColor);
 86332    }
 333
 334    public Color GetRandomColor()
 335    {
 2336        return Color.HSVToRGB(UnityEngine.Random.Range(0, 1f), UnityEngine.Random.Range(0, 1f), UnityEngine.Random.Range
 337    }
 338
 339    public void SelectSkinColor(Color skinColor)
 340    {
 85341        skinColorSelector.Select(skinColor);
 85342    }
 343
 344    public void SelectEyeColor(Color eyesColor)
 345    {
 86346        eyeColorPickerComponent.SetColorSelector(eyesColor);
 86347        eyeColorPickerComponent.UpdateSliderValues(eyesColor);
 86348    }
 349
 350    public void SetColors(List<Color> skinColors, List<Color> hairColors, List<Color> eyeColors)
 351    {
 48352        skinColorSelector.Populate(skinColors);
 48353        eyeColorPickerComponent.SetColorList(eyeColors);
 48354        hairColorPickerComponent.SetColorList(hairColors);
 48355        eyeBrowsColorPickerComponent.SetColorList(hairColors);
 48356        facialHairColorPickerComponent.SetColorList(hairColors);
 48357    }
 358
 359    public void UnselectAllWearables()
 360    {
 2952361        for (int i = 0; i < wearableGridPairs.Length; i++)
 362        {
 1394363            if (wearableGridPairs[i].categoryFilter != WearableLiterals.Categories.BODY_SHAPE)
 364            {
 1312365                wearableGridPairs[i].selector.UnselectAll();
 366            }
 367        }
 368
 82369        collectiblesItemSelector.UnselectAll();
 82370    }
 371
 372    public void UpdateAvatarPreview(AvatarModel avatarModel)
 373    {
 103374        if (avatarModel?.wearables == null)
 0375            return;
 376
 377        // We delay the updating of the avatar 1 frame to disengage from the kernel message flow
 378        // otherwise the cancellation of the updating task throws an exception that is catch by
 379        // kernel setthrew method, which floods the analytics.
 380        // Also it updates just once if its called many times in a row
 103381        isAvatarDirty = true;
 103382        avatarModelToUpdate = avatarModel;
 383
 103384        doneButton.interactable = false;
 103385        loadingSpinnerGameObject.SetActive(true);
 103386    }
 387
 388    public void AddFeedbackOnAppear()
 389    {
 18390        doAvatarFeedback = true;
 18391    }
 392
 393    public void AddWearable(WearableItem wearableItem, int amount,
 394        Func<WearableItem, bool> hideOtherWearablesToastStrategy,
 395        Func<WearableItem, bool> replaceOtherWearablesToastStrategy,
 396        Func<WearableItem, bool> incompatibleWearableToastStrategy)
 397    {
 3633398        if (wearableItem == null)
 0399            return;
 400
 3633401        if (!selectorsByCategory.ContainsKey(wearableItem.data.category))
 402        {
 0403            Debug.LogError($"Category couldn't find selector for category: {wearableItem.data.category} ");
 0404            return;
 405        }
 406
 3633407        string collectionName = GetWearableCollectionName(wearableItem);
 408
 3633409        selectorsByCategory[wearableItem.data.category].AddWearable(
 410            wearableItem,
 411            collectionName,
 412            amount,
 413            hideOtherWearablesToastStrategy,
 414            replaceOtherWearablesToastStrategy,
 415            incompatibleWearableToastStrategy);
 416
 3633417        if (wearableItem.IsCollectible() || wearableItem.IsFromThirdPartyCollection)
 418        {
 21419            collectiblesItemSelector.AddWearable(
 420                wearableItem,
 421                collectionName,
 422                amount,
 423                hideOtherWearablesToastStrategy,
 424                replaceOtherWearablesToastStrategy,
 425                incompatibleWearableToastStrategy);
 426        }
 3633427    }
 428
 429    public void RefreshSelectorsSize()
 430    {
 141431        using (var iterator = selectorsByCategory.GetEnumerator())
 432        {
 2538433            while (iterator.MoveNext())
 434            {
 2397435                iterator.Current.Value.UpdateSelectorLayout();
 436            }
 141437        }
 438
 141439        collectiblesItemSelector.UpdateSelectorLayout();
 141440    }
 441
 442    private string GetWearableCollectionName(WearableItem wearableItem)
 443    {
 3633444        string collectionName = string.Empty;
 445
 3633446        if (wearableItem.IsFromThirdPartyCollection)
 447        {
 0448            loadedCollectionModels.TryGetValue(wearableItem.ThirdPartyCollectionId, out ToggleComponentModel collectionM
 449
 0450            if (collectionModel != null)
 0451                collectionName = collectionModel.text;
 452        }
 453
 3633454        return collectionName;
 455    }
 456
 457    public void RemoveWearable(WearableItem wearableItem)
 458    {
 0459        if (wearableItem == null)
 0460            return;
 461
 0462        if (!selectorsByCategory.ContainsKey(wearableItem.data.category))
 463        {
 0464            Debug.LogError($"Category couldn't find selector for category: {wearableItem.data.category} ");
 0465            return;
 466        }
 467
 0468        selectorsByCategory[wearableItem.data.category].RemoveWearable(wearableItem.id);
 0469        if (wearableItem.IsCollectible() || wearableItem.IsFromThirdPartyCollection)
 0470            collectiblesItemSelector.RemoveWearable(wearableItem.id);
 0471    }
 472
 473    public void RemoveAllWearables()
 474    {
 130475        using (var enumerator = selectorsByCategory.GetEnumerator())
 476        {
 2340477            while (enumerator.MoveNext())
 478            {
 2210479                enumerator.Current.Value.RemoveAllWearables();
 480            }
 130481        }
 482
 130483        collectiblesItemSelector.RemoveAllWearables();
 130484    }
 485
 486    private void OnRandomizeButton()
 487    {
 0488        OnRandomize?.Invoke();
 0489        controller.RandomizeWearables();
 0490        randomizeAnimator?.SetBool(RANDOMIZE_ANIMATOR_LOADING_BOOL, true);
 0491    }
 492
 493    private void OnDoneButton()
 494    {
 0495        doneButton.interactable = false;
 0496        CoroutineStarter.Start(TakeSnapshotsAfterStopPreviewAnimation());
 0497        eyeColorPickerComponent.SetActive(false);
 0498        hairColorPickerComponent.SetActive(false);
 0499        facialHairColorPickerComponent.SetActive(false);
 0500        eyeBrowsColorPickerComponent.SetActive(false);
 0501    }
 502
 503    private void OnWearablesSelectorsClicked(string obj)
 504    {
 0505        WearableSelectorClicked?.Invoke(obj);
 0506    }
 507
 508    private IEnumerator TakeSnapshotsAfterStopPreviewAnimation()
 509    {
 510        // We need to stop the current preview animation in order to take a correct snapshot
 0511        ResetPreviewEmote();
 0512        yield return new WaitForSeconds(TIME_TO_RESET_PREVIEW_ANIMATION);
 0513        CharacterPreview.TakeSnapshots(OnSnapshotsReady, OnSnapshotsFailed);
 0514    }
 515
 516    private void OnSnapshotsReady(Texture2D face256, Texture2D body)
 517    {
 0518        doneButton.interactable = true;
 0519        controller.SaveAvatar(face256, body);
 0520    }
 521
 0522    private void OnSnapshotsFailed() { doneButton.interactable = true; }
 523
 524    public void SetVisibility(bool visible)
 525    {
 92526        CharacterPreview.SetEnabled(visible);
 92527        avatarEditorCanvas.enabled = visible;
 92528        avatarEditorCanvasGroup.blocksRaycasts = visible;
 529
 92530        if (visible && !isOpen)
 531        {
 43532            OnSetVisibility?.Invoke(visible);
 533        }
 49534        else if (!visible && isOpen)
 535        {
 1536            collectionsDropdown.Close();
 1537            noItemInCollectionWarning.Dismiss(true);
 1538            OnSetVisibility?.Invoke(visible);
 539        }
 540
 92541        isOpen = visible;
 92542    }
 543
 544    public void Dispose()
 545    {
 48546        loadingSpinnerGameObject = null;
 48547        randomizeAnimator = null;
 48548        if (wearableGridPairs != null)
 549        {
 48550            int nPairs = wearableGridPairs.Length;
 1728551            for (int i = 0; i < nPairs; i++)
 552            {
 816553                var itemSelector = wearableGridPairs[i].selector;
 816554                if (itemSelector != null)
 555                {
 816556                    itemSelector.OnItemClicked -= controller.WearableClicked;
 816557                    itemSelector.OnSellClicked -= controller.SellCollectible;
 816558                    itemSelector.OnItemClicked -= OnWearablesSelectorsClicked;
 559                }
 560            }
 561        }
 562
 48563        if (collectiblesItemSelector != null)
 564        {
 48565            collectiblesItemSelector.OnItemClicked -= controller.WearableClicked;
 48566            collectiblesItemSelector.OnSellClicked -= controller.SellCollectible;
 48567            collectiblesItemSelector.OnItemClicked -= OnWearablesSelectorsClicked;
 568        }
 569
 48570        if (skinColorSelector != null)
 48571            skinColorSelector.OnColorSelectorChange -= controller.SkinColorClicked;
 48572        if (eyeColorPickerComponent != null)
 48573            eyeColorPickerComponent.OnColorChanged -= controller.EyesColorClicked;
 48574        if (hairColorPickerComponent != null)
 48575            hairColorPickerComponent.OnColorChanged -= controller.HairColorClicked;
 48576        if (facialHairColorPickerComponent != null)
 48577            facialHairColorPickerComponent.OnColorChanged -= controller.HairColorClicked;
 48578        if (eyeBrowsColorPickerComponent != null)
 48579            eyeBrowsColorPickerComponent.OnColorChanged -= controller.HairColorClicked;
 580
 48581        if (this != null)
 48582            Destroy(gameObject);
 583
 48584        CharacterPreview.Dispose();
 585
 48586        collectionsDropdown.OnOptionSelectionChanged -= controller.ToggleThirdPartyCollection;
 48587        collectionsDropdown.Dispose();
 588
 48589        sectionSelector.GetSection(AVATAR_SECTION_INDEX).onSelect.RemoveAllListeners();
 48590        sectionSelector.GetSection(EMOTES_SECTION_INDEX).onSelect.RemoveAllListeners();
 591
 48592        clickBlocker.OnClicked -= ClickBlockerClicked;
 48593    }
 594
 595    public void SetAsFullScreenMenuMode(Transform parentTransform)
 596    {
 48597        if (parentTransform == null)
 48598            return;
 599
 0600        transform.SetParent(parentTransform);
 0601        transform.localScale = Vector3.one;
 602
 0603        RectTransform rectTransform = transform as RectTransform;
 0604        rectTransform.anchorMin = Vector2.zero;
 0605        rectTransform.anchorMax = Vector2.one;
 0606        rectTransform.pivot = new Vector2(0.5f, 0.5f);
 0607        rectTransform.localPosition = Vector2.zero;
 0608        rectTransform.offsetMax = Vector2.zero;
 0609        rectTransform.offsetMin = Vector2.zero;
 0610    }
 611
 612    public void OnPointerDown(PointerEventData eventData)
 613    {
 0614        if (eventData.pointerPressRaycast.gameObject != eyeColorPickerComponent.gameObject &&
 615            eventData.pointerPressRaycast.gameObject != hairColorPickerComponent.gameObject &&
 616            eventData.pointerPressRaycast.gameObject != eyeBrowsColorPickerComponent.gameObject &&
 617            eventData.pointerPressRaycast.gameObject != facialHairColorPickerComponent.gameObject)
 618        {
 0619            eyeColorPickerComponent.SetActive(false);
 0620            hairColorPickerComponent.SetActive(false);
 0621            eyeBrowsColorPickerComponent.SetActive(false);
 0622            facialHairColorPickerComponent.SetActive(false);
 623        }
 0624    }
 625
 626    public void LoadCollectionsDropdown(Collection[] collections)
 627    {
 0628        List<ToggleComponentModel> collectionsToAdd = new List<ToggleComponentModel>();
 0629        foreach (var collection in collections)
 630        {
 0631            ToggleComponentModel newCollectionModel = new ToggleComponentModel
 632            {
 633                id = collection.urn,
 634                text = collection.name,
 635                isOn = false,
 636                isTextActive = true
 637            };
 638
 0639            collectionsToAdd.Add(newCollectionModel);
 0640            loadedCollectionModels.Add(collection.urn, newCollectionModel);
 641        }
 642
 0643        collectionsDropdown.SetOptions(collectionsToAdd);
 0644    }
 645
 646    public void BlockCollectionsDropdown(bool isBlocked)
 647    {
 1648        collectionsDropdown.SetLoadingActive(isBlocked);
 1649    }
 650
 651    public void ShowSkinPopulatedList(bool show)
 652    {
 130653        skinsPopulatedListContainer.SetActive(show);
 130654        skinsEmptyListContainer.SetActive(!show);
 130655        skinsConnectWalletButtonContainer.SetActive(show);
 130656    }
 657
 658    public void ShowCollectiblesPopulatedList(bool show)
 659    {
 130660        collectiblesEmptyListContainer.SetActive(!show);
 130661    }
 662
 663    public void SetThirdPartyCollectionsVisibility(bool visible) =>
 48664        collectionsDropdown.gameObject.SetActive(visible);
 665
 666    internal void ConfigureSectionSelector()
 667    {
 48668        sectionTitle.text = AVATAR_SECTION_TITLE;
 669
 48670        sectionSelector.GetSection(AVATAR_SECTION_INDEX).onSelect.AddListener((isSelected) =>
 671        {
 0672            avatarSection.SetActive(isSelected);
 0673            randomizeButton.gameObject.SetActive(true);
 674
 0675            if (isSelected)
 676            {
 0677                sectionTitle.text = AVATAR_SECTION_TITLE;
 0678                ResetPreviewEmote();
 679            }
 680
 0681            emotesCustomizationDataStore.isEmotesCustomizationSelected.Set(false, notifyEvent: false);
 0682        });
 48683        sectionSelector.GetSection(EMOTES_SECTION_INDEX).onSelect.AddListener((isSelected) =>
 684        {
 0685            emotesSection.SetActive(isSelected);
 0686            randomizeButton.gameObject.SetActive(false);
 687
 0688            if (isSelected)
 689            {
 0690                sectionTitle.text = EMOTES_SECTION_TITLE;
 0691                ResetPreviewEmote();
 692            }
 693
 0694            CharacterPreview.SetFocus(global::MainScripts.DCL.Controllers.HUD.CharacterPreview.CharacterPreviewControlle
 0695            emotesCustomizationDataStore.isEmotesCustomizationSelected.Set(true, notifyEvent: false);
 0696        });
 48697    }
 698
 699    internal void SetSectionActive(int sectionIndex, bool isActive)
 700    {
 96701        sectionSelector.GetSection(sectionIndex).SetActive(isActive);
 288702        sectionSelector.gameObject.SetActive(sectionSelector.GetAllSections().Count(x => x.IsActive()) > 1);
 96703    }
 704
 2705    public void PlayPreviewEmote(string emoteId) { CharacterPreview.PlayEmote(emoteId, (long)Time.realtimeSinceStartup);
 706
 2707    public void ResetPreviewEmote() { PlayPreviewEmote(RESET_PREVIEW_ANIMATION); }
 708
 709    public void ToggleThirdPartyCollection(string collectionId, bool isOn)
 710    {
 0711        List<IToggleComponentView> allCollectionOptions = collectionsDropdown.GetAllOptions();
 0712        foreach (IToggleComponentView collectionOption in allCollectionOptions)
 713        {
 0714            if (collectionOption.id == collectionId)
 0715                collectionOption.isOn = isOn;
 716        }
 0717    }
 718    public void ShowNoItemOfWearableCollectionWarning()
 719    {
 0720        noItemInCollectionWarning.Dismiss(true);
 0721        noItemInCollectionWarning.Show(new DCL.NotificationModel.Model
 722        {
 723            timer = 5f,
 724        });
 0725    }
 726
 727    private void ClickBlockerClicked()
 728    {
 0729        noItemInCollectionWarning.Dismiss(false);
 0730    }
 731
 732    private void UpdateAvatarModelWhenNeeded()
 733    {
 1734        if (isAvatarDirty)
 735        {
 736            async UniTaskVoid UpdateAvatarAsync()
 737            {
 0738                await CharacterPreview.TryUpdateModelAsync(avatarModelToUpdate);
 0739                if (doneButton != null)
 0740                    doneButton.interactable = true;
 741
 0742                loadingSpinnerGameObject?.SetActive(false);
 743
 0744                if(doAvatarFeedback)
 0745                    OnAvatarAppearFeedback?.Invoke(avatarModelToUpdate);
 746
 0747                doAvatarFeedback = false;
 0748                ClearWearablesLoadingSpinner();
 0749                randomizeAnimator?.SetBool(RANDOMIZE_ANIMATOR_LOADING_BOOL, false);
 0750            }
 751
 0752            UpdateAvatarAsync().Forget();
 0753            isAvatarDirty = false;
 754        }
 1755    }
 756
 757}

Methods/Properties

AvatarEditorHUDView()
isOpen()
isOpen(System.Boolean)
emotesCustomizationDataStore()
Initialize()
AvatarEditorHUDView()
CharacterPreview()
CharacterPreview(MainScripts.DCL.Controllers.HUD.CharacterPreview.ICharacterPreviewController)
Awake()
Initialize(AvatarEditorHUDController)
Update()
SetIsWeb3(System.Boolean)
InitializeNavigationEvents(System.Boolean)
OnCharacterPreviewRotation(System.Single)
InitializeNavigationInfo(AvatarEditorHUDView/AvatarEditorNavigationInfo, System.Boolean)
InitializeNavigationInfo(AvatarEditorHUDView/AvatarEditorNavigationInfo)
InitializeWearableChangeEvents()
Create(AvatarEditorHUDController)
UpdateSelectedBody(WearableItem)
EquipWearable(WearableItem)
UnequipWearable(WearableItem)
SetWearableLoadingSpinner(WearableItem, System.Boolean)
ClearWearablesLoadingSpinner()
SelectHairColor(UnityEngine.Color)
GetRandomColor()
SelectSkinColor(UnityEngine.Color)
SelectEyeColor(UnityEngine.Color)
SetColors(System.Collections.Generic.List[Color], System.Collections.Generic.List[Color], System.Collections.Generic.List[Color])
UnselectAllWearables()
UpdateAvatarPreview(AvatarModel)
AddFeedbackOnAppear()
AddWearable(WearableItem, System.Int32, System.Func[WearableItem,Boolean], System.Func[WearableItem,Boolean], System.Func[WearableItem,Boolean])
RefreshSelectorsSize()
GetWearableCollectionName(WearableItem)
RemoveWearable(WearableItem)
RemoveAllWearables()
OnRandomizeButton()
OnDoneButton()
OnWearablesSelectorsClicked(System.String)
TakeSnapshotsAfterStopPreviewAnimation()
OnSnapshotsReady(UnityEngine.Texture2D, UnityEngine.Texture2D)
OnSnapshotsFailed()
SetVisibility(System.Boolean)
Dispose()
SetAsFullScreenMenuMode(UnityEngine.Transform)
OnPointerDown(UnityEngine.EventSystems.PointerEventData)
LoadCollectionsDropdown(WearableCollectionsAPIData/Collection[])
BlockCollectionsDropdown(System.Boolean)
ShowSkinPopulatedList(System.Boolean)
ShowCollectiblesPopulatedList(System.Boolean)
SetThirdPartyCollectionsVisibility(System.Boolean)
ConfigureSectionSelector()
SetSectionActive(System.Int32, System.Boolean)
PlayPreviewEmote(System.String)
ResetPreviewEmote()
ToggleThirdPartyCollection(System.String, System.Boolean)
ShowNoItemOfWearableCollectionWarning()
ClickBlockerClicked()
UpdateAvatarModelWhenNeeded()
<UpdateAvatarModelWhenNeeded()