< Summary

Class:BuilderMainPanelController
Assembly:BuilderProjectsPanel
File(s):/tmp/workspace/unity-renderer/unity-renderer/Assets/DCLPlugins/BuilderInWorld/HUD/ProjectsPanelHUD/Scripts/BuilderMainPanelController.cs
Covered lines:153
Uncovered lines:48
Coverable lines:201
Total lines:435
Line coverage:76.1% (153 of 201)
Covered branches:0
Total branches:0

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity NPath complexity Sequence coverage
BuilderMainPanelController()0%2.032080%
SetView(...)0%110100%
OnBack()0%6200%
Dispose()0%11110100%
Initialize(...)0%2100%
Initialize(...)0%22096.55%
GetManifestToEdit(...)0%6200%
CreateNewProject(...)0%6200%
OpenEditorFromManifest(...)0%2100%
SetVisibility(...)0%110100%
OnVisibilityChanged(...)0%5.25080%
OnClose()0%3.023087.5%
PanelOpenEvent(...)0%110100%
GetAmountOfLandsOwnedAndOperator(...)0%3.013088.89%
SetView()0%110100%
FetchPanelInfo(...)0%6.475061.11%
ProjectsFetched(...)0%110100%
ProjectsFetchedError(...)0%110100%
UpdateProjectsDeploymentStatus()0%3.143075%
LandsFetchedError(...)0%110100%
LandsFetched(...)0%5.935066.67%
GoToCoords(...)0%220100%
OpenUrl(...)0%2100%
OnGoToEditScene(...)0%330100%
StartFetchInterval()0%2.062075%
StopFetchInterval()0%110100%
RefreshDataInterval()0%5.673033.33%
OnSceneUnpublished(...)0%6200%

File(s)

/tmp/workspace/unity-renderer/unity-renderer/Assets/DCLPlugins/BuilderInWorld/HUD/ProjectsPanelHUD/Scripts/BuilderMainPanelController.cs

#LineLine coverage
 1using System;
 2using System.Collections;
 3using System.Collections.Generic;
 4using System.Linq;
 5using DCL;
 6using DCL.Builder;
 7using DCL.Builder.Manifest;
 8using DCL.Helpers;
 9using DCL.Interface;
 10using UnityEngine;
 11using Variables.RealmsInfo;
 12using Environment = DCL.Environment;
 13using Object = UnityEngine.Object;
 14
 15public class BuilderMainPanelController : IHUD, IBuilderMainPanelController
 16{
 17    private const string CREATING_PROJECT_ERROR = "Error creating a new project: ";
 18    private const string OBTAIN_PROJECT_ERROR = "Error obtaining the project: ";
 19    private const string TESTING_ETH_ADDRESS = "0xDc13378daFca7Fe2306368A16BCFac38c80BfCAD";
 20    private const string TESTING_TLD = "org";
 21    private const string VIEW_PREFAB_PATH = "BuilderProjectsPanel";
 22    private const string VIEW_PREFAB_PATH_DEV = "BuilderProjectsPanelDev";
 23
 24    private const float CACHE_TIME_LAND = 5 * 60;
 25    private const float CACHE_TIME_SCENES = 1 * 60;
 26    private const float REFRESH_INTERVAL = 2 * 60;
 27
 28    internal IBuilderMainPanelView view;
 29
 30    private ISectionsController sectionsController;
 31    private IProjectsController projectsController;
 32    private IScenesViewController scenesViewController;
 33    private ILandsController landsesController;
 34    private UnpublishPopupController unpublishPopupController;
 35
 36    private INewProjectFlowController newProjectFlowController;
 37
 38    private SectionsHandler sectionsHandler;
 39    private SceneContextMenuHandler sceneContextMenuHandler;
 40    private LeftMenuHandler leftMenuHandler;
 41    private LeftMenuSettingsViewHandler leftMenuSettingsViewHandler;
 42
 43    private ITheGraph theGraph;
 44    private ICatalyst catalyst;
 45
 46    private bool isInitialized = false;
 47    internal bool isFetchingLands = false;
 48    internal bool isFetchingProjects = false;
 49    private bool sendPlayerOpenPanelEvent = false;
 50    private Coroutine fetchDataInterval;
 51    private Promise<LandWithAccess[]> fetchLandPromise = null;
 52    private Promise<ProjectData[]> fetchProjectsPromise = null;
 53
 54    public event Action OnJumpInOrEdit;
 55
 56    internal IContext context;
 57
 1758    public BuilderMainPanelController()
 59    {
 1760        if (DataStore.i.builderInWorld.isDevBuild.Get())
 061            SetView(Object.Instantiate(Resources.Load<BuilderMainPanelView>(VIEW_PREFAB_PATH_DEV)));
 62        else
 1763            SetView(Object.Instantiate(Resources.Load<BuilderMainPanelView>(VIEW_PREFAB_PATH)));
 1764    }
 65
 66    internal void SetView(IBuilderMainPanelView view)
 67    {
 1768        this.view = view;
 1769        view.OnClosePressed += OnClose;
 1770        view.OnBackPressed += OnBack;
 1771    }
 72
 73    private void OnBack()
 74    {
 075        if (newProjectFlowController.IsActive())
 076            newProjectFlowController.Hide();
 77        else
 078            OnClose();
 079    }
 80
 81    public void Dispose()
 82    {
 1783        StopFetchInterval();
 84
 1785        sectionsController.OnRequestOpenUrl -= OpenUrl;
 1786        sectionsController.OnRequestGoToCoords -= GoToCoords;
 1787        sectionsController.OnRequestEditSceneAtCoords -= OnGoToEditScene;
 1788        sectionsController.OnCreateProjectRequest -= newProjectFlowController.NewProject;
 89
 1790        scenesViewController.OnJumpInPressed -= GoToCoords;
 1791        scenesViewController.OnRequestOpenUrl -= OpenUrl;
 1792        scenesViewController.OnEditorPressed -= OnGoToEditScene;
 1793        projectsController.OnEditorPressed -= GetManifestToEdit;
 94
 1795        newProjectFlowController.OnNewProjectCrated -= CreateNewProject;
 96
 1797        view.OnCreateProjectPressed -= newProjectFlowController.NewProject;
 98
 1799        DataStore.i.HUDs.builderProjectsPanelVisible.OnChange -= OnVisibilityChanged;
 17100        DataStore.i.builderInWorld.unpublishSceneResult.OnChange -= OnSceneUnpublished;
 17101        view.OnClosePressed -= OnClose;
 17102        view.OnBackPressed -= OnBack;
 103
 17104        unpublishPopupController?.Dispose();
 105
 17106        fetchLandPromise?.Dispose();
 17107        fetchProjectsPromise?.Dispose();
 108
 17109        leftMenuSettingsViewHandler?.Dispose();
 17110        sectionsHandler?.Dispose();
 17111        sceneContextMenuHandler?.Dispose();
 17112        leftMenuHandler?.Dispose();
 113
 17114        sectionsController?.Dispose();
 17115        scenesViewController?.Dispose();
 116
 17117        newProjectFlowController?.Dispose();
 118
 17119        view.Dispose();
 17120    }
 121
 122    public void Initialize(IContext context)
 123    {
 0124        this.context = context;
 0125        Initialize(new SectionsController(view.GetSectionContainer()),
 126            new ScenesViewController(view.GetSceneCardViewPrefab(), view.GetTransform()),
 127            new LandsController(),
 128            new ProjectsController(view.GetProjectCardView(), view.GetTransform()),
 129            new NewProjectFlowController(),
 130            Environment.i.platform.serviceProviders.theGraph,
 131            Environment.i.platform.serviceProviders.catalyst);
 0132    }
 133
 134    internal void Initialize(ISectionsController sectionsController,
 135        IScenesViewController scenesViewController, ILandsController landsesController, IProjectsController projectsCont
 136    {
 17137        if (isInitialized)
 0138            return;
 139
 17140        isInitialized = true;
 141
 17142        this.sectionsController = sectionsController;
 17143        this.scenesViewController = scenesViewController;
 17144        this.landsesController = landsesController;
 17145        this.projectsController = projectsController;
 146
 17147        this.newProjectFlowController = newProjectFlowController;
 148
 17149        this.theGraph = theGraph;
 17150        this.catalyst = catalyst;
 151
 17152        this.unpublishPopupController = new UnpublishPopupController(view.GetUnpublishPopup());
 153
 154        // set listeners for sections, setup searchbar for section, handle request for opening a new section
 17155        sectionsHandler = new SectionsHandler(sectionsController, scenesViewController, landsesController, projectsContr
 156        // handle if main panel or settings panel should be shown in current section
 17157        leftMenuHandler = new LeftMenuHandler(view, sectionsController);
 158        // handle project scene info on the left menu panel
 17159        leftMenuSettingsViewHandler = new LeftMenuSettingsViewHandler(view.GetSettingsViewReferences(), scenesViewContro
 160        // handle scene's context menu options
 17161        sceneContextMenuHandler = new SceneContextMenuHandler(view.GetSceneCardViewContextMenu(), sectionsController, sc
 162
 17163        SetView();
 164
 17165        sectionsController.OnRequestOpenUrl += OpenUrl;
 17166        sectionsController.OnRequestGoToCoords += GoToCoords;
 17167        sectionsController.OnRequestEditSceneAtCoords += OnGoToEditScene;
 17168        sectionsController.OnCreateProjectRequest += newProjectFlowController.NewProject;
 169
 17170        scenesViewController.OnJumpInPressed += GoToCoords;
 17171        scenesViewController.OnRequestOpenUrl += OpenUrl;
 17172        scenesViewController.OnEditorPressed += OnGoToEditScene;
 17173        newProjectFlowController.OnNewProjectCrated += CreateNewProject;
 174
 17175        view.OnCreateProjectPressed += this.newProjectFlowController.NewProject;
 17176        this.projectsController.OnEditorPressed += GetManifestToEdit;
 177
 17178        DataStore.i.HUDs.builderProjectsPanelVisible.OnChange += OnVisibilityChanged;
 17179        DataStore.i.builderInWorld.unpublishSceneResult.OnChange += OnSceneUnpublished;
 17180    }
 181
 182    private void GetManifestToEdit(ProjectData data)
 183    {
 0184        Promise<Manifest> manifestPromise = context.builderAPIController.GetManifestById(data.id);
 0185        manifestPromise.Then( OpenEditorFromManifest);
 186
 0187        manifestPromise.Catch( errorString =>
 188        {
 0189            BIWUtils.ShowGenericNotification(OBTAIN_PROJECT_ERROR + errorString);
 0190        });
 0191    }
 192
 193    private void CreateNewProject(ProjectData project)
 194    {
 0195        Promise<Manifest> projectPromise = context.builderAPIController.CreateNewProject(project);
 196
 0197        projectPromise.Then( OpenEditorFromManifest);
 198
 0199        projectPromise.Catch( errorString =>
 200        {
 0201            BIWUtils.ShowGenericNotification(CREATING_PROJECT_ERROR + errorString);
 0202        });
 0203    }
 204
 0205    private void OpenEditorFromManifest(Manifest manifest) { context.sceneManager.StartEditorFromManifest(manifest); }
 206
 14207    public void SetVisibility(bool visible) { DataStore.i.HUDs.builderProjectsPanelVisible.Set(visible); }
 208
 209    private void OnVisibilityChanged(bool isVisible, bool prev)
 210    {
 7211        if (isVisible == prev)
 0212            return;
 213
 7214        view.SetVisible(isVisible);
 215
 7216        if (isVisible)
 217        {
 4218            if (DataStore.i.builderInWorld.landsWithAccess.Get() != null)
 4219                PanelOpenEvent(DataStore.i.builderInWorld.landsWithAccess.Get());
 220            else
 0221                sendPlayerOpenPanelEvent = true;
 222
 4223            FetchPanelInfo();
 4224            StartFetchInterval();
 4225            if (DataStore.i.builderInWorld.isDevBuild.Get())
 0226                sectionsController.OpenSection(SectionId.PROJECTS);
 227            else
 4228                sectionsController.OpenSection(SectionId.SCENES);
 4229        }
 230        else
 231        {
 3232            StopFetchInterval();
 233        }
 3234    }
 235
 236    private void OnClose()
 237    {
 1238        if (!view.IsVisible())
 0239            return;
 240
 1241        SetVisibility(false);
 242
 1243        LandWithAccess[] lands = landsesController.GetLands();
 1244        if (lands != null)
 245        {
 1246            Vector2Int totalLands = GetAmountOfLandsOwnedAndOperator(lands);
 1247            BIWAnalytics.PlayerClosesPanel(totalLands.x, totalLands.y);
 248        }
 1249    }
 250
 251    private void PanelOpenEvent(LandWithAccess[] lands)
 252    {
 4253        Vector2Int totalLands = GetAmountOfLandsOwnedAndOperator(lands);
 4254        BIWAnalytics.PlayerOpenPanel(totalLands.x, totalLands.y);
 4255    }
 256
 257    /// <summary>
 258    /// This counts the amount of lands that the user own and the amount of lands that the user operate
 259    /// </summary>
 260    /// <param name="lands"></param>
 261    /// <returns>Vector2: X = amount of owned lands, Y = amount of operator lands</returns>
 262    private Vector2Int GetAmountOfLandsOwnedAndOperator(LandWithAccess[] lands)
 263    {
 5264        int ownedLandsCount = 0;
 5265        int operatorLandsCount = 0;
 18266        foreach (var land in lands)
 267        {
 4268            if (land.role == LandRole.OWNER)
 4269                ownedLandsCount++;
 270            else
 0271                operatorLandsCount++;
 272        }
 273
 5274        return new Vector2Int(ownedLandsCount, operatorLandsCount);
 275    }
 276
 277    private void SetView()
 278    {
 17279        scenesViewController.AddListener((ISceneListener) view);
 17280        projectsController.AddListener((IProjectsListener) view);
 17281    }
 282
 283    private void FetchPanelInfo(float landCacheTime = CACHE_TIME_LAND, float scenesCacheTime = CACHE_TIME_SCENES)
 284    {
 4285        if (isFetchingLands || isFetchingProjects)
 0286            return;
 287
 4288        isFetchingLands = true;
 4289        isFetchingProjects = true;
 290
 4291        var address = UserProfile.GetOwnUserProfile().ethAddress;
 4292        var network = KernelConfig.i.Get().network;
 293
 294#if UNITY_EDITOR
 295        // NOTE: to be able to test in editor without getting a profile we hardcode an address here
 4296        if (string.IsNullOrEmpty(address))
 297        {
 0298            address = TESTING_ETH_ADDRESS;
 0299            network = TESTING_TLD;
 0300            DataStore.i.playerRealm.Set(new CurrentRealmModel()
 301            {
 302                domain = $"https://peer-lb.decentraland.{TESTING_TLD}",
 303                contentServerUrl = $"https://peer-lb.decentraland.{TESTING_TLD}/content",
 304            });
 305        }
 306#endif
 307
 4308        sectionsController.SetFetchingDataStart();
 309
 4310        fetchLandPromise = DeployedScenesFetcher.FetchLandsFromOwner(catalyst, theGraph, address, network, landCacheTime
 4311        fetchLandPromise
 312            .Then(LandsFetched)
 313            .Catch(LandsFetchedError);
 314
 4315        if (!DataStore.i.builderInWorld.isDevBuild.Get())
 4316            return;
 0317        fetchProjectsPromise = BuilderPanelDataFetcher.FetchProjectData(context.builderAPIController);
 0318        fetchProjectsPromise
 319            .Then(ProjectsFetched)
 320            .Catch(ProjectsFetchedError);
 0321    }
 322
 323    internal void ProjectsFetched(ProjectData[] data)
 324    {
 1325        DataStore.i.builderInWorld.projectData.Set(data);
 1326        isFetchingProjects = false;
 1327        projectsController.SetProjects(data);
 1328        UpdateProjectsDeploymentStatus();
 1329    }
 330
 331    internal void ProjectsFetchedError(string error)
 332    {
 1333        isFetchingProjects = false;
 1334        sectionsController.SetFetchingDataEnd<SectionProjectController>();
 1335        projectsController.SetProjects(new ProjectData[] { });
 1336        BIWUtils.ShowGenericNotification(error);
 1337    }
 338
 339    private void UpdateProjectsDeploymentStatus()
 340    {
 2341        if (isFetchingLands || isFetchingProjects)
 0342            return;
 343
 2344        projectsController.UpdateDeploymentStatus();
 2345    }
 346
 347    internal void LandsFetchedError(string error)
 348    {
 1349        isFetchingLands = false;
 1350        sectionsController.SetFetchingDataEnd<SectionLandController>();
 1351        sectionsController.SetFetchingDataEnd<SectionScenesController>();
 1352        landsesController.SetLands(new LandWithAccess[] { });
 1353        scenesViewController.SetScenes(new ISceneData[] { });
 1354        Debug.LogError(error);
 1355    }
 356
 357    internal void LandsFetched(LandWithAccess[] lands)
 358    {
 1359        DataStore.i.builderInWorld.landsWithAccess.Set(lands.ToArray(), true);
 1360        sectionsController.SetFetchingDataEnd<SectionLandController>();
 1361        isFetchingLands = false;
 1362        UpdateProjectsDeploymentStatus();
 363
 364        try
 365        {
 2366            ISceneData[] places = lands.Where(land => land.scenes != null && land.scenes.Count > 0)
 2367                                       .Select(land => land.scenes.Where(scene => !scene.isEmpty).Select(scene => (IScen
 0368                                       .Aggregate((i, j) => i.Concat(j))
 369                                       .ToArray();
 370
 0371            if (sendPlayerOpenPanelEvent)
 0372                PanelOpenEvent(lands);
 0373            landsesController.SetLands(lands);
 0374            scenesViewController.SetScenes(places);
 0375        }
 1376        catch (Exception e)
 377        {
 1378            landsesController.SetLands(lands);
 1379            scenesViewController.SetScenes(new ISceneData[] { });
 1380        }
 1381    }
 382
 383    internal void GoToCoords(Vector2Int coords)
 384    {
 1385        WebInterface.GoTo(coords.x, coords.y);
 1386        SetVisibility(false);
 1387        OnJumpInOrEdit?.Invoke();
 1388    }
 389
 0390    private void OpenUrl(string url) { WebInterface.OpenURL(url); }
 391
 392    internal void OnGoToEditScene(Vector2Int coords)
 393    {
 1394        bool isGoingToTeleport = BIWTeleportAndEdit.TeleportAndEdit(coords);
 1395        if (isGoingToTeleport)
 396        {
 1397            SetVisibility(false);
 398        }
 399
 1400        OnJumpInOrEdit?.Invoke();
 1401    }
 402
 403    private void StartFetchInterval()
 404    {
 4405        if (fetchDataInterval != null)
 406        {
 0407            StopFetchInterval();
 408        }
 409
 4410        fetchDataInterval = CoroutineStarter.Start(RefreshDataInterval());
 4411    }
 412
 413    private void StopFetchInterval()
 414    {
 20415        CoroutineStarter.Stop(fetchDataInterval);
 20416        fetchDataInterval = null;
 20417    }
 418
 419    IEnumerator RefreshDataInterval()
 420    {
 0421        while (true)
 422        {
 4423            yield return WaitForSecondsCache.Get(REFRESH_INTERVAL);
 0424            FetchPanelInfo();
 425        }
 426    }
 427
 428    private void OnSceneUnpublished(PublishSceneResultPayload current, PublishSceneResultPayload previous)
 429    {
 0430        if (current.ok)
 431        {
 0432            FetchPanelInfo(CACHE_TIME_LAND, 0);
 433        }
 0434    }
 435}