< Summary

Class:PlayerInfoCardHUDController
Assembly:PlayerInfoCardHUD
File(s):/tmp/workspace/unity-renderer/unity-renderer/Assets/Scripts/MainScripts/DCL/Controllers/HUD/PlayerInfoCardHUD/PlayerInfoCardHUDController.cs
Covered lines:110
Uncovered lines:72
Coverable lines:182
Total lines:410
Line coverage:60.4% (110 of 182)
Covered branches:0
Total branches:0
Covered methods:17
Total methods:31
Method coverage:54.8% (17 of 31)

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity NPath complexity Sequence coverage
PlayerInfoCardHUDController(...)0%110100%
CloseCard()0%2100%
OnCloseButtonPressed(...)0%2100%
AddPlayerAsFriend()0%2100%
CancelInvitation()0%2100%
CancelInvitationAsync()0%30500%
AcceptFriendRequest()0%2100%
AcceptFriendRequestAsync()0%30500%
RejectFriendRequest()0%2100%
RejectFriendRequestAsync()0%30500%
OnCurrentPlayerIdChanged(...)0%110100%
OnCurrentPlayerIdUpdated(...)0%550100%
>c__DisplayClass33_0/<<OnCurrentPlayerIdUpdated()0%3.213071.43%
SetUserProfile(...)0%110100%
>c__DisplayClass34_0/<<SetUserProfile()0%5.673033.33%
AsyncSetUserProfile()0%9.738070%
SetVisibility(...)0%20400%
BlockPlayer()0%20400%
UnblockPlayer()0%6200%
ReportPlayer()0%12300%
Dispose()0%990100%
OnFriendStatusUpdated(...)0%6200%
UpdateFriendshipInteraction()0%2.262060%
CanBeFriends()0%440100%
LoadAndShowWearables()0%4.594066.67%
IsBlocked(...)0%220100%
FilterName()0%64050%
FilterDescription()0%64050%
IsProfanityFilteringEnabled()0%110100%

File(s)

/tmp/workspace/unity-renderer/unity-renderer/Assets/Scripts/MainScripts/DCL/Controllers/HUD/PlayerInfoCardHUD/PlayerInfoCardHUDController.cs

#LineLine coverage
 1using Cysharp.Threading.Tasks;
 2using DCL;
 3using DCL.Helpers;
 4using DCL.Interface;
 5using DCL.ProfanityFiltering;
 6using DCL.Social.Friends;
 7using DCL.Tasks;
 8using DCLServices.WearablesCatalogService;
 9using SocialFeaturesAnalytics;
 10using System;
 11using System.Collections.Generic;
 12using System.Linq;
 13using System.Threading;
 14using UnityEngine;
 15using UnityEngine.Assertions;
 16using Object = UnityEngine.Object;
 17
 18public class PlayerInfoCardHUDController : IHUD
 19{
 20    internal readonly PlayerInfoCardHUDView view;
 21    internal readonly StringVariable currentPlayerId;
 22    internal UserProfile currentUserProfile;
 23
 24    private UserProfile viewingUserProfile;
 6225    private UserProfile ownUserProfile => userProfileBridge.GetOwn();
 26
 27    private readonly IFriendsController friendsController;
 28    private readonly InputAction_Trigger toggleFriendsTrigger;
 29    private readonly InputAction_Trigger closeWindowTrigger;
 30    private readonly InputAction_Trigger toggleWorldChatTrigger;
 31    private readonly IUserProfileBridge userProfileBridge;
 32    private readonly IWearablesCatalogService wearablesCatalogService;
 33    private readonly IProfanityFilter profanityFilter;
 34    private readonly DataStore dataStore;
 35    private readonly BooleanVariable playerInfoCardVisibleState;
 1936    private readonly List<string> loadedWearables = new ();
 37    private readonly ISocialAnalytics socialAnalytics;
 38
 1939    private CancellationTokenSource friendOperationsCancellationToken = new ();
 1940    private CancellationTokenSource setUserProfileCancellationToken = new ();
 41    private double passportOpenStartTime;
 3142    private bool isFriendsEnabled => dataStore.featureFlags.flags.Get().IsFeatureEnabled("friends_enabled");
 43
 1944    public PlayerInfoCardHUDController(IFriendsController friendsController,
 45        StringVariable currentPlayerIdData,
 46        IUserProfileBridge userProfileBridge,
 47        IWearablesCatalogService wearablesCatalogService,
 48        ISocialAnalytics socialAnalytics,
 49        IProfanityFilter profanityFilter,
 50        DataStore dataStore,
 51        BooleanVariable playerInfoCardVisibleState)
 52    {
 1953        this.friendsController = friendsController;
 1954        view = PlayerInfoCardHUDView.CreateView();
 55
 1956        view.Initialize(() => OnCloseButtonPressed(),
 57            ReportPlayer, BlockPlayer, UnblockPlayer,
 58            AddPlayerAsFriend, CancelInvitation, AcceptFriendRequest, RejectFriendRequest);
 59
 1960        currentPlayerId = currentPlayerIdData;
 1961        this.userProfileBridge = userProfileBridge;
 1962        this.wearablesCatalogService = wearablesCatalogService;
 1963        this.socialAnalytics = socialAnalytics;
 1964        this.profanityFilter = profanityFilter;
 1965        this.dataStore = dataStore;
 1966        this.playerInfoCardVisibleState = playerInfoCardVisibleState;
 1967        currentPlayerId.OnSame += OnCurrentPlayerIdUpdated;
 1968        currentPlayerId.OnChange += OnCurrentPlayerIdChanged;
 1969        OnCurrentPlayerIdUpdated(currentPlayerId);
 70
 1971        toggleFriendsTrigger = Resources.Load<InputAction_Trigger>("ToggleFriends");
 1972        toggleFriendsTrigger.OnTriggered -= OnCloseButtonPressed;
 1973        toggleFriendsTrigger.OnTriggered += OnCloseButtonPressed;
 74
 1975        closeWindowTrigger = Resources.Load<InputAction_Trigger>("CloseWindow");
 1976        closeWindowTrigger.OnTriggered -= OnCloseButtonPressed;
 1977        closeWindowTrigger.OnTriggered += OnCloseButtonPressed;
 78
 1979        toggleWorldChatTrigger = Resources.Load<InputAction_Trigger>("ToggleWorldChat");
 1980        toggleWorldChatTrigger.OnTriggered -= OnCloseButtonPressed;
 1981        toggleWorldChatTrigger.OnTriggered += OnCloseButtonPressed;
 82
 1983        friendsController.OnUpdateFriendship -= OnFriendStatusUpdated;
 1984        friendsController.OnUpdateFriendship += OnFriendStatusUpdated;
 1985    }
 86
 87    private void CloseCard()
 88    {
 089        friendOperationsCancellationToken = friendOperationsCancellationToken.SafeRestart();
 090        currentPlayerId.Set(null);
 091    }
 92
 93    private void OnCloseButtonPressed(DCLAction_Trigger action = DCLAction_Trigger.CloseWindow)
 94    {
 095        CloseCard();
 096    }
 97
 98    private void AddPlayerAsFriend()
 99    {
 0100        dataStore.HUDs.sendFriendRequest.Set(currentPlayerId, true);
 0101        dataStore.HUDs.sendFriendRequestSource.Set((int)PlayerActionSource.Passport);
 0102    }
 103
 104    private void CancelInvitation()
 105    {
 0106        friendOperationsCancellationToken = friendOperationsCancellationToken.SafeRestart();
 0107        CancelInvitationAsync(friendOperationsCancellationToken.Token).Forget();
 0108    }
 109
 110    private async UniTaskVoid CancelInvitationAsync(CancellationToken cancellationToken)
 111    {
 112        try
 113        {
 0114            FriendRequest request = await friendsController.CancelRequestByUserIdAsync(currentPlayerId,
 115                cancellationToken);
 116
 0117            socialAnalytics.SendFriendRequestCancelled(request.From, request.To, PlayerActionSource.Passport.ToString(),
 0118        }
 0119        catch (Exception e) when (e is not OperationCanceledException)
 120        {
 0121            e.ReportFriendRequestErrorToAnalyticsByUserId(currentPlayerId, PlayerActionSource.Passport.ToString(),
 122                friendsController, socialAnalytics);
 123
 0124            throw;
 125        }
 0126    }
 127
 128    private void AcceptFriendRequest()
 129    {
 0130        friendOperationsCancellationToken = friendOperationsCancellationToken.SafeRestart();
 0131        AcceptFriendRequestAsync(friendOperationsCancellationToken.Token).Forget();
 0132    }
 133
 134    private async UniTaskVoid AcceptFriendRequestAsync(CancellationToken cancellationToken)
 135    {
 136        try
 137        {
 0138            FriendRequest request = friendsController.GetAllocatedFriendRequestByUser(currentPlayerId);
 139
 0140            request = await friendsController.AcceptFriendshipAsync(request.FriendRequestId,
 141                cancellationToken);
 142
 0143            socialAnalytics.SendFriendRequestApproved(request.From, request.To, PlayerActionSource.Passport.ToString(),
 144                request.HasBodyMessage, request.FriendRequestId);
 0145        }
 0146        catch (Exception e) when (e is not OperationCanceledException)
 147        {
 0148            e.ReportFriendRequestErrorToAnalyticsByUserId(currentPlayerId, PlayerActionSource.Passport.ToString(),
 149                friendsController, socialAnalytics);
 150
 0151            throw;
 152        }
 0153    }
 154
 155    private void RejectFriendRequest()
 156    {
 0157        friendOperationsCancellationToken = friendOperationsCancellationToken.SafeRestart();
 0158        RejectFriendRequestAsync(friendOperationsCancellationToken.Token).Forget();
 0159    }
 160
 161    private async UniTaskVoid RejectFriendRequestAsync(CancellationToken cancellationToken)
 162    {
 163        try
 164        {
 0165            FriendRequest request = friendsController.GetAllocatedFriendRequestByUser(currentPlayerId);
 166
 0167            request = await friendsController.RejectFriendshipAsync(request.FriendRequestId,
 168                cancellationToken);
 169
 0170            socialAnalytics.SendFriendRequestRejected(request.From, request.To,
 171                PlayerActionSource.Passport.ToString(), request.HasBodyMessage, request.FriendRequestId);
 0172        }
 0173        catch (Exception e) when (e is not OperationCanceledException)
 174        {
 0175            e.ReportFriendRequestErrorToAnalyticsByUserId(currentPlayerId, PlayerActionSource.Passport.ToString(),
 176                friendsController, socialAnalytics);
 177
 0178            throw;
 179        }
 0180    }
 181
 182    private void OnCurrentPlayerIdChanged(string current, string previous)
 183    {
 25184        OnCurrentPlayerIdUpdated(current);
 25185    }
 186
 187    private void OnCurrentPlayerIdUpdated(string current)
 188    {
 44189        if (currentUserProfile != null)
 4190            currentUserProfile.OnUpdate -= SetUserProfile;
 191
 44192        currentUserProfile = string.IsNullOrEmpty(current)
 193            ? null
 194            : userProfileBridge.Get(current);
 195
 44196        if (currentUserProfile == null)
 197        {
 22198            if (playerInfoCardVisibleState.Get())
 3199                socialAnalytics.SendPassportClose(current, Time.realtimeSinceStartup - passportOpenStartTime);
 200
 22201            CommonScriptableObjects.playerInfoCardVisibleState.Set(false);
 22202            view.SetCardActive(false);
 22203            wearablesCatalogService.RemoveWearablesInUse(loadedWearables);
 22204            loadedWearables.Clear();
 205        }
 206        else
 207        {
 22208            currentUserProfile.OnUpdate += SetUserProfile;
 209
 22210            setUserProfileCancellationToken = setUserProfileCancellationToken.SafeRestart();
 211
 22212            TaskUtils.Run(async () =>
 213                      {
 22214                          await AsyncSetUserProfile(currentUserProfile, setUserProfileCancellationToken.Token);
 22215                          CommonScriptableObjects.playerInfoCardVisibleState.Set(true);
 22216                          view.SetCardActive(true);
 22217                          socialAnalytics.SendPassportOpen(current);
 22218                      })
 219                     .Forget();
 220
 22221            passportOpenStartTime = Time.realtimeSinceStartup;
 222        }
 22223    }
 224
 225    private void SetUserProfile(UserProfile userProfile)
 226    {
 9227        Assert.IsTrue(userProfile != null, "userProfile can't be null");
 228
 9229        setUserProfileCancellationToken = setUserProfileCancellationToken.SafeRestart();
 230
 18231        TaskUtils.Run(async () => await AsyncSetUserProfile(userProfile, setUserProfileCancellationToken.Token)).Forget(
 9232    }
 233
 234    private async UniTask AsyncSetUserProfile(UserProfile userProfile, CancellationToken cancellationToken = default)
 235    {
 236        // TODO: pass cancellation tokens to profanity filtering
 31237        string filterName = await FilterName(userProfile);
 31238        string filterDescription = await FilterDescription(userProfile);
 31239        await UniTask.SwitchToMainThread(cancellationToken);
 240
 31241        view.SetName(filterName);
 31242        view.SetDescription(filterDescription);
 31243        view.ClearCollectibles();
 31244        view.SetIsBlocked(IsBlocked(userProfile.userId));
 31245        LoadAndShowWearables(userProfile, cancellationToken).Forget();
 31246        UpdateFriendshipInteraction();
 247
 31248        if (viewingUserProfile != null)
 13249            viewingUserProfile.snapshotObserver.RemoveListener(view.SetFaceSnapshot);
 250
 31251        userProfile.snapshotObserver.AddListener(view.SetFaceSnapshot);
 31252        viewingUserProfile = userProfile;
 31253    }
 254
 255    public void SetVisibility(bool visible)
 256    {
 0257        view.SetVisibility(visible);
 258
 0259        if (viewingUserProfile != null)
 0260            viewingUserProfile.snapshotObserver.RemoveListener(view.SetFaceSnapshot);
 261
 0262        if (visible)
 263        {
 0264            if (viewingUserProfile != null)
 0265                viewingUserProfile.snapshotObserver.AddListener(view.SetFaceSnapshot);
 266        }
 0267    }
 268
 269    private void BlockPlayer()
 270    {
 0271        if (ownUserProfile.IsBlocked(currentUserProfile.userId)) return;
 272
 0273        dataStore.notifications.GenericConfirmation.Set(GenericConfirmationNotificationData.CreateBlockUserData(
 274            userProfileBridge.Get(currentPlayerId)?.userName,
 275            () =>
 276            {
 0277                ownUserProfile.Block(currentUserProfile.userId);
 0278                view.SetIsBlocked(true);
 0279                WebInterface.SendBlockPlayer(currentUserProfile.userId);
 0280                socialAnalytics.SendPlayerBlocked(friendsController.IsFriend(currentUserProfile.userId), PlayerActionSou
 0281            }), true);
 0282    }
 283
 284    private void UnblockPlayer()
 285    {
 0286        if (!ownUserProfile.IsBlocked(currentUserProfile.userId)) return;
 0287        ownUserProfile.Unblock(currentUserProfile.userId);
 0288        view.SetIsBlocked(false);
 0289        WebInterface.SendUnblockPlayer(currentUserProfile.userId);
 0290        socialAnalytics.SendPlayerUnblocked(friendsController.IsFriend(currentUserProfile.userId), PlayerActionSource.Pa
 0291    }
 292
 293    private void ReportPlayer()
 294    {
 0295        WebInterface.SendReportPlayer(currentPlayerId, currentUserProfile?.name);
 0296        socialAnalytics.SendPlayerReport(PlayerReportIssueType.None, 0, PlayerActionSource.Passport, currentPlayerId);
 0297    }
 298
 299    public void Dispose()
 300    {
 19301        friendOperationsCancellationToken.SafeCancelAndDispose();
 19302        setUserProfileCancellationToken.SafeCancelAndDispose();
 303
 19304        if (currentUserProfile != null)
 18305            currentUserProfile.OnUpdate -= SetUserProfile;
 306
 19307        if (currentPlayerId != null)
 308        {
 19309            currentPlayerId.OnSame -= OnCurrentPlayerIdUpdated;
 19310            currentPlayerId.OnChange -= OnCurrentPlayerIdChanged;
 311        }
 312
 19313        if (closeWindowTrigger != null)
 19314            closeWindowTrigger.OnTriggered -= OnCloseButtonPressed;
 315
 19316        if (closeWindowTrigger != null)
 19317            closeWindowTrigger.OnTriggered -= OnCloseButtonPressed;
 318
 19319        if (toggleWorldChatTrigger != null)
 19320            toggleWorldChatTrigger.OnTriggered -= OnCloseButtonPressed;
 321
 19322        if (toggleFriendsTrigger != null)
 19323            toggleFriendsTrigger.OnTriggered -= OnCloseButtonPressed;
 324
 19325        if (viewingUserProfile != null)
 18326            viewingUserProfile.snapshotObserver.RemoveListener(view.SetFaceSnapshot);
 327
 19328        if (view != null)
 19329            Object.Destroy(view.gameObject);
 19330    }
 331
 332    private void OnFriendStatusUpdated(string userId, FriendshipAction action)
 333    {
 0334        if (currentUserProfile == null)
 0335            return;
 336
 0337        UpdateFriendshipInteraction();
 0338    }
 339
 340    private void UpdateFriendshipInteraction()
 341    {
 31342        if (currentUserProfile == null)
 343        {
 0344            view.HideFriendshipInteraction();
 0345            return;
 346        }
 347
 31348        view.UpdateFriendshipInteraction(CanBeFriends(),
 349            friendsController.GetUserStatus(currentUserProfile.userId));
 31350    }
 351
 352    private bool CanBeFriends()
 353    {
 31354        return friendsController != null && friendsController.IsInitialized && currentUserProfile.hasConnectedWeb3 && is
 355    }
 356
 357    private async UniTaskVoid LoadAndShowWearables(UserProfile userProfile, CancellationToken cancellationToken)
 358    {
 359        try
 360        {
 31361            var ownedWearables = await wearablesCatalogService.RequestOwnedWearablesAsync(
 362                userProfile.userId,
 363                1,
 364                int.MaxValue,
 365                true,
 366                cancellationToken);
 367
 217368            string[] wearableIds = ownedWearables.wearables.Select(x => x.id).ToArray();
 31369            userProfile.SetInventory(wearableIds);
 31370            loadedWearables.AddRange(wearableIds);
 371
 31372            var containedWearables = ownedWearables.wearables
 373                // this makes any sense?
 186374               .Where(wearable => wearablesCatalogService.IsValidWearable(wearable.id));
 375
 31376            view.SetWearables(containedWearables);
 31377        }
 0378        catch (Exception)
 379        {
 380            // Exception was ignored in the previous version
 381            // Debug.LogException(e);
 0382        }
 31383    }
 384
 385    private bool IsBlocked(string userId)
 386    {
 31387        return ownUserProfile != null && ownUserProfile.IsBlocked(userId);
 388    }
 389
 390    // TODO: support cancellation tokens on profanity filtering
 391    private async UniTask<string> FilterName(UserProfile userProfile)
 392    {
 31393        return IsProfanityFilteringEnabled()
 394            ? await profanityFilter.Filter(userProfile.userName)
 395            : userProfile.userName;
 31396    }
 397
 398    // TODO: support cancellation tokens on profanity filtering
 399    private async UniTask<string> FilterDescription(UserProfile userProfile)
 400    {
 31401        return IsProfanityFilteringEnabled()
 402            ? await profanityFilter.Filter(userProfile.description)
 403            : userProfile.description;
 31404    }
 405
 406    private bool IsProfanityFilteringEnabled()
 407    {
 62408        return dataStore.settings.profanityChatFilteringEnabled.Get();
 409    }
 410}