< Summary

Class:WorldChatWindowController
Assembly:WorldChatWindowHUD
File(s):/tmp/workspace/unity-renderer/unity-renderer/Assets/Scripts/MainScripts/DCL/Controllers/HUD/WorldChatWindowHUD/WorldChatWindowController.cs
Covered lines:111
Uncovered lines:22
Coverable lines:133
Total lines:274
Line coverage:83.4% (111 of 133)
Covered branches:0
Total branches:0

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity NPath complexity Sequence coverage
WorldChatWindowController(...)0%110100%
Initialize(...)0%770100%
Dispose()0%220100%
SetVisibility(...)0%330100%
HandleFriendsControllerInitialization()0%3.713057.14%
OpenPrivateChat(...)0%220100%
OpenPublicChannel(...)0%220100%
HandleViewCloseRequest()0%110100%
HandleUserStatusChanged(...)0%11.768061.11%
HandleMessageAdded(...)0%10.279075%
ShouldDisplayPrivateChat(...)0%4.054085.71%
CreatePrivateChatModel(...)0%110100%
ExtractRecipient(...)0%330100%
OnUserProfileUpdate(...)0%220100%
ShowOrHideMoreFriendsToLoadHint()0%2.52050%
SearchChannels(...)0%220100%
ShowMorePrivateChats()0%30500%
UpdateMoreChannelsToLoadHint()0%220100%

File(s)

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

#LineLine coverage
 1using System;
 2using System.Collections.Generic;
 3using System.Linq;
 4using System.Text.RegularExpressions;
 5using DCL.Interface;
 6
 7public class WorldChatWindowController : IHUD
 8{
 9    private const string GENERAL_CHANNEL_ID = "general";
 10    private const int MAX_SEARCHED_CHANNELS = 100;
 11    private const int LOAD_PRIVATE_CHATS_ON_DEMAND_COUNT = 30;
 12    private const int INITIAL_DISPLAYED_PRIVATE_CHAT_COUNT = 50;
 13
 14    private readonly IUserProfileBridge userProfileBridge;
 15    private readonly IFriendsController friendsController;
 16    private readonly IChatController chatController;
 17    private readonly ILastReadMessagesService lastReadMessagesService;
 2118    private readonly Queue<string> pendingPrivateChats = new Queue<string>();
 2119    private readonly Dictionary<string, PublicChatChannelModel> publicChannels = new Dictionary<string, PublicChatChanne
 2120    private readonly Dictionary<string, UserProfile> recipientsFromPrivateChats = new Dictionary<string, UserProfile>();
 2121    private readonly Dictionary<string, ChatMessage> lastPrivateMessages = new Dictionary<string, ChatMessage>();
 22
 23    private IWorldChatWindowView view;
 24    private UserProfile ownUserProfile;
 25
 026    public IWorldChatWindowView View => view;
 27
 28    public event Action<string> OnOpenPrivateChat;
 29    public event Action<string> OnOpenPublicChannel;
 30    public event Action OnOpen;
 31
 2132    public WorldChatWindowController(
 33        IUserProfileBridge userProfileBridge,
 34        IFriendsController friendsController,
 35        IChatController chatController,
 36        ILastReadMessagesService lastReadMessagesService)
 37    {
 2138        this.userProfileBridge = userProfileBridge;
 2139        this.friendsController = friendsController;
 2140        this.chatController = chatController;
 2141        this.lastReadMessagesService = lastReadMessagesService;
 2142    }
 43
 44    public void Initialize(IWorldChatWindowView view)
 45    {
 2146        this.view = view;
 2147        view.Initialize(chatController, lastReadMessagesService);
 2148        view.OnClose += HandleViewCloseRequest;
 2149        view.OnOpenPrivateChat += OpenPrivateChat;
 2150        view.OnOpenPublicChannel += OpenPublicChannel;
 2151        view.OnSearchChannelRequested += SearchChannels;
 2152        view.OnRequireMorePrivateChats += ShowMorePrivateChats;
 53
 2154        ownUserProfile = userProfileBridge.GetOwn();
 2155        if (ownUserProfile != null)
 2056            ownUserProfile.OnUpdate += OnUserProfileUpdate;
 57
 58        // TODO: this data should come from the chat service when channels are implemented
 2159        publicChannels[GENERAL_CHANNEL_ID] = new PublicChatChannelModel(GENERAL_CHANNEL_ID, "nearby",
 60            "Talk to the people around you. If you move far away from someone you will lose contact. All whispers will b
 2161        view.SetPublicChannel(publicChannels[GENERAL_CHANNEL_ID]);
 62
 6063        foreach (var value in chatController.GetEntries())
 964            HandleMessageAdded(value);
 65
 2166        if (!friendsController.isInitialized)
 767            if (ownUserProfile?.hasConnectedWeb3 ?? false)
 568                view.ShowPrivateChatsLoading();
 69
 2170        chatController.OnAddMessage += HandleMessageAdded;
 2171        friendsController.OnUpdateUserStatus += HandleUserStatusChanged;
 2172        friendsController.OnInitialized += HandleFriendsControllerInitialization;
 73
 2174        UpdateMoreChannelsToLoadHint();
 2175    }
 76
 77    public void Dispose()
 78    {
 379        view.OnClose -= HandleViewCloseRequest;
 380        view.OnOpenPrivateChat -= OpenPrivateChat;
 381        view.OnOpenPublicChannel -= OpenPublicChannel;
 382        view.OnSearchChannelRequested -= SearchChannels;
 383        view.OnRequireMorePrivateChats -= ShowMorePrivateChats;
 384        view.Dispose();
 385        chatController.OnAddMessage -= HandleMessageAdded;
 386        friendsController.OnUpdateUserStatus -= HandleUserStatusChanged;
 387        friendsController.OnInitialized -= HandleFriendsControllerInitialization;
 88
 389        if (ownUserProfile != null)
 290            ownUserProfile.OnUpdate -= OnUserProfileUpdate;
 391    }
 92
 93    public void SetVisibility(bool visible)
 94    {
 895        if (visible)
 96        {
 297            view.Show();
 298            OnOpen?.Invoke();
 199        }
 100        else
 6101            view.Hide();
 6102    }
 103
 104    private void HandleFriendsControllerInitialization()
 105    {
 1106        view.HidePrivateChatsLoading();
 107
 108        // show only private chats from friends. Change it whenever the catalyst supports to send pms to any user
 2109        foreach(var userId in recipientsFromPrivateChats.Keys)
 0110            if (!friendsController.IsFriend(userId))
 0111                view.RemovePrivateChat(userId);
 1112    }
 113
 1114    private void OpenPrivateChat(string userId) => OnOpenPrivateChat?.Invoke(userId);
 115
 1116    private void OpenPublicChannel(string channelId) => OnOpenPublicChannel?.Invoke(channelId);
 117
 1118    private void HandleViewCloseRequest() => SetVisibility(false);
 119
 120    private void HandleUserStatusChanged(string userId, FriendsController.UserStatus status)
 121    {
 2122        if (!recipientsFromPrivateChats.ContainsKey(userId)) return;
 2123        if (!lastPrivateMessages.ContainsKey(userId)) return;
 2124        if (pendingPrivateChats.Contains(userId)) return;
 125
 2126        if (status.friendshipStatus == FriendshipStatus.FRIEND)
 127        {
 1128            var profile = recipientsFromPrivateChats[userId];
 129
 1130            if (ShouldDisplayPrivateChat(profile.userId))
 131            {
 1132                view.SetPrivateChat(new PrivateChatModel
 133                {
 134                    user = profile,
 135                    recentMessage = lastPrivateMessages[userId],
 136                    isBlocked = ownUserProfile.IsBlocked(userId),
 137                    isOnline = status.presence == PresenceStatus.ONLINE
 138                });
 1139            }
 0140            else if (!pendingPrivateChats.Contains(profile.userId))
 141            {
 0142                pendingPrivateChats.Enqueue(profile.userId);
 0143                UpdateMoreChannelsToLoadHint();
 144            }
 0145        }
 1146        else if (status.friendshipStatus == FriendshipStatus.NOT_FRIEND)
 147        {
 148            // show only private chats from friends. Change it whenever the catalyst supports to send pms to any user
 1149            view.RemovePrivateChat(userId);
 150        }
 1151    }
 152
 153    private void HandleMessageAdded(ChatMessage message)
 154    {
 14155        if (message.messageType != ChatMessage.Type.PRIVATE) return;
 10156        var profile = ExtractRecipient(message);
 10157        if (profile == null) return;
 158
 10159        if (friendsController.isInitialized)
 10160            if (!friendsController.IsFriend(profile.userId))
 0161                return;
 162
 10163        if (lastPrivateMessages.ContainsKey(profile.userId))
 164        {
 0165            if (message.timestamp > lastPrivateMessages[profile.userId].timestamp)
 0166                lastPrivateMessages[profile.userId] = message;
 0167        }
 168        else
 10169            lastPrivateMessages[profile.userId] = message;
 170
 10171        recipientsFromPrivateChats[profile.userId] = profile;
 172
 10173        if (ShouldDisplayPrivateChat(profile.userId))
 9174            view.SetPrivateChat(CreatePrivateChatModel(message, profile));
 1175        else if (!pendingPrivateChats.Contains(profile.userId))
 176        {
 1177            pendingPrivateChats.Enqueue(profile.userId);
 1178            UpdateMoreChannelsToLoadHint();
 179        }
 1180    }
 181
 182    private bool ShouldDisplayPrivateChat(string userId)
 183    {
 11184        if (!friendsController.isInitialized) return false;
 20185        if (view.PrivateChannelsCount < INITIAL_DISPLAYED_PRIVATE_CHAT_COUNT) return true;
 3186        if (view.ContainsPrivateChannel(userId)) return true;
 1187        return false;
 188    }
 189
 190    private PrivateChatModel CreatePrivateChatModel(ChatMessage recentMessage, UserProfile profile)
 191    {
 10192        return new PrivateChatModel
 193        {
 194            user = profile,
 195            recentMessage = recentMessage,
 196            isBlocked = ownUserProfile.IsBlocked(profile.userId),
 197            isOnline = friendsController.GetUserStatus(profile.userId).presence == PresenceStatus.ONLINE
 198        };
 199    }
 200
 201    private UserProfile ExtractRecipient(ChatMessage message) =>
 10202        userProfileBridge.Get(message.sender != ownUserProfile.userId ? message.sender : message.recipient);
 203
 204    private void OnUserProfileUpdate(UserProfile profile)
 205    {
 1206        view.RefreshBlockedDirectMessages(profile.blocked);
 207
 1208        if (!profile.hasConnectedWeb3)
 1209            view.HidePrivateChatsLoading();
 1210    }
 211
 212    private void ShowOrHideMoreFriendsToLoadHint()
 213    {
 1214        if (pendingPrivateChats.Count == 0)
 1215            View.HideMoreChatsToLoadHint();
 216        else
 0217            View.ShowMoreChatsToLoadHint(pendingPrivateChats.Count);
 0218    }
 219
 220    private void SearchChannels(string search)
 221    {
 2222        if (string.IsNullOrEmpty(search))
 223        {
 1224            View.ClearFilter();
 1225            ShowOrHideMoreFriendsToLoadHint();
 1226            return;
 227        }
 228
 229        Dictionary<string, PrivateChatModel> FilterPrivateChannelsByUserName(string search)
 230        {
 1231            var regex = new Regex(search, RegexOptions.IgnoreCase);
 232
 1233            return recipientsFromPrivateChats.Values.Where(profile =>
 4234                !string.IsNullOrEmpty(profile.userName) && regex.IsMatch(profile.userName))
 235                .Take(MAX_SEARCHED_CHANNELS)
 2236                .ToDictionary(model => model.userId, profile => CreatePrivateChatModel(lastPrivateMessages[profile.userI
 237        }
 238
 239        Dictionary<string, PublicChatChannelModel> FilterPublicChannelsByName(string search)
 240        {
 1241            var regex = new Regex(search, RegexOptions.IgnoreCase);
 242
 1243            return publicChannels.Values
 1244                .Where(model => !string.IsNullOrEmpty(model.name) && regex.IsMatch(model.name))
 245                .Take(MAX_SEARCHED_CHANNELS)
 2246                .ToDictionary(model => model.channelId, model => model);
 247        }
 248
 1249        View.Filter(FilterPrivateChannelsByUserName(search), FilterPublicChannelsByName(search));
 1250    }
 251
 252    private void ShowMorePrivateChats()
 253    {
 0254        for (var i = 0; i < LOAD_PRIVATE_CHATS_ON_DEMAND_COUNT && pendingPrivateChats.Count > 0; i++)
 255        {
 0256            var userId = pendingPrivateChats.Dequeue();
 0257            if (!lastPrivateMessages.ContainsKey(userId)) continue;
 0258            if (!recipientsFromPrivateChats.ContainsKey(userId)) continue;
 0259            var recentMessage = lastPrivateMessages[userId];
 0260            var profile = recipientsFromPrivateChats[userId];
 0261            View.SetPrivateChat(CreatePrivateChatModel(recentMessage, profile));
 262        }
 263
 0264        UpdateMoreChannelsToLoadHint();
 0265    }
 266
 267    private void UpdateMoreChannelsToLoadHint()
 268    {
 22269        if (pendingPrivateChats.Count == 0)
 21270            View.HideMoreChatsToLoadHint();
 271        else
 1272            View.ShowMoreChatsToLoadHint(pendingPrivateChats.Count);
 1273    }
 274}