< Summary

Class:DCL.Chat.Notifications.ChatNotificationController
Assembly:NotificationMessagesHUD
File(s):/tmp/workspace/unity-renderer/unity-renderer/Assets/Scripts/MainScripts/DCL/Controllers/HUD/NotificationMessagesHUD/ChatNotificationController.cs
Covered lines:86
Uncovered lines:13
Coverable lines:99
Total lines:203
Line coverage:86.8% (86 of 99)
Covered branches:0
Total branches:0

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity NPath complexity Sequence coverage
ChatNotificationController(...)0%110100%
SetVisibility(...)0%5.024060%
Dispose()0%110100%
VisiblePanelsChanged(...)0%2100%
HandleMessageAdded(...)0%14.5813078.95%
AddNotification()0%29.9927084%
ResetFadeOut(...)0%330100%
TogglePanelBackground(...)0%6200%
WaitThenFadeOutNotifications()0%10.378066.67%
ExtractPeerId(...)0%220100%
ResetVisibility(...)0%110100%
IsProfanityFilteringEnabled()0%110100%

File(s)

/tmp/workspace/unity-renderer/unity-renderer/Assets/Scripts/MainScripts/DCL/Controllers/HUD/NotificationMessagesHUD/ChatNotificationController.cs

#LineLine coverage
 1using System.Collections.Generic;
 2using System.Threading;
 3using Cysharp.Threading.Tasks;
 4using DCL.Interface;
 5using DCL.Helpers;
 6using UnityEngine;
 7using System;
 8using Channel = DCL.Chat.Channels.Channel;
 9
 10namespace DCL.Chat.Notifications
 11{
 12    public class ChatNotificationController : IHUD
 13    {
 14        private const int FADEOUT_DELAY = 8000;
 15
 16        private readonly DataStore dataStore;
 17        private readonly IChatController chatController;
 18        private readonly IMainChatNotificationsComponentView mainChatNotificationView;
 19        private readonly ITopNotificationsComponentView topNotificationView;
 20        private readonly IUserProfileBridge userProfileBridge;
 21        private readonly IProfanityFilter profanityFilter;
 822        private readonly TimeSpan maxNotificationInterval = new TimeSpan(0, 1, 0);
 823        private readonly HashSet<string> notificationEntries = new HashSet<string>();
 2424        private BaseVariable<bool> shouldShowNotificationPanel => dataStore.HUDs.shouldShowNotificationPanel;
 825        private BaseVariable<Transform> notificationPanelTransform => dataStore.HUDs.notificationPanelTransform;
 3126        private BaseVariable<Transform> topNotificationPanelTransform => dataStore.HUDs.topNotificationPanelTransform;
 1627        private BaseVariable<HashSet<string>> visibleTaskbarPanels => dataStore.HUDs.visibleTaskbarPanels;
 728        private BaseVariable<string> openedChat => dataStore.HUDs.openedChat;
 829        private CancellationTokenSource fadeOutCT = new CancellationTokenSource();
 30        private UserProfile ownUserProfile;
 31
 832        public ChatNotificationController(DataStore dataStore,
 33            IMainChatNotificationsComponentView mainChatNotificationView,
 34            ITopNotificationsComponentView topNotificationView,
 35            IChatController chatController,
 36            IUserProfileBridge userProfileBridge,
 37            IProfanityFilter profanityFilter)
 38        {
 839            this.dataStore = dataStore;
 840            this.chatController = chatController;
 841            this.userProfileBridge = userProfileBridge;
 842            this.profanityFilter = profanityFilter;
 843            this.mainChatNotificationView = mainChatNotificationView;
 844            this.topNotificationView = topNotificationView;
 845            mainChatNotificationView.OnResetFade += ResetFadeOut;
 846            topNotificationView.OnResetFade += ResetFadeOut;
 847            mainChatNotificationView.OnPanelFocus += TogglePanelBackground;
 848            chatController.OnAddMessage += HandleMessageAdded;
 849            notificationPanelTransform.Set(mainChatNotificationView.GetPanelTransform());
 850            topNotificationPanelTransform.Set(topNotificationView.GetPanelTransform());
 851            visibleTaskbarPanels.OnChange += VisiblePanelsChanged;
 852            shouldShowNotificationPanel.OnChange += ResetVisibility;
 853            ResetVisibility(shouldShowNotificationPanel.Get(), false);
 854        }
 55
 56        public void SetVisibility(bool visible)
 57        {
 858            ResetFadeOut(visible);
 59
 860            if (visible)
 61            {
 862                if (shouldShowNotificationPanel.Get())
 863                    mainChatNotificationView.Show();
 64
 865                topNotificationView.Hide();
 866                mainChatNotificationView.ShowNotifications();
 67            }
 68            else
 69            {
 070                mainChatNotificationView.Hide();
 071                if (!visibleTaskbarPanels.Get().Contains("WorldChatPanel"))
 072                    topNotificationView.Show();
 73            }
 074        }
 75
 76        public void Dispose()
 77        {
 878            chatController.OnAddMessage -= HandleMessageAdded;
 879            visibleTaskbarPanels.OnChange -= VisiblePanelsChanged;
 880            mainChatNotificationView.OnResetFade -= ResetFadeOut;
 881            topNotificationView.OnResetFade -= ResetFadeOut;
 882        }
 83
 84        private void VisiblePanelsChanged(HashSet<string> newList, HashSet<string> oldList)
 85        {
 086            SetVisibility(newList.Count == 0);
 087        }
 88
 89        private void HandleMessageAdded(ChatMessage[] messages)
 90        {
 3191            foreach (var message in messages)
 92            {
 893                if (message.messageType != ChatMessage.Type.PRIVATE &&
 094                    message.messageType != ChatMessage.Type.PUBLIC) return;
 895                ownUserProfile ??= userProfileBridge.GetOwn();
 896                if (message.sender == ownUserProfile.userId) return;
 97
 898                var span = Utils.UnixToDateTimeWithTime((ulong) DateTimeOffset.UtcNow.ToUnixTimeMilliseconds()) -
 99                           Utils.UnixToDateTimeWithTime(message.timestamp);
 100
 9101                if (span >= maxNotificationInterval) return;
 102
 7103                var channel = chatController.GetAllocatedChannel(
 104                    string.IsNullOrEmpty(message.recipient) && message.messageType == ChatMessage.Type.PUBLIC
 105                        ? "nearby"
 106                        : message.recipient);
 7107                if (channel?.Muted ?? false) return;
 108
 109                // TODO: entries may have an inconsistent state. We should update the entry with new data
 7110                if (notificationEntries.Contains(message.messageId)) return;
 7111                notificationEntries.Add(message.messageId);
 112
 7113                AddNotification(message, channel).Forget();
 114            }
 7115        }
 116
 117        private async UniTaskVoid AddNotification(ChatMessage message, Channel channel = null)
 118        {
 7119            var peerId = ExtractPeerId(message);
 7120            var peerProfile = userProfileBridge.Get(peerId);
 7121            var peerName = peerProfile?.userName ?? peerId;
 7122            var peerProfilePicture = peerProfile?.face256SnapshotURL;
 7123            var body = message.body;
 124
 7125            switch (message.messageType)
 126            {
 127                case ChatMessage.Type.PRIVATE:
 2128                    var privateModel = new PrivateChatMessageNotificationModel(message.messageId,
 129                        message.sender, body, message.timestamp, peerName, peerProfilePicture);
 130
 2131                    if (message.sender != openedChat.Get())
 132                    {
 2133                        mainChatNotificationView.AddNewChatNotification(privateModel);
 2134                        if (topNotificationPanelTransform.Get().gameObject.activeInHierarchy)
 2135                            topNotificationView.AddNewChatNotification(privateModel);
 136                    }
 137
 2138                    break;
 139                case ChatMessage.Type.PUBLIC:
 5140                    if (IsProfanityFilteringEnabled())
 141                    {
 2142                        peerName = await profanityFilter.Filter(peerProfile?.userName ?? peerId);
 2143                        body = await profanityFilter.Filter(message.body);
 144                    }
 5145                    var publicModel = new PublicChannelMessageNotificationModel(message.messageId,
 146                        body, channel?.Name ?? message.recipient, channel?.ChannelId, message.timestamp,
 147                        peerName);
 148
 5149                    if (channel?.ChannelId != openedChat.Get())
 150                    {
 5151                        mainChatNotificationView.AddNewChatNotification(publicModel);
 5152                        if (topNotificationPanelTransform.Get().gameObject.activeInHierarchy)
 5153                            topNotificationView.AddNewChatNotification(publicModel);
 154                    }
 155
 156                    break;
 157            }
 7158        }
 159
 160        private void ResetFadeOut(bool fadeOutAfterDelay = false)
 161        {
 8162            mainChatNotificationView.ShowNotifications();
 8163            if (topNotificationPanelTransform.Get().gameObject.activeInHierarchy)
 8164                topNotificationView.ShowNotification();
 165
 8166            fadeOutCT.Cancel();
 8167            fadeOutCT = new CancellationTokenSource();
 168
 8169            if (fadeOutAfterDelay)
 8170                WaitThenFadeOutNotifications(fadeOutCT.Token).Forget();
 8171        }
 172
 173        private void TogglePanelBackground(bool isInFocus)
 174        {
 0175            if (isInFocus)
 0176                mainChatNotificationView.ShowPanel();
 177            else
 0178                mainChatNotificationView.HidePanel();
 0179        }
 180
 181        private async UniTaskVoid WaitThenFadeOutNotifications(CancellationToken cancellationToken)
 182        {
 24183            await UniTask.Delay(FADEOUT_DELAY, cancellationToken: cancellationToken);
 8184            await UniTask.SwitchToMainThread(cancellationToken);
 8185            if (cancellationToken.IsCancellationRequested)
 0186                return;
 187
 8188            mainChatNotificationView.HideNotifications();
 189
 8190            if (topNotificationPanelTransform.Get() != null &&
 191                topNotificationPanelTransform.Get().gameObject.activeInHierarchy)
 0192                topNotificationView.HideNotification();
 8193        }
 194
 195        private string ExtractPeerId(ChatMessage message) =>
 7196            message.sender != ownUserProfile.userId ? message.sender : message.recipient;
 197
 8198        private void ResetVisibility(bool current, bool previous) => SetVisibility(current);
 199
 200        private bool IsProfanityFilteringEnabled() =>
 5201            dataStore.settings.profanityChatFilteringEnabled.Get();
 202    }
 203}