< Summary

Class:PlayerInfoCardHUDController
Assembly:PlayerInfoCardHUD
File(s):/tmp/workspace/unity-renderer/unity-renderer/Assets/Scripts/MainScripts/DCL/Controllers/HUD/PlayerInfoCardHUD/PlayerInfoCardHUDController.cs
Covered lines:111
Uncovered lines:85
Coverable lines:196
Total lines:444
Line coverage:56.6% (111 of 196)
Covered branches:0
Total branches:0

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity NPath complexity Sequence coverage
PlayerInfoCardHUDController(...)0%110100%
CloseCard()0%2100%
OnCloseButtonPressed(...)0%2100%
AddPlayerAsFriend()0%6200%
CancelInvitation()0%2100%
CancelInvitationAsync()0%56700%
AcceptFriendRequest()0%2100%
AcceptFriendRequestAsync()0%56700%
RejectFriendRequest()0%2100%
RejectFriendRequestAsync()0%56700%
OnCurrentPlayerIdChanged(...)0%110100%
OnCurrentPlayerIdUpdated(...)0%550100%
<OnCurrentPlayerIdUpdated()0%3.213071.43%
SetUserProfile(...)0%110100%
>c__DisplayClass36_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.474069.23%
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 SocialFeaturesAnalytics;
 9using System;
 10using System.Collections.Generic;
 11using System.Linq;
 12using System.Threading;
 13using UnityEngine;
 14using UnityEngine.Assertions;
 15using Object = UnityEngine.Object;
 16
 17public class PlayerInfoCardHUDController : IHUD
 18{
 19    internal readonly PlayerInfoCardHUDView view;
 20    internal readonly StringVariable currentPlayerId;
 21    internal UserProfile currentUserProfile;
 22
 23    private UserProfile viewingUserProfile;
 6224    private UserProfile ownUserProfile => userProfileBridge.GetOwn();
 25
 26    private readonly IFriendsController friendsController;
 27    private readonly InputAction_Trigger toggleFriendsTrigger;
 28    private readonly InputAction_Trigger closeWindowTrigger;
 29    private readonly InputAction_Trigger toggleWorldChatTrigger;
 30    private readonly IUserProfileBridge userProfileBridge;
 31    private readonly IWearableCatalogBridge wearableCatalogBridge;
 32    private readonly IProfanityFilter profanityFilter;
 33    private readonly DataStore dataStore;
 34    private readonly BooleanVariable playerInfoCardVisibleState;
 1935    private readonly List<string> loadedWearables = new ();
 36    private readonly ISocialAnalytics socialAnalytics;
 37
 1938    private CancellationTokenSource friendOperationsCancellationToken = new ();
 1939    private CancellationTokenSource setUserProfileCancellationToken = new ();
 040    private bool isNewFriendRequestsEnabled => dataStore.featureFlags.flags.Get().IsFeatureEnabled("new_friend_requests"
 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        IWearableCatalogBridge wearableCatalogBridge,
 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.wearableCatalogBridge = wearableCatalogBridge;
 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        if (isNewFriendRequestsEnabled)
 101        {
 0102            dataStore.HUDs.sendFriendRequest.Set(currentPlayerId, true);
 0103            dataStore.HUDs.sendFriendRequestSource.Set((int)PlayerActionSource.Passport);
 104        }
 105        else
 106        {
 0107            friendsController.RequestFriendship(currentPlayerId);
 0108            socialAnalytics.SendFriendRequestSent(ownUserProfile.userId, currentPlayerId, 0, PlayerActionSource.Passport
 109        }
 0110    }
 111
 112    private void CancelInvitation()
 113    {
 0114        friendOperationsCancellationToken = friendOperationsCancellationToken.SafeRestart();
 0115        CancelInvitationAsync(friendOperationsCancellationToken.Token).Forget();
 0116    }
 117
 118    private async UniTaskVoid CancelInvitationAsync(CancellationToken cancellationToken)
 119    {
 0120        if (isNewFriendRequestsEnabled)
 121        {
 122            try
 123            {
 0124                FriendRequest request = await friendsController.CancelRequestByUserIdAsync(currentPlayerId,
 125                    cancellationToken);
 126
 0127                socialAnalytics.SendFriendRequestCancelled(request.From, request.To, PlayerActionSource.Passport.ToStrin
 0128            }
 0129            catch (Exception e) when (e is not OperationCanceledException)
 130            {
 0131                e.ReportFriendRequestErrorToAnalyticsByUserId(currentPlayerId, PlayerActionSource.Passport.ToString(),
 132                    friendsController, socialAnalytics);
 133
 0134                throw;
 135            }
 136        }
 137        else
 138        {
 0139            friendsController.CancelRequestByUserId(currentPlayerId);
 0140            socialAnalytics.SendFriendRequestCancelled(ownUserProfile.userId, currentPlayerId, PlayerActionSource.Passpo
 141        }
 0142    }
 143
 144    private void AcceptFriendRequest()
 145    {
 0146        friendOperationsCancellationToken = friendOperationsCancellationToken.SafeRestart();
 0147        AcceptFriendRequestAsync(friendOperationsCancellationToken.Token).Forget();
 0148    }
 149
 150    private async UniTaskVoid AcceptFriendRequestAsync(CancellationToken cancellationToken)
 151    {
 0152        if (isNewFriendRequestsEnabled)
 153        {
 154            try
 155            {
 0156                FriendRequest request = friendsController.GetAllocatedFriendRequestByUser(currentPlayerId);
 157
 0158                request = await friendsController.AcceptFriendshipAsync(request.FriendRequestId,
 159                    cancellationToken);
 160
 0161                socialAnalytics.SendFriendRequestApproved(request.From, request.To, PlayerActionSource.Passport.ToString
 162                    request.HasBodyMessage);
 0163            }
 0164            catch (Exception e) when (e is not OperationCanceledException)
 165            {
 0166                e.ReportFriendRequestErrorToAnalyticsByUserId(currentPlayerId, PlayerActionSource.Passport.ToString(),
 167                    friendsController, socialAnalytics);
 168
 0169                throw;
 170            }
 171        }
 172        else
 173        {
 0174            friendsController.AcceptFriendship(currentPlayerId);
 175
 0176            socialAnalytics.SendFriendRequestApproved(ownUserProfile.userId, currentPlayerId,
 177                PlayerActionSource.Passport.ToString(),
 178                false);
 179        }
 0180    }
 181
 182    private void RejectFriendRequest()
 183    {
 0184        friendOperationsCancellationToken = friendOperationsCancellationToken.SafeRestart();
 0185        RejectFriendRequestAsync(friendOperationsCancellationToken.Token).Forget();
 0186    }
 187
 188    private async UniTaskVoid RejectFriendRequestAsync(CancellationToken cancellationToken)
 189    {
 0190        if (isNewFriendRequestsEnabled)
 191        {
 192            try
 193            {
 0194                FriendRequest request = friendsController.GetAllocatedFriendRequestByUser(currentPlayerId);
 195
 0196                request = await friendsController.RejectFriendshipAsync(request.FriendRequestId,
 197                    cancellationToken);
 198
 0199                socialAnalytics.SendFriendRequestRejected(request.From, request.To,
 200                    PlayerActionSource.Passport.ToString(), request.HasBodyMessage);
 0201            }
 0202            catch (Exception e) when (e is not OperationCanceledException)
 203            {
 0204                e.ReportFriendRequestErrorToAnalyticsByUserId(currentPlayerId, PlayerActionSource.Passport.ToString(),
 205                    friendsController, socialAnalytics);
 206
 0207                throw;
 208            }
 209        }
 210        else
 211        {
 0212            friendsController.RejectFriendship(currentPlayerId);
 213
 0214            socialAnalytics.SendFriendRequestRejected(ownUserProfile.userId, currentPlayerId,
 215                PlayerActionSource.Passport.ToString(), false);
 216        }
 0217    }
 218
 219    private void OnCurrentPlayerIdChanged(string current, string previous)
 220    {
 25221        OnCurrentPlayerIdUpdated(current);
 25222    }
 223
 224    private void OnCurrentPlayerIdUpdated(string current)
 225    {
 44226        if (currentUserProfile != null)
 4227            currentUserProfile.OnUpdate -= SetUserProfile;
 228
 44229        currentUserProfile = string.IsNullOrEmpty(current)
 230            ? null
 231            : userProfileBridge.Get(current);
 232
 44233        if (currentUserProfile == null)
 234        {
 22235            if (playerInfoCardVisibleState.Get())
 3236                socialAnalytics.SendPassportClose(Time.realtimeSinceStartup - passportOpenStartTime);
 237
 22238            CommonScriptableObjects.playerInfoCardVisibleState.Set(false);
 22239            view.SetCardActive(false);
 22240            wearableCatalogBridge.RemoveWearablesInUse(loadedWearables);
 22241            loadedWearables.Clear();
 242        }
 243        else
 244        {
 22245            currentUserProfile.OnUpdate += SetUserProfile;
 246
 22247            setUserProfileCancellationToken = setUserProfileCancellationToken.SafeRestart();
 248
 22249            TaskUtils.Run(async () =>
 250                      {
 22251                          await AsyncSetUserProfile(currentUserProfile, setUserProfileCancellationToken.Token);
 22252                          CommonScriptableObjects.playerInfoCardVisibleState.Set(true);
 22253                          view.SetCardActive(true);
 22254                          socialAnalytics.SendPassportOpen();
 22255                      })
 256                     .Forget();
 257
 22258            passportOpenStartTime = Time.realtimeSinceStartup;
 259        }
 22260    }
 261
 262    private void SetUserProfile(UserProfile userProfile)
 263    {
 9264        Assert.IsTrue(userProfile != null, "userProfile can't be null");
 265
 9266        setUserProfileCancellationToken = setUserProfileCancellationToken.SafeRestart();
 267
 18268        TaskUtils.Run(async () => await AsyncSetUserProfile(userProfile, setUserProfileCancellationToken.Token)).Forget(
 9269    }
 270
 271    private async UniTask AsyncSetUserProfile(UserProfile userProfile, CancellationToken cancellationToken = default)
 272    {
 273        // TODO: pass cancellation tokens to profanity filtering
 31274        string filterName = await FilterName(userProfile);
 31275        string filterDescription = await FilterDescription(userProfile);
 31276        await UniTask.SwitchToMainThread(cancellationToken);
 277
 31278        view.SetName(filterName);
 31279        view.SetDescription(filterDescription);
 31280        view.ClearCollectibles();
 31281        view.SetIsBlocked(IsBlocked(userProfile.userId));
 31282        LoadAndShowWearables(userProfile, cancellationToken).Forget();
 31283        UpdateFriendshipInteraction();
 284
 31285        if (viewingUserProfile != null)
 13286            viewingUserProfile.snapshotObserver.RemoveListener(view.SetFaceSnapshot);
 287
 31288        userProfile.snapshotObserver.AddListener(view.SetFaceSnapshot);
 31289        viewingUserProfile = userProfile;
 31290    }
 291
 292    public void SetVisibility(bool visible)
 293    {
 0294        view.SetVisibility(visible);
 295
 0296        if (viewingUserProfile != null)
 0297            viewingUserProfile.snapshotObserver.RemoveListener(view.SetFaceSnapshot);
 298
 0299        if (visible)
 300        {
 0301            if (viewingUserProfile != null)
 0302                viewingUserProfile.snapshotObserver.AddListener(view.SetFaceSnapshot);
 303        }
 0304    }
 305
 306    private void BlockPlayer()
 307    {
 0308        if (ownUserProfile.IsBlocked(currentUserProfile.userId)) return;
 309
 0310        dataStore.notifications.GenericConfirmation.Set(GenericConfirmationNotificationData.CreateBlockUserData(
 311            userProfileBridge.Get(currentPlayerId)?.userName,
 312            () =>
 313            {
 0314                ownUserProfile.Block(currentUserProfile.userId);
 0315                view.SetIsBlocked(true);
 0316                WebInterface.SendBlockPlayer(currentUserProfile.userId);
 0317                socialAnalytics.SendPlayerBlocked(friendsController.IsFriend(currentUserProfile.userId), PlayerActionSou
 0318            }), true);
 0319    }
 320
 321    private void UnblockPlayer()
 322    {
 0323        if (!ownUserProfile.IsBlocked(currentUserProfile.userId)) return;
 0324        ownUserProfile.Unblock(currentUserProfile.userId);
 0325        view.SetIsBlocked(false);
 0326        WebInterface.SendUnblockPlayer(currentUserProfile.userId);
 0327        socialAnalytics.SendPlayerUnblocked(friendsController.IsFriend(currentUserProfile.userId), PlayerActionSource.Pa
 0328    }
 329
 330    private void ReportPlayer()
 331    {
 0332        WebInterface.SendReportPlayer(currentPlayerId, currentUserProfile?.name);
 0333        socialAnalytics.SendPlayerReport(PlayerReportIssueType.None, 0, PlayerActionSource.Passport);
 0334    }
 335
 336    public void Dispose()
 337    {
 19338        friendOperationsCancellationToken.SafeCancelAndDispose();
 19339        setUserProfileCancellationToken.SafeCancelAndDispose();
 340
 19341        if (currentUserProfile != null)
 18342            currentUserProfile.OnUpdate -= SetUserProfile;
 343
 19344        if (currentPlayerId != null)
 345        {
 19346            currentPlayerId.OnSame -= OnCurrentPlayerIdUpdated;
 19347            currentPlayerId.OnChange -= OnCurrentPlayerIdChanged;
 348        }
 349
 19350        if (closeWindowTrigger != null)
 19351            closeWindowTrigger.OnTriggered -= OnCloseButtonPressed;
 352
 19353        if (closeWindowTrigger != null)
 19354            closeWindowTrigger.OnTriggered -= OnCloseButtonPressed;
 355
 19356        if (toggleWorldChatTrigger != null)
 19357            toggleWorldChatTrigger.OnTriggered -= OnCloseButtonPressed;
 358
 19359        if (toggleFriendsTrigger != null)
 19360            toggleFriendsTrigger.OnTriggered -= OnCloseButtonPressed;
 361
 19362        if (viewingUserProfile != null)
 18363            viewingUserProfile.snapshotObserver.RemoveListener(view.SetFaceSnapshot);
 364
 19365        if (view != null)
 19366            Object.Destroy(view.gameObject);
 19367    }
 368
 369    private void OnFriendStatusUpdated(string userId, FriendshipAction action)
 370    {
 0371        if (currentUserProfile == null)
 0372            return;
 373
 0374        UpdateFriendshipInteraction();
 0375    }
 376
 377    private void UpdateFriendshipInteraction()
 378    {
 31379        if (currentUserProfile == null)
 380        {
 0381            view.HideFriendshipInteraction();
 0382            return;
 383        }
 384
 31385        view.UpdateFriendshipInteraction(CanBeFriends(),
 386            friendsController.GetUserStatus(currentUserProfile.userId));
 31387    }
 388
 389    private bool CanBeFriends()
 390    {
 31391        return friendsController != null && friendsController.IsInitialized && currentUserProfile.hasConnectedWeb3 && is
 392    }
 393
 394    private async UniTaskVoid LoadAndShowWearables(UserProfile userProfile, CancellationToken cancellationToken)
 395    {
 396        try
 397        {
 31398            var request = wearableCatalogBridge.RequestOwnedWearables(userProfile.userId);
 31399            await request.WithCancellation(cancellationToken);
 400
 186401            var wearableIds = request.value.Select(x => x.id).ToArray();
 31402            userProfile.SetInventory(wearableIds);
 31403            loadedWearables.AddRange(wearableIds);
 404
 31405            var containedWearables = request.value
 406
 407                // this makes any sense?
 155408               .Where(wearable => wearableCatalogBridge.IsValidWearable(wearable.id));
 409
 31410            view.SetWearables(containedWearables);
 31411        }
 0412        catch (Exception)
 413        {
 414            // Exception was ignored in the previous version
 415            // Debug.LogException(e);
 0416        }
 31417    }
 418
 419    private bool IsBlocked(string userId)
 420    {
 31421        return ownUserProfile != null && ownUserProfile.IsBlocked(userId);
 422    }
 423
 424    // TODO: support cancellation tokens on profanity filtering
 425    private async UniTask<string> FilterName(UserProfile userProfile)
 426    {
 31427        return IsProfanityFilteringEnabled()
 428            ? await profanityFilter.Filter(userProfile.userName)
 429            : userProfile.userName;
 31430    }
 431
 432    // TODO: support cancellation tokens on profanity filtering
 433    private async UniTask<string> FilterDescription(UserProfile userProfile)
 434    {
 31435        return IsProfanityFilteringEnabled()
 436            ? await profanityFilter.Filter(userProfile.description)
 437            : userProfile.description;
 31438    }
 439
 440    private bool IsProfanityFilteringEnabled()
 441    {
 62442        return dataStore.settings.profanityChatFilteringEnabled.Get();
 443    }
 444}