< 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:0
Uncovered lines:324
Coverable lines:324
Total lines:776
Line coverage:0% (0 of 324)
Covered branches:0
Total branches:0
Covered methods:0
Total methods:60
Method coverage:0% (0 of 60)

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity NPath complexity Sequence coverage
AvatarEditorHUDView()0%2100%
Initialize()0%2100%
AvatarEditorHUDView()0%2100%
Awake()0%2100%
Initialize(...)0%20400%
Update()0%2100%
SetIsWeb3(...)0%2100%
InitializeNavigationEvents(...)0%12300%
OnCharacterPreviewRotationController(...)0%2100%
InitializeNavigationInfo(...)0%30500%
InitializeNavigationInfo(...)0%2100%
InitializeWearableChangeEvents()0%6200%
Create(...)0%2100%
UpdateSelectedBody(...)0%12300%
EquipWearable(...)0%2100%
UnequipWearable(...)0%2100%
SetWearableLoadingSpinner(...)0%6200%
ClearWearablesLoadingSpinner()0%6200%
SelectHairColor(...)0%2100%
GetRandomColor()0%2100%
SelectSkinColor(...)0%2100%
SelectEyeColor(...)0%2100%
SetColors(...)0%2100%
UnselectAllWearables()0%12300%
UpdateAvatarPreview(...)0%20400%
AddFeedbackOnAppear()0%2100%
AddWearable(...)0%30500%
RefreshSelectorsSize()0%6200%
GetWearableCollectionName(...)0%12300%
RemoveWearable(...)0%30500%
RemoveAllWearables()0%6200%
OnRandomizeButton()0%12300%
OnDoneButton()0%2100%
OnWearablesSelectorsClicked(...)0%6200%
TakeSnapshotsAfterStopPreviewAnimation()0%12300%
OnSnapshotsReady(...)0%2100%
OnSnapshotsFailed()0%2100%
SetVisibility(...)0%56700%
Dispose()0%1321100%
SetAsFullScreenMenuMode(...)0%6200%
OnPointerDown(...)0%30500%
LoadCollectionsDropdown(...)0%6200%
BlockCollectionsDropdown(...)0%2100%
ShowSkinPopulatedList(...)0%2100%
ShowCollectiblesPopulatedList(...)0%2100%
SetThirdPartyCollectionsVisibility(...)0%2100%
ConfigureSectionSelector()0%2100%
SetSectionActive(...)0%6200%
PlayPreviewEmote(...)0%2100%
ResetPreviewEmote()0%2100%
ToggleThirdPartyCollection(...)0%12300%
ShowNoItemOfWearableCollectionWarning()0%2100%
ClickBlockerClicked()0%2100%
UpdateAvatarModelWhenNeeded()0%6200%
<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{
 020    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
 030    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 PreviewCameraFocus focus = PreviewCameraFocus.DefaultEditing;
 42
 43        //To remove when we refactor this to avoid ToggleGroup issues when quitting application
 044        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 RawImage characterPreviewImage;
 89
 90    [SerializeField]
 91    internal Button randomizeButton;
 92
 93    [SerializeField]
 94    internal Animator randomizeAnimator;
 95
 96    [SerializeField]
 97    internal Button doneButton;
 98
 99    [SerializeField] internal Button[] goToMarketplaceButtons;
 100
 101    [SerializeField] internal GameObject loadingSpinnerGameObject;
 102
 103    [Header("Collectibles")]
 104    [SerializeField] internal GameObject web3Container;
 105    [SerializeField] internal GameObject noWeb3Container;
 106    [SerializeField] private GameObject collectiblesEmptyListContainer;
 107
 108    [Header("Skins")]
 109
 110    [SerializeField] internal GameObject skinsFeatureContainer;
 111
 112    [SerializeField] internal GameObject skinsWeb3Container;
 113
 114    [SerializeField] internal GameObject skinsMissingWeb3Container;
 115
 116    [SerializeField] internal GameObject skinsConnectWalletButtonContainer;
 117
 118    [SerializeField] private GameObject skinsPopulatedListContainer;
 119    [SerializeField] private GameObject skinsEmptyListContainer;
 120
 121    [SerializeField]
 122    internal DropdownComponentView collectionsDropdown;
 123
 124    [Header("Section Selector")]
 125    [SerializeField] internal SectionSelectorComponentView sectionSelector;
 126    [SerializeField] internal TMP_Text sectionTitle;
 127    [SerializeField] internal GameObject avatarSection;
 128    [SerializeField] internal GameObject emotesSection;
 129
 130    [SerializeField] internal UIHelper_ClickBlocker clickBlocker;
 131    [SerializeField] internal Notification noItemInCollectionWarning;
 132
 133    [Header("MOUSE INPUT CONFIGURATION")]
 134    [SerializeField] private CharacterPreviewInputDetector characterPreviewInputDetector;
 135    [SerializeField] internal InputAction_Hold firstClickAction;
 136
 137    [Header("ROTATE CONFIGURATION")]
 0138    [SerializeField] internal float rotationFactor = -30f;
 0139    [SerializeField] internal float slowDownTime = 0.5f;
 140
 141    private Service<ICharacterPreviewFactory> characterPreviewFactory;
 142
 143    private AvatarEditorHUDController controller;
 0144    internal readonly Dictionary<string, ItemSelector> selectorsByCategory = new Dictionary<string, ItemSelector>();
 0145    private readonly HashSet<WearableItem> wearablesWithLoadingSpinner = new HashSet<WearableItem>();
 0146    private readonly Dictionary<string, ToggleComponentModel> loadedCollectionModels = new Dictionary<string, ToggleComp
 147    private bool isAvatarDirty;
 148    private AvatarModel avatarModelToUpdate;
 149    private bool doAvatarFeedback;
 150    private IPreviewCameraRotationController avatarPreviewRotationController;
 151
 0152    public ICharacterPreviewController CharacterPreview { get; private set; }
 153
 154    public event Action<AvatarModel> OnAvatarAppearFeedback;
 155    public event Action<bool> OnSetVisibility;
 156    public event Action OnRandomize;
 157    public event Action<string> WearableSelectorClicked;
 158
 159    private void Awake()
 160    {
 0161        loadingSpinnerGameObject.SetActive(false);
 0162        doneButton.interactable = false; //the default state of the button should be disable until a profile has been lo
 0163        isOpen = false;
 0164        arePanelsInitialized = false;
 0165    }
 166
 167    private void Initialize(AvatarEditorHUDController controller, IPreviewCameraRotationController avatarPreviewRotation
 168    {
 0169        this.controller = controller;
 0170        this.avatarPreviewRotationController = avatarPreviewRotationController;
 0171        gameObject.name = VIEW_OBJECT_NAME;
 172
 0173        randomizeButton.onClick.AddListener(OnRandomizeButton);
 0174        doneButton.onClick.AddListener(OnDoneButton);
 0175        InitializeWearableChangeEvents();
 176
 0177        foreach (var button in goToMarketplaceButtons)
 0178            button.onClick.RemoveAllListeners();
 0179        foreach (var button in goToMarketplaceButtons)
 0180            button.onClick.AddListener(controller.GoToMarketplaceOrConnectWallet);
 181
 0182        CharacterPreview = characterPreviewFactory.Ref.Create(CharacterPreviewMode.WithoutHologram, (RenderTexture) char
 183
 0184        collectionsDropdown.OnOptionSelectionChanged -= controller.ToggleThirdPartyCollection;
 0185        collectionsDropdown.OnOptionSelectionChanged += controller.ToggleThirdPartyCollection;
 186
 0187        clickBlocker.OnClicked += ClickBlockerClicked;
 188
 0189        for (int i = 0; i < wearableGridPairs.Length; i++)
 190        {
 0191            wearableGridPairs[i].selector.OnItemClicked += OnWearablesSelectorsClicked;
 192        }
 0193        collectiblesItemSelector.OnItemClicked += OnWearablesSelectorsClicked;
 194
 0195        ConfigureSectionSelector();
 0196    }
 197
 198    private void Update()
 199    {
 0200        UpdateAvatarModelWhenNeeded();
 0201    }
 202
 203    public void SetIsWeb3(bool isWeb3User)
 204    {
 0205        web3Container.SetActive(isWeb3User);
 0206        noWeb3Container.SetActive(!isWeb3User);
 0207        skinsWeb3Container.SetActive(isWeb3User);
 0208        skinsMissingWeb3Container.SetActive(!isWeb3User);
 0209    }
 210
 211    internal void InitializeNavigationEvents(bool isGuest)
 212    {
 0213        if (arePanelsInitialized)
 0214            return;
 215
 0216        for (int i = 0; i < navigationInfos.Length; i++)
 217        {
 0218            InitializeNavigationInfo(navigationInfos[i]);
 219        }
 0220        InitializeNavigationInfo(collectiblesNavigationInfo, !isGuest);
 221
 0222        avatarPreviewRotationController.Configure(
 223            firstClickAction,
 224            rotationFactor,
 225            slowDownTime,
 226            characterPreviewInputDetector,
 227            null);
 228
 0229        avatarPreviewRotationController.OnHorizontalRotation += OnCharacterPreviewRotationController;
 0230        arePanelsInitialized = true;
 0231    }
 232
 233    private void OnCharacterPreviewRotationController(float angularVelocity)
 234    {
 0235        CharacterPreview.Rotate(angularVelocity);
 0236    }
 237
 238    private void InitializeNavigationInfo(AvatarEditorNavigationInfo current, bool isActive)
 239    {
 0240        current.Initialize();
 241
 0242        current.toggle.isOn = isActive ? current.enabledByDefault : false;
 0243        current.canvas.gameObject.SetActive(isActive ? current.enabledByDefault : false);
 244
 0245        current.toggle.onValueChanged.AddListener((on) =>
 246        {
 0247            current.canvas.gameObject.SetActive(@on);
 0248            CharacterPreview.SetFocus(current.focus);
 0249        });
 0250    }
 251
 252    private void InitializeNavigationInfo(AvatarEditorNavigationInfo current)
 253    {
 0254        InitializeNavigationInfo(current, true);
 0255    }
 256
 257    private void InitializeWearableChangeEvents()
 258    {
 0259        int nPairs = wearableGridPairs.Length;
 0260        for (int i = 0; i < nPairs; i++)
 261        {
 0262            wearableGridPairs[i].selector.OnItemClicked += controller.WearableClicked;
 0263            wearableGridPairs[i].selector.OnSellClicked += controller.SellCollectible;
 0264            selectorsByCategory.Add(wearableGridPairs[i].categoryFilter, wearableGridPairs[i].selector);
 265        }
 266
 0267        collectiblesItemSelector.OnItemClicked += controller.WearableClicked;
 0268        collectiblesItemSelector.OnSellClicked += controller.SellCollectible;
 269
 0270        skinColorSelector.OnColorSelectorChange += controller.SkinColorClicked;
 0271        eyeColorPickerComponent.OnColorChanged += controller.EyesColorClicked;
 0272        hairColorPickerComponent.OnColorChanged += controller.HairColorClicked;
 0273        facialHairColorPickerComponent.OnColorChanged += controller.HairColorClicked;
 0274        eyeBrowsColorPickerComponent.OnColorChanged += controller.HairColorClicked;
 0275    }
 276
 277    internal static AvatarEditorHUDView Create(AvatarEditorHUDController controller, IPreviewCameraRotationController av
 278    {
 0279        var view = Instantiate(Resources.Load<GameObject>(VIEW_PATH)).GetComponent<AvatarEditorHUDView>();
 0280        view.Initialize(controller, avatarPreviewRotationController);
 0281        return view;
 282    }
 283
 284    public void UpdateSelectedBody(WearableItem bodyShape)
 285    {
 0286        for (int i = 0; i < wearableGridPairs.Length; i++)
 287        {
 0288            if (wearableGridPairs[i].categoryFilter == WearableLiterals.Categories.BODY_SHAPE)
 289            {
 0290                wearableGridPairs[i].selector.UnselectAll();
 0291                wearableGridPairs[i].selector.Select(bodyShape.id);
 292            }
 293            else
 294            {
 0295                wearableGridPairs[i].selector.SetBodyShape(bodyShape.id);
 296            }
 297        }
 298
 0299        collectiblesItemSelector.SetBodyShape(bodyShape.id);
 0300    }
 301
 302    public void EquipWearable(WearableItem wearable)
 303    {
 0304        selectorsByCategory[wearable.data.category].Select(wearable.id);
 0305        SetWearableLoadingSpinner(wearable, true);
 0306        collectiblesItemSelector.Select(wearable.id);
 0307    }
 308
 309    public void UnequipWearable(WearableItem wearable)
 310    {
 0311        selectorsByCategory[wearable.data.category].Unselect(wearable.id);
 0312        SetWearableLoadingSpinner(wearable, false);
 0313        collectiblesItemSelector.Unselect(wearable.id);
 0314    }
 315
 316    internal void SetWearableLoadingSpinner(WearableItem wearable, bool isActive)
 317    {
 0318        selectorsByCategory[wearable.data.category].SetWearableLoadingSpinner(wearable.id, isActive);
 0319        collectiblesItemSelector.SetWearableLoadingSpinner(wearable.id, isActive);
 0320        if (isActive)
 0321            wearablesWithLoadingSpinner.Add(wearable);
 322        else
 0323            wearablesWithLoadingSpinner.Remove(wearable);
 0324    }
 325
 326    internal void ClearWearablesLoadingSpinner()
 327    {
 0328        foreach (WearableItem wearable in wearablesWithLoadingSpinner)
 329        {
 0330            selectorsByCategory[wearable.data.category].SetWearableLoadingSpinner(wearable.id, false);
 0331            collectiblesItemSelector.SetWearableLoadingSpinner(wearable.id, false);
 332        }
 333
 0334        wearablesWithLoadingSpinner.Clear();
 0335    }
 336
 337    public void SelectHairColor(Color hairColor)
 338    {
 0339        hairColorPickerComponent.SetColorSelector(hairColor);
 0340        hairColorPickerComponent.UpdateSliderValues(hairColor);
 0341        eyeBrowsColorPickerComponent.SetColorSelector(hairColor);
 0342        eyeBrowsColorPickerComponent.UpdateSliderValues(hairColor);
 0343        facialHairColorPickerComponent.SetColorSelector(hairColor);
 0344        facialHairColorPickerComponent.UpdateSliderValues(hairColor);
 0345    }
 346
 347    public Color GetRandomColor()
 348    {
 0349        return Color.HSVToRGB(UnityEngine.Random.Range(0, 1f), UnityEngine.Random.Range(0, 1f), UnityEngine.Random.Range
 350    }
 351
 352    public void SelectSkinColor(Color skinColor)
 353    {
 0354        skinColorSelector.Select(skinColor);
 0355    }
 356
 357    public void SelectEyeColor(Color eyesColor)
 358    {
 0359        eyeColorPickerComponent.SetColorSelector(eyesColor);
 0360        eyeColorPickerComponent.UpdateSliderValues(eyesColor);
 0361    }
 362
 363    public void SetColors(List<Color> skinColors, List<Color> hairColors, List<Color> eyeColors)
 364    {
 0365        skinColorSelector.Populate(skinColors);
 0366        eyeColorPickerComponent.SetColorList(eyeColors);
 0367        hairColorPickerComponent.SetColorList(hairColors);
 0368        eyeBrowsColorPickerComponent.SetColorList(hairColors);
 0369        facialHairColorPickerComponent.SetColorList(hairColors);
 0370    }
 371
 372    public void UnselectAllWearables()
 373    {
 0374        for (int i = 0; i < wearableGridPairs.Length; i++)
 375        {
 0376            if (wearableGridPairs[i].categoryFilter != WearableLiterals.Categories.BODY_SHAPE)
 377            {
 0378                wearableGridPairs[i].selector.UnselectAll();
 379            }
 380        }
 381
 0382        collectiblesItemSelector.UnselectAll();
 0383    }
 384
 385    public void UpdateAvatarPreview(AvatarModel avatarModel)
 386    {
 0387        if (avatarModel?.wearables == null)
 0388            return;
 389
 390        // We delay the updating of the avatar 1 frame to disengage from the kernel message flow
 391        // otherwise the cancellation of the updating task throws an exception that is catch by
 392        // kernel setthrew method, which floods the analytics.
 393        // Also it updates just once if its called many times in a row
 0394        isAvatarDirty = true;
 0395        avatarModelToUpdate = avatarModel;
 396
 0397        doneButton.interactable = false;
 0398        loadingSpinnerGameObject.SetActive(true);
 0399    }
 400
 401    public void AddFeedbackOnAppear()
 402    {
 0403        doAvatarFeedback = true;
 0404    }
 405
 406    public void AddWearable(WearableItem wearableItem, int amount,
 407        Func<WearableItem, bool> hideOtherWearablesToastStrategy,
 408        Func<WearableItem, bool> replaceOtherWearablesToastStrategy,
 409        Func<WearableItem, bool> incompatibleWearableToastStrategy)
 410    {
 0411        if (wearableItem == null)
 0412            return;
 413
 0414        if (!selectorsByCategory.ContainsKey(wearableItem.data.category))
 415        {
 0416            Debug.LogError($"Category couldn't find selector for category: {wearableItem.data.category} ");
 0417            return;
 418        }
 419
 0420        string collectionName = GetWearableCollectionName(wearableItem);
 421
 0422        selectorsByCategory[wearableItem.data.category].AddWearable(
 423            wearableItem,
 424            collectionName,
 425            amount,
 426            hideOtherWearablesToastStrategy,
 427            replaceOtherWearablesToastStrategy,
 428            incompatibleWearableToastStrategy);
 429
 0430        if (wearableItem.IsCollectible() || wearableItem.IsFromThirdPartyCollection)
 431        {
 0432            collectiblesItemSelector.AddWearable(
 433                wearableItem,
 434                collectionName,
 435                amount,
 436                hideOtherWearablesToastStrategy,
 437                replaceOtherWearablesToastStrategy,
 438                incompatibleWearableToastStrategy);
 439        }
 0440    }
 441
 442    public void RefreshSelectorsSize()
 443    {
 0444        using (var iterator = selectorsByCategory.GetEnumerator())
 445        {
 0446            while (iterator.MoveNext())
 447            {
 0448                iterator.Current.Value.UpdateSelectorLayout();
 449            }
 0450        }
 451
 0452        collectiblesItemSelector.UpdateSelectorLayout();
 0453    }
 454
 455    private string GetWearableCollectionName(WearableItem wearableItem)
 456    {
 0457        string collectionName = string.Empty;
 458
 0459        if (wearableItem.IsFromThirdPartyCollection)
 460        {
 0461            loadedCollectionModels.TryGetValue(wearableItem.ThirdPartyCollectionId, out ToggleComponentModel collectionM
 462
 0463            if (collectionModel != null)
 0464                collectionName = collectionModel.text;
 465        }
 466
 0467        return collectionName;
 468    }
 469
 470    public void RemoveWearable(WearableItem wearableItem)
 471    {
 0472        if (wearableItem == null)
 0473            return;
 474
 0475        if (!selectorsByCategory.ContainsKey(wearableItem.data.category))
 476        {
 0477            Debug.LogError($"Category couldn't find selector for category: {wearableItem.data.category} ");
 0478            return;
 479        }
 480
 0481        selectorsByCategory[wearableItem.data.category].RemoveWearable(wearableItem.id);
 0482        if (wearableItem.IsCollectible() || wearableItem.IsFromThirdPartyCollection)
 0483            collectiblesItemSelector.RemoveWearable(wearableItem.id);
 0484    }
 485
 486    public void RemoveAllWearables()
 487    {
 0488        using (var enumerator = selectorsByCategory.GetEnumerator())
 489        {
 0490            while (enumerator.MoveNext())
 491            {
 0492                enumerator.Current.Value.RemoveAllWearables();
 493            }
 0494        }
 495
 0496        collectiblesItemSelector.RemoveAllWearables();
 0497    }
 498
 499    private void OnRandomizeButton()
 500    {
 0501        OnRandomize?.Invoke();
 0502        controller.RandomizeWearables();
 0503        randomizeAnimator?.SetBool(RANDOMIZE_ANIMATOR_LOADING_BOOL, true);
 0504    }
 505
 506    private void OnDoneButton()
 507    {
 0508        doneButton.interactable = false;
 0509        CoroutineStarter.Start(TakeSnapshotsAfterStopPreviewAnimation());
 0510        eyeColorPickerComponent.SetActive(false);
 0511        hairColorPickerComponent.SetActive(false);
 0512        facialHairColorPickerComponent.SetActive(false);
 0513        eyeBrowsColorPickerComponent.SetActive(false);
 0514    }
 515
 516    private void OnWearablesSelectorsClicked(string obj)
 517    {
 0518        WearableSelectorClicked?.Invoke(obj);
 0519    }
 520
 521    private IEnumerator TakeSnapshotsAfterStopPreviewAnimation()
 522    {
 523        // We need to stop the current preview animation in order to take a correct snapshot
 0524        ResetPreviewEmote();
 0525        yield return new WaitForSeconds(TIME_TO_RESET_PREVIEW_ANIMATION);
 0526        CharacterPreview.TakeSnapshots(OnSnapshotsReady, OnSnapshotsFailed);
 0527    }
 528
 529    private void OnSnapshotsReady(Texture2D face256, Texture2D body)
 530    {
 0531        doneButton.interactable = true;
 0532        controller.SaveAvatar(face256, body);
 0533    }
 534
 0535    private void OnSnapshotsFailed() { doneButton.interactable = true; }
 536
 537    public void SetVisibility(bool visible)
 538    {
 0539        CharacterPreview.SetEnabled(visible);
 0540        avatarEditorCanvas.enabled = visible;
 0541        avatarEditorCanvasGroup.blocksRaycasts = visible;
 542
 0543        if (visible && !isOpen)
 544        {
 0545            OnSetVisibility?.Invoke(visible);
 546        }
 0547        else if (!visible && isOpen)
 548        {
 0549            collectionsDropdown.Close();
 0550            noItemInCollectionWarning.Dismiss(true);
 0551            OnSetVisibility?.Invoke(visible);
 552        }
 553
 0554        isOpen = visible;
 0555    }
 556
 557    public void Dispose()
 558    {
 0559        loadingSpinnerGameObject = null;
 0560        randomizeAnimator = null;
 0561        if (wearableGridPairs != null)
 562        {
 0563            int nPairs = wearableGridPairs.Length;
 0564            for (int i = 0; i < nPairs; i++)
 565            {
 0566                var itemSelector = wearableGridPairs[i].selector;
 0567                if (itemSelector != null)
 568                {
 0569                    itemSelector.OnItemClicked -= controller.WearableClicked;
 0570                    itemSelector.OnSellClicked -= controller.SellCollectible;
 0571                    itemSelector.OnItemClicked -= OnWearablesSelectorsClicked;
 572                }
 573            }
 574        }
 575
 0576        if (collectiblesItemSelector != null)
 577        {
 0578            collectiblesItemSelector.OnItemClicked -= controller.WearableClicked;
 0579            collectiblesItemSelector.OnSellClicked -= controller.SellCollectible;
 0580            collectiblesItemSelector.OnItemClicked -= OnWearablesSelectorsClicked;
 581        }
 582
 0583        if (skinColorSelector != null)
 0584            skinColorSelector.OnColorSelectorChange -= controller.SkinColorClicked;
 0585        if (eyeColorPickerComponent != null)
 0586            eyeColorPickerComponent.OnColorChanged -= controller.EyesColorClicked;
 0587        if (hairColorPickerComponent != null)
 0588            hairColorPickerComponent.OnColorChanged -= controller.HairColorClicked;
 0589        if (facialHairColorPickerComponent != null)
 0590            facialHairColorPickerComponent.OnColorChanged -= controller.HairColorClicked;
 0591        if (eyeBrowsColorPickerComponent != null)
 0592            eyeBrowsColorPickerComponent.OnColorChanged -= controller.HairColorClicked;
 593
 0594        if (this != null)
 0595            Destroy(gameObject);
 596
 0597        CharacterPreview.Dispose();
 598
 0599        collectionsDropdown.OnOptionSelectionChanged -= controller.ToggleThirdPartyCollection;
 0600        collectionsDropdown.Dispose();
 601
 0602        sectionSelector.GetSection(AVATAR_SECTION_INDEX).onSelect.RemoveAllListeners();
 0603        sectionSelector.GetSection(EMOTES_SECTION_INDEX).onSelect.RemoveAllListeners();
 604
 0605        clickBlocker.OnClicked -= ClickBlockerClicked;
 606
 0607        avatarPreviewRotationController.OnHorizontalRotation -= OnCharacterPreviewRotationController;
 0608        avatarPreviewRotationController.Dispose();
 0609    }
 610
 611    public void SetAsFullScreenMenuMode(Transform parentTransform)
 612    {
 0613        if (parentTransform == null)
 0614            return;
 615
 0616        transform.SetParent(parentTransform);
 0617        transform.localScale = Vector3.one;
 618
 0619        RectTransform rectTransform = transform as RectTransform;
 0620        rectTransform.anchorMin = Vector2.zero;
 0621        rectTransform.anchorMax = Vector2.one;
 0622        rectTransform.pivot = new Vector2(0.5f, 0.5f);
 0623        rectTransform.localPosition = Vector2.zero;
 0624        rectTransform.offsetMax = Vector2.zero;
 0625        rectTransform.offsetMin = Vector2.zero;
 0626    }
 627
 628    public void OnPointerDown(PointerEventData eventData)
 629    {
 0630        if (eventData.pointerPressRaycast.gameObject != eyeColorPickerComponent.gameObject &&
 631            eventData.pointerPressRaycast.gameObject != hairColorPickerComponent.gameObject &&
 632            eventData.pointerPressRaycast.gameObject != eyeBrowsColorPickerComponent.gameObject &&
 633            eventData.pointerPressRaycast.gameObject != facialHairColorPickerComponent.gameObject)
 634        {
 0635            eyeColorPickerComponent.SetActive(false);
 0636            hairColorPickerComponent.SetActive(false);
 0637            eyeBrowsColorPickerComponent.SetActive(false);
 0638            facialHairColorPickerComponent.SetActive(false);
 639        }
 0640    }
 641
 642    public void LoadCollectionsDropdown(Collection[] collections)
 643    {
 0644        List<ToggleComponentModel> collectionsToAdd = new List<ToggleComponentModel>();
 0645        foreach (var collection in collections)
 646        {
 0647            ToggleComponentModel newCollectionModel = new ToggleComponentModel
 648            {
 649                id = collection.urn,
 650                text = collection.name,
 651                isOn = false,
 652                isTextActive = true
 653            };
 654
 0655            collectionsToAdd.Add(newCollectionModel);
 0656            loadedCollectionModels.Add(collection.urn, newCollectionModel);
 657        }
 658
 0659        collectionsDropdown.SetOptions(collectionsToAdd);
 0660    }
 661
 662    public void BlockCollectionsDropdown(bool isBlocked)
 663    {
 0664        collectionsDropdown.SetLoadingActive(isBlocked);
 0665    }
 666
 667    public void ShowSkinPopulatedList(bool show)
 668    {
 0669        skinsPopulatedListContainer.SetActive(show);
 0670        skinsEmptyListContainer.SetActive(!show);
 0671        skinsConnectWalletButtonContainer.SetActive(show);
 0672    }
 673
 674    public void ShowCollectiblesPopulatedList(bool show)
 675    {
 0676        collectiblesEmptyListContainer.SetActive(!show);
 0677    }
 678
 679    public void SetThirdPartyCollectionsVisibility(bool visible) =>
 0680        collectionsDropdown.gameObject.SetActive(visible);
 681
 682    internal void ConfigureSectionSelector()
 683    {
 0684        sectionTitle.text = AVATAR_SECTION_TITLE;
 685
 0686        sectionSelector.GetSection(AVATAR_SECTION_INDEX).onSelect.AddListener((isSelected) =>
 687        {
 0688            avatarSection.SetActive(isSelected);
 0689            randomizeButton.gameObject.SetActive(true);
 690
 0691            if (isSelected)
 692            {
 0693                sectionTitle.text = AVATAR_SECTION_TITLE;
 0694                ResetPreviewEmote();
 695            }
 696
 0697            emotesCustomizationDataStore.isEmotesCustomizationSelected.Set(false, notifyEvent: false);
 0698        });
 0699        sectionSelector.GetSection(EMOTES_SECTION_INDEX).onSelect.AddListener((isSelected) =>
 700        {
 0701            emotesSection.SetActive(isSelected);
 0702            randomizeButton.gameObject.SetActive(false);
 703
 0704            if (isSelected)
 705            {
 0706                sectionTitle.text = EMOTES_SECTION_TITLE;
 0707                ResetPreviewEmote();
 708            }
 709
 0710            CharacterPreview.SetFocus(PreviewCameraFocus.DefaultEditing);
 0711            emotesCustomizationDataStore.isEmotesCustomizationSelected.Set(true, notifyEvent: false);
 0712        });
 0713    }
 714
 715    internal void SetSectionActive(int sectionIndex, bool isActive)
 716    {
 0717        sectionSelector.GetSection(sectionIndex).SetActive(isActive);
 0718        sectionSelector.gameObject.SetActive(sectionSelector.GetAllSections().Count(x => x.IsActive()) > 1);
 0719    }
 720
 0721    public void PlayPreviewEmote(string emoteId) { CharacterPreview.PlayEmote(emoteId, (long)Time.realtimeSinceStartup);
 722
 723    public void ResetPreviewEmote()
 724    {
 0725        CharacterPreview.StopEmote();
 0726    }
 727
 728    public void ToggleThirdPartyCollection(string collectionId, bool isOn)
 729    {
 0730        List<IToggleComponentView> allCollectionOptions = collectionsDropdown.GetAllOptions();
 0731        foreach (IToggleComponentView collectionOption in allCollectionOptions)
 732        {
 0733            if (collectionOption.id == collectionId)
 0734                collectionOption.isOn = isOn;
 735        }
 0736    }
 737    public void ShowNoItemOfWearableCollectionWarning()
 738    {
 0739        noItemInCollectionWarning.Dismiss(true);
 0740        noItemInCollectionWarning.Show(new DCL.NotificationModel.Model
 741        {
 742            timer = 5f,
 743        });
 0744    }
 745
 746    private void ClickBlockerClicked()
 747    {
 0748        noItemInCollectionWarning.Dismiss(false);
 0749    }
 750
 751    private void UpdateAvatarModelWhenNeeded()
 752    {
 0753        if (isAvatarDirty)
 754        {
 755            async UniTaskVoid UpdateAvatarAsync()
 756            {
 0757                await CharacterPreview.TryUpdateModelAsync(avatarModelToUpdate);
 0758                if (doneButton != null)
 0759                    doneButton.interactable = true;
 760
 0761                loadingSpinnerGameObject?.SetActive(false);
 762
 0763                if(doAvatarFeedback)
 0764                    OnAvatarAppearFeedback?.Invoke(avatarModelToUpdate);
 765
 0766                doAvatarFeedback = false;
 0767                ClearWearablesLoadingSpinner();
 0768                randomizeAnimator?.SetBool(RANDOMIZE_ANIMATOR_LOADING_BOOL, false);
 0769            }
 770
 0771            UpdateAvatarAsync().Forget();
 0772            isAvatarDirty = false;
 773        }
 0774    }
 775
 776}

Methods/Properties

AvatarEditorHUDView()
isOpen()
isOpen(System.Boolean)
emotesCustomizationDataStore()
Initialize()
AvatarEditorHUDView()
CharacterPreview()
CharacterPreview(MainScripts.DCL.Controllers.HUD.CharacterPreview.ICharacterPreviewController)
Awake()
Initialize(AvatarEditorHUDController, MainScripts.DCL.Controllers.HUD.CharacterPreview.IPreviewCameraRotationController)
Update()
SetIsWeb3(System.Boolean)
InitializeNavigationEvents(System.Boolean)
OnCharacterPreviewRotationController(System.Single)
InitializeNavigationInfo(AvatarEditorHUDView/AvatarEditorNavigationInfo, System.Boolean)
InitializeNavigationInfo(AvatarEditorHUDView/AvatarEditorNavigationInfo)
InitializeWearableChangeEvents()
Create(AvatarEditorHUDController, MainScripts.DCL.Controllers.HUD.CharacterPreview.IPreviewCameraRotationController)
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()