< Summary

Class:DCL.Social.Chat.WorldChatWindowController
Assembly:WorldChatWindowHUD
File(s):/tmp/workspace/unity-renderer/unity-renderer/Assets/Scripts/MainScripts/DCL/Controllers/HUD/WorldChatWindowHUD/WorldChatWindowController.cs
Covered lines:307
Uncovered lines:62
Coverable lines:369
Total lines:761
Line coverage:83.1% (307 of 369)
Covered branches:0
Total branches:0
Covered methods:48
Total methods:56
Method coverage:85.7% (48 of 56)

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity NPath complexity Sequence coverage
WorldChatWindowController(...)0%110100%
Initialize(...)0%880100%
Dispose()0%330100%
SetVisibility(...)0%13130100%
OpenChannelCreationWindow()0%6200%
SetVisiblePanelList(...)0%220100%
LeaveChannel(...)0%220100%
RequestJoinedChannels()0%3.023087.5%
WaitThenHideChannelsLoading()0%9.834028.57%
HandleChatInitialization()0%110100%
ConnectToAutoJoinChannels()0%6.016093.33%
HandleFriendsControllerInitialization()0%330100%
OpenPrivateChat(...)0%220100%
OpenPublicChat(...)0%440100%
HandleViewCloseRequest()0%220100%
HandleFriendshipUpdated(...)0%220100%
HandleUserStatusChanged(...)0%2.52050%
<HandleMessageAdded()0%25.7414060.87%
HandleMessageAdded(...)0%110100%
<HandleFriendsWithDirectMessagesAdded()0%12.9110069.23%
HandleFriendsWithDirectMessagesAdded(...)0%110100%
CreatePrivateChatModel(...)0%110100%
ExtractRecipientId(...)0%220100%
OnUserProfileUpdate(...)0%220100%
SearchChats(...)0%440100%
ShowMorePrivateChats()0%4.254075%
UpdateMoreChannelsToLoadHint()0%330100%
RequestFriendsWithDirectMessages()0%220100%
HidePrivateChatsLoadingWhenTimeout()0%6.984042.86%
RequestFriendsWithDirectMessagesFromSearch(...)0%220100%
HandleChannelUpdated(...)0%3.113076.92%
ClearOfflineUnseenMessages(...)0%220100%
HandleAutoChannelJoined(...)0%110100%
HandleChannelJoined(...)0%110100%
ReportChannelJoinedToAnalytics(...)0%220100%
HandleJoinChannelError(...)0%20400%
HandleLeaveChannelError(...)0%2100%
HandleChannelLeft(...)0%440100%
HandleChannelOpened(...)0%6200%
HandleAskForJoinChannel(...)0%12300%
HandleAskForJoinChannelAfterRendererState(...)0%6200%
RequestUnreadMessages()0%110100%
RequestUnreadChannelsMessages()0%110100%
OpenChannelSearch()0%12300%
HideSearchLoadingWhenTimeout()0%9.834028.57%
OnAllowedToCreateChannelsChanged(...)0%2100%
SetAutomaticChannelsInfoUpdatingActive(...)0%220100%
ReloadChannelsInfoPeriodically()0%10.754025%
GetCurrentChannelsInfo()0%330100%
OpenWalletReadme()0%110100%
SignUp()0%110100%
CopyChannelNameToClipboard(...)0%110100%

File(s)

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

#LineLine coverage
 1using Cysharp.Threading.Tasks;
 2using DCL.Chat;
 3using DCL.Chat.Channels;
 4using DCL.Interface;
 5using SocialFeaturesAnalytics;
 6using System;
 7using System.Collections.Generic;
 8using System.Linq;
 9using System.Threading;
 10using DCL.Browser;
 11using DCl.Social.Friends;
 12using DCL.Social.Friends;
 13using UnityEngine;
 14using Channel = DCL.Chat.Channels.Channel;
 15using DCL.Tasks;
 16using DCLServices.CopyPaste.Analytics;
 17
 18namespace DCL.Social.Chat
 19{
 20    public class WorldChatWindowController : IHUD
 21    {
 22        private const int DMS_PAGE_SIZE = 30;
 23        private const int USER_DM_ENTRIES_TO_REQUEST_FOR_SEARCH = 20;
 24        private const int CHANNELS_PAGE_SIZE = 10;
 25        private const int MINUTES_FOR_AUTOMATIC_CHANNELS_INFO_RELOADING = 1;
 26
 27        private readonly IUserProfileBridge userProfileBridge;
 28        private readonly IFriendsController friendsController;
 29        private readonly IChatController chatController;
 30        private readonly DataStore dataStore;
 31        private readonly IMouseCatcher mouseCatcher;
 32        private readonly ISocialAnalytics socialAnalytics;
 33        private readonly IChannelsFeatureFlagService channelsFeatureFlagService;
 34        private readonly IBrowserBridge browserBridge;
 35        private readonly RendererState rendererState;
 36        private readonly DataStore_Mentions mentionsDataStore;
 37        private readonly IClipboard clipboard;
 38        private readonly ICopyPasteAnalyticsService copyPasteAnalyticsService;
 5339        private readonly Dictionary<string, PublicChatModel> publicChannels = new Dictionary<string, PublicChatModel>();
 5340        private readonly Dictionary<string, ChatMessage> lastPrivateMessages = new Dictionary<string, ChatMessage>();
 5341        private readonly HashSet<string> channelsClearedUnseenNotifications = new HashSet<string>();
 142        private HashSet<string> autoJoinChannelList => dataStore.HUDs.autoJoinChannelList.Get();
 6843        private BaseVariable<HashSet<string>> visibleTaskbarPanels => dataStore.HUDs.visibleTaskbarPanels;
 44        private int hiddenDMs;
 5345        private string currentSearch = "";
 46        private DateTime channelsRequestTimestamp;
 47        private bool areDMsRequestedByFirstTime;
 48        private int lastSkipForDMs;
 5349        private CancellationTokenSource hideLoadingCancellationToken = new CancellationTokenSource();
 50        private IWorldChatWindowView view;
 51        private UserProfile ownUserProfile;
 52        private bool isRequestingDMs;
 53        private bool areUnseenMessagesRequestedByFirstTime;
 54        private string channelToJoinAtTheBeginning;
 5355        private CancellationTokenSource hideChannelsLoadingCancellationToken = new CancellationTokenSource();
 5356        private CancellationTokenSource hidePrivateChatsLoadingCancellationToken = new CancellationTokenSource();
 5357        private CancellationTokenSource reloadingChannelsInfoCancellationToken = new CancellationTokenSource();
 5358        private CancellationTokenSource showDMsCancellationToken = new ();
 5759        private bool showOnlyOnlineMembersOnPublicChannels => !dataStore.featureFlags.flags.Get().IsFeatureEnabled("matr
 60
 5361        private bool isVisible = true;
 1662        public IWorldChatWindowView View => view;
 63
 64        public event Action OnCloseView;
 65        public event Action<string> OnOpenPrivateChat;
 66        public event Action<string> OnOpenPublicChat;
 67        public event Action<string> OnOpenChannel;
 68        public event Action OnOpen;
 69        public event Action OnOpenChannelSearch;
 70        public event Action OnOpenChannelCreation;
 71        public event Action<string> OnOpenChannelLeave;
 72
 5373        public WorldChatWindowController(
 74            IUserProfileBridge userProfileBridge,
 75            IFriendsController friendsController,
 76            IChatController chatController,
 77            DataStore dataStore,
 78            IMouseCatcher mouseCatcher,
 79            ISocialAnalytics socialAnalytics,
 80            IChannelsFeatureFlagService channelsFeatureFlagService,
 81            IBrowserBridge browserBridge,
 82            RendererState rendererState,
 83            DataStore_Mentions mentionsDataStore,
 84            IClipboard clipboard,
 85            ICopyPasteAnalyticsService copyPasteAnalyticsService)
 86        {
 5387            this.userProfileBridge = userProfileBridge;
 5388            this.friendsController = friendsController;
 5389            this.chatController = chatController;
 5390            this.dataStore = dataStore;
 5391            this.mouseCatcher = mouseCatcher;
 5392            this.socialAnalytics = socialAnalytics;
 5393            this.channelsFeatureFlagService = channelsFeatureFlagService;
 5394            this.browserBridge = browserBridge;
 5395            this.rendererState = rendererState;
 5396            this.mentionsDataStore = mentionsDataStore;
 5397            this.clipboard = clipboard;
 5398            this.copyPasteAnalyticsService = copyPasteAnalyticsService;
 5399        }
 100
 101        public void Initialize(IWorldChatWindowView view, bool isVisible = true)
 102        {
 53103            this.view = view;
 53104            view.Initialize(chatController, mentionsDataStore);
 105
 53106            if (mouseCatcher != null)
 52107                mouseCatcher.OnMouseLock += HandleViewCloseRequest;
 108
 53109            view.OnClose += HandleViewCloseRequest;
 53110            view.OnOpenPrivateChat += OpenPrivateChat;
 53111            view.OnOpenPublicChat += OpenPublicChat;
 53112            view.OnSearchChatRequested += SearchChats;
 53113            view.OnRequireMorePrivateChats += ShowMorePrivateChats;
 53114            view.OnSignUp += SignUp;
 53115            view.OnRequireWalletReadme += OpenWalletReadme;
 116
 53117            ownUserProfile = userProfileBridge.GetOwn();
 53118            if (ownUserProfile != null)
 53119                ownUserProfile.OnUpdate += OnUserProfileUpdate;
 120
 53121            var channel = chatController.GetAllocatedChannel(ChatUtils.NEARBY_CHANNEL_ID);
 53122            publicChannels[ChatUtils.NEARBY_CHANNEL_ID] = new PublicChatModel(ChatUtils.NEARBY_CHANNEL_ID, channel.Name,
 123                channel.Description,
 124                channel.Joined,
 125                channel.MemberCount,
 126                false,
 127                showOnlyOnlineMembersOnPublicChannels);
 53128            view.SetPublicChat(publicChannels[ChatUtils.NEARBY_CHANNEL_ID]);
 129
 53130            if (!friendsController.IsInitialized)
 7131                if (ownUserProfile?.hasConnectedWeb3 ?? false)
 6132                    view.ShowPrivateChatsLoading();
 133
 53134            chatController.OnInitialized += HandleChatInitialization;
 53135            chatController.OnAddMessage += HandleMessageAdded;
 53136            friendsController.OnAddFriendsWithDirectMessages += HandleFriendsWithDirectMessagesAdded;
 53137            friendsController.OnUpdateUserStatus += HandleUserStatusChanged;
 53138            friendsController.OnUpdateFriendship += HandleFriendshipUpdated;
 53139            friendsController.OnInitialized += HandleFriendsControllerInitialization;
 140
 53141            if (channelsFeatureFlagService.IsChannelsFeatureEnabled())
 142            {
 50143                channelsFeatureFlagService.OnAllowedToCreateChannelsChanged += OnAllowedToCreateChannelsChanged;
 144
 50145                view.OnOpenChannelSearch += OpenChannelSearch;
 50146                view.OnLeaveChannel += LeaveChannel;
 50147                view.OnCreateChannel += OpenChannelCreationWindow;
 50148                view.OnCopyChannelNameRequested += CopyChannelNameToClipboard;
 149
 50150                chatController.OnChannelUpdated += HandleChannelUpdated;
 50151                chatController.OnChannelJoined += HandleChannelJoined;
 50152                chatController.OnAutoChannelJoined += HandleAutoChannelJoined;
 50153                chatController.OnJoinChannelError += HandleJoinChannelError;
 50154                chatController.OnChannelLeaveError += HandleLeaveChannelError;
 50155                chatController.OnChannelLeft += HandleChannelLeft;
 50156                chatController.OnAskForJoinChannel += HandleAskForJoinChannel;
 50157                dataStore.channels.channelToBeOpened.OnChange += HandleChannelOpened;
 158
 50159                view.ShowChannelsLoading();
 50160                view.SetSearchAndCreateContainerActive(true);
 161            }
 162            else
 163            {
 3164                view.HideChannelsLoading();
 3165                view.SetSearchAndCreateContainerActive(false);
 166            }
 167
 53168            view.SetChannelsPromoteLabelVisible(channelsFeatureFlagService.IsPromoteChannelsToastEnabled());
 169
 53170            SetVisibility(isVisible);
 53171            this.isVisible = isVisible;
 53172        }
 173
 174        public void Dispose()
 175        {
 3176            view.OnClose -= HandleViewCloseRequest;
 3177            view.OnOpenPrivateChat -= OpenPrivateChat;
 3178            view.OnOpenPublicChat -= OpenPublicChat;
 3179            view.OnSearchChatRequested -= SearchChats;
 3180            view.OnRequireMorePrivateChats -= ShowMorePrivateChats;
 3181            view.OnOpenChannelSearch -= OpenChannelSearch;
 3182            view.OnCreateChannel -= OpenChannelCreationWindow;
 3183            view.OnSignUp -= SignUp;
 3184            view.OnRequireWalletReadme -= OpenWalletReadme;
 3185            view.Dispose();
 3186            chatController.OnInitialized -= HandleChatInitialization;
 3187            chatController.OnAddMessage -= HandleMessageAdded;
 3188            chatController.OnChannelUpdated -= HandleChannelUpdated;
 3189            chatController.OnChannelJoined -= HandleChannelJoined;
 3190            chatController.OnAutoChannelJoined -= HandleAutoChannelJoined;
 3191            chatController.OnJoinChannelError -= HandleJoinChannelError;
 3192            chatController.OnChannelLeaveError -= HandleLeaveChannelError;
 3193            chatController.OnChannelLeft -= HandleChannelLeft;
 3194            chatController.OnAskForJoinChannel -= HandleAskForJoinChannel;
 3195            friendsController.OnAddFriendsWithDirectMessages -= HandleFriendsWithDirectMessagesAdded;
 3196            friendsController.OnUpdateUserStatus -= HandleUserStatusChanged;
 3197            friendsController.OnUpdateFriendship -= HandleFriendshipUpdated;
 3198            friendsController.OnInitialized -= HandleFriendsControllerInitialization;
 3199            dataStore.channels.channelToBeOpened.OnChange -= HandleChannelOpened;
 3200            rendererState.OnChange -= HandleAskForJoinChannelAfterRendererState;
 201
 3202            if (ownUserProfile != null)
 3203                ownUserProfile.OnUpdate -= OnUserProfileUpdate;
 204
 3205            hideChannelsLoadingCancellationToken?.SafeCancelAndDispose();
 3206            reloadingChannelsInfoCancellationToken.SafeCancelAndDispose();
 3207            showDMsCancellationToken.SafeCancelAndDispose();
 208
 3209            channelsFeatureFlagService.OnAllowedToCreateChannelsChanged -= OnAllowedToCreateChannelsChanged;
 3210        }
 211
 212        public void SetVisibility(bool visible)
 213        {
 74214            if (isVisible == visible)
 40215                return;
 216
 34217            isVisible = visible;
 34218            SetVisiblePanelList(visible);
 219
 34220            if (visible)
 221            {
 16222                view.Show();
 16223                OnOpen?.Invoke();
 224
 16225                if (friendsController.IsInitialized && !areDMsRequestedByFirstTime)
 226                {
 12227                    RequestFriendsWithDirectMessages();
 12228                    RequestUnreadMessages();
 229                }
 230
 16231                if (channelsFeatureFlagService.IsChannelsFeatureEnabled())
 232                {
 14233                    if (chatController.IsInitialized)
 234                    {
 13235                        RequestJoinedChannels();
 13236                        SetAutomaticChannelsInfoUpdatingActive(true);
 237                    }
 1238                    else if (ownUserProfile.isGuest)
 239                    {
 240                        // TODO: channels are not allowed for guests. When we support it in the future, remove this call
 1241                        view.HideChannelsLoading();
 242                    }
 243
 14244                    if (!areUnseenMessagesRequestedByFirstTime)
 14245                        RequestUnreadChannelsMessages();
 246                }
 247
 16248                if (ownUserProfile?.isGuest ?? false)
 2249                    view.ShowConnectWallet();
 250                else
 14251                    view.HideConnectWallet();
 252            }
 253            else
 254            {
 18255                view.DisableSearchMode();
 18256                view.Hide();
 18257                SetAutomaticChannelsInfoUpdatingActive(false);
 258            }
 18259        }
 260
 261        private void OpenChannelCreationWindow()
 262        {
 0263            dataStore.channels.channelJoinedSource.Set(ChannelJoinedSource.ConversationList);
 0264            OnOpenChannelCreation?.Invoke();
 0265        }
 266
 267        private void SetVisiblePanelList(bool visible)
 268        {
 34269            HashSet<string> newSet = visibleTaskbarPanels.Get();
 34270            if (visible)
 16271                newSet.Add("WorldChatPanel");
 272            else
 18273                newSet.Remove("WorldChatPanel");
 274
 34275            visibleTaskbarPanels.Set(newSet, true);
 34276        }
 277
 278        private void LeaveChannel(string channelId)
 279        {
 1280            dataStore.channels.channelLeaveSource.Set(ChannelLeaveSource.ConversationList);
 1281            OnOpenChannelLeave?.Invoke(channelId);
 1282        }
 283
 284        private void RequestJoinedChannels()
 285        {
 15286            if ((DateTime.UtcNow - channelsRequestTimestamp).TotalSeconds < 3) return;
 287
 288            // skip=0: we do not support pagination for channels, it is supposed that a user can have a limited amount o
 15289            chatController.GetJoinedChannels(CHANNELS_PAGE_SIZE, 0);
 15290            channelsRequestTimestamp = DateTime.UtcNow;
 291
 15292            hideChannelsLoadingCancellationToken?.Cancel();
 15293            hideChannelsLoadingCancellationToken = new CancellationTokenSource();
 15294            WaitThenHideChannelsLoading(hideChannelsLoadingCancellationToken.Token).Forget();
 15295        }
 296
 297        private async UniTask WaitThenHideChannelsLoading(CancellationToken cancellationToken)
 298        {
 30299            await UniTask.Delay(3000, cancellationToken: cancellationToken);
 0300            if (cancellationToken.IsCancellationRequested) return;
 0301            view.HideChannelsLoading();
 0302        }
 303
 304        private void HandleChatInitialization()
 305        {
 306            // we do request joined channels as soon as possible to be able to display messages correctly in the notific
 2307            RequestJoinedChannels();
 2308            ConnectToAutoJoinChannels();
 2309        }
 310
 311        private void ConnectToAutoJoinChannels()
 312        {
 2313            AutomaticJoinChannelList joinChannelList = channelsFeatureFlagService.GetAutoJoinChannelsList();
 3314            if (joinChannelList == null) return;
 1315            if (joinChannelList.automaticJoinChannelList == null) return;
 316
 4317            foreach (var channel in joinChannelList.automaticJoinChannelList)
 318            {
 1319                var channelId = channel.channelId;
 1320                if (string.IsNullOrEmpty(channelId)) continue;
 1321                autoJoinChannelList.Add(channelId);
 1322                chatController.JoinOrCreateChannel(channelId);
 1323                if (!channel.enableNotifications)
 1324                    chatController.MuteChannel(channelId);
 325            }
 1326        }
 327
 328        private void HandleFriendsControllerInitialization()
 329        {
 3330            if (view.IsActive && !areDMsRequestedByFirstTime)
 331            {
 2332                RequestFriendsWithDirectMessages();
 2333                RequestUnreadMessages();
 334            }
 335            else
 1336                view.HidePrivateChatsLoading();
 1337        }
 338
 339        private void OpenPrivateChat(string userId)
 340        {
 1341            OnOpenPrivateChat?.Invoke(userId);
 1342        }
 343
 344        private void OpenPublicChat(string channelId)
 345        {
 4346            if (channelId == ChatUtils.NEARBY_CHANNEL_ID)
 1347                OnOpenPublicChat?.Invoke(channelId);
 348            else
 3349                OnOpenChannel?.Invoke(channelId);
 1350        }
 351
 352        private void HandleViewCloseRequest()
 353        {
 1354            OnCloseView?.Invoke();
 1355            SetVisibility(false);
 1356        }
 357
 358        private void HandleFriendshipUpdated(string userId, FriendshipAction friendship)
 359        {
 6360            if (friendship != FriendshipAction.APPROVED)
 361            {
 362                // show only private chats from friends. Change it whenever the catalyst supports to send pms to any use
 6363                view.RemovePrivateChat(userId);
 364            }
 6365        }
 366
 367        private void HandleUserStatusChanged(string userId, UserStatus status)
 368        {
 4369            if (status.friendshipStatus != FriendshipStatus.FRIEND)
 370            {
 371                // show only private chats from friends. Change it whenever the catalyst supports to send pms to any use
 4372                view.RemovePrivateChat(userId);
 373            }
 374            else
 375            {
 0376                view.RefreshPrivateChatPresence(userId, status.presence == PresenceStatus.ONLINE);
 377            }
 0378        }
 379
 380        private void HandleMessageAdded(ChatMessage[] messages)
 381        {
 382            async UniTaskVoid AddMessages(ChatMessage[] messages, CancellationToken cancellationToken)
 383            {
 11384                foreach (var message in messages)
 385                {
 3386                    if (message.messageType != ChatMessage.Type.PRIVATE) continue;
 387
 3388                    var userId = ExtractRecipientId(message);
 389
 3390                    if (lastPrivateMessages.ContainsKey(userId))
 391                    {
 0392                        if (message.timestamp > lastPrivateMessages[userId].timestamp)
 0393                            lastPrivateMessages[userId] = message;
 394                    }
 395                    else
 3396                        lastPrivateMessages[userId] = message;
 397
 398                    try
 399                    {
 400                        // incoming friend request's message is added as a DM. This check filters it
 4401                        if (await friendsController.GetFriendshipStatus(userId, cancellationToken) != FriendshipStatus.F
 402
 2403                        var profile = userProfileBridge.Get(userId)
 404                                      ?? await userProfileBridge.RequestFullUserProfileAsync(userId, cancellationToken);
 405
 2406                        view.SetPrivateChat(CreatePrivateChatModel(message, profile));
 2407                    }
 0408                    catch (Exception e) when (e is not OperationCanceledException)
 409                    {
 0410                        Debug.LogException(e);
 0411                    }
 2412                }
 3413            }
 414
 3415            AddMessages(messages, showDMsCancellationToken.Token).Forget();
 3416        }
 417
 418        private void HandleFriendsWithDirectMessagesAdded(List<FriendWithDirectMessages> usersWithDM)
 419        {
 420            async UniTaskVoid HandleFriendsWithDirectMessagesAddedAsync(List<FriendWithDirectMessages> usersWithDM, Canc
 421            {
 12422                for (var i = 0; i < usersWithDM.Count; i++)
 423                {
 3424                    FriendWithDirectMessages dm = usersWithDM[i];
 425
 3426                    var lastMessage = new ChatMessage
 427                    {
 428                        messageType = ChatMessage.Type.PRIVATE,
 429                        body = dm.lastMessageBody,
 430                        timestamp = (ulong) dm.lastMessageTimestamp
 431                    };
 432
 3433                    string userId = dm.userId;
 434
 3435                    if (lastPrivateMessages.ContainsKey(userId))
 436                    {
 0437                        if (lastMessage.timestamp > lastPrivateMessages[userId].timestamp)
 0438                            lastPrivateMessages[userId] = lastMessage;
 439                    }
 440                    else
 3441                        lastPrivateMessages[userId] = lastMessage;
 442
 3443                    var profile = userProfileBridge.Get(userId);
 444
 6445                    try { profile ??= await userProfileBridge.RequestFullUserProfileAsync(userId, cancellationToken); }
 0446                    catch (Exception e) when (e is not OperationCanceledException)
 447                    {
 0448                        var fallbackDM = new PrivateChatModel
 449                        {
 450                            recentMessage = lastMessage,
 451                            faceSnapshotUrl = "",
 452                            isBlocked = ownUserProfile.IsBlocked(userId),
 453                            isOnline = false,
 454                            userId = userId,
 455                            userName = userId,
 456                        };
 457
 0458                        view.SetPrivateChat(fallbackDM);
 459
 0460                        throw;
 461                    }
 462
 3463                    view.SetPrivateChat(CreatePrivateChatModel(lastMessage, profile));
 3464                }
 465
 3466                UpdateMoreChannelsToLoadHint();
 3467                view.HidePrivateChatsLoading();
 3468                view.HideSearchLoading();
 469
 3470                isRequestingDMs = false;
 3471            }
 472
 3473            HandleFriendsWithDirectMessagesAddedAsync(usersWithDM, showDMsCancellationToken.Token).Forget();
 3474        }
 475
 476        private PrivateChatModel CreatePrivateChatModel(ChatMessage recentMessage, UserProfile profile)
 477        {
 5478            return new PrivateChatModel
 479            {
 480                userId = profile.userId,
 481                userName = profile.userName,
 482                faceSnapshotUrl = profile.face256SnapshotURL,
 483                recentMessage = recentMessage,
 484                isBlocked = ownUserProfile.IsBlocked(profile.userId),
 485                isOnline = friendsController.GetUserStatus(profile.userId).presence == PresenceStatus.ONLINE
 486            };
 487        }
 488
 489        private string ExtractRecipientId(ChatMessage message)
 490        {
 3491            return message.sender != ownUserProfile.userId ? message.sender : message.recipient;
 492        }
 493
 494        private void OnUserProfileUpdate(UserProfile profile)
 495        {
 2496            view.RefreshBlockedDirectMessages(profile.blocked);
 497
 2498            if (profile.isGuest)
 1499                view.ShowConnectWallet();
 500            else
 1501                view.HideConnectWallet();
 1502        }
 503
 504        private void SearchChats(string search)
 505        {
 2506            currentSearch = search;
 507
 2508            if (string.IsNullOrEmpty(search))
 509            {
 1510                View.DisableSearchMode();
 1511                UpdateMoreChannelsToLoadHint();
 1512                return;
 513            }
 514
 1515            UpdateMoreChannelsToLoadHint();
 1516            View.EnableSearchMode();
 517
 1518            var matchedChannels = publicChannels.Values
 2519                                                .Where(model => model.name.ToLower().Contains(search.ToLower()));
 4520            foreach (var channelMatch in matchedChannels)
 1521                View.SetPublicChat(channelMatch);
 522
 1523            RequestFriendsWithDirectMessagesFromSearch(search, USER_DM_ENTRIES_TO_REQUEST_FOR_SEARCH);
 1524        }
 525
 526        private void ShowMorePrivateChats()
 527        {
 1528            if (isRequestingDMs ||
 529                hiddenDMs == 0 ||
 530                !string.IsNullOrEmpty(currentSearch))
 0531                return;
 532
 1533            RequestFriendsWithDirectMessages();
 1534        }
 535
 536        private void UpdateMoreChannelsToLoadHint()
 537        {
 5538            hiddenDMs = Mathf.Clamp(friendsController.TotalFriendsWithDirectMessagesCount - lastSkipForDMs,
 539                0,
 540                friendsController.TotalFriendsWithDirectMessagesCount);
 541
 5542            if (hiddenDMs <= 0 || !string.IsNullOrEmpty(currentSearch))
 3543                View.HideMoreChatsToLoadHint();
 544            else
 2545                View.ShowMoreChatsToLoadHint(hiddenDMs);
 2546        }
 547
 548        private void RequestFriendsWithDirectMessages()
 549        {
 15550            isRequestingDMs = true;
 551
 15552            if (!areDMsRequestedByFirstTime)
 553            {
 14554                view.ShowPrivateChatsLoading();
 14555                view.HideMoreChatsToLoadHint();
 556            }
 557
 15558            friendsController.GetFriendsWithDirectMessages(DMS_PAGE_SIZE, lastSkipForDMs);
 15559            lastSkipForDMs += DMS_PAGE_SIZE;
 15560            areDMsRequestedByFirstTime = true;
 561
 15562            hidePrivateChatsLoadingCancellationToken.Cancel();
 15563            hidePrivateChatsLoadingCancellationToken = new CancellationTokenSource();
 15564            HidePrivateChatsLoadingWhenTimeout(hidePrivateChatsLoadingCancellationToken.Token).Forget();
 15565        }
 566
 567        private async UniTaskVoid HidePrivateChatsLoadingWhenTimeout(CancellationToken cancellationToken)
 568        {
 31569            await UniTask.Delay(3000, cancellationToken: cancellationToken);
 0570            if (cancellationToken.IsCancellationRequested) return;
 0571            view.HidePrivateChatsLoading();
 0572        }
 573
 574        internal void RequestFriendsWithDirectMessagesFromSearch(string userNameOrId, int limit)
 575        {
 2576            view.ShowSearchLoading();
 2577            friendsController.GetFriendsWithDirectMessages(userNameOrId, limit);
 2578            hideLoadingCancellationToken?.Cancel();
 2579            hideLoadingCancellationToken = new CancellationTokenSource();
 2580            HideSearchLoadingWhenTimeout(hideLoadingCancellationToken.Token).Forget();
 2581        }
 582
 583        private void HandleChannelUpdated(Channel channel)
 584        {
 4585            if (!channel.Joined)
 586            {
 0587                view.RemovePublicChat(channel.ChannelId);
 0588                publicChannels.Remove(channel.ChannelId);
 0589                return;
 590            }
 591
 4592            var channelId = channel.ChannelId;
 4593            var model = new PublicChatModel(channelId, channel.Name, channel.Description, channel.Joined,
 594                channel.MemberCount, channel.Muted, showOnlyOnlineMembersOnPublicChannels);
 595
 4596            if (publicChannels.ContainsKey(channelId))
 1597                publicChannels[channelId].CopyFrom(model);
 598            else
 3599                publicChannels[channelId] = model;
 600
 4601            view.SetPublicChat(model);
 4602            view.HideChannelsLoading();
 603
 604            // we clear the unseen messages to avoid showing many of them while the user was offline
 605            // TODO: we should consider avoid clearing when the channel is private in the future
 4606            ClearOfflineUnseenMessages(channelId);
 4607        }
 608
 609        private void ClearOfflineUnseenMessages(string channelId)
 610        {
 5611            if (channelsClearedUnseenNotifications.Contains(channelId)) return;
 3612            chatController.MarkChannelMessagesAsSeen(channelId);
 3613            channelsClearedUnseenNotifications.Add(channelId);
 3614        }
 615
 1616        private void HandleAutoChannelJoined(Channel channel) => ReportChannelJoinedToAnalytics(channel, "auto");
 617
 618        private void HandleChannelJoined(Channel channel)
 619        {
 2620            ReportChannelJoinedToAnalytics(channel, "manual");
 2621            OpenPublicChat(channel.ChannelId);
 2622        }
 623
 624        private void ReportChannelJoinedToAnalytics(Channel channel, string method)
 625        {
 3626            if (channel.MemberCount <= 1)
 1627                socialAnalytics.SendEmptyChannelCreated(channel.Name, dataStore.channels.channelJoinedSource.Get());
 628            else
 2629                socialAnalytics.SendPopulatedChannelJoined(channel.Name, dataStore.channels.channelJoinedSource.Get(), m
 2630        }
 631
 632        private void HandleJoinChannelError(string channelId, ChannelErrorCode errorCode)
 633        {
 0634            if (dataStore.channels.isCreationModalVisible.Get()) return;
 635
 636            switch (errorCode)
 637            {
 638                case ChannelErrorCode.LimitExceeded:
 0639                    dataStore.channels.currentChannelLimitReached.Set(channelId, true);
 0640                    break;
 641                case ChannelErrorCode.Unknown:
 0642                    dataStore.channels.joinChannelError.Set(channelId, true);
 643                    break;
 644            }
 0645        }
 646
 647        private void HandleLeaveChannelError(string channelId, ChannelErrorCode errorCode) =>
 0648            dataStore.channels.leaveChannelError.Set(channelId, true);
 649
 650        private void HandleChannelLeft(string channelId)
 651        {
 1652            publicChannels.Remove(channelId);
 1653            view.RemovePublicChat(channelId);
 1654            var channel = chatController.GetAllocatedChannel(channelId);
 1655            socialAnalytics.SendLeaveChannel(channel?.Name ?? channelId, dataStore.channels.channelLeaveSource.Get());
 1656        }
 657
 658        private void HandleChannelOpened(string channelId, string previousChannelId)
 659        {
 0660            if (string.IsNullOrEmpty(channelId))
 0661                return;
 662
 0663            OpenPublicChat(channelId);
 0664        }
 665
 666        private void HandleAskForJoinChannel(string channelName)
 667        {
 0668            chatController.OnAskForJoinChannel -= HandleAskForJoinChannel;
 669
 0670            if (!channelsFeatureFlagService.IsAllowedToCreateChannels())
 0671                return;
 672
 0673            if (rendererState.Get())
 0674                dataStore.channels.currentJoinChannelModal.Set(channelName, true);
 675            else
 676            {
 0677                channelToJoinAtTheBeginning = channelName;
 0678                rendererState.OnChange += HandleAskForJoinChannelAfterRendererState;
 679            }
 0680        }
 681
 682        private void HandleAskForJoinChannelAfterRendererState(bool current, bool _)
 683        {
 0684            if (!current)
 0685                return;
 686
 0687            rendererState.OnChange -= HandleAskForJoinChannelAfterRendererState;
 0688            dataStore.channels.currentJoinChannelModal.Set(channelToJoinAtTheBeginning, true);
 0689        }
 690
 14691        private void RequestUnreadMessages() => chatController.GetUnseenMessagesByUser();
 692
 693        private void RequestUnreadChannelsMessages()
 694        {
 14695            chatController.GetUnseenMessagesByChannel();
 14696            areUnseenMessagesRequestedByFirstTime = true;
 14697        }
 698
 699        private void OpenChannelSearch()
 700        {
 0701            if (!ownUserProfile.isGuest)
 0702                OnOpenChannelSearch?.Invoke();
 703            else
 0704                dataStore.HUDs.connectWalletModalVisible.Set(true);
 0705        }
 706
 707        private async UniTask HideSearchLoadingWhenTimeout(CancellationToken cancellationToken)
 708        {
 4709            await UniTask.Delay(3000, cancellationToken: cancellationToken);
 0710            if (cancellationToken.IsCancellationRequested) return;
 0711            view.HideSearchLoading();
 0712        }
 713
 0714        private void OnAllowedToCreateChannelsChanged(bool isAllowed) => view.SetCreateChannelButtonActive(isAllowed);
 715
 716        private void SetAutomaticChannelsInfoUpdatingActive(bool isActive)
 717        {
 31718            reloadingChannelsInfoCancellationToken.Cancel();
 719
 31720            if (isActive)
 721            {
 13722                GetCurrentChannelsInfo();
 13723                reloadingChannelsInfoCancellationToken = new CancellationTokenSource();
 13724                ReloadChannelsInfoPeriodically(reloadingChannelsInfoCancellationToken.Token).Forget();
 725            }
 31726        }
 727
 728        private async UniTask ReloadChannelsInfoPeriodically(CancellationToken cancellationToken)
 729        {
 0730            while (true)
 731            {
 26732                await UniTask.Delay(MINUTES_FOR_AUTOMATIC_CHANNELS_INFO_RELOADING * 60 * 1000,
 733                    cancellationToken: cancellationToken);
 734
 0735                if (cancellationToken.IsCancellationRequested)
 0736                    return;
 737
 0738                GetCurrentChannelsInfo();
 739            }
 0740        }
 741
 742        private void GetCurrentChannelsInfo()
 743        {
 13744            chatController.GetChannelInfo(publicChannels
 13745                                         .Select(x => x.Key)
 13746                                         .Where(x => x != ChatUtils.NEARBY_CHANNEL_ID)
 747                                         .ToArray());
 13748        }
 749
 750        private void OpenWalletReadme() =>
 1751            browserBridge.OpenUrl("https://docs.decentraland.org/player/blockchain-integration/get-a-wallet/");
 752
 1753        private void SignUp() => userProfileBridge.SignUp();
 754
 755        private void CopyChannelNameToClipboard(string channelName)
 756        {
 1757            clipboard.WriteText(channelName);
 1758            copyPasteAnalyticsService.Copy("channel_name");
 1759        }
 760    }
 761}

Methods/Properties

WorldChatWindowController(IUserProfileBridge, DCL.Social.Friends.IFriendsController, IChatController, DCL.DataStore, DCL.IMouseCatcher, SocialFeaturesAnalytics.ISocialAnalytics, DCL.Chat.IChannelsFeatureFlagService, DCL.Browser.IBrowserBridge, RendererState, DCL.DataStore_Mentions, DCL.IClipboard, DCLServices.CopyPaste.Analytics.ICopyPasteAnalyticsService)
autoJoinChannelList()
visibleTaskbarPanels()
showOnlyOnlineMembersOnPublicChannels()
View()
Initialize(DCL.Social.Chat.IWorldChatWindowView, System.Boolean)
Dispose()
SetVisibility(System.Boolean)
OpenChannelCreationWindow()
SetVisiblePanelList(System.Boolean)
LeaveChannel(System.String)
RequestJoinedChannels()
WaitThenHideChannelsLoading()
HandleChatInitialization()
ConnectToAutoJoinChannels()
HandleFriendsControllerInitialization()
OpenPrivateChat(System.String)
OpenPublicChat(System.String)
HandleViewCloseRequest()
HandleFriendshipUpdated(System.String, DCL.Social.Friends.FriendshipAction)
HandleUserStatusChanged(System.String, UserStatus)
<HandleMessageAdded()
HandleMessageAdded(DCL.Interface.ChatMessage[])
<HandleFriendsWithDirectMessagesAdded()
HandleFriendsWithDirectMessagesAdded(System.Collections.Generic.List[FriendWithDirectMessages])
CreatePrivateChatModel(DCL.Interface.ChatMessage, UserProfile)
ExtractRecipientId(DCL.Interface.ChatMessage)
OnUserProfileUpdate(UserProfile)
SearchChats(System.String)
ShowMorePrivateChats()
UpdateMoreChannelsToLoadHint()
RequestFriendsWithDirectMessages()
HidePrivateChatsLoadingWhenTimeout()
RequestFriendsWithDirectMessagesFromSearch(System.String, System.Int32)
HandleChannelUpdated(DCL.Chat.Channels.Channel)
ClearOfflineUnseenMessages(System.String)
HandleAutoChannelJoined(DCL.Chat.Channels.Channel)
HandleChannelJoined(DCL.Chat.Channels.Channel)
ReportChannelJoinedToAnalytics(DCL.Chat.Channels.Channel, System.String)
HandleJoinChannelError(System.String, DCL.Chat.Channels.ChannelErrorCode)
HandleLeaveChannelError(System.String, DCL.Chat.Channels.ChannelErrorCode)
HandleChannelLeft(System.String)
HandleChannelOpened(System.String, System.String)
HandleAskForJoinChannel(System.String)
HandleAskForJoinChannelAfterRendererState(System.Boolean, System.Boolean)
RequestUnreadMessages()
RequestUnreadChannelsMessages()
OpenChannelSearch()
HideSearchLoadingWhenTimeout()
OnAllowedToCreateChannelsChanged(System.Boolean)
SetAutomaticChannelsInfoUpdatingActive(System.Boolean)
ReloadChannelsInfoPeriodically()
GetCurrentChannelsInfo()
OpenWalletReadme()
SignUp()
CopyChannelNameToClipboard(System.String)