< Summary

Class:WorldChatWindowController
Assembly:WorldChatWindowHUD
File(s):/tmp/workspace/unity-renderer/unity-renderer/Assets/Scripts/MainScripts/DCL/Controllers/HUD/WorldChatWindowHUD/WorldChatWindowController.cs
Covered lines:128
Uncovered lines:15
Coverable lines:143
Total lines:303
Line coverage:89.5% (128 of 143)
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%550100%
HandleFriendsControllerInitialization()0%330100%
OpenPrivateChat(...)0%220100%
OpenPublicChannel(...)0%220100%
HandleViewCloseRequest()0%110100%
HandleFriendshipUpdated(...)0%220100%
HandleUserStatusChanged(...)0%3.073080%
HandleMessageAdded(...)0%5.735069.23%
HandleFriendsWithDirectMessagesAdded(...)0%6.755058.82%
CreatePrivateChatModel(...)0%110100%
ExtractRecipientId(...)0%220100%
OnUserProfileUpdate(...)0%220100%
SearchChannels(...)0%220100%
ShowMorePrivateChats()0%4.254075%
UpdateMoreChannelsToLoadHint()0%330100%
RequestFriendsWithDirectMessages()0%220100%
RequestFriendsWithDirectMessagesFromSearch(...)0%220100%
RequestUnreadMessages()0%110100%
HideSearchLoadingWhenTimeout()0%9.834028.57%

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.Threading;
 4using Cysharp.Threading.Tasks;
 5using DCL.Chat;
 6using DCL.Friends.WebApi;
 7using DCL.Interface;
 8using UnityEngine;
 9
 10public class WorldChatWindowController : IHUD
 11{
 12    private const int DMS_PAGE_SIZE = 30;
 13    private const int USER_DM_ENTRIES_TO_REQUEST_FOR_SEARCH = 30;
 14
 15    private readonly IUserProfileBridge userProfileBridge;
 16    private readonly IFriendsController friendsController;
 17    private readonly IChatController chatController;
 18
 3519    private readonly Dictionary<string, PublicChatChannelModel> publicChannels =
 20        new Dictionary<string, PublicChatChannelModel>();
 21
 3522    private readonly Dictionary<string, ChatMessage> lastPrivateMessages = new Dictionary<string, ChatMessage>();
 23    private int hiddenDMs;
 3524    private string currentSearch = "";
 25    private bool areDMsRequestedByFirstTime;
 26    private bool isRequestingFriendsWithDMs;
 27    private int lastSkipForDMs;
 3528    private CancellationTokenSource hideLoadingCancellationToken = new CancellationTokenSource();
 29    private IWorldChatWindowView view;
 30    private UserProfile ownUserProfile;
 31
 032    public IWorldChatWindowView View => view;
 33
 34    public event Action<string> OnOpenPrivateChat;
 35    public event Action<string> OnOpenPublicChannel;
 36    public event Action OnOpen;
 37
 3538    public WorldChatWindowController(
 39        IUserProfileBridge userProfileBridge,
 40        IFriendsController friendsController,
 41        IChatController chatController)
 42    {
 3543        this.userProfileBridge = userProfileBridge;
 3544        this.friendsController = friendsController;
 3545        this.chatController = chatController;
 3546    }
 47
 48    public void Initialize(IWorldChatWindowView view)
 49    {
 3550        this.view = view;
 3551        view.Initialize(chatController);
 3552        view.OnClose += HandleViewCloseRequest;
 3553        view.OnOpenPrivateChat += OpenPrivateChat;
 3554        view.OnOpenPublicChannel += OpenPublicChannel;
 3555        view.OnSearchChannelRequested += SearchChannels;
 3556        view.OnRequireMorePrivateChats += ShowMorePrivateChats;
 57
 3558        ownUserProfile = userProfileBridge.GetOwn();
 3559        if (ownUserProfile != null)
 3460            ownUserProfile.OnUpdate += OnUserProfileUpdate;
 61
 62        // TODO: this data should come from the chat service when channels are implemented
 3563        publicChannels[ChatUtils.NEARBY_CHANNEL_ID] = new PublicChatChannelModel(ChatUtils.NEARBY_CHANNEL_ID, ChatUtils.
 64            "Talk to the people around you. If you move far away from someone you will lose contact. All whispers will b
 3565        view.SetPublicChannel(publicChannels[ChatUtils.NEARBY_CHANNEL_ID]);
 66
 8467        foreach (var value in chatController.GetAllocatedEntries())
 768            HandleMessageAdded(value);
 69
 3570        if (!friendsController.IsInitialized)
 771            if (ownUserProfile?.hasConnectedWeb3 ?? false)
 572                view.ShowPrivateChatsLoading();
 73
 3574        chatController.OnAddMessage += HandleMessageAdded;
 3575        friendsController.OnAddFriendsWithDirectMessages += HandleFriendsWithDirectMessagesAdded;
 3576        friendsController.OnUpdateUserStatus += HandleUserStatusChanged;
 3577        friendsController.OnUpdateFriendship += HandleFriendshipUpdated;
 3578        friendsController.OnInitialized += HandleFriendsControllerInitialization;
 3579    }
 80
 81    public void Dispose()
 82    {
 383        view.OnClose -= HandleViewCloseRequest;
 384        view.OnOpenPrivateChat -= OpenPrivateChat;
 385        view.OnOpenPublicChannel -= OpenPublicChannel;
 386        view.OnSearchChannelRequested -= SearchChannels;
 387        view.OnRequireMorePrivateChats -= ShowMorePrivateChats;
 388        view.Dispose();
 389        chatController.OnAddMessage -= HandleMessageAdded;
 390        friendsController.OnAddFriendsWithDirectMessages -= HandleFriendsWithDirectMessagesAdded;
 391        friendsController.OnUpdateUserStatus -= HandleUserStatusChanged;
 392        friendsController.OnUpdateFriendship -= HandleFriendshipUpdated;
 393        friendsController.OnInitialized -= HandleFriendsControllerInitialization;
 94
 395        if (ownUserProfile != null)
 296            ownUserProfile.OnUpdate -= OnUserProfileUpdate;
 397    }
 98
 99    public void SetVisibility(bool visible)
 100    {
 14101        if (visible)
 102        {
 8103            view.Show();
 8104            OnOpen?.Invoke();
 105
 8106            if (friendsController.IsInitialized && !areDMsRequestedByFirstTime)
 107            {
 6108                RequestFriendsWithDirectMessages();
 6109                RequestUnreadMessages();
 110            }
 6111        }
 112        else
 6113            view.Hide();
 8114    }
 115
 116    private void HandleFriendsControllerInitialization()
 117    {
 2118        if (view.IsActive && !areDMsRequestedByFirstTime)
 119        {
 1120            RequestFriendsWithDirectMessages();
 1121            lastSkipForDMs += DMS_PAGE_SIZE;
 1122            RequestUnreadMessages();
 1123        }
 124        else
 1125            view.HidePrivateChatsLoading();
 1126    }
 127
 128    private void OpenPrivateChat(string userId)
 129    {
 1130        OnOpenPrivateChat?.Invoke(userId);
 1131    }
 132
 1133    private void OpenPublicChannel(string channelId) => OnOpenPublicChannel?.Invoke(channelId);
 134
 1135    private void HandleViewCloseRequest() => SetVisibility(false);
 136
 137    private void HandleFriendshipUpdated(string userId, FriendshipAction friendship)
 138    {
 6139        if (friendship != FriendshipAction.APPROVED)
 140        {
 141            // show only private chats from friends. Change it whenever the catalyst supports to send pms to any user
 6142            view.RemovePrivateChat(userId);
 143        }
 6144    }
 145
 146    private void HandleUserStatusChanged(string userId, UserStatus status)
 147    {
 4148        if (!lastPrivateMessages.ContainsKey(userId)) return;
 149
 4150        if (status.friendshipStatus != FriendshipStatus.FRIEND)
 151        {
 152            // show only private chats from friends. Change it whenever the catalyst supports to send pms to any user
 4153            view.RemovePrivateChat(userId);
 154        }
 4155    }
 156
 157    private void HandleMessageAdded(ChatMessage message)
 158    {
 11159        if (message.messageType != ChatMessage.Type.PRIVATE) return;
 160
 7161        var userId = ExtractRecipientId(message);
 162
 7163        if (lastPrivateMessages.ContainsKey(userId))
 164        {
 0165            if (message.timestamp > lastPrivateMessages[userId].timestamp)
 0166                lastPrivateMessages[userId] = message;
 0167        }
 168        else
 7169            lastPrivateMessages[userId] = message;
 170
 7171        var profile = userProfileBridge.Get(userId);
 7172        if (profile == null) return;
 173
 7174        view.SetPrivateChat(CreatePrivateChatModel(message, profile));
 7175    }
 176
 177    private void HandleFriendsWithDirectMessagesAdded(List<FriendWithDirectMessages> usersWithDM)
 178    {
 12179        for (var i = 0; i < usersWithDM.Count; i++)
 180        {
 3181            var profile = userProfileBridge.Get(usersWithDM[i].userId);
 3182            if (profile == null) continue;
 183
 0184            var lastMessage = new ChatMessage
 185            {
 186                messageType = ChatMessage.Type.PRIVATE,
 187                body = usersWithDM[i].lastMessageBody,
 188                timestamp = (ulong) usersWithDM[i].lastMessageTimestamp
 189            };
 190
 0191            if (lastPrivateMessages.ContainsKey(profile.userId))
 192            {
 0193                if (lastMessage.timestamp > lastPrivateMessages[profile.userId].timestamp)
 0194                    lastPrivateMessages[profile.userId] = lastMessage;
 0195            }
 196            else
 0197                lastPrivateMessages[profile.userId] = lastMessage;
 198
 0199            view.SetPrivateChat(CreatePrivateChatModel(lastMessage, profile));
 200        }
 201
 3202        UpdateMoreChannelsToLoadHint();
 3203        view.HidePrivateChatsLoading();
 3204        view.HideSearchLoading();
 205
 3206        isRequestingFriendsWithDMs = false;
 3207    }
 208
 209    private PrivateChatModel CreatePrivateChatModel(ChatMessage recentMessage, UserProfile profile)
 210    {
 7211        return new PrivateChatModel
 212        {
 213            user = profile,
 214            recentMessage = recentMessage,
 215            isBlocked = ownUserProfile.IsBlocked(profile.userId),
 216            isOnline = friendsController.GetUserStatus(profile.userId).presence == PresenceStatus.ONLINE
 217        };
 218    }
 219
 220    private string ExtractRecipientId(ChatMessage message)
 221    {
 7222        return message.sender != ownUserProfile.userId ? message.sender : message.recipient;
 223    }
 224
 225    private void OnUserProfileUpdate(UserProfile profile)
 226    {
 1227        view.RefreshBlockedDirectMessages(profile.blocked);
 228
 1229        if (!profile.hasConnectedWeb3)
 1230            view.HidePrivateChatsLoading();
 1231    }
 232
 233    private void SearchChannels(string search)
 234    {
 2235        currentSearch = search;
 236
 2237        if (string.IsNullOrEmpty(search))
 238        {
 1239            View.DisableSearchMode();
 1240            UpdateMoreChannelsToLoadHint();
 1241            return;
 242        }
 243
 1244        UpdateMoreChannelsToLoadHint();
 1245        View.EnableSearchMode();
 1246        RequestFriendsWithDirectMessagesFromSearch(search, USER_DM_ENTRIES_TO_REQUEST_FOR_SEARCH);
 1247    }
 248
 249    private void ShowMorePrivateChats()
 250    {
 1251        if (isRequestingFriendsWithDMs ||
 252            hiddenDMs == 0 ||
 253            !string.IsNullOrEmpty(currentSearch))
 0254            return;
 255
 1256        RequestFriendsWithDirectMessages();
 1257    }
 258
 259    private void UpdateMoreChannelsToLoadHint()
 260    {
 5261        hiddenDMs = Mathf.Clamp(friendsController.TotalFriendsWithDirectMessagesCount - lastSkipForDMs,
 262            0,
 263            friendsController.TotalFriendsWithDirectMessagesCount);
 264
 5265        if (hiddenDMs <= 0 || !string.IsNullOrEmpty(currentSearch))
 3266            View.HideMoreChatsToLoadHint();
 267        else
 2268            View.ShowMoreChatsToLoadHint(hiddenDMs);
 2269    }
 270
 271    private void RequestFriendsWithDirectMessages()
 272    {
 8273        isRequestingFriendsWithDMs = true;
 274
 8275        if (!areDMsRequestedByFirstTime)
 276        {
 7277            view.ShowPrivateChatsLoading();
 7278            view.HideMoreChatsToLoadHint();
 279        }
 280
 8281        friendsController.GetFriendsWithDirectMessages(DMS_PAGE_SIZE, lastSkipForDMs);
 8282        lastSkipForDMs += DMS_PAGE_SIZE;
 8283        areDMsRequestedByFirstTime = true;
 8284    }
 285
 286    internal void RequestFriendsWithDirectMessagesFromSearch(string userNameOrId, int limit)
 287    {
 2288        view.ShowSearchLoading();
 2289        friendsController.GetFriendsWithDirectMessages(userNameOrId, limit);
 2290        hideLoadingCancellationToken?.Cancel();
 2291        hideLoadingCancellationToken = new CancellationTokenSource();
 2292        HideSearchLoadingWhenTimeout(hideLoadingCancellationToken.Token).Forget();
 2293    }
 294
 7295    private void RequestUnreadMessages() => chatController.GetUnseenMessagesByUser();
 296
 297    private async UniTask HideSearchLoadingWhenTimeout(CancellationToken cancellationToken)
 298    {
 4299        await UniTask.Delay(3000, cancellationToken: cancellationToken);
 0300        if (cancellationToken.IsCancellationRequested) return;
 0301        view.HideSearchLoading();
 0302    }
 303}