< Summary

Class:ChatHeadGroupView
Assembly:TaskbarHUD
File(s):/tmp/workspace/unity-renderer/unity-renderer/Assets/Scripts/MainScripts/DCL/Controllers/HUD/TaskbarHUD/ChatHeadGroupView.cs
Covered lines:66
Uncovered lines:73
Coverable lines:139
Total lines:301
Line coverage:47.4% (66 of 139)
Covered branches:0
Total branches:0

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity NPath complexity Sequence coverage
ChatHeadGroupView()0%110100%
Initialize(...)0%330100%
Start()0%110100%
Update()0%2100%
FriendsController_OnUpdateFriendship(...)0%6200%
FriendsController_OnUpdateUserStatus(...)0%6200%
FriendsController_OnInitialized()0%2100%
RendererState_OnChange(...)0%2100%
OnDestroy()0%330100%
ChatController_OnAddMessage(...)0%7.997072.73%
OnToggleOn(...)0%220100%
OnToggleOff(...)0%3.143075%
SortChatHeads()0%330100%
AddChatHead(...)0%15.8811065.71%
ClearChatHeads()0%6200%
RemoveChatHead(...)0%2100%
RemoveChatHead(...)0%20400%
Animator_OnWillFinishHide(...)0%2100%
SaveLatestOpenChats()0%110100%
LoadLatestOpenChats()0%20400%
DestroyChatHead(...)0%12300%
SetParentContainerAsDirty()0%110100%

File(s)

/tmp/workspace/unity-renderer/unity-renderer/Assets/Scripts/MainScripts/DCL/Controllers/HUD/TaskbarHUD/ChatHeadGroupView.cs

#LineLine coverage
 1using Newtonsoft.Json;
 2using System.Collections.Generic;
 3using System.Linq;
 4using DCL.Helpers;
 5using UnityEngine;
 6
 7public class ChatHeadGroupView : MonoBehaviour
 8{
 9    const int MAX_GROUP_SIZE = 5;
 10    const string CHAT_HEAD_PATH = "ChatHead";
 11    const string PLAYER_PREFS_LATEST_OPEN_CHATS = "LatestOpenChats";
 12
 13    public event System.Action<TaskbarButton> OnHeadToggleOn;
 14    public event System.Action<TaskbarButton> OnHeadToggleOff;
 15
 16    public Transform container;
 17
 18    [System.NonSerialized]
 519    public List<ChatHeadButton> chatHeads = new List<ChatHeadButton>();
 20
 21    private IChatController chatController;
 22    private IFriendsController friendsController;
 23    private ulong rendererStateTimeMark;
 24    private RectTransform contentParentRT;
 25
 26    public void Initialize(IChatController chatController, IFriendsController friendsController)
 27    {
 428        this.chatController = chatController;
 429        this.friendsController = friendsController;
 30
 431        if (chatController != null)
 332            chatController.OnAddMessage += ChatController_OnAddMessage;
 33
 434        if (friendsController != null)
 35        {
 136            friendsController.OnUpdateFriendship += FriendsController_OnUpdateFriendship;
 137            friendsController.OnUpdateUserStatus += FriendsController_OnUpdateUserStatus;
 138            friendsController.OnInitialized += FriendsController_OnInitialized;
 39        }
 40
 441        CommonScriptableObjects.rendererState.OnChange -= RendererState_OnChange;
 442        CommonScriptableObjects.rendererState.OnChange += RendererState_OnChange;
 443    }
 44
 45    private void Start()
 46    {
 447        contentParentRT = container.parent as RectTransform;
 448        gameObject.SetActive(false);
 449    }
 50
 51    private void Update()
 52    {
 53        // NOTE: Update is only enabled when SetParentContainerAsDirty is called
 054        DCL.Helpers.Utils.ForceUpdateLayout(contentParentRT, delayed: true);
 055        this.enabled = false;
 056    }
 57
 58    private void FriendsController_OnUpdateFriendship(string id, FriendshipAction action)
 59    {
 060        if (action != FriendshipAction.NONE)
 061            return;
 62
 063        RemoveChatHead(id);
 064    }
 65
 66    private void FriendsController_OnUpdateUserStatus(string userId, FriendsController.UserStatus userStatus)
 67    {
 068        ChatHeadButton updatedChatHead = chatHeads.FirstOrDefault(ch => ch.profile.userId == userId);
 069        if (updatedChatHead != null)
 070            updatedChatHead.SetOnlineStatus(userStatus.presence == PresenceStatus.ONLINE);
 071    }
 72
 73    private void FriendsController_OnInitialized()
 74    {
 75        // Load the chat heads from local storage just after FriendsController has been initialized
 076        LoadLatestOpenChats();
 077        friendsController.OnInitialized -= FriendsController_OnInitialized;
 078    }
 79
 80    private void RendererState_OnChange(bool current, bool previous)
 81    {
 082        rendererStateTimeMark = (ulong) System.DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
 083        CommonScriptableObjects.rendererState.OnChange -= RendererState_OnChange;
 084    }
 85
 86    private void OnDestroy()
 87    {
 488        if (chatController != null)
 389            chatController.OnAddMessage -= ChatController_OnAddMessage;
 90
 491        if (friendsController != null)
 92        {
 193            friendsController.OnUpdateFriendship -= FriendsController_OnUpdateFriendship;
 194            friendsController.OnUpdateUserStatus -= FriendsController_OnUpdateUserStatus;
 195            friendsController.OnInitialized -= FriendsController_OnInitialized;
 96        }
 97
 498        CommonScriptableObjects.rendererState.OnChange -= RendererState_OnChange;
 499    }
 100
 101    private void ChatController_OnAddMessage(DCL.Interface.ChatMessage obj)
 102    {
 1103        if (!CommonScriptableObjects.rendererState.Get() ||
 104            obj.messageType != DCL.Interface.ChatMessage.Type.PRIVATE ||
 105            obj.timestamp < rendererStateTimeMark)
 0106            return;
 107
 1108        var ownProfile = UserProfile.GetOwnUserProfile();
 109
 1110        string userId = string.Empty;
 111
 1112        if (obj.sender != ownProfile.userId)
 1113            userId = obj.sender;
 0114        else if (obj.recipient != ownProfile.userId)
 0115            userId = obj.recipient;
 116
 1117        if (!string.IsNullOrEmpty(userId))
 118        {
 1119            AddChatHead(userId, obj.timestamp);
 120        }
 1121    }
 122
 2123    private void OnToggleOn(TaskbarButton head) { OnHeadToggleOn?.Invoke(head); }
 124
 125    private void OnToggleOff(TaskbarButton head)
 126    {
 1127        if (!(head is ChatHeadButton))
 0128            return;
 129
 1130        OnHeadToggleOff?.Invoke(head);
 1131    }
 132
 133    private void SortChatHeads()
 134    {
 2135        chatHeads = chatHeads.OrderByDescending((x) => x.lastTimestamp).ToList();
 136
 4137        for (int i = 0; i < chatHeads.Count; i++)
 138        {
 1139            chatHeads[i].transform.SetSiblingIndex(i);
 140        }
 1141    }
 142
 143    internal ChatHeadButton AddChatHead(string userId, ulong timestamp, bool saveStatusInStorage = true, bool forceLayou
 144    {
 1145        var existingHead = chatHeads.FirstOrDefault(x => x.profile.userId == userId);
 146
 1147        if (existingHead != null)
 148        {
 0149            existingHead.lastTimestamp = timestamp;
 0150            SortChatHeads();
 151
 0152            if (saveStatusInStorage)
 153            {
 0154                LatestOpenChatsList.Model existingHeadInStorage = CommonScriptableObjects.latestOpenChats.GetList().Firs
 0155                if (existingHeadInStorage != null)
 156                {
 0157                    existingHeadInStorage.lastTimestamp = timestamp;
 0158                    SaveLatestOpenChats();
 159                }
 160            }
 161
 0162            return existingHead;
 163        }
 164
 1165        if (!gameObject.activeSelf)
 166        {
 0167            gameObject.SetActive(true);
 168        }
 169
 1170        GameObject prefab = Resources.Load(CHAT_HEAD_PATH) as GameObject;
 1171        GameObject instance = Instantiate(prefab, container);
 1172        ChatHeadButton chatHead = instance.GetComponent<ChatHeadButton>();
 173
 1174        chatHead.Initialize(UserProfileController.userProfilesCatalog.Get(userId));
 1175        chatHead.lastTimestamp = timestamp;
 1176        chatHead.OnToggleOn += OnToggleOn;
 1177        chatHead.OnToggleOff += OnToggleOff;
 178
 1179        if (friendsController != null &&
 180            friendsController.GetFriends().TryGetValue(userId, out FriendsController.UserStatus friendStatus))
 181        {
 0182            chatHead.SetOnlineStatus(friendStatus.presence == PresenceStatus.ONLINE);
 183        }
 184
 1185        var animator = chatHead.GetComponent<ShowHideAnimator>();
 186
 1187        if (animator != null)
 1188            animator.Show();
 189
 1190        chatHeads.Add(chatHead);
 1191        SortChatHeads();
 192
 1193        if (saveStatusInStorage)
 194        {
 1195            CommonScriptableObjects.latestOpenChats.Add(new LatestOpenChatsList.Model { userId = userId, lastTimestamp =
 1196            SaveLatestOpenChats();
 197        }
 198
 1199        if (chatHeads.Count > MAX_GROUP_SIZE)
 200        {
 0201            var lastChatHead = chatHeads[chatHeads.Count - 1];
 0202            RemoveChatHead(lastChatHead, saveStatusInStorage, forceLayoutUpdate: false);
 203        }
 204
 1205        if (forceLayoutUpdate)
 206        {
 1207            SetParentContainerAsDirty();
 208        }
 209
 1210        return chatHead;
 211    }
 212
 213    internal void ClearChatHeads()
 214    {
 0215        var chatHeadsToRemove = chatHeads.ToArray();
 216
 0217        for (int i = 0; i < chatHeadsToRemove.Length; i++)
 218        {
 0219            RemoveChatHead(chatHeadsToRemove[i], forceLayoutUpdate: false);
 220        }
 221
 0222        SetParentContainerAsDirty();
 0223    }
 224
 0225    internal void RemoveChatHead(string userId, bool forceLayoutUpdate = true) { RemoveChatHead(chatHeads.FirstOrDefault
 226
 227    internal void RemoveChatHead(ChatHeadButton chatHead, bool saveStatusInStorage = true, bool forceLayoutUpdate = true
 228    {
 0229        if (chatHead == null)
 0230            return;
 231
 0232        var animator = chatHead.GetComponent<ShowHideAnimator>();
 233
 0234        if (animator != null)
 235        {
 0236            animator.OnWillFinishHide -= Animator_OnWillFinishHide;
 0237            animator.OnWillFinishHide += Animator_OnWillFinishHide;
 0238            animator.Hide();
 0239        }
 240        else
 241        {
 0242            DestroyChatHead(chatHead.gameObject, forceLayoutUpdate);
 243        }
 244
 0245        chatHeads.Remove(chatHead);
 246
 0247        if (saveStatusInStorage)
 248        {
 0249            LatestOpenChatsList.Model chatHeadToRemove = CommonScriptableObjects.latestOpenChats.GetList().FirstOrDefaul
 0250            CommonScriptableObjects.latestOpenChats.Remove(chatHeadToRemove);
 0251            SaveLatestOpenChats();
 252        }
 0253    }
 254
 255    private void Animator_OnWillFinishHide(ShowHideAnimator animator)
 256    {
 0257        animator.OnWillFinishHide -= Animator_OnWillFinishHide;
 0258        DestroyChatHead(animator.gameObject, true);
 0259    }
 260
 261    private void SaveLatestOpenChats()
 262    {
 1263        PlayerPrefsUtils.SetString(PLAYER_PREFS_LATEST_OPEN_CHATS, JsonConvert.SerializeObject(CommonScriptableObjects.l
 1264        PlayerPrefsUtils.Save();
 1265    }
 266
 267    private void LoadLatestOpenChats()
 268    {
 0269        CommonScriptableObjects.latestOpenChats.Clear();
 0270        List<LatestOpenChatsList.Model> latestOpenChatsFromStorage = JsonConvert.DeserializeObject<List<LatestOpenChatsL
 0271        if (latestOpenChatsFromStorage != null)
 272        {
 0273            foreach (LatestOpenChatsList.Model item in latestOpenChatsFromStorage)
 274            {
 0275                if (UserProfileController.userProfilesCatalog.Get(item.userId) == null)
 276                    continue;
 277
 0278                CommonScriptableObjects.latestOpenChats.Add(item);
 0279                AddChatHead(item.userId, item.lastTimestamp, false, forceLayoutUpdate: false);
 280            }
 281
 0282            SetParentContainerAsDirty();
 283        }
 0284    }
 285
 286    private void DestroyChatHead(GameObject chatHeadGO, bool forceLayoutUpdate)
 287    {
 0288        Destroy(chatHeadGO);
 289
 0290        if (container.childCount <= 1)
 291        {
 0292            gameObject.SetActive(false);
 0293        }
 0294        else if (forceLayoutUpdate)
 295        {
 0296            SetParentContainerAsDirty();
 297        }
 0298    }
 299
 2300    private void SetParentContainerAsDirty() { this.enabled = true; }
 301}