< Summary

Class:ItemSelector
Assembly:AvatarEditorHUD
File(s):/tmp/workspace/unity-renderer/unity-renderer/Assets/Scripts/MainScripts/DCL/Controllers/HUD/AvatarEditorHUD/Scripts/ItemSelector.cs
Covered lines:91
Uncovered lines:24
Coverable lines:115
Total lines:244
Line coverage:79.1% (91 of 115)
Covered branches:0
Total branches:0

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity NPath complexity Sequence coverage
ItemSelector()0%110100%
Awake()0%110100%
OnEnable()0%110100%
OnDestroy()0%110100%
OnScreenSizeChanged(...)0%2100%
CheckScreenSize()0%110100%
CheckScreenSizeAsync()0%4.123050%
SetupWearablePagination()0%110100%
GetMaxPages()0%110100%
UpdateWearableList(...)0%440100%
AddWearable(...)0%3.143075%
RemoveWearable(...)0%6200%
RemoveAllWearables()0%110100%
SetBodyShape(...)0%2.032080%
UpdateSelectorLayout()0%110100%
RefreshAvailableWearables()0%110100%
Select(...)0%220100%
SetWearableLoadingSpinner(...)0%330100%
Unselect(...)0%220100%
UnselectAll()0%220100%
ToggleClicked(...)0%6200%
SellClicked(...)0%6200%
GetItemToggleByID(...)0%3.333066.67%

File(s)

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

#LineLine coverage
 1using System;
 2using System.Collections.Generic;
 3using System.Linq;
 4using System.Runtime.CompilerServices;
 5using System.Threading;
 6using Cysharp.Threading.Tasks;
 7using DCL;
 8using UnityEngine;
 9using UnityEngine.UI;
 10#pragma warning disable CS4014
 11
 12[assembly: InternalsVisibleTo("AvatarEditorHUDTests")]
 13
 14public class ItemSelector : MonoBehaviour
 15{
 16    private const int MIN_SCREEN_SIZE = 200;
 17    private const int AVATAR_MARGIN = 450;
 18    private const float ASPECT_RATIO_PER_COLUMN = 0.15f;
 19    private const int TOTAL_ROWS_OF_ITEMS = 3;
 20    private const int MIN_AMOUNT_OF_COLUMNS = 3;
 21
 22    [SerializeField] internal UIPageSelector pageSelector;
 23    [SerializeField] internal ItemToggleContainer itemToggleContainer;
 24
 25    public event Action<string> OnItemClicked;
 26    public event Action<string> OnSellClicked;
 27
 90028    internal readonly Dictionary<string, ItemToggle> itemToggles = new Dictionary<string, ItemToggle>();
 90029    internal readonly Dictionary<string, WearableSettings> totalWearables = new Dictionary<string, WearableSettings>();
 90030    internal List<WearableSettings> availableWearables = new List<WearableSettings>();
 90031    internal readonly List<string> selectedItems = new List<string>();
 32
 33    private string currentBodyShape;
 90034    private int maxVisibleWearables = 9;
 35    private int lastPage;
 36
 90037    private CancellationTokenSource cancellationTokenSource = new CancellationTokenSource();
 38
 39    private void Awake()
 40    {
 9441        Application.quitting += () =>
 42        {
 043            OnItemClicked = null;
 044        };
 45
 9446        pageSelector.OnValueChanged += UpdateWearableList;
 9447        DataStore.i.screen.size.OnChange += OnScreenSizeChanged;
 9448    }
 49
 50    private void OnEnable()
 51    {
 9452        CheckScreenSize();
 9453    }
 54
 55    private void OnDestroy()
 56    {
 9457        cancellationTokenSource.Cancel();
 9458        cancellationTokenSource.Dispose();
 9459    }
 60
 61    private void OnScreenSizeChanged(Vector2Int current, Vector2Int previous)
 62    {
 063        CheckScreenSize();
 064    }
 65
 66    private void CheckScreenSize()
 67    {
 9468        cancellationTokenSource.Cancel();
 9469        cancellationTokenSource.Dispose();
 9470        cancellationTokenSource = new CancellationTokenSource();
 9471        CheckScreenSizeAsync(cancellationTokenSource.Token);
 9472    }
 73
 74    private async UniTask CheckScreenSizeAsync(CancellationToken cancellationToken)
 75    {
 76        try {
 9477            RectTransform rt = (RectTransform)transform;
 9478            LayoutRebuilder.MarkLayoutForRebuild(rt);
 79
 28280            await UniTask.NextFrame(PlayerLoopTiming.LastPostLateUpdate, cancellationToken);
 81
 082            cancellationToken.ThrowIfCancellationRequested();
 83
 084            var rect = rt.rect;
 085            var width = Mathf.Max(rect.width, MIN_SCREEN_SIZE);
 086            float itemAndSpaceSize = 130 + 32f;
 087            var columns =  Mathf.Max(Mathf.CeilToInt(width / itemAndSpaceSize), MIN_AMOUNT_OF_COLUMNS);
 88
 089            maxVisibleWearables = TOTAL_ROWS_OF_ITEMS * columns;
 90
 091            SetupWearablePagination();
 092        }
 18893        catch (OperationCanceledException) { }
 9494    }
 95
 96    private void SetupWearablePagination()
 97    {
 668898        itemToggleContainer.Setup(maxVisibleWearables);
 668899        pageSelector.Setup(GetMaxPages());
 6688100        UpdateWearableList(lastPage);
 6688101    }
 102
 6688103    private int GetMaxPages() => Mathf.CeilToInt(availableWearables.Count / (float)maxVisibleWearables);
 104
 105    private void UpdateWearableList( int page )
 106    {
 7184107        lastPage = page;
 7184108        itemToggles.Clear();
 143680109        for (int itemToggleIndex = 0; itemToggleIndex < maxVisibleWearables; itemToggleIndex++)
 110        {
 64656111            var baseIndex = page * maxVisibleWearables;
 64656112            var wearableIndex = itemToggleIndex + baseIndex;
 113
 64656114            if (wearableIndex < availableWearables.Count)
 115            {
 6447116                WearableSettings wearableSettings = availableWearables[wearableIndex];
 6447117                var item = wearableSettings.Item;
 6447118                var itemToggle = itemToggleContainer.LoadItem(itemToggleIndex, wearableSettings);
 6447119                itemToggle.SetCallbacks(ToggleClicked, SellClicked);
 6447120                itemToggle.SetLoadingSpinner(wearableSettings.isLoading);
 121
 6447122                if (selectedItems.Contains(item.id))
 442123                    itemToggle.selected = true;
 124
 6447125                itemToggles[item.id] = itemToggle;
 6447126            }
 127            else
 128            {
 58209129                itemToggleContainer.HideItem(itemToggleIndex);
 130            }
 131        }
 7184132    }
 133
 134    public void AddWearable(
 135        WearableItem item,
 136        string collectionName,
 137        int amount,
 138        Func<WearableItem, bool> hideOtherWearablesToastStrategy,
 139        Func<WearableItem, bool> replaceOtherWearablesToastStrategy,
 140        Func<WearableItem, bool> incompatibleWearableToastStrategy)
 141    {
 4242142        if (item == null)
 0143            return;
 144
 4242145        if (totalWearables.ContainsKey(item.id))
 0146            return;
 147
 4242148        WearableSettings wearableSettings = new WearableSettings(item, collectionName, amount, hideOtherWearablesToastSt
 4242149        totalWearables.Add(item.id, wearableSettings);
 150
 4242151        availableWearables.Add(wearableSettings);
 4242152    }
 153
 154    public void RemoveWearable(string itemID)
 155    {
 0156        if (string.IsNullOrEmpty(itemID))
 0157            return;
 158
 0159        totalWearables.Remove(itemID);
 0160        itemToggles.Remove(itemID);
 161
 0162        RefreshAvailableWearables();
 0163    }
 164
 165    public void RemoveAllWearables()
 166    {
 2718167        totalWearables.Clear();
 2718168        availableWearables.Clear();
 2718169        itemToggles.Clear();
 170
 2718171        UpdateSelectorLayout();
 2718172    }
 173
 174    public void SetBodyShape(string bodyShape)
 175    {
 1054176        if (currentBodyShape == bodyShape)
 0177            return;
 178
 1054179        currentBodyShape = bodyShape;
 1054180        RefreshAvailableWearables();
 1054181    }
 182
 183    public void UpdateSelectorLayout()
 184    {
 5634185        SetupWearablePagination();
 5634186    }
 187
 188    private void RefreshAvailableWearables()
 189    {
 1054190        availableWearables = totalWearables.Values.ToList();
 1054191        SetupWearablePagination();
 1054192    }
 193
 194    public void Select(string itemID)
 195    {
 2242196        selectedItems.Add(itemID);
 2242197        ItemToggle toggle = GetItemToggleByID(itemID);
 2242198        if (toggle != null)
 1152199            toggle.selected = true;
 2242200    }
 201
 202    public void SetWearableLoadingSpinner(string wearableID, bool isActive)
 203    {
 3108204        if (totalWearables.ContainsKey(wearableID))
 205        {
 1554206            totalWearables[wearableID].isLoading = isActive;
 207        }
 208
 3108209        ItemToggle toggle = GetItemToggleByID(wearableID);
 3108210        if (toggle != null)
 1554211            toggle.SetLoadingSpinner(isActive);
 3108212    }
 213
 214    public void Unselect(string itemID)
 215    {
 928216        selectedItems.Remove(itemID);
 928217        ItemToggle toggle = GetItemToggleByID(itemID);
 928218        if (toggle != null)
 464219            toggle.selected = false;
 928220    }
 221
 222    public void UnselectAll()
 223    {
 1813224        selectedItems.Clear();
 1813225        using (var iterator = itemToggles.GetEnumerator())
 226        {
 4635227            while (iterator.MoveNext())
 228            {
 2822229                iterator.Current.Value.selected = false;
 230            }
 1813231        }
 1813232    }
 233
 0234    private void ToggleClicked(ItemToggle toggle) { OnItemClicked?.Invoke(toggle.wearableItem.id); }
 235
 0236    private void SellClicked(ItemToggle toggle) { OnSellClicked?.Invoke(toggle.wearableItem.id); }
 237
 238    private ItemToggle GetItemToggleByID(string itemID)
 239    {
 6278240        if (string.IsNullOrEmpty(itemID))
 0241            return null;
 6278242        return itemToggles.ContainsKey(itemID) ? itemToggles[itemID] : null;
 243    }
 244}