< Summary

Class:DCL.EmotesCustomization.EmotesCustomizationComponentController
Assembly:AvatarEditorHUD
File(s):/tmp/workspace/unity-renderer/unity-renderer/Assets/Scripts/MainScripts/DCL/Controllers/HUD/AvatarEditorHUD/Scripts/EmotesCustomization/EmotesCustomizationComponentController.cs
Covered lines:154
Uncovered lines:36
Coverable lines:190
Total lines:406
Line coverage:81% (154 of 190)
Covered branches:0
Total branches:0

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity NPath complexity Sequence coverage
EmotesCustomizationComponentController()0%110100%
Initialize(...)0%110100%
RestoreEmoteSlots()0%110100%
Dispose()0%110100%
OnEquippedEmotesSet(...)0%550100%
ConfigureView()0%110100%
IsStarMenuOpenChanged(...)0%110100%
OnAvatarEditorVisibleChanged(...)0%110100%
ProcessCatalog()0%330100%
AddEmote(...)0%7.147085.71%
RemoveEmote(...)0%110100%
OnAnimationAdded(...)0%110100%
RefreshEmoteLoadingState(...)0%330100%
ParseWearableItemIntoEmoteCardModel(...)0%110100%
ConfigureUserProfileAndCatalog(...)0%110100%
OnUserProfileUpdated(...)0%220100%
OnUserProfileInventorySet(...)0%110100%
UpdateEmoteSlots()0%770100%
StoreEquippedEmotes()0%6.744044.44%
OnEmoteEquipped(...)0%330100%
OnEmoteUnequipped(...)0%220100%
OnSellEmoteClicked(...)0%220100%
OnSlotSelected(...)0%220100%
ConfigureShortcuts()0%110100%
OnEquipInputActionTriggered(...)0%14.115028.57%
OnShowInfoInputActionTriggered(...)0%42600%
OnNumericShortcutInputActionTriggered(...)0%2101400%
CreateView()0%110100%

File(s)

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

#LineLine coverage
 1using System;
 2using System.Collections.Generic;
 3using System.Linq;
 4using UnityEngine;
 5
 6namespace DCL.EmotesCustomization
 7{
 8    public class EmotesCustomizationComponentController : IEmotesCustomizationComponentController
 9    {
 10        internal const int NUMBER_OF_SLOTS = 10;
 11
 4812        internal bool isEmotesCustomizationSectionOpen => exploreV2DataStore.isOpen.Get() && view.isActive;
 13
 14        internal IEmotesCustomizationComponentView view;
 15        internal InputAction_Hold equipInputAction;
 16        internal InputAction_Hold showInfoInputAction;
 17        internal InputAction_Trigger shortcut0InputAction;
 18        internal InputAction_Trigger shortcut1InputAction;
 19        internal InputAction_Trigger shortcut2InputAction;
 20        internal InputAction_Trigger shortcut3InputAction;
 21        internal InputAction_Trigger shortcut4InputAction;
 22        internal InputAction_Trigger shortcut5InputAction;
 23        internal InputAction_Trigger shortcut6InputAction;
 24        internal InputAction_Trigger shortcut7InputAction;
 25        internal InputAction_Trigger shortcut8InputAction;
 26        internal InputAction_Trigger shortcut9InputAction;
 27        internal readonly DataStore dataStore;
 28        internal UserProfile userProfile;
 29        internal BaseDictionary<string, WearableItem> catalog;
 6330        internal BaseDictionary<string, EmoteCardComponentView> emotesInLoadingState = new BaseDictionary<string, EmoteC
 31
 32        internal DataStore_EmotesCustomization emotesCustomizationDataStore;
 33        internal DataStore_Emotes emotesDataStore;
 34        internal DataStore_ExploreV2 exploreV2DataStore;
 35        internal DataStore_HUDs hudsDataStore;
 36
 37        public event Action<string> onEmotePreviewed;
 38        public event Action<string> onEmoteEquipped;
 39        public event Action<string> onEmoteUnequipped;
 40        public event Action<string> onEmoteSell;
 41
 42        public IEmotesCustomizationComponentView Initialize(
 43            DataStore_EmotesCustomization emotesCustomizationDataStore,
 44            DataStore_Emotes emotesDataStore,
 45            DataStore_ExploreV2 exploreV2DataStore,
 46            DataStore_HUDs hudsDataStore,
 47            UserProfile userProfile,
 48            BaseDictionary<string, WearableItem> catalog)
 49        {
 6350            this.emotesCustomizationDataStore = emotesCustomizationDataStore;
 6351            this.emotesDataStore = emotesDataStore;
 6352            this.exploreV2DataStore = exploreV2DataStore;
 6353            this.hudsDataStore = hudsDataStore;
 54
 6355            IEmotesCustomizationComponentView view = ConfigureView();
 6356            ConfigureUserProfileAndCatalog(userProfile, catalog);
 6357            ConfigureShortcuts();
 58
 6359            emotesCustomizationDataStore.equippedEmotes.OnSet += OnEquippedEmotesSet;
 6360            OnEquippedEmotesSet(emotesCustomizationDataStore.equippedEmotes.Get());
 61
 6362            return view;
 63        }
 64
 65        public void RestoreEmoteSlots()
 66        {
 167            emotesCustomizationDataStore.unsavedEquippedEmotes.Set(emotesCustomizationDataStore.equippedEmotes.Get());
 168            UpdateEmoteSlots();
 169        }
 70
 71        public void Dispose()
 72        {
 1573            view.onEmoteEquipped -= OnEmoteEquipped;
 1574            view.onEmoteUnequipped -= OnEmoteUnequipped;
 1575            view.onSellEmoteClicked -= OnSellEmoteClicked;
 1576            view.onSlotSelected -= OnSlotSelected;
 1577            exploreV2DataStore.isOpen.OnChange -= IsStarMenuOpenChanged;
 1578            hudsDataStore.avatarEditorVisible.OnChange -= OnAvatarEditorVisibleChanged;
 1579            emotesCustomizationDataStore.equippedEmotes.OnSet -= OnEquippedEmotesSet;
 1580            catalog.OnAdded -= AddEmote;
 1581            catalog.OnRemoved -= RemoveEmote;
 1582            emotesDataStore.animations.OnAdded -= OnAnimationAdded;
 1583            userProfile.OnInventorySet -= OnUserProfileInventorySet;
 1584            userProfile.OnUpdate -= OnUserProfileUpdated;
 1585            equipInputAction.OnFinished -= OnEquipInputActionTriggered;
 1586            showInfoInputAction.OnFinished -= OnShowInfoInputActionTriggered;
 1587            shortcut0InputAction.OnTriggered -= OnNumericShortcutInputActionTriggered;
 1588            shortcut1InputAction.OnTriggered -= OnNumericShortcutInputActionTriggered;
 1589            shortcut2InputAction.OnTriggered -= OnNumericShortcutInputActionTriggered;
 1590            shortcut3InputAction.OnTriggered -= OnNumericShortcutInputActionTriggered;
 1591            shortcut4InputAction.OnTriggered -= OnNumericShortcutInputActionTriggered;
 1592            shortcut5InputAction.OnTriggered -= OnNumericShortcutInputActionTriggered;
 1593            shortcut6InputAction.OnTriggered -= OnNumericShortcutInputActionTriggered;
 1594            shortcut7InputAction.OnTriggered -= OnNumericShortcutInputActionTriggered;
 1595            shortcut8InputAction.OnTriggered -= OnNumericShortcutInputActionTriggered;
 1596            shortcut9InputAction.OnTriggered -= OnNumericShortcutInputActionTriggered;
 1597        }
 98
 99        internal void OnEquippedEmotesSet(IEnumerable<EquippedEmoteData> equippedEmotes)
 100        {
 1420101            foreach (EquippedEmoteData equippedEmote in equippedEmotes)
 102            {
 644103                if (equippedEmote == null || string.IsNullOrEmpty(equippedEmote.id))
 104                    continue;
 105
 106                // TODO: We should avoid static calls and create injectable interfaces
 4107                CatalogController.RequestWearable(equippedEmote.id);
 108            }
 109
 66110            emotesCustomizationDataStore.unsavedEquippedEmotes.Set(equippedEmotes);
 66111            UpdateEmoteSlots();
 66112        }
 113
 114        internal IEmotesCustomizationComponentView ConfigureView()
 115        {
 63116            view = CreateView();
 63117            view.onEmoteEquipped += OnEmoteEquipped;
 63118            view.onEmoteUnequipped += OnEmoteUnequipped;
 63119            view.onSellEmoteClicked += OnSellEmoteClicked;
 63120            view.onSlotSelected += OnSlotSelected;
 63121            exploreV2DataStore.isOpen.OnChange += IsStarMenuOpenChanged;
 63122            hudsDataStore.avatarEditorVisible.OnChange += OnAvatarEditorVisibleChanged;
 123
 63124            return view;
 125        }
 126
 2127        internal void IsStarMenuOpenChanged(bool currentIsOpen, bool previousIsOpen) { view.SetEmoteInfoPanelActive(fals
 128
 92129        internal void OnAvatarEditorVisibleChanged(bool current, bool previous) { view.SetActive(current); }
 130
 131        internal void ProcessCatalog()
 132        {
 155133            emotesCustomizationDataStore.currentLoadedEmotes.Set(new List<string>());
 155134            view.CleanEmotes();
 135
 155136            using (var iterator = catalog.Get().GetEnumerator())
 137            {
 5125138                while (iterator.MoveNext())
 139                {
 4970140                    AddEmote(iterator.Current.Key, iterator.Current.Value);
 141                }
 155142            }
 155143        }
 144
 145        internal void AddEmote(string id, WearableItem wearable)
 146        {
 4974147            if (!wearable.IsEmote() || emotesCustomizationDataStore.currentLoadedEmotes.Contains(id))
 4968148                return;
 149
 6150            if (!wearable.data.tags.Contains(WearableLiterals.Tags.BASE_WEARABLE) && userProfile.GetItemAmount(id) == 0)
 0151                return;
 152
 6153            emotesCustomizationDataStore.currentLoadedEmotes.Add(id);
 6154            EmoteCardComponentModel emoteToAdd = ParseWearableItemIntoEmoteCardModel(wearable);
 6155            EmoteCardComponentView newEmote = view.AddEmote(emoteToAdd);
 156
 6157            if (newEmote != null)
 0158                newEmote.SetAsLoading(true);
 159
 6160            if (!emotesInLoadingState.ContainsKey(id))
 4161                emotesInLoadingState.Add(id, newEmote);
 162
 6163            RefreshEmoteLoadingState(id);
 164
 6165            UpdateEmoteSlots();
 6166        }
 167
 168        internal void RemoveEmote(string id, WearableItem wearable)
 169        {
 1170            emotesCustomizationDataStore.currentLoadedEmotes.Remove(id);
 1171            view.RemoveEmote(id);
 1172            UpdateEmoteSlots();
 1173        }
 174
 2175        internal void OnAnimationAdded((string bodyshapeId, string emoteId) values, AnimationClip animationClip) { Refre
 176
 177        internal void RefreshEmoteLoadingState(string emoteId)
 178        {
 8179            if (emotesDataStore.animations.ContainsKey((userProfile.avatar.bodyShape, emoteId)))
 180            {
 2181                emotesInLoadingState.TryGetValue(emoteId, out EmoteCardComponentView emote);
 2182                if (emote != null)
 183                {
 1184                    emote.SetAsLoading(false);
 1185                    emotesInLoadingState.Remove(emoteId);
 186                }
 187            }
 8188        }
 189
 190        internal EmoteCardComponentModel ParseWearableItemIntoEmoteCardModel(WearableItem wearable)
 191        {
 7192            return new EmoteCardComponentModel
 193            {
 194                id = wearable.id,
 195                name = wearable.GetName(),
 196                description = wearable.description,
 197                pictureUri = wearable.ComposeThumbnailUrl(),
 198                pictureSprite = wearable.thumbnailSprite,
 199                isAssignedInSelectedSlot = false,
 200                isSelected = false,
 201                assignedSlot = -1,
 202                rarity = wearable.rarity,
 203                isInL2 = wearable.IsInL2(),
 204                isLoading = false,
 205                isCollectible = wearable.IsCollectible()
 206            };
 207        }
 208
 209        internal void ConfigureUserProfileAndCatalog(UserProfile userProfile, BaseDictionary<string, WearableItem> catal
 210        {
 63211            this.userProfile = userProfile;
 63212            this.catalog = catalog;
 213
 63214            this.userProfile.OnInventorySet += OnUserProfileInventorySet;
 63215            this.userProfile.OnUpdate += OnUserProfileUpdated;
 216
 63217            OnUserProfileUpdated(this.userProfile);
 63218        }
 219
 220        internal void OnUserProfileUpdated(UserProfile userProfile)
 221        {
 261222            if (string.IsNullOrEmpty(userProfile.userId))
 245223                return;
 224
 16225            this.userProfile.OnUpdate -= OnUserProfileUpdated;
 16226            catalog.OnAdded += AddEmote;
 16227            catalog.OnRemoved += RemoveEmote;
 16228            emotesDataStore.animations.OnAdded += OnAnimationAdded;
 229
 16230            ProcessCatalog();
 16231        }
 232
 276233        internal void OnUserProfileInventorySet(Dictionary<string, int> inventory) { ProcessCatalog(); }
 234
 235        internal void UpdateEmoteSlots()
 236        {
 1586237            for (int i = 0; i < emotesCustomizationDataStore.unsavedEquippedEmotes.Count(); i++)
 238            {
 718239                if (i > NUMBER_OF_SLOTS)
 240                    break;
 241
 718242                if (emotesCustomizationDataStore.unsavedEquippedEmotes[i] == null)
 243                {
 710244                    EmoteSlotCardComponentView existingEmoteIntoSlot = view.GetSlot(i);
 710245                    if (existingEmoteIntoSlot != null)
 490246                        view.UnequipEmote(existingEmoteIntoSlot.model.emoteId, i, false);
 247
 490248                    continue;
 249                }
 250
 8251                catalog.TryGetValue(emotesCustomizationDataStore.unsavedEquippedEmotes[i].id, out WearableItem emoteItem
 8252                if (emoteItem != null && emotesCustomizationDataStore.currentLoadedEmotes.Contains(emoteItem.id))
 2253                    view.EquipEmote(emoteItem.id, emoteItem.GetName(), i, false, false);
 254            }
 75255        }
 256
 257        internal void StoreEquippedEmotes()
 258        {
 2259            List<EquippedEmoteData> newEquippedEmotesList = new List<EquippedEmoteData> { null, null, null, null, null, 
 260
 2261            if (view.currentSlots != null)
 262            {
 0263                foreach (EmoteSlotCardComponentView slot in view.currentSlots)
 264                {
 0265                    if (!string.IsNullOrEmpty(slot.model.emoteId))
 0266                        newEquippedEmotesList[slot.model.slotNumber] = new EquippedEmoteData
 267                        {
 268                            id = slot.model.emoteId,
 269                            cachedThumbnail = slot.model.pictureSprite
 270                        };
 271                }
 272            }
 273
 2274            emotesCustomizationDataStore.unsavedEquippedEmotes.Set(newEquippedEmotesList);
 2275        }
 276
 277        internal void OnEmoteEquipped(string emoteId, int slotNumber)
 278        {
 1279            StoreEquippedEmotes();
 1280            onEmotePreviewed?.Invoke(emoteId);
 1281            onEmoteEquipped?.Invoke(emoteId);
 1282        }
 283
 284        internal void OnEmoteUnequipped(string emoteId, int slotNumber)
 285        {
 1286            StoreEquippedEmotes();
 1287            onEmoteUnequipped?.Invoke(emoteId);
 1288        }
 289
 2290        internal void OnSellEmoteClicked(string emoteId) { onEmoteSell?.Invoke(emoteId); }
 291
 2292        internal void OnSlotSelected(string emoteId, int slotNumber) { onEmotePreviewed?.Invoke(emoteId); }
 293
 294        internal void ConfigureShortcuts()
 295        {
 63296            equipInputAction = Resources.Load<InputAction_Hold>("DefaultConfirmAction");
 63297            equipInputAction.OnFinished += OnEquipInputActionTriggered;
 298
 63299            showInfoInputAction = Resources.Load<InputAction_Hold>("ZoomIn");
 63300            showInfoInputAction.OnFinished += OnShowInfoInputActionTriggered;
 301
 63302            shortcut0InputAction = Resources.Load<InputAction_Trigger>("ToggleShortcut0");
 63303            shortcut0InputAction.OnTriggered += OnNumericShortcutInputActionTriggered;
 304
 63305            shortcut1InputAction = Resources.Load<InputAction_Trigger>("ToggleShortcut1");
 63306            shortcut1InputAction.OnTriggered += OnNumericShortcutInputActionTriggered;
 307
 63308            shortcut2InputAction = Resources.Load<InputAction_Trigger>("ToggleShortcut2");
 63309            shortcut2InputAction.OnTriggered += OnNumericShortcutInputActionTriggered;
 310
 63311            shortcut3InputAction = Resources.Load<InputAction_Trigger>("ToggleShortcut3");
 63312            shortcut3InputAction.OnTriggered += OnNumericShortcutInputActionTriggered;
 313
 63314            shortcut4InputAction = Resources.Load<InputAction_Trigger>("ToggleShortcut4");
 63315            shortcut4InputAction.OnTriggered += OnNumericShortcutInputActionTriggered;
 316
 63317            shortcut5InputAction = Resources.Load<InputAction_Trigger>("ToggleShortcut5");
 63318            shortcut5InputAction.OnTriggered += OnNumericShortcutInputActionTriggered;
 319
 63320            shortcut6InputAction = Resources.Load<InputAction_Trigger>("ToggleShortcut6");
 63321            shortcut6InputAction.OnTriggered += OnNumericShortcutInputActionTriggered;
 322
 63323            shortcut7InputAction = Resources.Load<InputAction_Trigger>("ToggleShortcut7");
 63324            shortcut7InputAction.OnTriggered += OnNumericShortcutInputActionTriggered;
 325
 63326            shortcut8InputAction = Resources.Load<InputAction_Trigger>("ToggleShortcut8");
 63327            shortcut8InputAction.OnTriggered += OnNumericShortcutInputActionTriggered;
 328
 63329            shortcut9InputAction = Resources.Load<InputAction_Trigger>("ToggleShortcut9");
 63330            shortcut9InputAction.OnTriggered += OnNumericShortcutInputActionTriggered;
 63331        }
 332
 333        internal void OnEquipInputActionTriggered(DCLAction_Hold action)
 334        {
 48335            if (!isEmotesCustomizationSectionOpen || view.selectedCard == null || view.selectedCard.model.isLoading)
 48336                return;
 337
 0338            if (!view.selectedCard.model.isAssignedInSelectedSlot)
 339            {
 0340                view.EquipEmote(
 341                    view.selectedCard.model.id,
 342                    view.selectedCard.model.name,
 343                    view.selectedSlot);
 0344            }
 345            else
 346            {
 0347                view.UnequipEmote(
 348                    view.selectedCard.model.id,
 349                    view.selectedSlot);
 350            }
 0351        }
 352
 353        internal void OnShowInfoInputActionTriggered(DCLAction_Hold action)
 354        {
 0355            if (!isEmotesCustomizationSectionOpen || view.selectedCard == null || !view.selectedCard.model.isCollectible
 0356                return;
 357
 0358            view.OpenEmoteInfoPanel(
 359                view.selectedCard.model,
 360                view.selectedCard.rarityMark.gameObject.activeSelf ? view.selectedCard.rarityMark.color : Color.grey,
 361                view.selectedCard.emoteInfoAnchor);
 0362        }
 363
 364        internal void OnNumericShortcutInputActionTriggered(DCLAction_Trigger action)
 365        {
 0366            if (!isEmotesCustomizationSectionOpen || view.selectedCard == null || view.selectedCard.model.isLoading)
 0367                return;
 368
 369            switch (action)
 370            {
 371                case DCLAction_Trigger.ToggleShortcut0:
 0372                    view.EquipEmote(view.selectedCard.model.id, view.selectedCard.model.name, 0);
 0373                    break;
 374                case DCLAction_Trigger.ToggleShortcut1:
 0375                    view.EquipEmote(view.selectedCard.model.id, view.selectedCard.model.name, 1);
 0376                    break;
 377                case DCLAction_Trigger.ToggleShortcut2:
 0378                    view.EquipEmote(view.selectedCard.model.id, view.selectedCard.model.name, 2);
 0379                    break;
 380                case DCLAction_Trigger.ToggleShortcut3:
 0381                    view.EquipEmote(view.selectedCard.model.id, view.selectedCard.model.name, 3);
 0382                    break;
 383                case DCLAction_Trigger.ToggleShortcut4:
 0384                    view.EquipEmote(view.selectedCard.model.id, view.selectedCard.model.name, 4);
 0385                    break;
 386                case DCLAction_Trigger.ToggleShortcut5:
 0387                    view.EquipEmote(view.selectedCard.model.id, view.selectedCard.model.name, 5);
 0388                    break;
 389                case DCLAction_Trigger.ToggleShortcut6:
 0390                    view.EquipEmote(view.selectedCard.model.id, view.selectedCard.model.name, 6);
 0391                    break;
 392                case DCLAction_Trigger.ToggleShortcut7:
 0393                    view.EquipEmote(view.selectedCard.model.id, view.selectedCard.model.name, 7);
 0394                    break;
 395                case DCLAction_Trigger.ToggleShortcut8:
 0396                    view.EquipEmote(view.selectedCard.model.id, view.selectedCard.model.name, 8);
 0397                    break;
 398                case DCLAction_Trigger.ToggleShortcut9:
 0399                    view.EquipEmote(view.selectedCard.model.id, view.selectedCard.model.name, 9);
 400                    break;
 401            }
 0402        }
 403
 48404        internal virtual IEmotesCustomizationComponentView CreateView() => EmotesCustomizationComponentView.Create();
 405    }
 406}