< Summary

Class:DCL.ContentModeration.ContentModerationHUDController
Assembly:ContentModerationHUD
File(s):/tmp/workspace/unity-renderer/unity-renderer/Assets/Scripts/MainScripts/DCL/Controllers/HUD/ContentModerationHUD/ContentModerationHUDController.cs
Covered lines:105
Uncovered lines:23
Coverable lines:128
Total lines:279
Line coverage:82% (105 of 128)
Covered branches:0
Total branches:0
Covered methods:14
Total methods:17
Method coverage:82.3% (14 of 17)

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity NPath complexity Sequence coverage
ContentModerationHUDController(...)0%110100%
Dispose()0%110100%
OnSceneNumberChanged(...)0%550100%
UpdateSceneNameByCoords(...)0%2.062075%
OnGoToSettingsPanelClicked()0%110100%
OnAdultContentAgeConfirmationVisible(...)0%220100%
OnAgeConfirmationAccepted()0%110100%
HideNotificationAfterDelay(...)0%110100%
OnAgeConfirmationRejected()0%110100%
OnAdultContentSettingChanged(...)0%330100%
OnReportingScenePanelVisible(...)0%220100%
OnContentModerationReportingClosed(...)0%110100%
OnContentModerationReportingSendClicked(...)0%30500%
SendReportAsync()0%12300%
OnLearnMoreClicked()0%110100%
OpenContentModerationPanel()0%2100%
OnIsWorldChanged(...)0%2.062075%

File(s)

/tmp/workspace/unity-renderer/unity-renderer/Assets/Scripts/MainScripts/DCL/Controllers/HUD/ContentModerationHUD/ContentModerationHUDController.cs

#LineLine coverage
 1using Cysharp.Threading.Tasks;
 2using DCL.Browser;
 3using DCL.Controllers;
 4using DCL.Helpers;
 5using DCL.NotificationModel;
 6using DCL.Tasks;
 7using DCLServices.PlacesAPIService;
 8using System;
 9using System.Collections.Generic;
 10using System.Threading;
 11using UnityEngine;
 12
 13namespace DCL.ContentModeration
 14{
 15    public class ContentModerationHUDController
 16    {
 17        private const int SECONDS_TO_HIDE_ADULT_CONTENT_ENABLED_NOTIFICATION = 5;
 18        private const int REPORT_PLACE_TIMEOUT = 30;
 19        private const string LEARN_MORE_URL = "https://docs.decentraland.org/player/general/in-world-features/age-rating
 20        private const string REPORTING_ERROR_MESSAGE = "There was an error sending the information. Please try again lat
 21
 22        private readonly IAdultContentSceneWarningComponentView adultContentSceneWarningComponentView;
 23        private readonly IAdultContentAgeConfirmationComponentView adultContentAgeConfirmationComponentView;
 24        private readonly IAdultContentEnabledNotificationComponentView adultContentEnabledNotificationComponentView;
 25        private readonly IContentModerationReportingComponentView contentModerationReportingComponentView;
 26        private readonly IContentModerationReportingButtonComponentView contentModerationReportingButtonForWorldsCompone
 27        private readonly IWorldState worldState;
 28        private readonly DataStore_Common commonDataStore;
 29        private readonly DataStore_Settings settingsDataStore;
 30        private readonly DataStore_ContentModeration contentModerationDataStore;
 31        private readonly IBrowserBridge browserBridge;
 32        private readonly IPlacesAPIService placesAPIService;
 33        private readonly IUserProfileBridge userProfileBridge;
 34        private readonly IContentModerationAnalytics contentModerationAnalytics;
 35        private readonly NotificationsController notificationsController;
 36
 37        private string currentPlaceId;
 38        private SceneContentCategory currentContentCategory;
 39        private CancellationTokenSource reportPlaceCts;
 40
 2341        public ContentModerationHUDController(
 42            IAdultContentSceneWarningComponentView adultContentSceneWarningComponentView,
 43            IAdultContentAgeConfirmationComponentView adultContentAgeConfirmationComponentView,
 44            IAdultContentEnabledNotificationComponentView adultContentEnabledNotificationComponentView,
 45            IContentModerationReportingComponentView contentModerationReportingComponentView,
 46            IContentModerationReportingButtonComponentView contentModerationReportingButtonForWorldsComponentView,
 47            IWorldState worldState,
 48            DataStore_Common commonDataStore,
 49            DataStore_Settings settingsDataStore,
 50            DataStore_ContentModeration contentModerationDataStore,
 51            IBrowserBridge browserBridge,
 52            IPlacesAPIService placesAPIService,
 53            IUserProfileBridge userProfileBridge,
 54            IContentModerationAnalytics contentModerationAnalytics,
 55            NotificationsController notificationsController)
 56        {
 2357            this.adultContentSceneWarningComponentView = adultContentSceneWarningComponentView;
 2358            this.adultContentAgeConfirmationComponentView = adultContentAgeConfirmationComponentView;
 2359            this.adultContentEnabledNotificationComponentView = adultContentEnabledNotificationComponentView;
 2360            this.contentModerationReportingComponentView = contentModerationReportingComponentView;
 2361            this.contentModerationReportingButtonForWorldsComponentView = contentModerationReportingButtonForWorldsCompo
 2362            this.worldState = worldState;
 2363            this.commonDataStore = commonDataStore;
 2364            this.settingsDataStore = settingsDataStore;
 2365            this.contentModerationDataStore = contentModerationDataStore;
 2366            this.browserBridge = browserBridge;
 2367            this.placesAPIService = placesAPIService;
 2368            this.userProfileBridge = userProfileBridge;
 2369            this.contentModerationAnalytics = contentModerationAnalytics;
 2370            this.notificationsController = notificationsController;
 71
 2372            OnSceneNumberChanged(CommonScriptableObjects.sceneNumber.Get(), 0);
 2373            CommonScriptableObjects.sceneNumber.OnChange += OnSceneNumberChanged;
 2374            UpdateSceneNameByCoords(CommonScriptableObjects.playerCoords.Get(), Vector2Int.zero);
 2375            CommonScriptableObjects.playerCoords.OnChange += UpdateSceneNameByCoords;
 2376            adultContentSceneWarningComponentView.OnGoToSettingsClicked += OnGoToSettingsPanelClicked;
 2377            contentModerationDataStore.adultContentAgeConfirmationVisible.OnChange += OnAdultContentAgeConfirmationVisib
 2378            adultContentAgeConfirmationComponentView.OnConfirmClicked += OnAgeConfirmationAccepted;
 2379            adultContentAgeConfirmationComponentView.OnCancelClicked += OnAgeConfirmationRejected;
 2380            contentModerationDataStore.adultContentSettingEnabled.OnChange += OnAdultContentSettingChanged;
 2381            contentModerationDataStore.reportingScenePanelVisible.OnChange += OnReportingScenePanelVisible;
 2382            contentModerationReportingComponentView.OnPanelClosed += OnContentModerationReportingClosed;
 2383            contentModerationReportingComponentView.OnSendClicked += OnContentModerationReportingSendClicked;
 2384            contentModerationReportingComponentView.OnLearnMoreClicked += OnLearnMoreClicked;
 2385            contentModerationReportingButtonForWorldsComponentView.OnContentModerationPressed += OpenContentModerationPa
 2386            OnIsWorldChanged(commonDataStore.isWorld.Get(), false);
 2387            commonDataStore.isWorld.OnChange += OnIsWorldChanged;
 2388        }
 89
 90        public void Dispose()
 91        {
 2392            CommonScriptableObjects.sceneNumber.OnChange -= OnSceneNumberChanged;
 2393            CommonScriptableObjects.playerCoords.OnChange -= UpdateSceneNameByCoords;
 2394            adultContentSceneWarningComponentView.OnGoToSettingsClicked -= OnGoToSettingsPanelClicked;
 2395            contentModerationDataStore.adultContentAgeConfirmationVisible.OnChange -= OnAdultContentAgeConfirmationVisib
 2396            adultContentAgeConfirmationComponentView.OnConfirmClicked -= OnAgeConfirmationAccepted;
 2397            adultContentAgeConfirmationComponentView.OnCancelClicked -= OnAgeConfirmationRejected;
 2398            contentModerationDataStore.adultContentSettingEnabled.OnChange -= OnAdultContentSettingChanged;
 2399            contentModerationDataStore.reportingScenePanelVisible.OnChange -= OnReportingScenePanelVisible;
 23100            contentModerationReportingComponentView.OnPanelClosed -= OnContentModerationReportingClosed;
 23101            contentModerationReportingComponentView.OnSendClicked -= OnContentModerationReportingSendClicked;
 23102            contentModerationReportingComponentView.OnLearnMoreClicked -= OnLearnMoreClicked;
 23103            contentModerationReportingButtonForWorldsComponentView.OnContentModerationPressed -= OpenContentModerationPa
 23104            commonDataStore.isWorld.OnChange -= OnIsWorldChanged;
 105
 23106            reportPlaceCts.SafeCancelAndDispose();
 23107        }
 108
 109        private void OnSceneNumberChanged(int currentSceneNumber, int _)
 110        {
 44111            if (!worldState.TryGetScene(currentSceneNumber, out IParcelScene currentParcelScene))
 29112                return;
 113
 15114            currentContentCategory = currentParcelScene.contentCategory;
 15115            contentModerationReportingButtonForWorldsComponentView.SetContentCategory(currentParcelScene.contentCategory
 116
 15117            switch (currentParcelScene.contentCategory)
 118            {
 7119                case SceneContentCategory.ADULT when !contentModerationDataStore.adultContentSettingEnabled.Get():
 6120                    Utils.UnlockCursor();
 6121                    adultContentSceneWarningComponentView.ShowModal();
 6122                    adultContentSceneWarningComponentView.SetRestrictedMode(false);
 6123                    break;
 124                case SceneContentCategory.RESTRICTED:
 4125                    adultContentSceneWarningComponentView.ShowModal();
 4126                    adultContentSceneWarningComponentView.SetRestrictedMode(true);
 4127                    break;
 128                case SceneContentCategory.TEEN:
 129                default:
 5130                    adultContentSceneWarningComponentView.HideModal();
 131                    break;
 132            }
 133
 15134            currentPlaceId = currentParcelScene.associatedPlaceId;
 15135            UpdateSceneNameByCoords(CommonScriptableObjects.playerCoords.Get(), Vector2Int.zero);
 15136            contentModerationReportingComponentView.HidePanel(true);
 15137        }
 138
 139        private void UpdateSceneNameByCoords(Vector2Int playerCoords, Vector2Int _)
 140        {
 38141            MinimapMetadata.MinimapSceneInfo sceneInfo = MinimapMetadata.GetMetadata().GetSceneInfo(playerCoords.x, play
 142
 38143            if (sceneInfo != null)
 0144                contentModerationReportingComponentView.SetScene(sceneInfo.name);
 38145        }
 146
 147        private void OnGoToSettingsPanelClicked()
 148        {
 1149            settingsDataStore.settingsPanelVisible.Set(true);
 1150            contentModerationAnalytics.OpenSettingsFromContentWarning();
 1151        }
 152
 153        private void OnAdultContentAgeConfirmationVisible(bool isVisible, bool _)
 154        {
 2155            if (isVisible)
 1156                adultContentAgeConfirmationComponentView.ShowModal();
 2157        }
 158
 159        private void OnAgeConfirmationAccepted()
 160        {
 1161            contentModerationDataStore.adultContentAgeConfirmationResult.Set(DataStore_ContentModeration.AdultContentAge
 1162            settingsDataStore.settingsPanelVisible.Set(false);
 1163            adultContentEnabledNotificationComponentView.ShowNotification();
 1164            HideNotificationAfterDelay(SECONDS_TO_HIDE_ADULT_CONTENT_ENABLED_NOTIFICATION).Forget();
 1165        }
 166
 167        private UniTask HideNotificationAfterDelay(int delayInSeconds)
 168        {
 1169            return UniTask.Delay(delayInSeconds * 1000).ContinueWith(() =>
 1170                adultContentEnabledNotificationComponentView.HideNotification());
 171        }
 172
 173        private void OnAgeConfirmationRejected()
 174        {
 1175            contentModerationDataStore.adultContentAgeConfirmationResult.Set(DataStore_ContentModeration.AdultContentAge
 1176        }
 177
 178        private void OnAdultContentSettingChanged(bool currentIsEnabled, bool previousIsEnabled)
 179        {
 2180            if (!currentIsEnabled)
 1181                adultContentEnabledNotificationComponentView.HideNotification();
 182
 2183            OnSceneNumberChanged(CommonScriptableObjects.sceneNumber.Get(), 0);
 184
 2185            if (currentIsEnabled != previousIsEnabled)
 2186                contentModerationAnalytics.SwitchAdultContentSetting(currentIsEnabled);
 2187        }
 188
 189        private void OnReportingScenePanelVisible((bool isVisible, SceneContentCategory rating) panelStatus, (bool isVis
 190        {
 6191            if (panelStatus.isVisible)
 192            {
 3193                contentModerationReportingComponentView.ShowPanel();
 3194                contentModerationReportingComponentView.SetRatingAsMarked(panelStatus.rating);
 3195                contentModerationReportingComponentView.SetRating(panelStatus.rating);
 3196                contentModerationAnalytics.OpenReportForm(currentPlaceId);
 197            }
 198            else
 3199                contentModerationReportingComponentView.HidePanel(false);
 3200        }
 201
 202        private void OnContentModerationReportingClosed(bool isCancelled)
 203        {
 6204            contentModerationDataStore.reportingScenePanelVisible.Set((false, contentModerationDataStore.reportingSceneP
 6205            contentModerationAnalytics.CloseReportForm(currentPlaceId, isCancelled);
 6206        }
 207
 208        private void OnContentModerationReportingSendClicked((SceneContentCategory contentCategory, List<string> issues,
 209        {
 0210            reportPlaceCts = reportPlaceCts.SafeRestart();
 0211            SendReportAsync(
 212                    new PlaceContentReportPayload
 213                    {
 214                        placeId = currentPlaceId,
 215                        guest = userProfileBridge.GetOwn().isGuest,
 216                        coordinates = $"{CommonScriptableObjects.playerCoords.Get().x},{CommonScriptableObjects.playerCo
 217                        rating = report.contentCategory switch
 218                                 {
 0219                                     SceneContentCategory.TEEN => "T",
 0220                                     SceneContentCategory.ADULT => "A",
 0221                                     SceneContentCategory.RESTRICTED => "R",
 0222                                     _ => "E",
 223                                 },
 224                        issues = report.issues.ToArray(),
 225                        comment = report.comments,
 226                    },
 227                    reportPlaceCts.Token)
 228               .Forget();
 0229        }
 230
 231        private async UniTask SendReportAsync(PlaceContentReportPayload placeContentReport, CancellationToken ct)
 232        {
 233            try
 234            {
 0235                contentModerationAnalytics.SubmitReportForm(
 236                    placeContentReport.placeId,
 237                    placeContentReport.rating,
 238                    placeContentReport.issues,
 239                    placeContentReport.comment);
 240
 0241                contentModerationReportingComponentView.SetLoadingState(true);
 0242                await placesAPIService.ReportPlace(placeContentReport, ct)
 243                                      .Timeout(TimeSpan.FromSeconds(REPORT_PLACE_TIMEOUT));
 0244                contentModerationReportingComponentView.SetPanelAsSent(true);
 0245                contentModerationReportingComponentView.SetLoadingState(false);
 0246            }
 0247            catch (Exception ex)
 248            {
 0249                contentModerationAnalytics.ErrorSendingReportingForm(currentPlaceId);
 0250                contentModerationReportingComponentView.ResetPanelState();
 0251                notificationsController.ShowNotification(new Model
 252                {
 253                    message = REPORTING_ERROR_MESSAGE,
 254                    type = NotificationModel.Type.ERROR,
 255                    timer = 10f,
 256                    destroyOnFinish = true,
 257                });
 0258                Debug.LogError($"An error occurred while reporting the content category for ({placeContentReport.coordin
 0259            }
 0260        }
 261
 262        private void OnLearnMoreClicked()
 263        {
 1264            browserBridge.OpenUrl(LEARN_MORE_URL);
 1265            contentModerationAnalytics.ClickLearnMoreContentModeration(currentPlaceId);
 1266        }
 267
 268        private void OpenContentModerationPanel() =>
 0269            contentModerationDataStore.reportingScenePanelVisible.Set((!contentModerationDataStore.reportingScenePanelVi
 270
 271        private void OnIsWorldChanged(bool current, bool _)
 272        {
 23273            if (current)
 0274                contentModerationReportingButtonForWorldsComponentView.Show();
 275            else
 23276                contentModerationReportingButtonForWorldsComponentView.Hide();
 23277        }
 278    }
 279}