< Summary

Class:ChatEntry
Assembly:ChatHUD
File(s):/tmp/workspace/unity-renderer/unity-renderer/Assets/Scripts/MainScripts/DCL/Controllers/HUD/ChatWidgetHUD/ChatEntry.cs
Covered lines:67
Uncovered lines:48
Coverable lines:115
Total lines:291
Line coverage:58.2% (67 of 115)
Covered branches:0
Total branches:0

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity NPath complexity Sequence coverage
ChatEntry()0%110100%
Populate(...)0%42.9325069.39%
OnPointerClick(...)0%90900%
OnPointerEnter(...)0%2100%
OnPointerExit(...)0%220100%
OnDisable()0%110100%
SetFadeout(...)0%2.382054.55%
Update()0%110100%
Fade()0%7.933018.18%
ProcessHoverPanelTimer()0%9.834028.57%
RemoveTabs(...)0%2.152066.67%
GetDefaultSenderString(...)0%2.152066.67%
UnixTimeStampToLocalDateTime(...)0%110100%

File(s)

/tmp/workspace/unity-renderer/unity-renderer/Assets/Scripts/MainScripts/DCL/Controllers/HUD/ChatWidgetHUD/ChatEntry.cs

#LineLine coverage
 1using DCL.Helpers;
 2using DCL.Interface;
 3using System;
 4using DCL.SettingsCommon;
 5using TMPro;
 6using UnityEngine;
 7using UnityEngine.Events;
 8using UnityEngine.EventSystems;
 9using UnityEngine.Serialization;
 10
 11public class ChatEntry : MonoBehaviour, IPointerClickHandler, IPointerEnterHandler, IPointerExitHandler
 12{
 13    public struct Model
 14    {
 15        public enum SubType
 16        {
 17            NONE,
 18            PRIVATE_FROM,
 19            PRIVATE_TO
 20        }
 21
 22        public ChatMessage.Type messageType;
 23        public string bodyText;
 24        public string senderId;
 25        public string senderName;
 26        public string recipientName;
 27        public string otherUserId;
 28        public ulong timestamp;
 29
 30        public SubType subType;
 31    }
 32
 3733    [SerializeField] internal float timeToFade = 10f;
 3734    [SerializeField] internal float fadeDuration = 5f;
 35
 36    [SerializeField] internal TextMeshProUGUI username;
 37    [SerializeField] internal TextMeshProUGUI body;
 38
 3739    [SerializeField] internal Color worldMessageColor = Color.white;
 40
 41    [FormerlySerializedAs("privateMessageColor")]
 3742    [SerializeField] internal Color privateToMessageColor = Color.white;
 43
 44    [FormerlySerializedAs("privateMessageColor")]
 3745    [SerializeField] internal Color privateFromMessageColor = Color.white;
 46
 3747    [SerializeField] internal Color systemColor = Color.white;
 3748    [SerializeField] internal Color playerNameColor = Color.yellow;
 3749    [SerializeField] internal Color nonPlayerNameColor = Color.white;
 50    [SerializeField] CanvasGroup group;
 3751    [SerializeField] internal float timeToHoverPanel = 1f;
 52
 53    [NonSerialized] public string messageLocalDateTime;
 54
 55    bool fadeEnabled = false;
 56    double fadeoutStartTime;
 57    float hoverPanelTimer = 0;
 58
 59    public RectTransform hoverPanelPositionReference;
 60    public RectTransform contextMenuPositionReference;
 61
 062    public Model model { get; private set; }
 63
 64    public event UnityAction<string> OnPress;
 65    public event UnityAction<ChatEntry> OnPressRightButton;
 66    public event UnityAction<ChatEntry> OnTriggerHover;
 67    public event UnityAction OnCancelHover;
 68
 69    public void Populate(Model chatEntryModel)
 70    {
 3271        this.model = chatEntryModel;
 72
 3273        string userString = GetDefaultSenderString(chatEntryModel.senderName);
 74
 3275        if (chatEntryModel.subType == Model.SubType.PRIVATE_FROM)
 76        {
 677            userString = $"<b>From {chatEntryModel.senderName}:</b>";
 678        }
 2679        else if (chatEntryModel.subType == Model.SubType.PRIVATE_TO)
 80        {
 281            userString = $"<b>To {chatEntryModel.recipientName}:</b>";
 82        }
 83
 3284        switch (chatEntryModel.messageType)
 85        {
 86            case ChatMessage.Type.PUBLIC:
 1887                body.color = worldMessageColor;
 88
 1889                if (username != null)
 1890                    username.color = chatEntryModel.senderName == UserProfile.GetOwnUserProfile().userName ? playerNameC
 1891                break;
 92            case ChatMessage.Type.PRIVATE:
 1393                body.color = worldMessageColor;
 94
 1395                if (username != null)
 96                {
 697                    if (model.subType == Model.SubType.PRIVATE_TO)
 298                        username.color = privateToMessageColor;
 99                    else
 4100                        username.color = privateFromMessageColor;
 101                }
 102
 4103                break;
 104            case ChatMessage.Type.SYSTEM:
 1105                body.color = systemColor;
 106
 1107                if (username != null)
 1108                    username.color = systemColor;
 109                break;
 110        }
 111
 32112        chatEntryModel.bodyText = RemoveTabs(chatEntryModel.bodyText);
 113
 32114        if (username != null && !string.IsNullOrEmpty(userString))
 115        {
 25116            if (username != null)
 25117                username.text = userString;
 118
 25119            body.text = $"{userString} {chatEntryModel.bodyText}";
 25120        }
 121        else
 122        {
 7123            if (username != null)
 0124                username.text = "";
 125
 7126            body.text = $"{chatEntryModel.bodyText}";
 127        }
 128
 32129        messageLocalDateTime = UnixTimeStampToLocalDateTime(chatEntryModel.timestamp).ToString();
 130
 32131        Utils.ForceUpdateLayout(transform as RectTransform);
 132
 32133        if (fadeEnabled)
 0134            group.alpha = 0;
 135
 32136        if (HUDAudioHandler.i != null)
 137        {
 138            // Check whether or not this message is new, and chat sounds are enabled in settings
 0139            if (chatEntryModel.timestamp > HUDAudioHandler.i.chatLastCheckedTimestamp && Settings.i.audioSettings.Data.c
 140            {
 0141                switch (chatEntryModel.messageType)
 142                {
 143                    case ChatMessage.Type.PUBLIC:
 144                        // Check whether or not the message was sent by the local player
 0145                        if (chatEntryModel.senderId == UserProfile.GetOwnUserProfile().userId)
 0146                            AudioScriptableObjects.chatSend.Play(true);
 147                        else
 0148                            AudioScriptableObjects.chatReceiveGlobal.Play(true);
 0149                        break;
 150                    case ChatMessage.Type.PRIVATE:
 0151                        switch (chatEntryModel.subType)
 152                        {
 153                            case Model.SubType.PRIVATE_FROM:
 0154                                AudioScriptableObjects.chatReceivePrivate.Play(true);
 0155                                break;
 156                            case Model.SubType.PRIVATE_TO:
 0157                                AudioScriptableObjects.chatSend.Play(true);
 0158                                break;
 159                            default:
 160                                break;
 161                        }
 162                        break;
 163                    case ChatMessage.Type.SYSTEM:
 0164                        AudioScriptableObjects.chatReceiveGlobal.Play(true);
 165                        break;
 166                    default:
 167                        break;
 168                }
 169            }
 170
 0171            HUDAudioHandler.i.RefreshChatLastCheckedTimestamp();
 172        }
 32173    }
 174
 175    public void OnPointerClick(PointerEventData pointerEventData)
 176    {
 0177        if (pointerEventData.button == PointerEventData.InputButton.Left)
 178        {
 0179            if (model.messageType != ChatMessage.Type.PRIVATE)
 0180                return;
 181
 0182            OnPress?.Invoke(model.otherUserId);
 0183        }
 0184        else if (pointerEventData.button == PointerEventData.InputButton.Right)
 185        {
 0186            if ((model.messageType != ChatMessage.Type.PUBLIC && model.messageType != ChatMessage.Type.PRIVATE) ||
 187                model.senderId == UserProfile.GetOwnUserProfile().userId)
 0188                return;
 189
 0190            OnPressRightButton?.Invoke(this);
 191        }
 0192    }
 193
 0194    public void OnPointerEnter(PointerEventData pointerEventData) { hoverPanelTimer = timeToHoverPanel; }
 195
 196    public void OnPointerExit(PointerEventData pointerEventData)
 197    {
 29198        hoverPanelTimer = 0f;
 199
 29200        OnCancelHover?.Invoke();
 28201    }
 202
 58203    void OnDisable() { OnPointerExit(null); }
 204
 205    public void SetFadeout(bool enabled)
 206    {
 29207        if (!enabled)
 208        {
 29209            group.alpha = 1;
 29210            group.blocksRaycasts = true;
 29211            group.interactable = true;
 29212            fadeEnabled = false;
 29213            return;
 214        }
 215
 0216        fadeoutStartTime = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds() / 1000.0;
 0217        fadeEnabled = true;
 0218        group.blocksRaycasts = false;
 0219        group.interactable = false;
 0220    }
 221
 222    void Update()
 223    {
 3224        Fade();
 225
 3226        ProcessHoverPanelTimer();
 3227    }
 228
 229    void Fade()
 230    {
 3231        if (!fadeEnabled)
 3232            return;
 233
 234        //NOTE(Brian): Small offset using normalized Y so we keep the cascade effect
 0235        double yOffset = (transform as RectTransform).anchoredPosition.y / (double)Screen.height * 2.0;
 236
 0237        double fadeTime = Math.Max(model.timestamp / 1000.0, fadeoutStartTime) + timeToFade - yOffset;
 0238        double currentTime = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds() / 1000.0;
 239
 0240        if (currentTime > fadeTime)
 241        {
 0242            double timeSinceFadeTime = currentTime - fadeTime;
 0243            group.alpha = Mathf.Clamp01(1 - (float)(timeSinceFadeTime / fadeDuration));
 0244        }
 245        else
 246        {
 0247            group.alpha += (1 - group.alpha) * 0.05f;
 248        }
 0249    }
 250
 251    void ProcessHoverPanelTimer()
 252    {
 3253        if (hoverPanelTimer <= 0f)
 3254            return;
 255
 0256        hoverPanelTimer -= Time.deltaTime;
 0257        if (hoverPanelTimer <= 0f)
 258        {
 0259            hoverPanelTimer = 0f;
 260
 0261            OnTriggerHover?.Invoke(this);
 262        }
 0263    }
 264
 265    string RemoveTabs(string text)
 266    {
 32267        if (string.IsNullOrEmpty(text))
 0268            return "";
 269
 270        //NOTE(Brian): ContentSizeFitter doesn't fare well with tabs, so i'm replacing these
 271        //             with spaces.
 32272        return text.Replace("\t", "    ");
 273    }
 274
 275    string GetDefaultSenderString(string sender)
 276    {
 32277        if (!string.IsNullOrEmpty(sender))
 32278            return $"<b>{sender}:</b>";
 279
 0280        return "";
 281    }
 282
 283    DateTime UnixTimeStampToLocalDateTime(ulong unixTimeStampMilliseconds)
 284    {
 285        // TODO see if we can simplify with 'DateTimeOffset.FromUnixTimeMilliseconds'
 32286        System.DateTime dtDateTime = new DateTime(1970, 1, 1, 0, 0, 0, 0, System.DateTimeKind.Utc);
 32287        dtDateTime = dtDateTime.AddMilliseconds(unixTimeStampMilliseconds).ToLocalTime();
 288
 32289        return dtDateTime;
 290    }
 291}