| | 1 | | using DCLServices.WearablesCatalogService; |
| | 2 | | using System; |
| | 3 | | using System.Collections.Generic; |
| | 4 | | using UIComponents.Scripts.Components; |
| | 5 | | using UnityEngine; |
| | 6 | | using UnityEngine.UI; |
| | 7 | |
|
| | 8 | | namespace DCL.Backpack |
| | 9 | | { |
| | 10 | | public class WearableGridComponentView : MonoBehaviour, IWearableGridView |
| | 11 | | { |
| | 12 | | [SerializeField] internal NftBreadcrumbComponentView wearablesBreadcrumbComponentView; |
| | 13 | | [SerializeField] internal GridContainerComponentView wearablesGridContainer; |
| | 14 | | [SerializeField] internal WearableGridItemComponentView wearableGridItemPrefab; |
| | 15 | | [SerializeField] internal PageSelectorComponentView wearablePageSelector; |
| | 16 | | [SerializeField] internal InfoCardComponentView infoCardComponentView; |
| | 17 | | [SerializeField] internal GameObject emptyStateContainer; |
| | 18 | | [SerializeField] internal GameObject emptyStateContainerForSignUp; |
| | 19 | | [SerializeField] internal Button goToMarketplaceButton; |
| | 20 | | [SerializeField] internal GameObject loadingSpinner; |
| | 21 | |
|
| 37 | 22 | | private readonly Dictionary<WearableGridItemComponentView, PoolableObject> wearablePooledObjects = new (); |
| 37 | 23 | | private readonly Dictionary<string, WearableGridItemComponentView> wearablesById = new (); |
| | 24 | |
|
| | 25 | | private Pool wearableGridItemsPool; |
| | 26 | | private WearableGridItemComponentView selectedWearableItem; |
| | 27 | |
|
| | 28 | | public event Action<int> OnWearablePageChanged; |
| | 29 | | public event Action<string> OnFilterSelected; |
| | 30 | | public event Action<string> OnFilterRemoved; |
| | 31 | | public event Action OnGoToMarketplace; |
| | 32 | | public event Action<WearableGridItemModel> OnWearableSelected; |
| | 33 | | public event Action<WearableGridItemModel, EquipWearableSource> OnWearableEquipped; |
| | 34 | | public event Action<WearableGridItemModel, UnequipWearableSource> OnWearableUnequipped; |
| | 35 | |
|
| | 36 | | private void Awake() |
| | 37 | | { |
| 35 | 38 | | wearablePageSelector.OnValueChanged += i => OnWearablePageChanged?.Invoke(i + 1); |
| | 39 | |
|
| 35 | 40 | | wearableGridItemsPool = PoolManager.i.AddPool( |
| | 41 | | $"GridWearableItems_{GetInstanceID()}", |
| | 42 | | Instantiate(wearableGridItemPrefab).gameObject, |
| | 43 | | maxPrewarmCount: 15, |
| | 44 | | isPersistent: true); |
| | 45 | |
|
| 35 | 46 | | wearableGridItemsPool.ForcePrewarm(); |
| | 47 | |
|
| 35 | 48 | | wearablesBreadcrumbComponentView.OnFilterSelected += reference => OnFilterSelected?.Invoke(reference); |
| 35 | 49 | | wearablesBreadcrumbComponentView.OnFilterRemoved += reference => OnFilterRemoved?.Invoke(reference); |
| | 50 | |
|
| 35 | 51 | | infoCardComponentView.OnEquipWearable += () => OnWearableEquipped?.Invoke(selectedWearableItem.Model, EquipW |
| 35 | 52 | | infoCardComponentView.OnUnEquipWearable += () => OnWearableUnequipped?.Invoke(selectedWearableItem.Model, Un |
| | 53 | |
|
| 35 | 54 | | goToMarketplaceButton.onClick.AddListener(() => OnGoToMarketplace?.Invoke()); |
| 35 | 55 | | } |
| | 56 | |
|
| | 57 | | private void OnEnable() |
| | 58 | | { |
| 36 | 59 | | ClearWearableSelection(); |
| 36 | 60 | | } |
| | 61 | |
|
| | 62 | | public void Dispose() |
| | 63 | | { |
| 18 | 64 | | if (this && gameObject) |
| 18 | 65 | | Destroy(gameObject); |
| 18 | 66 | | } |
| | 67 | |
|
| | 68 | | public void SetWearablePages(int pageNumber, int totalPages) |
| | 69 | | { |
| 4 | 70 | | if (totalPages <= 1) |
| | 71 | | { |
| 1 | 72 | | wearablePageSelector.gameObject.SetActive(false); |
| 1 | 73 | | return; |
| | 74 | | } |
| | 75 | |
|
| 3 | 76 | | wearablePageSelector.gameObject.SetActive(true); |
| 3 | 77 | | wearablePageSelector.Setup(totalPages, true); |
| 3 | 78 | | wearablePageSelector.SelectPage(pageNumber - 1, false); |
| 3 | 79 | | } |
| | 80 | |
|
| | 81 | | public void ShowWearables(IEnumerable<WearableGridItemModel> wearables) |
| | 82 | | { |
| 16 | 83 | | foreach (WearableGridItemModel wearable in wearables) |
| 4 | 84 | | SetWearable(wearable); |
| | 85 | |
|
| 4 | 86 | | UpdateEmptyState(); |
| 4 | 87 | | } |
| | 88 | |
|
| | 89 | | public void ClearWearables() |
| | 90 | | { |
| 4 | 91 | | wearablesGridContainer.ExtractItems(); |
| | 92 | |
|
| 12 | 93 | | foreach ((WearableGridItemComponentView wearableGridItem, PoolableObject poolObj) in wearablePooledObjects) |
| | 94 | | { |
| 2 | 95 | | wearableGridItem.OnSelected -= HandleWearableSelected; |
| 2 | 96 | | wearableGridItem.OnEquipped -= HandleWearableEquipped; |
| 2 | 97 | | wearableGridItem.OnUnequipped -= HandleWearableUnequipped; |
| | 98 | |
|
| 2 | 99 | | poolObj.Release(); |
| | 100 | | } |
| | 101 | |
|
| 4 | 102 | | wearablePooledObjects.Clear(); |
| 4 | 103 | | wearablesById.Clear(); |
| | 104 | |
|
| 4 | 105 | | UpdateEmptyState(); |
| 4 | 106 | | } |
| | 107 | |
|
| | 108 | | public void SetWearable(WearableGridItemModel model) |
| | 109 | | { |
| 10 | 110 | | string shortenedWearableId = ExtendedUrnParser.GetShortenedUrn(model.WearableId); |
| | 111 | |
|
| 10 | 112 | | if (wearablesById.TryGetValue(shortenedWearableId, out var view)) |
| 1 | 113 | | view.SetModel(model); |
| | 114 | | else |
| | 115 | | { |
| 9 | 116 | | PoolableObject poolObj = wearableGridItemsPool.Get(); |
| 9 | 117 | | WearableGridItemComponentView wearableGridItem = poolObj.gameObject.GetComponent<WearableGridItemCompone |
| 9 | 118 | | wearablePooledObjects[wearableGridItem] = poolObj; |
| 9 | 119 | | wearablesById[shortenedWearableId] = wearableGridItem; |
| 9 | 120 | | wearableGridItem.SetModel(model); |
| 9 | 121 | | wearablesGridContainer.AddItem(wearableGridItem); |
| 9 | 122 | | wearableGridItem.OnSelected += HandleWearableSelected; |
| 9 | 123 | | wearableGridItem.OnEquipped += HandleWearableEquipped; |
| 9 | 124 | | wearableGridItem.OnUnequipped += HandleWearableUnequipped; |
| | 125 | | } |
| | 126 | |
|
| 10 | 127 | | if (model.IsEquipped) |
| 3 | 128 | | infoCardComponentView.Equip(model.WearableId); |
| | 129 | | else |
| 7 | 130 | | infoCardComponentView.UnEquip(model.WearableId); |
| | 131 | |
|
| 10 | 132 | | UpdateEmptyState(); |
| 10 | 133 | | } |
| | 134 | |
|
| | 135 | | public void ClearWearableSelection() |
| | 136 | | { |
| 78 | 137 | | foreach (WearableGridItemComponentView view in wearablePooledObjects.Keys) |
| 2 | 138 | | view.Unselect(); |
| | 139 | |
|
| 37 | 140 | | selectedWearableItem = null; |
| 37 | 141 | | SetInfoCardVisible(false); |
| 37 | 142 | | } |
| | 143 | |
|
| | 144 | | public void SelectWearable(string wearableId) |
| | 145 | | { |
| 1 | 146 | | selectedWearableItem = wearablesById[wearableId]; |
| 1 | 147 | | selectedWearableItem.Select(); |
| 1 | 148 | | SetInfoCardVisible(true); |
| 1 | 149 | | } |
| | 150 | |
|
| | 151 | | public void FillInfoCard(InfoCardComponentModel model) => |
| 1 | 152 | | infoCardComponentView.SetModel(model); |
| | 153 | |
|
| | 154 | | public void SetInfoCardVisible(bool isVisible) => |
| 40 | 155 | | infoCardComponentView.SetVisible(isVisible); |
| | 156 | |
|
| | 157 | | public void SetLoadingActive(bool isActive) |
| | 158 | | { |
| 2 | 159 | | loadingSpinner.SetActive(isActive); |
| 2 | 160 | | UpdateEmptyState(); |
| 2 | 161 | | } |
| | 162 | |
|
| | 163 | | public void SetWearableBreadcrumb(NftBreadcrumbModel model) => |
| 1 | 164 | | wearablesBreadcrumbComponentView.SetModel(model); |
| | 165 | |
|
| | 166 | | public void RefreshWearable(string wearableId) |
| | 167 | | { |
| 0 | 168 | | if (!wearablesById.TryGetValue(wearableId, out var view)) |
| 0 | 169 | | return; |
| | 170 | |
|
| 0 | 171 | | view.RefreshControl(); |
| 0 | 172 | | } |
| | 173 | |
|
| | 174 | | public void RefreshAllWearables() |
| | 175 | | { |
| 0 | 176 | | foreach (WearableGridItemComponentView view in wearablePooledObjects.Keys) |
| 0 | 177 | | view.RefreshControl(); |
| 0 | 178 | | } |
| | 179 | |
|
| | 180 | | private void HandleWearableSelected(WearableGridItemModel model) => |
| 0 | 181 | | OnWearableSelected?.Invoke(model); |
| | 182 | |
|
| | 183 | | private void HandleWearableEquipped(WearableGridItemModel model) => |
| 0 | 184 | | OnWearableEquipped?.Invoke(model, EquipWearableSource.Wearable); |
| | 185 | |
|
| | 186 | | private void HandleWearableUnequipped(WearableGridItemModel model) => |
| 0 | 187 | | OnWearableUnequipped?.Invoke(model, UnequipWearableSource.Wearable); |
| | 188 | |
|
| | 189 | | private void UpdateEmptyState() |
| | 190 | | { |
| 20 | 191 | | bool isEmpty = wearablesById.Count == 0; |
| | 192 | |
|
| 20 | 193 | | wearablesGridContainer.gameObject.SetActive(!isEmpty && !loadingSpinner.activeSelf); |
| | 194 | |
|
| 20 | 195 | | emptyStateContainer.SetActive(isEmpty && !loadingSpinner.activeSelf && !DataStore.i.common.isSignUpFlow.Get( |
| 20 | 196 | | emptyStateContainerForSignUp.SetActive(isEmpty && !loadingSpinner.activeSelf && DataStore.i.common.isSignUpF |
| 20 | 197 | | } |
| | 198 | | } |
| | 199 | | } |