< Summary

Class:WorldChatWindowComponentView
Assembly:WorldChatWindowHUD
File(s):/tmp/workspace/unity-renderer/unity-renderer/Assets/Scripts/MainScripts/DCL/Controllers/HUD/WorldChatWindowHUD/WorldChatWindowComponentView.cs
Covered lines:117
Uncovered lines:23
Coverable lines:140
Total lines:303
Line coverage:83.5% (117 of 140)
Covered branches:0
Total branches:0

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity NPath complexity Sequence coverage
WorldChatWindowComponentView()0%110100%
add_OnUnfriend(...)0%2100%
remove_OnUnfriend(...)0%2100%
Create()0%110100%
Awake()0%220100%
OnEnable()0%110100%
Initialize(...)0%110100%
Update()0%330100%
Show()0%110100%
Hide()0%110100%
SetPrivateChat(...)0%110100%
RemovePrivateChat(...)0%110100%
SetPublicChannel(...)0%110100%
Configure(...)0%2100%
ShowPrivateChatsLoading()0%110100%
HidePrivateChatsLoading()0%110100%
RefreshBlockedDirectMessages(...)0%6200%
HideMoreChatsToLoadHint()0%110100%
ShowMoreChatsToLoadHint(...)0%110100%
ClearFilter()0%440100%
Filter(...)0%55095.24%
ContainsPrivateChannel(...)0%6200%
RefreshControl()0%12300%
Set(...)0%440100%
SortLists()0%2100%
ShowMoreChatsToLoadHint()0%110100%
SetPrivateChatLoadingVisibility(...)0%110100%
UpdateHeaders()0%110100%
UpdateLayout()0%2100%
SetQueuedEntries()0%440100%
FetchProfilePicturesForVisibleEntries()0%5.025090%

File(s)

/tmp/workspace/unity-renderer/unity-renderer/Assets/Scripts/MainScripts/DCL/Controllers/HUD/WorldChatWindowHUD/WorldChatWindowComponentView.cs

#LineLine coverage
 1using System;
 2using System.Collections.Generic;
 3using System.Linq;
 4using DCL.Helpers;
 5using TMPro;
 6using UnityEngine;
 7using UnityEngine.UI;
 8
 9public class WorldChatWindowComponentView : BaseComponentView, IWorldChatWindowView, IComponentModelConfig<WorldChatWind
 10{
 11    private const int CREATION_AMOUNT_PER_FRAME = 5;
 12    private const int AVATAR_SNAPSHOTS_PER_FRAME = 5;
 13
 14    [SerializeField] internal CollapsablePublicChannelListComponentView publicChannelList;
 15    [SerializeField] internal CollapsableDirectChatListComponentView directChatList;
 16    [SerializeField] internal CollapsableChatSearchListComponentView searchResultsList;
 17    [SerializeField] internal Button closeButton;
 18    [SerializeField] internal GameObject directChatsLoadingContainer;
 19    [SerializeField] internal GameObject directChatsContainer;
 20    [SerializeField] internal GameObject directChannelHeader;
 21    [SerializeField] internal GameObject searchResultsHeader;
 22    [SerializeField] internal TMP_Text directChatsHeaderLabel;
 23    [SerializeField] internal TMP_Text searchResultsHeaderLabel;
 24    [SerializeField] internal ScrollRect scroll;
 25    [SerializeField] internal SearchBarComponentView searchBar;
 26    [SerializeField] private WorldChatWindowModel model;
 27
 28    [Header("Load More Entries")] [SerializeField]
 29    internal Button loadMoreEntriesButton;
 30
 31    [SerializeField] internal GameObject loadMoreEntriesContainer;
 32    [SerializeField] internal TMP_Text loadMoreEntriesLabel;
 33
 2534    private readonly Dictionary<string, PrivateChatModel> creationQueue = new Dictionary<string, PrivateChatModel>();
 35    private bool isSortingDirty;
 36    private bool isLayoutDirty;
 37    private Dictionary<string, PrivateChatModel> filteredPrivateChats;
 38    private int currentAvatarSnapshotIndex;
 39    private bool isLoadingPrivateChannels;
 40
 41    public event Action OnClose;
 42    public event Action<string> OnOpenPrivateChat;
 43    public event Action<string> OnOpenPublicChannel;
 44
 45    public event Action<string> OnUnfriend
 46    {
 047        add => directChatList.OnUnfriend += value;
 048        remove => directChatList.OnUnfriend -= value;
 49    }
 50
 51    public event Action<string> OnSearchChannelRequested;
 52    public event Action OnRequireMorePrivateChats;
 53
 054    public RectTransform Transform => (RectTransform) transform;
 055    public bool IsActive => gameObject.activeInHierarchy;
 1856    public int PrivateChannelsCount => directChatList.Count() + creationQueue.Keys.Count(s => !directChatList.Contains(s
 57
 58    public static WorldChatWindowComponentView Create()
 59    {
 2360        return Instantiate(Resources.Load<WorldChatWindowComponentView>("SocialBarV1/ConversationListHUD"));
 61    }
 62
 63    public override void Awake()
 64    {
 2365        base.Awake();
 2466        closeButton.onClick.AddListener(() => OnClose?.Invoke());
 4567        directChatList.SortingMethod = (a, b) => b.Model.lastMessageTimestamp.CompareTo(a.Model.lastMessageTimestamp);
 2468        directChatList.OnOpenChat += entry => OnOpenPrivateChat?.Invoke(entry.Model.userId);
 2469        publicChannelList.OnOpenChat += entry => OnOpenPublicChannel?.Invoke(entry.Model.channelId);
 2470        searchBar.OnSearchText += text => OnSearchChannelRequested?.Invoke(text);
 2471        loadMoreEntriesButton.onClick.AddListener(() => OnRequireMorePrivateChats?.Invoke());
 2372        UpdateHeaders();
 2373    }
 74
 75    public override void OnEnable()
 76    {
 2477        base.OnEnable();
 2478        UpdateLayout();
 2479    }
 80
 81    public void Initialize(IChatController chatController, ILastReadMessagesService lastReadMessagesService)
 82    {
 2383        directChatList.Initialize(chatController, lastReadMessagesService);
 2384        publicChannelList.Initialize(chatController, lastReadMessagesService);
 2385        searchResultsList.Initialize(chatController, lastReadMessagesService);
 2386    }
 87
 88    public override void Update()
 89    {
 4090        base.Update();
 91
 4092        SetQueuedEntries();
 93
 4094        if (isSortingDirty)
 95        {
 1496            directChatList.Sort();
 1497            searchResultsList.Sort();
 1498            publicChannelList.Sort();
 99        }
 100
 40101        isSortingDirty = false;
 102
 40103        if (isLayoutDirty)
 27104            ((RectTransform) scroll.transform).ForceUpdateLayout();
 40105        isLayoutDirty = false;
 106
 40107        FetchProfilePicturesForVisibleEntries();
 40108    }
 109
 2110    public void Show() => gameObject.SetActive(true);
 111
 2112    public void Hide() => gameObject.SetActive(false);
 113
 30114    public void SetPrivateChat(PrivateChatModel model) => creationQueue[model.user.userId] = model;
 115
 116    public void RemovePrivateChat(string userId)
 117    {
 1118        directChatList.Remove(userId);
 1119        UpdateHeaders();
 1120        UpdateLayout();
 1121    }
 122
 123    public void SetPublicChannel(PublicChatChannelModel model)
 124    {
 14125        publicChannelList.Set(model.channelId,
 126            new PublicChannelEntry.PublicChannelEntryModel(model.channelId, name = model.name));
 14127        UpdateLayout();
 14128    }
 129
 130    public void Configure(WorldChatWindowModel newModel)
 131    {
 0132        model = newModel;
 0133        RefreshControl();
 0134    }
 135
 2136    public void ShowPrivateChatsLoading() => SetPrivateChatLoadingVisibility(true);
 137
 1138    public void HidePrivateChatsLoading() => SetPrivateChatLoadingVisibility(false);
 139
 140    public void RefreshBlockedDirectMessages(List<string> blockedUsers)
 141    {
 0142        if (blockedUsers == null) return;
 0143        directChatList.RefreshBlockedEntries(blockedUsers);
 0144    }
 145
 146    public void HideMoreChatsToLoadHint()
 147    {
 2148        loadMoreEntriesContainer.SetActive(false);
 2149        UpdateLayout();
 2150    }
 151
 152    public void ShowMoreChatsToLoadHint(int count)
 153    {
 1154        loadMoreEntriesLabel.SetText(
 155            $"{count} chats hidden. Use the search bar to find them or click below to show more.");
 1156        ShowMoreChatsToLoadHint();
 1157    }
 158
 159    public void ClearFilter()
 160    {
 3161        filteredPrivateChats = null;
 3162        searchResultsList.Export(publicChannelList, directChatList);
 3163        searchResultsList.Hide();
 3164        publicChannelList.Show();
 3165        publicChannelList.Sort();
 166
 3167        if (!isLoadingPrivateChannels)
 168        {
 3169            directChatList.Show();
 3170            directChatList.Sort();
 3171            directChannelHeader.SetActive(true);
 172        }
 173
 3174        searchResultsHeader.SetActive(false);
 175
 12176        directChatList.Filter(entry => true);
 6177        publicChannelList.Filter(entry => true);
 178
 3179        UpdateHeaders();
 3180    }
 181
 182    public void Filter(Dictionary<string, PrivateChatModel> privateChats,
 183        Dictionary<string, PublicChatChannelModel> publicChannels)
 184    {
 6185        filteredPrivateChats = privateChats;
 186
 36187        foreach (var chat in privateChats)
 12188            if (!directChatList.Contains(chat.Key))
 4189                SetPrivateChat(chat.Value);
 190
 24191        foreach (var channel in publicChannels)
 6192            if (!publicChannelList.Contains(channel.Key))
 0193                SetPublicChannel(channel.Value);
 194
 6195        searchResultsList.Import(publicChannelList, directChatList);
 6196        searchResultsList.Show();
 6197        searchResultsList.Sort();
 6198        publicChannelList.Hide();
 6199        directChatList.Hide();
 6200        directChannelHeader.SetActive(false);
 6201        searchResultsHeader.SetActive(true);
 202
 24203        searchResultsList.Filter(entry => privateChats.ContainsKey(entry.Model.userId),
 6204            entry => publicChannels.ContainsKey(entry.Model.channelId));
 205
 6206        UpdateHeaders();
 6207    }
 208
 0209    public bool ContainsPrivateChannel(string userId) => creationQueue.ContainsKey(userId)
 210                                                         || directChatList.Get(userId) != null;
 211
 212    public override void RefreshControl()
 213    {
 0214        publicChannelList.Clear();
 0215        foreach (var entry in model.publicChannels)
 0216            publicChannelList.Set(entry.channelId, entry);
 0217        directChatList.Clear();
 0218        foreach (var entry in model.privateChats)
 0219            directChatList.Set(entry.userId, entry);
 0220        SetPrivateChatLoadingVisibility(model.isLoadingDirectChats);
 0221    }
 222
 223    private void Set(PrivateChatModel model)
 224    {
 29225        var user = model.user;
 29226        var userId = user.userId;
 227
 29228        var entry = new PrivateChatEntry.PrivateChatEntryModel(
 229            user.userId,
 230            user.userName,
 231            model.recentMessage.body,
 232            user.face256SnapshotURL,
 233            model.isBlocked,
 234            model.isOnline,
 235            model.recentMessage.timestamp);
 236
 29237        if (filteredPrivateChats?.ContainsKey(userId) ?? false)
 238        {
 8239            directChatList.Remove(userId);
 8240            searchResultsList.Set(entry);
 8241        }
 242        else
 21243            directChatList.Set(userId, entry);
 244
 29245        UpdateHeaders();
 29246        UpdateLayout();
 29247        SortLists();
 29248    }
 249
 0250    private void SortLists() => isSortingDirty = true;
 251
 252    private void ShowMoreChatsToLoadHint()
 253    {
 1254        loadMoreEntriesContainer.SetActive(true);
 1255        UpdateLayout();
 1256    }
 257
 258    private void SetPrivateChatLoadingVisibility(bool visible)
 259    {
 3260        model.isLoadingDirectChats = visible;
 3261        directChatsLoadingContainer.SetActive(visible);
 3262        directChatsContainer.SetActive(!visible);
 3263        scroll.enabled = !visible;
 3264        isLoadingPrivateChannels = visible;
 3265    }
 266
 267    private void UpdateHeaders()
 268    {
 62269        directChatsHeaderLabel.text = $"Direct Messages ({directChatList.Count()})";
 62270        searchResultsHeaderLabel.text = $"Results ({searchResultsList.Count()})";
 62271    }
 272
 0273    private void UpdateLayout() => isLayoutDirty = true;
 274
 275    private void SetQueuedEntries()
 276    {
 66277        if (creationQueue.Count == 0) return;
 278
 86279        for (var i = 0; i < CREATION_AMOUNT_PER_FRAME && creationQueue.Count > 0; i++)
 280        {
 29281            var (userId, model) = creationQueue.First();
 29282            creationQueue.Remove(userId);
 29283            Set(model);
 284        }
 14285    }
 286
 287    private void FetchProfilePicturesForVisibleEntries()
 288    {
 122289        foreach (var entry in directChatList.Entries.Values.Skip(currentAvatarSnapshotIndex)
 290                     .Take(AVATAR_SNAPSHOTS_PER_FRAME))
 291        {
 21292            if (entry.IsVisible((RectTransform) scroll.transform))
 21293                entry.EnableAvatarSnapshotFetching();
 294            else
 0295                entry.DisableAvatarSnapshotFetching();
 296        }
 297
 40298        currentAvatarSnapshotIndex += AVATAR_SNAPSHOTS_PER_FRAME;
 299
 40300        if (currentAvatarSnapshotIndex >= directChatList.Entries.Count)
 40301            currentAvatarSnapshotIndex = 0;
 40302    }
 303}