< Summary

Class:DCL.Social.Friends.FriendsHUDController
Assembly:FriendsHUD
File(s):/tmp/workspace/unity-renderer/unity-renderer/Assets/Scripts/MainScripts/DCL/Controllers/HUD/FriendsHUD/Scripts/FriendsHUDController.cs
Covered lines:109
Uncovered lines:249
Coverable lines:358
Total lines:742
Line coverage:30.4% (109 of 358)
Covered branches:0
Total branches:0
Covered methods:14
Total methods:51
Method coverage:27.4% (14 of 51)

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity NPath complexity Sequence coverage
FriendsHUDController(...)0%110100%
Initialize(...)0%33097.06%
SetVisiblePanelList(...)0%220100%
Dispose()0%8.148087.1%
SetVisibility(...)0%8.38083.33%
HandleViewClosed()0%6200%
HandleFriendsInitialized()0%56700%
HandleProfileUpdated(...)0%2100%
UpdateBlockStatus()0%1561200%
<HandleRequestFriendship()0%1101000%
HandleRequestFriendship(...)0%2100%
SolveUserIdFromUserInput(...)0%30500%
AreAlreadyFriends(...)0%12300%
HandleUserStatusUpdated(...)0%2100%
UpdateUserStatus(...)0%30500%
<HandleFriendshipUpdated()0%2101400%
HandleFriendshipUpdated(...)0%2100%
EnsureProfileOrShowFallbackFriend()0%42600%
RemoveFriendship(...)0%2100%
HandleFriendProfileUpdated(...)0%12300%
IsUserBlocked(...)0%12300%
OnFriendNotFound(...)0%2100%
UpdateNotificationsCounter()0%220100%
HandleOpenWhisperChat(...)0%6200%
HandleRequestRejected(...)0%2100%
HandleRequestRejectedAsync()0%30500%
HandleRequestCancelledAsync()0%30500%
HandleRequestCancelled(...)0%2100%
HandleRequestAccepted(...)0%2100%
HandleRequestAcceptedAsync()0%30500%
DisplayFriendsIfAnyIsLoaded()0%12300%
DisplayMoreFriends()0%2.52050%
DisplayMoreFriendsAsync()0%20400%
DisplayMoreFriendRequests()0%12300%
DisplayMoreFriendRequestsAsync()0%12300%
AddFriendRequests(...)0%20400%
<ShowFriendRequest()0%90900%
ShowFriendRequest(...)0%2100%
DisplayFriendRequestsIfAnyIsLoaded()0%20400%
ShowOrHideMoreFriendRequestsToLoadHint()0%2.52050%
ShowOrHideMoreFriendsToLoadHint()0%4.123050%
SearchFriends(...)0%2100%
SearchFriendsAsync()0%30500%
OpenFriendRequestDetails(...)0%12300%
RestartFriendsOperationsCancellationToken()0%2100%

File(s)

/tmp/workspace/unity-renderer/unity-renderer/Assets/Scripts/MainScripts/DCL/Controllers/HUD/FriendsHUD/Scripts/FriendsHUDController.cs

#LineLine coverage
 1using Cysharp.Threading.Tasks;
 2using DCL.Tasks;
 3using SocialFeaturesAnalytics;
 4using System;
 5using System.Collections.Generic;
 6using System.Text.RegularExpressions;
 7using System.Threading;
 8using UnityEngine;
 9
 10namespace DCL.Social.Friends
 11{
 12    public class FriendsHUDController : IHUD
 13    {
 14        private const int LOAD_FRIENDS_ON_DEMAND_COUNT = 30;
 15        private const int MAX_SEARCHED_FRIENDS = 100;
 16        private const string ENABLE_QUICK_ACTIONS_FOR_FRIEND_REQUESTS_FLAG = "enable_quick_actions_on_friend_requests";
 17        private const int GET_FRIENDS_TIMEOUT = 10;
 18
 319        private readonly Dictionary<string, FriendEntryModel> friends = new ();
 320        private readonly Dictionary<string, FriendEntryModel> onlineFriends = new ();
 21        private readonly DataStore dataStore;
 22        private readonly IFriendsController friendsController;
 23        private readonly IUserProfileBridge userProfileBridge;
 24        private readonly ISocialAnalytics socialAnalytics;
 25        private readonly IChatController chatController;
 26        private readonly IMouseCatcher mouseCatcher;
 327        private readonly Regex ethAddressRegex = new (@"^0x[a-fA-F0-9]{40}$");
 28
 1229        private BaseVariable<HashSet<string>> visibleTaskbarPanels => dataStore.HUDs.visibleTaskbarPanels;
 030        private bool isQuickActionsForFriendRequestsEnabled => dataStore.featureFlags.flags.Get().IsFeatureEnabled(ENABL
 331        private CancellationTokenSource friendOperationsCancellationToken = new ();
 332        private CancellationTokenSource ensureProfilesCancellationToken = new ();
 33        private UserProfile ownUserProfile;
 34        private bool searchingFriends;
 35        private int lastSkipForFriends;
 36        private int lastSkipForFriendRequests;
 37
 1738        public bool IsVisible { get; private set; }
 10339        public IFriendsHUDComponentView View { get; private set; }
 40
 41        public event Action<string> OnPressWhisper;
 42        public event Action OnOpened;
 43        public event Action OnClosed;
 44        public event Action OnViewClosed;
 45
 346        public FriendsHUDController(DataStore dataStore,
 47            IFriendsController friendsController,
 48            IUserProfileBridge userProfileBridge,
 49            ISocialAnalytics socialAnalytics,
 50            IChatController chatController,
 51            IMouseCatcher mouseCatcher)
 52        {
 353            this.dataStore = dataStore;
 354            this.friendsController = friendsController;
 355            this.userProfileBridge = userProfileBridge;
 356            this.socialAnalytics = socialAnalytics;
 357            this.chatController = chatController;
 358            this.mouseCatcher = mouseCatcher;
 359        }
 60
 61        public void Initialize(IFriendsHUDComponentView view, bool isVisible = true)
 62        {
 363            View = view;
 64
 365            view.Initialize(chatController, friendsController, socialAnalytics);
 366            view.RefreshFriendsTab();
 367            view.OnFriendRequestApproved += HandleRequestAccepted;
 368            view.OnCancelConfirmation += HandleRequestCancelled;
 369            view.OnRejectConfirmation += HandleRequestRejected;
 370            view.OnFriendRequestSent += HandleRequestFriendship;
 371            view.OnFriendRequestOpened += OpenFriendRequestDetails;
 372            view.OnWhisper += HandleOpenWhisperChat;
 373            view.OnClose += HandleViewClosed;
 374            view.OnRequireMoreFriends += DisplayMoreFriends;
 375            view.OnRequireMoreFriendRequests += DisplayMoreFriendRequests;
 376            view.OnSearchFriendsRequested += SearchFriends;
 377            view.OnFriendListDisplayed += DisplayFriendsIfAnyIsLoaded;
 378            view.OnRequestListDisplayed += DisplayFriendRequestsIfAnyIsLoaded;
 79
 380            if (mouseCatcher != null)
 281                mouseCatcher.OnMouseLock += HandleViewClosed;
 82
 383            ownUserProfile = userProfileBridge.GetOwn();
 384            ownUserProfile.OnUpdate -= HandleProfileUpdated;
 385            ownUserProfile.OnUpdate += HandleProfileUpdated;
 86
 387            friendsController.OnUpdateFriendship += HandleFriendshipUpdated;
 388            friendsController.OnUpdateUserStatus += HandleUserStatusUpdated;
 389            friendsController.OnFriendNotFound += OnFriendNotFound;
 390            friendsController.OnFriendRequestReceived += ShowFriendRequest;
 91
 392            if (friendsController.IsInitialized)
 093                view.HideLoadingSpinner();
 94            else
 95            {
 396                view.ShowLoadingSpinner();
 397                friendsController.OnInitialized -= HandleFriendsInitialized;
 398                friendsController.OnInitialized += HandleFriendsInitialized;
 99            }
 100
 3101            ShowOrHideMoreFriendsToLoadHint();
 3102            ShowOrHideMoreFriendRequestsToLoadHint();
 103
 3104            SetVisibility(isVisible);
 3105            IsVisible = isVisible;
 3106        }
 107
 108        private void SetVisiblePanelList(bool visible)
 109        {
 6110            HashSet<string> newSet = visibleTaskbarPanels.Get();
 111
 6112            if (visible)
 4113                newSet.Add("FriendsPanel");
 114            else
 2115                newSet.Remove("FriendsPanel");
 116
 6117            visibleTaskbarPanels.Set(newSet, true);
 6118        }
 119
 120        public void Dispose()
 121        {
 4122            friendOperationsCancellationToken?.SafeCancelAndDispose();
 4123            friendOperationsCancellationToken = null;
 4124            ensureProfilesCancellationToken?.SafeCancelAndDispose();
 4125            ensureProfilesCancellationToken = null;
 126
 4127            friendsController.OnInitialized -= HandleFriendsInitialized;
 4128            friendsController.OnUpdateFriendship -= HandleFriendshipUpdated;
 4129            friendsController.OnUpdateUserStatus -= HandleUserStatusUpdated;
 130
 4131            if (View != null)
 132            {
 4133                View.OnFriendRequestApproved -= HandleRequestAccepted;
 4134                View.OnCancelConfirmation -= HandleRequestCancelled;
 4135                View.OnRejectConfirmation -= HandleRequestRejected;
 4136                View.OnFriendRequestSent -= HandleRequestFriendship;
 4137                View.OnFriendRequestOpened -= OpenFriendRequestDetails;
 4138                View.OnWhisper -= HandleOpenWhisperChat;
 4139                View.OnClose -= HandleViewClosed;
 4140                View.OnRequireMoreFriends -= DisplayMoreFriends;
 4141                View.OnRequireMoreFriendRequests -= DisplayMoreFriendRequests;
 4142                View.OnSearchFriendsRequested -= SearchFriends;
 4143                View.OnFriendListDisplayed -= DisplayFriendsIfAnyIsLoaded;
 4144                View.OnRequestListDisplayed -= DisplayFriendRequestsIfAnyIsLoaded;
 4145                View.Dispose();
 146            }
 147
 4148            if (ownUserProfile != null)
 4149                ownUserProfile.OnUpdate -= HandleProfileUpdated;
 150
 4151            if (userProfileBridge != null)
 152            {
 8153                foreach (string friendId in friends.Keys)
 154                {
 0155                    var profile = userProfileBridge.Get(friendId);
 0156                    if (profile == null) continue;
 0157                    profile.OnUpdate -= HandleFriendProfileUpdated;
 158                }
 159            }
 4160        }
 161
 162        public void SetVisibility(bool visible)
 163        {
 8164            if (IsVisible == visible)
 2165                return;
 166
 6167            IsVisible = visible;
 6168            SetVisiblePanelList(visible);
 169
 6170            if (visible)
 171            {
 4172                lastSkipForFriends = 0;
 4173                lastSkipForFriendRequests = 0;
 4174                View.ClearAll();
 4175                View.Show();
 4176                UpdateNotificationsCounter();
 177
 8178                foreach (var friend in onlineFriends)
 0179                    View.Set(friend.Key, friend.Value);
 180
 4181                if (View.IsFriendListActive)
 1182                    DisplayMoreFriends();
 3183                else if (View.IsRequestListActive)
 0184                    DisplayMoreFriendRequests();
 185
 4186                OnOpened?.Invoke();
 187            }
 188            else
 189            {
 2190                View.Hide();
 2191                View.DisableSearchMode();
 2192                searchingFriends = false;
 2193                OnClosed?.Invoke();
 194            }
 0195        }
 196
 197        private void HandleViewClosed()
 198        {
 0199            OnViewClosed?.Invoke();
 0200            SetVisibility(false);
 0201        }
 202
 203        private void HandleFriendsInitialized()
 204        {
 0205            friendsController.OnInitialized -= HandleFriendsInitialized;
 0206            View.HideLoadingSpinner();
 207
 0208            if (View.IsActive())
 209            {
 0210                if (View.IsFriendListActive && lastSkipForFriends <= 0)
 0211                    DisplayMoreFriendsAsync(RestartFriendsOperationsCancellationToken()).Forget();
 0212                else if (View.IsRequestListActive && lastSkipForFriendRequests <= 0 && !searchingFriends)
 0213                    DisplayMoreFriendRequestsAsync(RestartFriendsOperationsCancellationToken()).Forget();
 214            }
 215
 0216            UpdateNotificationsCounter();
 0217        }
 218
 219        private void HandleProfileUpdated(UserProfile profile) =>
 0220            UpdateBlockStatus(profile).Forget();
 221
 222        private async UniTask UpdateBlockStatus(UserProfile profile)
 223        {
 224            const int ITERATIONS_PER_FRAME = 10;
 225
 0226            var iterations = 0;
 227
 0228            foreach (var friendPair in friends)
 229            {
 0230                string friendId = friendPair.Key;
 0231                var model = friendPair.Value;
 232
 0233                model.blocked = profile.blocked?.Contains(friendId) ?? false;
 0234                await UniTask.SwitchToMainThread();
 0235                View.UpdateBlockStatus(friendId, model.blocked);
 236
 0237                iterations++;
 238
 0239                if (iterations > 0 && iterations % ITERATIONS_PER_FRAME == 0)
 0240                    await UniTask.NextFrame();
 0241            }
 0242        }
 243
 244        private void HandleRequestFriendship(string userNameOrId)
 245        {
 246            async UniTaskVoid HandleRequestFriendshipAsync(string userNameOrId, CancellationToken cancellationToken)
 247            {
 0248                if (AreAlreadyFriends(userNameOrId))
 0249                    View.ShowRequestSendError(FriendRequestError.AlreadyFriends);
 250                else
 251                {
 252                    try
 253                    {
 0254                        string userId = SolveUserIdFromUserInput(userNameOrId);
 255
 0256                        if (!string.IsNullOrEmpty(userId))
 257                        {
 0258                            FriendRequest request = await friendsController.RequestFriendshipAsync(userId, "", cancellat
 259
 0260                            ShowFriendRequest(request);
 261
 0262                            socialAnalytics.SendFriendRequestSent(request.From, request.To, request.MessageBody?.Length 
 263                                PlayerActionSource.FriendsHUD, request.FriendRequestId);
 264                        }
 265                        else
 0266                            View.ShowRequestSendError(FriendRequestError.UserNotFound);
 0267                    }
 0268                    catch (Exception e) when (e is not OperationCanceledException)
 269                    {
 0270                        e.ReportFriendRequestErrorToAnalyticsAsSender(userNameOrId, PlayerActionSource.FriendsHUD.ToStri
 271                            userProfileBridge, socialAnalytics);
 272
 0273                        Debug.LogException(e);
 0274                    }
 275
 0276                    View.ShowRequestSendSuccess();
 277                }
 0278            }
 279
 0280            HandleRequestFriendshipAsync(userNameOrId, RestartFriendsOperationsCancellationToken()).Forget();
 0281        }
 282
 283        private string SolveUserIdFromUserInput(string userNameOrId)
 284        {
 0285            Match ethAddressMatch = ethAddressRegex.Match(userNameOrId);
 286
 0287            if (ethAddressMatch.Success)
 0288                return userNameOrId;
 289
 290            // TODO: a request to the catalyst is needed to retrieve a user profile by user name
 291            // the user may exist with the name but not loaded in the current catalog
 0292            UserProfile profile = userProfileBridge.GetByName(userNameOrId, false);
 0293            return profile?.userId ?? "";
 294        }
 295
 296        private bool AreAlreadyFriends(string userNameOrId)
 297        {
 0298            var userId = userNameOrId;
 0299            var profile = userProfileBridge.GetByName(userNameOrId);
 300
 0301            if (profile != default)
 0302                userId = profile.userId;
 303
 0304            return friendsController != null
 305                   && friendsController.ContainsStatus(userId, FriendshipStatus.FRIEND);
 306        }
 307
 308        private void HandleUserStatusUpdated(string userId, UserStatus status) =>
 0309            UpdateUserStatus(userId, status);
 310
 311        private void UpdateUserStatus(string userId, UserStatus status)
 312        {
 0313            switch (status.friendshipStatus)
 314            {
 315                case FriendshipStatus.FRIEND:
 0316                    var friend = friends.ContainsKey(userId)
 317                        ? new FriendEntryModel(friends[userId])
 318                        : new FriendEntryModel();
 319
 0320                    friend.CopyFrom(status);
 0321                    friend.blocked = IsUserBlocked(userId);
 0322                    friends[userId] = friend;
 0323                    View.Set(userId, friend);
 324
 0325                    if (status.presence == PresenceStatus.ONLINE)
 0326                        onlineFriends[userId] = friend;
 327                    else
 0328                        onlineFriends.Remove(userId);
 329
 0330                    break;
 331                case FriendshipStatus.NOT_FRIEND:
 0332                    View.Remove(userId);
 0333                    friends.Remove(userId);
 0334                    onlineFriends.Remove(userId);
 335                    break;
 336            }
 337
 0338            UpdateNotificationsCounter();
 0339            ShowOrHideMoreFriendsToLoadHint();
 0340            ShowOrHideMoreFriendRequestsToLoadHint();
 0341        }
 342
 343        private void HandleFriendshipUpdated(string userId, FriendshipAction friendshipAction)
 344        {
 345            async UniTaskVoid HandleFriendshipUpdatedAsync(string userId, FriendshipAction friendshipAction, Cancellatio
 346            {
 0347                var userProfile = userProfileBridge.Get(userId);
 348
 349                switch (friendshipAction)
 350                {
 351                    case FriendshipAction.NONE:
 352                    case FriendshipAction.REJECTED:
 353                    case FriendshipAction.CANCELLED:
 354                    case FriendshipAction.DELETED:
 0355                        RemoveFriendship(userId);
 0356                        break;
 357                    case FriendshipAction.APPROVED:
 0358                        userProfile = await EnsureProfileOrShowFallbackFriend(userId, userProfile, cancellationToken);
 359
 0360                        var approved = friends.ContainsKey(userId)
 361                            ? new FriendEntryModel(friends[userId])
 362                            : new FriendEntryModel();
 363
 0364                        approved.CopyFrom(userProfile);
 0365                        approved.blocked = IsUserBlocked(userId);
 0366                        friends[userId] = approved;
 0367                        View.Set(userId, approved);
 0368                        userProfile.OnUpdate -= HandleFriendProfileUpdated;
 0369                        userProfile.OnUpdate += HandleFriendProfileUpdated;
 0370                        break;
 371                    case FriendshipAction.REQUESTED_FROM:
 0372                        userProfile = await EnsureProfileOrShowFallbackFriend(userId, userProfile, cancellationToken);
 373
 0374                        var requestReceived = friends.ContainsKey(userId)
 375                            ? new FriendRequestEntryModel(friends[userId], string.Empty, true, new DateTime(0), isQuickA
 376                            : new FriendRequestEntryModel { bodyMessage = string.Empty, isReceived = true, timestamp = n
 377
 0378                        requestReceived.CopyFrom(userProfile);
 0379                        requestReceived.blocked = IsUserBlocked(userId);
 0380                        friends[userId] = requestReceived;
 0381                        View.Set(userId, requestReceived);
 0382                        userProfile.OnUpdate -= HandleFriendProfileUpdated;
 0383                        userProfile.OnUpdate += HandleFriendProfileUpdated;
 0384                        break;
 385                    case FriendshipAction.REQUESTED_TO:
 0386                        userProfile = await EnsureProfileOrShowFallbackFriend(userId, userProfile, cancellationToken);
 387
 0388                        var requestSent = friends.ContainsKey(userId)
 389                            ? new FriendRequestEntryModel(friends[userId], string.Empty, false, new DateTime(0), isQuick
 390                            : new FriendRequestEntryModel { bodyMessage = string.Empty, isReceived = false, timestamp = 
 391
 0392                        requestSent.CopyFrom(userProfile);
 0393                        requestSent.blocked = IsUserBlocked(userId);
 0394                        friends[userId] = requestSent;
 0395                        View.Set(userId, requestSent);
 0396                        userProfile.OnUpdate -= HandleFriendProfileUpdated;
 0397                        userProfile.OnUpdate += HandleFriendProfileUpdated;
 398                        break;
 399                }
 400
 0401                UpdateNotificationsCounter();
 0402                ShowOrHideMoreFriendsToLoadHint();
 0403                ShowOrHideMoreFriendRequestsToLoadHint();
 0404            }
 405
 0406            HandleFriendshipUpdatedAsync(userId, friendshipAction, ensureProfilesCancellationToken.Token).Forget();
 0407        }
 408
 409        private async UniTask<UserProfile> EnsureProfileOrShowFallbackFriend(string userId, UserProfile userProfile, Can
 410        {
 0411            try { userProfile ??= await userProfileBridge.RequestFullUserProfileAsync(userId, cancellationToken); }
 0412            catch (Exception e) when (e is not OperationCanceledException)
 413            {
 0414                FriendEntryModel fallbackModel = new ()
 415                {
 416                    userId = userId,
 417                    userName = userId,
 418                    blocked = IsUserBlocked(userId),
 419                };
 420
 0421                friends[userId] = fallbackModel;
 0422                View.Set(userId, fallbackModel);
 423
 0424                throw;
 425            }
 426
 0427            return userProfile;
 0428        }
 429
 430        private void RemoveFriendship(string userId)
 431        {
 0432            friends.Remove(userId);
 0433            View.Remove(userId);
 0434            onlineFriends.Remove(userId);
 0435        }
 436
 437        private void HandleFriendProfileUpdated(UserProfile profile)
 438        {
 0439            var userId = profile.userId;
 0440            if (!friends.ContainsKey(userId)) return;
 0441            friends[userId].CopyFrom(profile);
 442
 0443            var status = friendsController.GetUserStatus(profile.userId);
 0444            if (status == null) return;
 445
 0446            UpdateUserStatus(userId, status);
 0447        }
 448
 449        private bool IsUserBlocked(string userId)
 450        {
 0451            if (ownUserProfile != null && ownUserProfile.blocked != null)
 0452                return ownUserProfile.blocked.Contains(userId);
 453
 0454            return false;
 455        }
 456
 457        private void OnFriendNotFound(string name)
 458        {
 0459            View.DisplayFriendUserNotFound();
 0460        }
 461
 462        private void UpdateNotificationsCounter()
 463        {
 4464            if (View.IsActive())
 4465                dataStore.friendNotifications.seenFriends.Set(View.FriendCount);
 466
 4467            dataStore.friendNotifications.pendingFriendRequestCount.Set(friendsController.ReceivedRequestCount);
 4468        }
 469
 470        private void HandleOpenWhisperChat(FriendEntryModel entry) =>
 0471            OnPressWhisper?.Invoke(entry.userId);
 472
 473        private void HandleRequestRejected(FriendRequestEntryModel entry)
 474        {
 0475            HandleRequestRejectedAsync(entry.userId, RestartFriendsOperationsCancellationToken()).Forget();
 0476        }
 477
 478        private async UniTaskVoid HandleRequestRejectedAsync(string userId, CancellationToken cancellationToken)
 479        {
 480            try
 481            {
 0482                FriendRequest request = await friendsController.RejectFriendshipAsync(userId, cancellationToken);
 483
 0484                socialAnalytics.SendFriendRequestRejected(request.From, request.To,
 485                    PlayerActionSource.FriendsHUD.ToString(), request.HasBodyMessage, request.FriendRequestId);
 486
 0487                RemoveFriendship(userId);
 0488            }
 0489            catch (Exception e) when (e is not OperationCanceledException)
 490            {
 0491                e.ReportFriendRequestErrorToAnalyticsByUserId(userId, PlayerActionSource.FriendsHUD.ToString(),
 492                    friendsController, socialAnalytics);
 493
 0494                throw;
 495            }
 496
 0497            UpdateNotificationsCounter();
 0498        }
 499
 500        private async UniTaskVoid HandleRequestCancelledAsync(string userId, CancellationToken cancellationToken)
 501        {
 502            try
 503            {
 0504                FriendRequest request = await friendsController.CancelRequestByUserIdAsync(userId, cancellationToken);
 505
 0506                socialAnalytics.SendFriendRequestCancelled(request.From, request.To,
 507                    PlayerActionSource.FriendsHUD.ToString(), request.FriendRequestId);
 508
 0509                RemoveFriendship(userId);
 0510            }
 0511            catch (Exception e) when (e is not OperationCanceledException)
 512            {
 0513                e.ReportFriendRequestErrorToAnalyticsByUserId(userId, PlayerActionSource.FriendsHUD.ToString(),
 514                    friendsController, socialAnalytics);
 515
 0516                throw;
 517            }
 0518        }
 519
 520        private void HandleRequestCancelled(FriendRequestEntryModel entry)
 521        {
 0522            HandleRequestCancelledAsync(entry.userId, RestartFriendsOperationsCancellationToken()).Forget();
 0523        }
 524
 525        private void HandleRequestAccepted(FriendRequestEntryModel entry)
 526        {
 0527            HandleRequestAcceptedAsync(entry.userId, RestartFriendsOperationsCancellationToken()).Forget();
 0528        }
 529
 530        private async UniTaskVoid HandleRequestAcceptedAsync(string userId, CancellationToken cancellationToken)
 531        {
 532            try
 533            {
 0534                FriendRequest request = friendsController.GetAllocatedFriendRequestByUser(userId);
 0535                request = await friendsController.AcceptFriendshipAsync(request.FriendRequestId, cancellationToken);
 536
 0537                socialAnalytics.SendFriendRequestApproved(request.From, request.To,
 538                    PlayerActionSource.FriendsHUD.ToString(),
 539                    request.HasBodyMessage,
 540                    request.FriendRequestId);
 0541            }
 0542            catch (Exception e) when (e is not OperationCanceledException)
 543            {
 0544                e.ReportFriendRequestErrorToAnalyticsByUserId(userId, PlayerActionSource.FriendsHUD.ToString(),
 545                    friendsController, socialAnalytics);
 546
 0547                throw;
 548            }
 0549        }
 550
 551        private void DisplayFriendsIfAnyIsLoaded()
 552        {
 0553            if (lastSkipForFriends > 0) return;
 0554            if (!friendsController.IsInitialized) return;
 0555            DisplayMoreFriendsAsync(RestartFriendsOperationsCancellationToken()).Forget();
 0556        }
 557
 558        private void DisplayMoreFriends()
 559        {
 2560            if (!friendsController.IsInitialized) return;
 0561            DisplayMoreFriendsAsync(RestartFriendsOperationsCancellationToken()).Forget();
 0562        }
 563
 564        private async UniTask DisplayMoreFriendsAsync(CancellationToken cancellationToken)
 565        {
 0566            string[] friendsToAdd = await friendsController
 567                                         .GetFriendsAsync(LOAD_FRIENDS_ON_DEMAND_COUNT, lastSkipForFriends, cancellation
 568                                         .Timeout(TimeSpan.FromSeconds(GET_FRIENDS_TIMEOUT));
 569
 0570            for (var i = 0; i < friendsToAdd.Length; i++)
 0571                HandleFriendshipUpdated(friendsToAdd[i], FriendshipAction.APPROVED);
 572
 573            // We are not handling properly the case when the friends are not fetched correctly from server.
 574            // 'lastSkipForFriends' will have an invalid value.
 575            // this may happen only on the old flow.. the task operation should throw an exception if anything goes wron
 0576            lastSkipForFriends += LOAD_FRIENDS_ON_DEMAND_COUNT;
 577
 0578            ShowOrHideMoreFriendsToLoadHint();
 0579        }
 580
 581        private void DisplayMoreFriendRequests()
 582        {
 0583            if (!friendsController.IsInitialized) return;
 0584            if (searchingFriends) return;
 0585            DisplayMoreFriendRequestsAsync(RestartFriendsOperationsCancellationToken()).Forget();
 0586        }
 587
 588        private async UniTask DisplayMoreFriendRequestsAsync(CancellationToken cancellationToken)
 589        {
 0590            var allFriendRequests = await friendsController.GetFriendRequestsAsync(
 591                LOAD_FRIENDS_ON_DEMAND_COUNT, lastSkipForFriendRequests,
 592                LOAD_FRIENDS_ON_DEMAND_COUNT, lastSkipForFriendRequests,
 593                cancellationToken);
 594
 0595            AddFriendRequests(allFriendRequests);
 596
 597            // We are not handling properly the case when the friend requests are not fetched correctly from server.
 598            // 'lastSkipForFriendRequests' will have an invalid value.
 599            // this may happen only on the old flow.. the task operation should throw an exception if anything goes wron
 0600            lastSkipForFriendRequests += LOAD_FRIENDS_ON_DEMAND_COUNT;
 601
 0602            ShowOrHideMoreFriendRequestsToLoadHint();
 0603        }
 604
 605        private void AddFriendRequests(IEnumerable<FriendRequest> friendRequests)
 606        {
 0607            if (friendRequests == null)
 0608                return;
 609
 0610            foreach (var friendRequest in friendRequests)
 0611                ShowFriendRequest(friendRequest);
 0612        }
 613
 614        private void ShowFriendRequest(FriendRequest friendRequest)
 615        {
 616            async UniTaskVoid ShowFriendRequestAsync(FriendRequest friendRequest, CancellationToken cancellationToken)
 617            {
 0618                bool isReceivedRequest = friendRequest.IsSentTo(ownUserProfile.userId);
 0619                string userId = isReceivedRequest ? friendRequest.From : friendRequest.To;
 0620                UserProfile userProfile = userProfileBridge.Get(userId);
 621
 0622                try { userProfile ??= await userProfileBridge.RequestFullUserProfileAsync(userId, cancellationToken); }
 0623                catch (Exception e) when (e is not OperationCanceledException)
 624                {
 0625                    FriendRequestEntryModel fallbackModel = new ()
 626                    {
 627                        bodyMessage = friendRequest.MessageBody,
 628                        isReceived = isReceivedRequest,
 629                        timestamp = friendRequest.Timestamp,
 630                        isShortcutButtonsActive = isQuickActionsForFriendRequestsEnabled,
 631                        blocked = IsUserBlocked(userId),
 632                        userId = userId,
 633                        userName = userId,
 634                    };
 635
 0636                    friends[userId] = fallbackModel;
 0637                    onlineFriends.Remove(userId);
 0638                    View.Set(userId, fallbackModel);
 639
 0640                    throw;
 641                }
 642
 0643                var request = friends.ContainsKey(userId)
 644                    ? new FriendRequestEntryModel(friends[userId], friendRequest.MessageBody, isReceivedRequest, friendR
 645                    : new FriendRequestEntryModel
 646                    {
 647                        bodyMessage = friendRequest.MessageBody,
 648                        isReceived = isReceivedRequest,
 649                        timestamp = friendRequest.Timestamp,
 650                        isShortcutButtonsActive = isQuickActionsForFriendRequestsEnabled
 651                    };
 652
 0653                request.CopyFrom(userProfile);
 0654                request.blocked = IsUserBlocked(userId);
 0655                friends[userId] = request;
 0656                onlineFriends.Remove(userId);
 0657                View.Set(userId, request);
 0658                userProfile.OnUpdate -= HandleFriendProfileUpdated;
 0659                userProfile.OnUpdate += HandleFriendProfileUpdated;
 0660            }
 661
 0662            ShowFriendRequestAsync(friendRequest, ensureProfilesCancellationToken.Token).Forget();
 0663        }
 664
 665        private void DisplayFriendRequestsIfAnyIsLoaded()
 666        {
 0667            if (lastSkipForFriendRequests > 0) return;
 0668            if (!friendsController.IsInitialized) return;
 0669            if (searchingFriends) return;
 0670            DisplayMoreFriendRequestsAsync(RestartFriendsOperationsCancellationToken()).Forget();
 0671        }
 672
 673        private void ShowOrHideMoreFriendRequestsToLoadHint()
 674        {
 3675            if (lastSkipForFriendRequests >= friendsController.TotalFriendRequestCount)
 3676                View.HideMoreRequestsToLoadHint();
 677            else
 0678                View.ShowMoreRequestsToLoadHint(Mathf.Clamp(friendsController.TotalFriendRequestCount - lastSkipForFrien
 679                    0,
 680                    friendsController.TotalFriendRequestCount));
 0681        }
 682
 683        private void ShowOrHideMoreFriendsToLoadHint()
 684        {
 3685            if (lastSkipForFriends >= friendsController.TotalFriendCount || searchingFriends)
 3686                View.HideMoreFriendsToLoadHint();
 687            else
 0688                View.ShowMoreFriendsToLoadHint(Mathf.Clamp(friendsController.TotalFriendCount - lastSkipForFriends,
 689                    0,
 690                    friendsController.TotalFriendCount));
 0691        }
 692
 693        private void SearchFriends(string search)
 694        {
 0695            SearchFriendsAsync(search, RestartFriendsOperationsCancellationToken()).Forget();
 0696        }
 697
 698        private async UniTask SearchFriendsAsync(string search, CancellationToken cancellationToken)
 699        {
 0700            if (string.IsNullOrEmpty(search))
 701            {
 0702                View.DisableSearchMode();
 0703                searchingFriends = false;
 0704                ShowOrHideMoreFriendsToLoadHint();
 0705                return;
 706            }
 707
 0708            IReadOnlyList<string> friendsToAdd = await friendsController
 709                                         .GetFriendsAsync(search, MAX_SEARCHED_FRIENDS, cancellationToken)
 710                                         .Timeout(TimeSpan.FromSeconds(GET_FRIENDS_TIMEOUT));
 711
 0712            for (int i = 0; i < friendsToAdd.Count; i++)
 0713                HandleFriendshipUpdated(friendsToAdd[i], FriendshipAction.APPROVED);
 714
 0715            View.EnableSearchMode();
 0716            View.HideMoreFriendsToLoadHint();
 0717            searchingFriends = true;
 0718        }
 719
 720        private void OpenFriendRequestDetails(string userId)
 721        {
 0722            FriendRequest friendRequest = friendsController.GetAllocatedFriendRequestByUser(userId);
 723
 0724            if (friendRequest == null)
 725            {
 0726                Debug.LogError($"Could not find an allocated friend request for user: {userId}");
 0727                return;
 728            }
 729
 0730            if (friendRequest.IsSentTo(userId))
 0731                dataStore.HUDs.openSentFriendRequestDetail.Set(friendRequest.FriendRequestId, true);
 732            else
 0733                dataStore.HUDs.openReceivedFriendRequestDetail.Set(friendRequest.FriendRequestId, true);
 0734        }
 735
 736        private CancellationToken RestartFriendsOperationsCancellationToken()
 737        {
 0738            friendOperationsCancellationToken = friendOperationsCancellationToken.SafeRestart();
 0739            return friendOperationsCancellationToken.Token;
 740        }
 741    }
 742}

Methods/Properties

FriendsHUDController(DCL.DataStore, DCL.Social.Friends.IFriendsController, IUserProfileBridge, SocialFeaturesAnalytics.ISocialAnalytics, IChatController, DCL.IMouseCatcher)
visibleTaskbarPanels()
isQuickActionsForFriendRequestsEnabled()
IsVisible()
IsVisible(System.Boolean)
View()
View(IFriendsHUDComponentView)
Initialize(IFriendsHUDComponentView, System.Boolean)
SetVisiblePanelList(System.Boolean)
Dispose()
SetVisibility(System.Boolean)
HandleViewClosed()
HandleFriendsInitialized()
HandleProfileUpdated(UserProfile)
UpdateBlockStatus()
<HandleRequestFriendship()
HandleRequestFriendship(System.String)
SolveUserIdFromUserInput(System.String)
AreAlreadyFriends(System.String)
HandleUserStatusUpdated(System.String, UserStatus)
UpdateUserStatus(System.String, UserStatus)
<HandleFriendshipUpdated()
HandleFriendshipUpdated(System.String, DCL.Social.Friends.FriendshipAction)
EnsureProfileOrShowFallbackFriend()
RemoveFriendship(System.String)
HandleFriendProfileUpdated(UserProfile)
IsUserBlocked(System.String)
OnFriendNotFound(System.String)
UpdateNotificationsCounter()
HandleOpenWhisperChat(FriendEntryModel)
HandleRequestRejected(FriendRequestEntryModel)
HandleRequestRejectedAsync()
HandleRequestCancelledAsync()
HandleRequestCancelled(FriendRequestEntryModel)
HandleRequestAccepted(FriendRequestEntryModel)
HandleRequestAcceptedAsync()
DisplayFriendsIfAnyIsLoaded()
DisplayMoreFriends()
DisplayMoreFriendsAsync()
DisplayMoreFriendRequests()
DisplayMoreFriendRequestsAsync()
AddFriendRequests(System.Collections.Generic.IEnumerable[FriendRequest])
<ShowFriendRequest()
ShowFriendRequest(DCL.Social.Friends.FriendRequest)
DisplayFriendRequestsIfAnyIsLoaded()
ShowOrHideMoreFriendRequestsToLoadHint()
ShowOrHideMoreFriendsToLoadHint()
SearchFriends(System.String)
SearchFriendsAsync()
OpenFriendRequestDetails(System.String)
RestartFriendsOperationsCancellationToken()