< 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:101
Uncovered lines:15
Coverable lines:116
Total lines:241
Line coverage:87% (101 of 116)
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%
HandleFriendRequestAdded(...)0%10.3610084.62%
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;
 9using DCl.Social.Friends;
 10using DCL.Social.Friends;
 11
 12namespace DCL.Chat.Notifications
 13{
 14    public class ChatNotificationController : IHUD
 15    {
 16        private const int FADEOUT_DELAY = 8000;
 17        private const string NEW_FRIEND_REQUESTS_FLAG = "new_friend_requests";
 18
 19        private readonly DataStore dataStore;
 20        private readonly IChatController chatController;
 21        private readonly IFriendsController friendsController;
 22        private readonly IMainChatNotificationsComponentView mainChatNotificationView;
 23        private readonly ITopNotificationsComponentView topNotificationView;
 24        private readonly IUserProfileBridge userProfileBridge;
 25        private readonly IProfanityFilter profanityFilter;
 926        private readonly TimeSpan maxNotificationInterval = new TimeSpan(0, 1, 0);
 927        private readonly HashSet<string> notificationEntries = new HashSet<string>();
 2728        private BaseVariable<bool> shouldShowNotificationPanel => dataStore.HUDs.shouldShowNotificationPanel;
 929        private BaseVariable<Transform> notificationPanelTransform => dataStore.HUDs.notificationPanelTransform;
 3530        private BaseVariable<Transform> topNotificationPanelTransform => dataStore.HUDs.topNotificationPanelTransform;
 1831        private BaseVariable<HashSet<string>> visibleTaskbarPanels => dataStore.HUDs.visibleTaskbarPanels;
 732        private BaseVariable<string> openedChat => dataStore.HUDs.openedChat;
 933        private CancellationTokenSource fadeOutCT = new CancellationTokenSource();
 34        private UserProfile ownUserProfile;
 135        private bool isNewFriendRequestsEnabled => dataStore.featureFlags.flags.Get().IsFeatureEnabled(NEW_FRIEND_REQUES
 36
 937        public ChatNotificationController(DataStore dataStore,
 38            IMainChatNotificationsComponentView mainChatNotificationView,
 39            ITopNotificationsComponentView topNotificationView,
 40            IChatController chatController,
 41            IFriendsController friendsController,
 42            IUserProfileBridge userProfileBridge,
 43            IProfanityFilter profanityFilter)
 44        {
 945            this.dataStore = dataStore;
 946            this.chatController = chatController;
 947            this.friendsController = friendsController;
 948            this.userProfileBridge = userProfileBridge;
 949            this.profanityFilter = profanityFilter;
 950            this.mainChatNotificationView = mainChatNotificationView;
 951            this.topNotificationView = topNotificationView;
 952            mainChatNotificationView.OnResetFade += ResetFadeOut;
 953            topNotificationView.OnResetFade += ResetFadeOut;
 954            mainChatNotificationView.OnPanelFocus += TogglePanelBackground;
 955            chatController.OnAddMessage += HandleMessageAdded;
 956            friendsController.OnAddFriendRequest += HandleFriendRequestAdded;
 957            notificationPanelTransform.Set(mainChatNotificationView.GetPanelTransform());
 958            topNotificationPanelTransform.Set(topNotificationView.GetPanelTransform());
 959            visibleTaskbarPanels.OnChange += VisiblePanelsChanged;
 960            shouldShowNotificationPanel.OnChange += ResetVisibility;
 961            ResetVisibility(shouldShowNotificationPanel.Get(), false);
 962        }
 63
 64        public void SetVisibility(bool visible)
 65        {
 966            ResetFadeOut(visible);
 67
 968            if (visible)
 69            {
 970                if (shouldShowNotificationPanel.Get())
 971                    mainChatNotificationView.Show();
 72
 973                topNotificationView.Hide();
 974                mainChatNotificationView.ShowNotifications();
 75            }
 76            else
 77            {
 078                mainChatNotificationView.Hide();
 079                if (!visibleTaskbarPanels.Get().Contains("WorldChatPanel"))
 080                    topNotificationView.Show();
 81            }
 082        }
 83
 84        public void Dispose()
 85        {
 986            chatController.OnAddMessage -= HandleMessageAdded;
 987            friendsController.OnAddFriendRequest -= HandleFriendRequestAdded;
 988            visibleTaskbarPanels.OnChange -= VisiblePanelsChanged;
 989            mainChatNotificationView.OnResetFade -= ResetFadeOut;
 990            topNotificationView.OnResetFade -= ResetFadeOut;
 991        }
 92
 93        private void VisiblePanelsChanged(HashSet<string> newList, HashSet<string> oldList)
 94        {
 095            SetVisibility(newList.Count == 0);
 096        }
 97
 98        private void HandleMessageAdded(ChatMessage[] messages)
 99        {
 31100            foreach (var message in messages)
 101            {
 8102                if (message.messageType != ChatMessage.Type.PRIVATE &&
 0103                    message.messageType != ChatMessage.Type.PUBLIC) return;
 8104                ownUserProfile ??= userProfileBridge.GetOwn();
 8105                if (message.sender == ownUserProfile.userId) return;
 106
 8107                var span = Utils.UnixToDateTimeWithTime((ulong) DateTimeOffset.UtcNow.ToUnixTimeMilliseconds()) -
 108                           Utils.UnixToDateTimeWithTime(message.timestamp);
 109
 9110                if (span >= maxNotificationInterval) return;
 111
 7112                var channel = chatController.GetAllocatedChannel(
 113                    string.IsNullOrEmpty(message.recipient) && message.messageType == ChatMessage.Type.PUBLIC
 114                        ? "nearby"
 115                        : message.recipient);
 7116                if (channel?.Muted ?? false) return;
 117
 118                // TODO: entries may have an inconsistent state. We should update the entry with new data
 7119                if (notificationEntries.Contains(message.messageId)) return;
 7120                notificationEntries.Add(message.messageId);
 121
 7122                AddNotification(message, channel).Forget();
 123            }
 7124        }
 125
 126        private async UniTaskVoid AddNotification(ChatMessage message, Channel channel = null)
 127        {
 7128            var peerId = ExtractPeerId(message);
 7129            var peerProfile = userProfileBridge.Get(peerId);
 7130            var peerName = peerProfile?.userName ?? peerId;
 7131            var peerProfilePicture = peerProfile?.face256SnapshotURL;
 7132            var body = message.body;
 133
 7134            switch (message.messageType)
 135            {
 136                case ChatMessage.Type.PRIVATE:
 2137                    var privateModel = new PrivateChatMessageNotificationModel(message.messageId,
 138                        message.sender, body, message.timestamp, peerName, peerProfilePicture);
 139
 2140                    if (message.sender != openedChat.Get())
 141                    {
 2142                        mainChatNotificationView.AddNewChatNotification(privateModel);
 2143                        if (topNotificationPanelTransform.Get().gameObject.activeInHierarchy)
 2144                            topNotificationView.AddNewChatNotification(privateModel);
 145                    }
 146
 2147                    break;
 148                case ChatMessage.Type.PUBLIC:
 5149                    if (IsProfanityFilteringEnabled())
 150                    {
 2151                        peerName = await profanityFilter.Filter(peerProfile?.userName ?? peerId);
 2152                        body = await profanityFilter.Filter(message.body);
 153                    }
 5154                    var publicModel = new PublicChannelMessageNotificationModel(message.messageId,
 155                        body, channel?.Name ?? message.recipient, channel?.ChannelId, message.timestamp,
 156                        peerName);
 157
 5158                    if (channel?.ChannelId != openedChat.Get())
 159                    {
 5160                        mainChatNotificationView.AddNewChatNotification(publicModel);
 5161                        if (topNotificationPanelTransform.Get().gameObject.activeInHierarchy)
 5162                            topNotificationView.AddNewChatNotification(publicModel);
 163                    }
 164
 165                    break;
 166            }
 7167        }
 168
 169        private void HandleFriendRequestAdded(FriendRequest friendRequest)
 170        {
 1171            if (!isNewFriendRequestsEnabled)
 0172                return;
 173
 1174            var ownUserProfile = userProfileBridge.GetOwn();
 175
 1176            if (friendRequest.From == ownUserProfile.userId ||
 177                friendRequest.To != ownUserProfile.userId)
 0178                return;
 179
 1180            var friendRequestProfile = userProfileBridge.Get(friendRequest.From);
 1181            var friendRequestName = friendRequestProfile?.userName ?? friendRequest.From;
 1182            var friendRequestProfilePicture = friendRequestProfile?.face256SnapshotURL;
 183
 1184            FriendRequestNotificationModel friendRequestNotificationModel = new FriendRequestNotificationModel(
 185                friendRequest.From,
 186                friendRequestName,
 187                "Friend Request",
 188                $"wants to be your friend.",
 189                (ulong)friendRequest.Timestamp,
 190                friendRequestProfilePicture,
 191                false);
 192
 1193            mainChatNotificationView.AddNewFriendRequestNotification(friendRequestNotificationModel);
 1194            if (topNotificationPanelTransform.Get().gameObject.activeInHierarchy)
 1195                topNotificationView.AddNewFriendRequestNotification(friendRequestNotificationModel);
 1196        }
 197
 198        private void ResetFadeOut(bool fadeOutAfterDelay = false)
 199        {
 9200            mainChatNotificationView.ShowNotifications();
 9201            if (topNotificationPanelTransform.Get().gameObject.activeInHierarchy)
 9202                topNotificationView.ShowNotification();
 203
 9204            fadeOutCT.Cancel();
 9205            fadeOutCT = new CancellationTokenSource();
 206
 9207            if (fadeOutAfterDelay)
 9208                WaitThenFadeOutNotifications(fadeOutCT.Token).Forget();
 9209        }
 210
 211        private void TogglePanelBackground(bool isInFocus)
 212        {
 0213            if (isInFocus)
 0214                mainChatNotificationView.ShowPanel();
 215            else
 0216                mainChatNotificationView.HidePanel();
 0217        }
 218
 219        private async UniTaskVoid WaitThenFadeOutNotifications(CancellationToken cancellationToken)
 220        {
 27221            await UniTask.Delay(FADEOUT_DELAY, cancellationToken: cancellationToken);
 9222            await UniTask.SwitchToMainThread(cancellationToken);
 9223            if (cancellationToken.IsCancellationRequested)
 0224                return;
 225
 9226            mainChatNotificationView.HideNotifications();
 227
 9228            if (topNotificationPanelTransform.Get() != null &&
 229                topNotificationPanelTransform.Get().gameObject.activeInHierarchy)
 0230                topNotificationView.HideNotification();
 9231        }
 232
 233        private string ExtractPeerId(ChatMessage message) =>
 7234            message.sender != ownUserProfile.userId ? message.sender : message.recipient;
 235
 9236        private void ResetVisibility(bool current, bool previous) => SetVisibility(current);
 237
 238        private bool IsProfanityFilteringEnabled() =>
 5239            dataStore.settings.profanityChatFilteringEnabled.Get();
 240    }
 241}