< Summary

Class:UserContextMenu
Assembly:UserContextMenu
File(s):/tmp/workspace/unity-renderer/unity-renderer/Assets/Scripts/MainScripts/DCL/Controllers/UserContextMenu/Scripts/UserContextMenu.cs
Covered lines:112
Uncovered lines:58
Coverable lines:170
Total lines:436
Line coverage:65.8% (112 of 170)
Covered branches:0
Total branches:0

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity NPath complexity Sequence coverage
UserContextMenu()0%110100%
Show(...)0%110100%
Show(...)0%4.034087.5%
SetConfirmationDialog(...)0%2100%
Hide()0%2.152066.67%
SetFriendshipContentActive(...)0%110100%
Awake()0%220100%
Update()0%2100%
OnDisable()0%110100%
ClickReportButton()0%2100%
OnPassportButtonPressed()0%220100%
OnReportUserButtonPressed()0%440100%
OnDeleteUserButtonPressed()0%30500%
UnfriendUser()0%2100%
OnAddFriendButtonPressed()0%30500%
OnCancelFriendRequestButtonPressed()0%12300%
OnMessageButtonPressed()0%12300%
OnBlockUserButtonPressed()0%3.13077.78%
UpdateBlockButton()0%330100%
HideIfClickedOutside()0%12300%
ProcessActiveElements(...)0%110100%
Setup(...)0%11.0211095%
SetupFriendship(...)0%15.0213077.14%
OnFriendActionUpdate(...)0%7.077088.89%
GetSocialAnalytics()0%2.152066.67%
OnValidate()0%2.062075%

File(s)

/tmp/workspace/unity-renderer/unity-renderer/Assets/Scripts/MainScripts/DCL/Controllers/UserContextMenu/Scripts/UserContextMenu.cs

#LineLine coverage
 1using System.Collections.Generic;
 2using System.Linq;
 3using Cysharp.Threading.Tasks;
 4using DCL;
 5using DCL.Interface;
 6using DCL.Social.Friends;
 7using SocialFeaturesAnalytics;
 8using TMPro;
 9using UnityEngine;
 10using UnityEngine.EventSystems;
 11using UnityEngine.UI;
 12
 13/// <summary>
 14/// Contextual menu with different options about an user.
 15/// </summary>
 16[RequireComponent(typeof(RectTransform))]
 17public class UserContextMenu : MonoBehaviour
 18{
 19    internal const string CURRENT_PLAYER_ID = "CurrentPlayerInfoCardId";
 20
 21    const string BLOCK_BTN_BLOCK_TEXT = "Block";
 22    const string BLOCK_BTN_UNBLOCK_TEXT = "Unblock";
 23    const string DELETE_MSG_PATTERN = "Are you sure you want to delete {0} as a friend?";
 24
 25    [System.Flags]
 26    public enum MenuConfigFlags
 27    {
 28        Name = 1,
 29        Friendship = 2,
 30        Message = 4,
 31        Passport = 8,
 32        Block = 16,
 33        Report = 32
 34    }
 35
 36    const MenuConfigFlags headerFlags = MenuConfigFlags.Name | MenuConfigFlags.Friendship;
 37    const MenuConfigFlags usesFriendsApiFlags = MenuConfigFlags.Friendship | MenuConfigFlags.Message;
 38
 39    [Header("Optional: Set Confirmation Dialog")]
 40    [SerializeField] internal UserContextConfirmationDialog confirmationDialog;
 41
 42    [Header("Enable Actions")]
 22343    [SerializeField] internal MenuConfigFlags menuConfigFlags = MenuConfigFlags.Passport | MenuConfigFlags.Block | MenuC
 44
 45    [Header("Containers")]
 46    [SerializeField] internal GameObject headerContainer;
 47    [SerializeField] internal GameObject bodyContainer;
 48    [SerializeField] internal GameObject friendshipContainer;
 49    [SerializeField] internal GameObject friendAddContainer;
 50    [SerializeField] internal GameObject friendRemoveContainer;
 51    [SerializeField] internal GameObject friendRequestedContainer;
 52
 53    [Header("Texts")]
 54    [SerializeField] internal TextMeshProUGUI userName;
 55    [SerializeField] internal TextMeshProUGUI blockText;
 56
 57    [Header("Buttons")]
 58    [SerializeField] internal Button passportButton;
 59    [SerializeField] internal Button blockButton;
 60    [SerializeField] internal Button reportButton;
 61    [SerializeField] internal Button addFriendButton;
 62    [SerializeField] internal Button cancelFriendButton;
 63    [SerializeField] internal Button deleteFriendButton;
 64    [SerializeField] internal Button messageButton;
 65
 66    public static event System.Action<string> OnOpenPrivateChatRequest;
 67
 2368    public bool isVisible => gameObject.activeSelf;
 069    public string UserId => userId;
 70
 71    public event System.Action OnShowMenu;
 72    public event System.Action<string> OnPassport;
 73    public event System.Action<string> OnReport;
 74    public event System.Action<string, bool> OnBlock;
 75    public event System.Action<string> OnUnfriend;
 76    public event System.Action<string> OnAddFriend;
 77    public event System.Action<string> OnCancelFriend;
 78    public event System.Action<string> OnMessage;
 79    public event System.Action OnHide;
 80
 81    private static StringVariable currentPlayerId = null;
 82    private RectTransform rectTransform;
 83    private string userId;
 84    private bool isBlocked;
 85    private MenuConfigFlags currentConfigFlags;
 86    private IConfirmationDialog currentConfirmationDialog;
 087    private bool isNewFriendRequestsEnabled => DataStore.i.featureFlags.flags.Get().IsFeatureEnabled("new_friend_request
 88    internal ISocialAnalytics socialAnalytics;
 89
 90    /// <summary>
 91    /// Show context menu
 92    /// </summary>
 93    /// <param name="userId"> user id</param>
 1094    public void Show(string userId) { Show(userId, menuConfigFlags); }
 95
 96    /// <summary>
 97    /// Show context menu
 98    /// </summary>
 99    /// <param name="userId"> user id</param>
 100    /// <param name="configFlags">set buttons to enable in menu</param>
 101    public void Show(string userId, MenuConfigFlags configFlags)
 102    {
 7103        this.userId = userId;
 7104        ProcessActiveElements(configFlags);
 7105        Setup(userId, configFlags);
 7106        if (currentConfirmationDialog == null && confirmationDialog != null)
 107        {
 0108            SetConfirmationDialog(confirmationDialog);
 109        }
 7110        gameObject.SetActive(true);
 7111        OnShowMenu?.Invoke();
 1112    }
 113
 114    /// <summary>
 115    /// Set confirmation popup to reference use
 116    /// </summary>
 117    /// <param name="confirmationPopup">confirmation popup reference</param>
 0118    public void SetConfirmationDialog(IConfirmationDialog confirmationPopup) { this.currentConfirmationDialog = confirma
 119
 120    /// <summary>
 121    /// Hides the context menu.
 122    /// </summary>
 123    public void Hide()
 124    {
 20125        gameObject.SetActive(false);
 20126        OnHide?.Invoke();
 0127    }
 128
 129    /// <summary>
 130    /// Shows/Hides the friendship container
 131    /// </summary>
 2132    public void SetFriendshipContentActive(bool isActive) => friendshipContainer.SetActive(isActive);
 133
 134    private void Awake()
 135    {
 10136        if (!currentPlayerId)
 137        {
 1138            currentPlayerId = Resources.Load<StringVariable>(CURRENT_PLAYER_ID);
 139        }
 140
 10141        rectTransform = GetComponent<RectTransform>();
 142
 10143        passportButton.onClick.AddListener(OnPassportButtonPressed);
 10144        blockButton.onClick.AddListener(OnBlockUserButtonPressed);
 10145        reportButton.onClick.AddListener(OnReportUserButtonPressed);
 10146        deleteFriendButton.onClick.AddListener(OnDeleteUserButtonPressed);
 10147        addFriendButton.onClick.AddListener(OnAddFriendButtonPressed);
 10148        cancelFriendButton.onClick.AddListener(OnCancelFriendRequestButtonPressed);
 10149        messageButton.onClick.AddListener(OnMessageButtonPressed);
 10150    }
 151
 0152    private void Update() { HideIfClickedOutside(); }
 153
 154    private void OnDisable()
 155    {
 10156        FriendsController.i.OnUpdateFriendship -= OnFriendActionUpdate;
 10157    }
 158
 0159    public void ClickReportButton() => reportButton.onClick.Invoke();
 160
 161    private void OnPassportButtonPressed()
 162    {
 1163        OnPassport?.Invoke(userId);
 1164        currentPlayerId.Set(userId);
 1165        Hide();
 166
 1167        AudioScriptableObjects.dialogOpen.Play(true);
 1168    }
 169
 170    private void OnReportUserButtonPressed()
 171    {
 1172        OnReport?.Invoke(userId);
 1173        WebInterface.SendReportPlayer(userId, UserProfileController.userProfilesCatalog.Get(userId)?.userName);
 1174        GetSocialAnalytics().SendPlayerReport(PlayerReportIssueType.None, 0, PlayerActionSource.ProfileContextMenu);
 1175        Hide();
 1176    }
 177
 178    private void OnDeleteUserButtonPressed()
 179    {
 0180        OnUnfriend?.Invoke(userId);
 181
 0182        if (currentConfirmationDialog != null)
 183        {
 0184            currentConfirmationDialog.SetText(string.Format(DELETE_MSG_PATTERN, UserProfileController.userProfilesCatalo
 0185            currentConfirmationDialog.Show(() =>
 186            {
 0187                UnfriendUser();
 0188            });
 189        }
 190        else
 191        {
 0192            UnfriendUser();
 193        }
 194
 0195        GetSocialAnalytics().SendFriendDeleted(UserProfile.GetOwnUserProfile().userId, userId, PlayerActionSource.Profil
 0196        Hide();
 0197    }
 198
 199    private void UnfriendUser()
 200    {
 0201        FriendsController.i.RemoveFriend(userId);
 0202    }
 203
 204    private void OnAddFriendButtonPressed()
 205    {
 0206        OnAddFriend?.Invoke(userId);
 207
 208        // NOTE: if we don't add this, the friend request has strange behaviors
 0209        UserProfileController.i.AddUserProfileToCatalog(new UserProfileModel()
 210        {
 211            userId = userId,
 212            name = UserProfileController.userProfilesCatalog.Get(userId)?.userName
 213        });
 214
 0215        if (isNewFriendRequestsEnabled)
 216        {
 0217            DataStore.i.HUDs.sendFriendRequest.Set(userId);
 0218            DataStore.i.HUDs.sendFriendRequestSource.Set((int)PlayerActionSource.ProfileContextMenu);
 219        }
 220        else
 221        {
 0222            FriendsController.i.RequestFriendship(userId);
 0223            GetSocialAnalytics().SendFriendRequestSent(UserProfile.GetOwnUserProfile().userId, userId, 0, PlayerActionSo
 224        }
 0225    }
 226
 227    private void OnCancelFriendRequestButtonPressed()
 228    {
 0229        OnCancelFriend?.Invoke(userId);
 230
 0231        if (isNewFriendRequestsEnabled)
 0232            FriendsController.i.CancelRequestByUserIdAsync(userId).Forget();
 233        else
 0234            FriendsController.i.CancelRequestByUserId(userId);
 235
 0236        GetSocialAnalytics().SendFriendRequestCancelled(UserProfile.GetOwnUserProfile().userId, userId, PlayerActionSour
 0237    }
 238
 239    private void OnMessageButtonPressed()
 240    {
 0241        OnMessage?.Invoke(userId);
 0242        OnOpenPrivateChatRequest?.Invoke(userId);
 0243        Hide();
 0244    }
 245
 246    private void OnBlockUserButtonPressed()
 247    {
 1248        bool blockUser = !isBlocked;
 1249        OnBlock?.Invoke(userId, blockUser);
 1250        if (blockUser)
 251        {
 1252            WebInterface.SendBlockPlayer(userId);
 1253            GetSocialAnalytics().SendPlayerBlocked(FriendsController.i.IsFriend(userId), PlayerActionSource.ProfileConte
 254        }
 255        else
 256        {
 0257            WebInterface.SendUnblockPlayer(userId);
 0258            GetSocialAnalytics().SendPlayerUnblocked(FriendsController.i.IsFriend(userId), PlayerActionSource.ProfileCon
 259        }
 1260        Hide();
 1261    }
 262
 10263    private void UpdateBlockButton() { blockText.text = isBlocked ? BLOCK_BTN_UNBLOCK_TEXT : BLOCK_BTN_BLOCK_TEXT; }
 264
 265    private void HideIfClickedOutside()
 266    {
 0267        if (!Input.GetMouseButtonDown(0)) return;
 0268        var pointerEventData = new PointerEventData(EventSystem.current)
 269        {
 270            position = Input.mousePosition
 271        };
 0272        var raycastResults = new List<RaycastResult>();
 0273        EventSystem.current.RaycastAll(pointerEventData, raycastResults);
 274
 0275        if (raycastResults.All(result => result.gameObject != gameObject))
 0276            Hide();
 0277    }
 278
 279    private void ProcessActiveElements(MenuConfigFlags flags)
 280    {
 30281        headerContainer.SetActive((flags & headerFlags) != 0);
 30282        userName.gameObject.SetActive((flags & MenuConfigFlags.Name) != 0);
 30283        friendshipContainer.SetActive((flags & MenuConfigFlags.Friendship) != 0);
 30284        deleteFriendButton.gameObject.SetActive((flags & MenuConfigFlags.Friendship) != 0);
 30285        passportButton.gameObject.SetActive((flags & MenuConfigFlags.Passport) != 0);
 30286        blockButton.gameObject.SetActive((flags & MenuConfigFlags.Block) != 0);
 30287        reportButton.gameObject.SetActive((flags & MenuConfigFlags.Report) != 0);
 30288        messageButton.gameObject.SetActive((flags & MenuConfigFlags.Message) != 0);
 30289    }
 290
 291    private void Setup(string userId, MenuConfigFlags configFlags)
 292    {
 7293        this.userId = userId;
 294
 7295        UserProfile profile = UserProfileController.userProfilesCatalog.Get(userId);
 7296        bool userHasWallet = profile?.hasConnectedWeb3 ?? false;
 297
 7298        if (!userHasWallet || !UserProfile.GetOwnUserProfile().hasConnectedWeb3)
 299        {
 1300            configFlags &= ~usesFriendsApiFlags;
 301        }
 302
 7303        currentConfigFlags = configFlags;
 7304        ProcessActiveElements(configFlags);
 305
 7306        if ((configFlags & MenuConfigFlags.Block) != 0)
 307        {
 5308            isBlocked = UserProfile.GetOwnUserProfile().blocked.Contains(userId);
 5309            UpdateBlockButton();
 310        }
 7311        if ((configFlags & MenuConfigFlags.Name) != 0)
 312        {
 5313            string name = profile?.userName;
 5314            userName.text = name;
 315        }
 7316        if ((configFlags & usesFriendsApiFlags) != 0)
 317        {
 6318            if (FriendsController.i.friends.TryGetValue(userId, out UserStatus status))
 319            {
 0320                SetupFriendship(status.friendshipStatus);
 321            }
 322            else
 323            {
 6324                SetupFriendship(FriendshipStatus.NOT_FRIEND);
 325            }
 6326            FriendsController.i.OnUpdateFriendship -= OnFriendActionUpdate;
 6327            FriendsController.i.OnUpdateFriendship += OnFriendActionUpdate;
 328        }
 7329    }
 330
 331    private void SetupFriendship(FriendshipStatus friendshipStatus)
 332    {
 12333        bool friendshipEnabled = (currentConfigFlags & MenuConfigFlags.Friendship) != 0;
 12334        bool messageEnabled = (currentConfigFlags & MenuConfigFlags.Message) != 0;
 335
 12336        if (friendshipStatus == FriendshipStatus.FRIEND)
 337        {
 2338            if (friendshipEnabled)
 339            {
 1340                friendAddContainer.SetActive(false);
 1341                friendRemoveContainer.SetActive(true);
 1342                friendRequestedContainer.SetActive(false);
 1343                deleteFriendButton.gameObject.SetActive(true);
 344            }
 2345            if (messageEnabled)
 346            {
 1347                messageButton.gameObject.SetActive(true);
 348            }
 349        }
 10350        else if (friendshipStatus == FriendshipStatus.REQUESTED_TO)
 351        {
 2352            if (friendshipEnabled)
 353            {
 1354                friendAddContainer.SetActive(false);
 1355                friendRemoveContainer.SetActive(false);
 1356                friendRequestedContainer.SetActive(true);
 1357                deleteFriendButton.gameObject.SetActive(false);
 358            }
 2359            if (messageEnabled)
 360            {
 1361                messageButton.gameObject.SetActive(false);
 362            }
 363        }
 8364        else if (friendshipStatus == FriendshipStatus.NOT_FRIEND)
 365        {
 8366            if (friendshipEnabled)
 367            {
 6368                friendAddContainer.SetActive(true);
 6369                friendRemoveContainer.SetActive(false);
 6370                friendRequestedContainer.SetActive(false);
 6371                deleteFriendButton.gameObject.SetActive(false);
 372            }
 8373            if (messageEnabled)
 374            {
 6375                messageButton.gameObject.SetActive(false);
 376            }
 377        }
 0378        else if (friendshipStatus == FriendshipStatus.REQUESTED_FROM)
 379        {
 0380            if (friendshipEnabled)
 381            {
 0382                friendAddContainer.SetActive(true);
 0383                friendRemoveContainer.SetActive(false);
 0384                friendRequestedContainer.SetActive(false);
 0385                deleteFriendButton.gameObject.SetActive(false);
 386            }
 0387            if (messageEnabled)
 388            {
 0389                messageButton.gameObject.SetActive(false);
 390            }
 391        }
 4392    }
 393
 394    private void OnFriendActionUpdate(string userId, FriendshipAction action)
 395    {
 6396        if (this.userId != userId)
 397        {
 0398            return;
 399        }
 400
 6401        if (action == FriendshipAction.APPROVED)
 402        {
 2403            SetupFriendship(FriendshipStatus.FRIEND);
 404        }
 4405        else if (action == FriendshipAction.REQUESTED_TO)
 406        {
 2407            SetupFriendship(FriendshipStatus.REQUESTED_TO);
 408        }
 2409        else if (action == FriendshipAction.DELETED || action == FriendshipAction.CANCELLED || action == FriendshipActio
 410        {
 2411            SetupFriendship(FriendshipStatus.NOT_FRIEND);
 412        }
 2413    }
 414
 415    private ISocialAnalytics GetSocialAnalytics()
 416    {
 2417        if (socialAnalytics == null)
 418        {
 0419            socialAnalytics = new SocialAnalytics(
 420                DCL.Environment.i.platform.serviceProviders.analytics,
 421                new UserProfileWebInterfaceBridge());
 422        }
 423
 2424        return socialAnalytics;
 425    }
 426
 427#if UNITY_EDITOR
 428    //This is just to process buttons and container visibility on editor
 429    private void OnValidate()
 430    {
 16431        if (headerContainer == null)
 0432            return;
 16433        ProcessActiveElements(menuConfigFlags);
 16434    }
 435#endif
 436}