< 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:92
Uncovered lines:24
Coverable lines:116
Total lines:246
Line coverage:79.3% (92 of 116)
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%5.275077.78%
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            {
 2815116                WearableSettings wearableSettings = availableWearables[wearableIndex];
 2815117                var item = wearableSettings.Item;
 2815118                var itemToggle = itemToggleContainer.LoadItem(itemToggleIndex, wearableSettings);
 2815119                itemToggle.SetCallbacks(ToggleClicked, SellClicked);
 2815120                itemToggle.SetLoadingSpinner(wearableSettings.isLoading);
 121
 2815122                if (selectedItems.Contains(item.id))
 417123                    itemToggle.selected = true;
 124
 2815125                itemToggles[item.id] = itemToggle;
 2815126            }
 127            else
 128            {
 61841129                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    {
 4242141        if (item == null)
 0142            return;
 143
 4242144        if (totalWearables.ContainsKey(item.id))
 0145            return;
 146
 4242147        WearableSettings wearableSettings = new WearableSettings(item, collectionName, amount, hideOtherWearablesToastSt
 4242148        totalWearables.Add(item.id, wearableSettings);
 149
 4242150        if (item.SupportsBodyShape(currentBodyShape) || item.data.category == WearableLiterals.Categories.BODY_SHAPE)
 151        {
 1306152            availableWearables.Add(wearableSettings);
 153        }
 4242154    }
 155
 156    public void RemoveWearable(string itemID)
 157    {
 0158        if (string.IsNullOrEmpty(itemID))
 0159            return;
 160
 0161        totalWearables.Remove(itemID);
 0162        itemToggles.Remove(itemID);
 163
 0164        RefreshAvailableWearables();
 0165    }
 166
 167    public void RemoveAllWearables()
 168    {
 2718169        totalWearables.Clear();
 2718170        availableWearables.Clear();
 2718171        itemToggles.Clear();
 172
 2718173        UpdateSelectorLayout();
 2718174    }
 175
 176    public void SetBodyShape(string bodyShape)
 177    {
 1054178        if (currentBodyShape == bodyShape)
 0179            return;
 180
 1054181        currentBodyShape = bodyShape;
 1054182        RefreshAvailableWearables();
 1054183    }
 184
 185    public void UpdateSelectorLayout()
 186    {
 5634187        SetupWearablePagination();
 5634188    }
 189
 190    private void RefreshAvailableWearables()
 191    {
 2684192        availableWearables = totalWearables.Values.Where(w => w.Item.SupportsBodyShape(currentBodyShape)).ToList();
 1054193        SetupWearablePagination();
 1054194    }
 195
 196    public void Select(string itemID)
 197    {
 2260198        selectedItems.Add(itemID);
 2260199        ItemToggle toggle = GetItemToggleByID(itemID);
 2260200        if (toggle != null)
 1161201            toggle.selected = true;
 2260202    }
 203
 204    public void SetWearableLoadingSpinner(string wearableID, bool isActive)
 205    {
 3126206        if (totalWearables.ContainsKey(wearableID))
 207        {
 1563208            totalWearables[wearableID].isLoading = isActive;
 209        }
 210
 3126211        ItemToggle toggle = GetItemToggleByID(wearableID);
 3126212        if (toggle != null)
 1538213            toggle.SetLoadingSpinner(isActive);
 3126214    }
 215
 216    public void Unselect(string itemID)
 217    {
 928218        selectedItems.Remove(itemID);
 928219        ItemToggle toggle = GetItemToggleByID(itemID);
 928220        if (toggle != null)
 439221            toggle.selected = false;
 928222    }
 223
 224    public void UnselectAll()
 225    {
 1830226        selectedItems.Clear();
 1830227        using (var iterator = itemToggles.GetEnumerator())
 228        {
 3760229            while (iterator.MoveNext())
 230            {
 1930231                iterator.Current.Value.selected = false;
 232            }
 1830233        }
 1830234    }
 235
 0236    private void ToggleClicked(ItemToggle toggle) { OnItemClicked?.Invoke(toggle.wearableItem.id); }
 237
 0238    private void SellClicked(ItemToggle toggle) { OnSellClicked?.Invoke(toggle.wearableItem.id); }
 239
 240    private ItemToggle GetItemToggleByID(string itemID)
 241    {
 6314242        if (string.IsNullOrEmpty(itemID))
 0243            return null;
 6314244        return itemToggles.ContainsKey(itemID) ? itemToggles[itemID] : null;
 245    }
 246}