< Summary

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

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity NPath complexity Sequence coverage
BuilderMainPanelController()0%2.012085.71%
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%
ConfigureBuilderInFullscreenMenuChanged(...)0%110100%

File(s)

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

#LineLine coverage
 1using DCL;
 2using DCL.Builder;
 3using DCL.Builder.Manifest;
 4using DCL.Helpers;
 5using DCL.Interface;
 6using System;
 7using System.Collections;
 8using System.Linq;
 9using UnityEngine;
 10using Variables.RealmsInfo;
 11using Environment = DCL.Environment;
 12using Object = UnityEngine.Object;
 13
 14public class BuilderMainPanelController : IHUD, IBuilderMainPanelController
 15{
 16    private const string CREATING_PROJECT_ERROR = "Error creating a new project: ";
 17    private const string OBTAIN_PROJECT_ERROR = "Error obtaining the project: ";
 18    private const string TESTING_ETH_ADDRESS = "0xDc13378daFca7Fe2306368A16BCFac38c80BfCAD";
 19    private const string TESTING_TLD = "org";
 20    private const string VIEW_PREFAB_PATH = "BuilderProjectsPanel";
 21    private const string VIEW_PREFAB_PATH_DEV = "BuilderProjectsPanelDev";
 22
 23    private const float CACHE_TIME_LAND = 5 * 60;
 24    private const float CACHE_TIME_SCENES = 1 * 60;
 25    private const float REFRESH_INTERVAL = 2 * 60;
 26
 27    internal IBuilderMainPanelView view;
 28
 29    private ISectionsController sectionsController;
 30    private IProjectsController projectsController;
 31    private IScenesViewController scenesViewController;
 32    private ILandsController landsesController;
 33    private UnpublishPopupController unpublishPopupController;
 34
 35    private INewProjectFlowController newProjectFlowController;
 36
 37    private SectionsHandler sectionsHandler;
 38    private SceneContextMenuHandler sceneContextMenuHandler;
 39    private LeftMenuHandler leftMenuHandler;
 40    private LeftMenuSettingsViewHandler leftMenuSettingsViewHandler;
 41
 42    private ITheGraph theGraph;
 43    private ICatalyst catalyst;
 44
 45    private bool isInitialized = false;
 46    internal bool isFetchingLands = false;
 47    internal bool isFetchingProjects = false;
 48    private bool sendPlayerOpenPanelEvent = false;
 49    private Coroutine fetchDataInterval;
 50    private Promise<LandWithAccess[]> fetchLandPromise = null;
 51    private Promise<ProjectData[]> fetchProjectsPromise = null;
 52
 53    public event Action OnJumpInOrEdit;
 54
 55    internal IContext context;
 56
 5157    BaseVariable<Transform> configureBuilderInFullscreenMenu => DataStore.i.exploreV2.configureBuilderInFullscreenMenu;
 58
 1759    public BuilderMainPanelController()
 60    {
 1761        if (DataStore.i.builderInWorld.isDevBuild.Get())
 062            SetView(Object.Instantiate(Resources.Load<BuilderMainPanelView>(VIEW_PREFAB_PATH_DEV)));
 63        else
 1764            SetView(Object.Instantiate(Resources.Load<BuilderMainPanelView>(VIEW_PREFAB_PATH)));
 65
 1766        configureBuilderInFullscreenMenu.OnChange += ConfigureBuilderInFullscreenMenuChanged;
 1767        ConfigureBuilderInFullscreenMenuChanged(configureBuilderInFullscreenMenu.Get(), null);
 1768    }
 69
 70    internal void SetView(IBuilderMainPanelView view)
 71    {
 1772        this.view = view;
 1773        view.OnClosePressed += OnClose;
 1774        view.OnBackPressed += OnBack;
 1775    }
 76
 77    private void OnBack()
 78    {
 079        if (newProjectFlowController.IsActive())
 080            newProjectFlowController.Hide();
 81        else
 082            OnClose();
 083    }
 84
 85    public void Dispose()
 86    {
 1787        StopFetchInterval();
 88
 1789        sectionsController.OnRequestOpenUrl -= OpenUrl;
 1790        sectionsController.OnRequestGoToCoords -= GoToCoords;
 1791        sectionsController.OnRequestEditSceneAtCoords -= OnGoToEditScene;
 1792        sectionsController.OnCreateProjectRequest -= newProjectFlowController.NewProject;
 93
 1794        scenesViewController.OnJumpInPressed -= GoToCoords;
 1795        scenesViewController.OnRequestOpenUrl -= OpenUrl;
 1796        scenesViewController.OnEditorPressed -= OnGoToEditScene;
 1797        projectsController.OnEditorPressed -= GetManifestToEdit;
 98
 1799        newProjectFlowController.OnNewProjectCrated -= CreateNewProject;
 100
 17101        view.OnCreateProjectPressed -= newProjectFlowController.NewProject;
 102
 17103        DataStore.i.HUDs.builderProjectsPanelVisible.OnChange -= OnVisibilityChanged;
 17104        DataStore.i.builderInWorld.unpublishSceneResult.OnChange -= OnSceneUnpublished;
 17105        view.OnClosePressed -= OnClose;
 17106        view.OnBackPressed -= OnBack;
 107
 17108        unpublishPopupController?.Dispose();
 109
 17110        fetchLandPromise?.Dispose();
 17111        fetchProjectsPromise?.Dispose();
 112
 17113        leftMenuSettingsViewHandler?.Dispose();
 17114        sectionsHandler?.Dispose();
 17115        sceneContextMenuHandler?.Dispose();
 17116        leftMenuHandler?.Dispose();
 117
 17118        sectionsController?.Dispose();
 17119        scenesViewController?.Dispose();
 120
 17121        newProjectFlowController?.Dispose();
 122
 17123        configureBuilderInFullscreenMenu.OnChange -= ConfigureBuilderInFullscreenMenuChanged;
 124
 17125        view.Dispose();
 17126    }
 127
 128    public void Initialize(IContext context)
 129    {
 0130        this.context = context;
 0131        Initialize(new SectionsController(view.GetSectionContainer()),
 132            new ScenesViewController(view.GetSceneCardViewPrefab(), view.GetTransform()),
 133            new LandsController(),
 134            new ProjectsController(view.GetProjectCardView(), view.GetTransform()),
 135            new NewProjectFlowController(),
 136            Environment.i.platform.serviceProviders.theGraph,
 137            Environment.i.platform.serviceProviders.catalyst);
 0138    }
 139
 140    internal void Initialize(ISectionsController sectionsController,
 141        IScenesViewController scenesViewController, ILandsController landsesController, IProjectsController projectsCont
 142    {
 17143        if (isInitialized)
 0144            return;
 145
 17146        isInitialized = true;
 147
 17148        this.sectionsController = sectionsController;
 17149        this.scenesViewController = scenesViewController;
 17150        this.landsesController = landsesController;
 17151        this.projectsController = projectsController;
 152
 17153        this.newProjectFlowController = newProjectFlowController;
 154
 17155        this.theGraph = theGraph;
 17156        this.catalyst = catalyst;
 157
 17158        this.unpublishPopupController = new UnpublishPopupController(view.GetUnpublishPopup());
 159
 160        // set listeners for sections, setup searchbar for section, handle request for opening a new section
 17161        sectionsHandler = new SectionsHandler(sectionsController, scenesViewController, landsesController, projectsContr
 162        // handle if main panel or settings panel should be shown in current section
 17163        leftMenuHandler = new LeftMenuHandler(view, sectionsController);
 164        // handle project scene info on the left menu panel
 17165        leftMenuSettingsViewHandler = new LeftMenuSettingsViewHandler(view.GetSettingsViewReferences(), scenesViewContro
 166        // handle scene's context menu options
 17167        sceneContextMenuHandler = new SceneContextMenuHandler(view.GetSceneCardViewContextMenu(), sectionsController, sc
 168
 17169        SetView();
 170
 17171        sectionsController.OnRequestOpenUrl += OpenUrl;
 17172        sectionsController.OnRequestGoToCoords += GoToCoords;
 17173        sectionsController.OnRequestEditSceneAtCoords += OnGoToEditScene;
 17174        sectionsController.OnCreateProjectRequest += newProjectFlowController.NewProject;
 175
 17176        scenesViewController.OnJumpInPressed += GoToCoords;
 17177        scenesViewController.OnRequestOpenUrl += OpenUrl;
 17178        scenesViewController.OnEditorPressed += OnGoToEditScene;
 17179        newProjectFlowController.OnNewProjectCrated += CreateNewProject;
 180
 17181        view.OnCreateProjectPressed += this.newProjectFlowController.NewProject;
 17182        this.projectsController.OnEditorPressed += GetManifestToEdit;
 183
 17184        DataStore.i.HUDs.builderProjectsPanelVisible.OnChange += OnVisibilityChanged;
 17185        DataStore.i.builderInWorld.unpublishSceneResult.OnChange += OnSceneUnpublished;
 17186    }
 187
 188    private void GetManifestToEdit(ProjectData data)
 189    {
 0190        Promise<Manifest> manifestPromise = context.builderAPIController.GetManifestById(data.id);
 0191        manifestPromise.Then( OpenEditorFromManifest);
 192
 0193        manifestPromise.Catch( errorString =>
 194        {
 0195            BIWUtils.ShowGenericNotification(OBTAIN_PROJECT_ERROR + errorString);
 0196        });
 0197    }
 198
 199    private void CreateNewProject(ProjectData project)
 200    {
 0201        Promise<Manifest> projectPromise = context.builderAPIController.CreateNewProject(project);
 202
 0203        projectPromise.Then( OpenEditorFromManifest);
 204
 0205        projectPromise.Catch( errorString =>
 206        {
 0207            BIWUtils.ShowGenericNotification(CREATING_PROJECT_ERROR + errorString);
 0208        });
 0209    }
 210
 0211    private void OpenEditorFromManifest(Manifest manifest) { context.sceneManager.StartEditorFromManifest(manifest); }
 212
 14213    public void SetVisibility(bool visible) { DataStore.i.HUDs.builderProjectsPanelVisible.Set(visible); }
 214
 215    private void OnVisibilityChanged(bool isVisible, bool prev)
 216    {
 7217        if (isVisible == prev)
 0218            return;
 219
 7220        view.SetVisible(isVisible);
 221
 7222        if (isVisible)
 223        {
 4224            if (DataStore.i.builderInWorld.landsWithAccess.Get() != null)
 4225                PanelOpenEvent(DataStore.i.builderInWorld.landsWithAccess.Get());
 226            else
 0227                sendPlayerOpenPanelEvent = true;
 228
 4229            FetchPanelInfo();
 4230            StartFetchInterval();
 4231            if (DataStore.i.builderInWorld.isDevBuild.Get())
 0232                sectionsController.OpenSection(SectionId.PROJECTS);
 233            else
 4234                sectionsController.OpenSection(SectionId.SCENES);
 4235        }
 236        else
 237        {
 3238            StopFetchInterval();
 239        }
 3240    }
 241
 242    private void OnClose()
 243    {
 1244        if (!view.IsVisible())
 0245            return;
 246
 1247        SetVisibility(false);
 248
 1249        LandWithAccess[] lands = landsesController.GetLands();
 1250        if (lands != null)
 251        {
 1252            Vector2Int totalLands = GetAmountOfLandsOwnedAndOperator(lands);
 1253            BIWAnalytics.PlayerClosesPanel(totalLands.x, totalLands.y);
 254        }
 1255    }
 256
 257    private void PanelOpenEvent(LandWithAccess[] lands)
 258    {
 4259        Vector2Int totalLands = GetAmountOfLandsOwnedAndOperator(lands);
 4260        BIWAnalytics.PlayerOpenPanel(totalLands.x, totalLands.y);
 4261    }
 262
 263    /// <summary>
 264    /// This counts the amount of lands that the user own and the amount of lands that the user operate
 265    /// </summary>
 266    /// <param name="lands"></param>
 267    /// <returns>Vector2: X = amount of owned lands, Y = amount of operator lands</returns>
 268    private Vector2Int GetAmountOfLandsOwnedAndOperator(LandWithAccess[] lands)
 269    {
 5270        int ownedLandsCount = 0;
 5271        int operatorLandsCount = 0;
 18272        foreach (var land in lands)
 273        {
 4274            if (land.role == LandRole.OWNER)
 4275                ownedLandsCount++;
 276            else
 0277                operatorLandsCount++;
 278        }
 279
 5280        return new Vector2Int(ownedLandsCount, operatorLandsCount);
 281    }
 282
 283    private void SetView()
 284    {
 17285        scenesViewController.AddListener((ISceneListener) view);
 17286        projectsController.AddListener((IProjectsListener) view);
 17287    }
 288
 289    private void FetchPanelInfo(float landCacheTime = CACHE_TIME_LAND, float scenesCacheTime = CACHE_TIME_SCENES)
 290    {
 4291        if (isFetchingLands || isFetchingProjects)
 0292            return;
 293
 4294        isFetchingLands = true;
 4295        isFetchingProjects = true;
 296
 4297        var address = UserProfile.GetOwnUserProfile().ethAddress;
 4298        var network = KernelConfig.i.Get().network;
 299
 300#if UNITY_EDITOR
 301        // NOTE: to be able to test in editor without getting a profile we hardcode an address here
 4302        if (string.IsNullOrEmpty(address))
 303        {
 0304            address = TESTING_ETH_ADDRESS;
 0305            network = TESTING_TLD;
 0306            DataStore.i.realm.playerRealm.Set(new CurrentRealmModel()
 307            {
 308                domain = $"https://peer-lb.decentraland.{TESTING_TLD}",
 309                contentServerUrl = $"https://peer-lb.decentraland.{TESTING_TLD}/content",
 310            });
 311        }
 312#endif
 313
 4314        sectionsController.SetFetchingDataStart();
 315
 4316        fetchLandPromise = DeployedScenesFetcher.FetchLandsFromOwner(catalyst, theGraph, address, network, landCacheTime
 4317        fetchLandPromise
 318            .Then(LandsFetched)
 319            .Catch(LandsFetchedError);
 320
 4321        if (!DataStore.i.builderInWorld.isDevBuild.Get())
 4322            return;
 0323        fetchProjectsPromise = BuilderPanelDataFetcher.FetchProjectData(context.builderAPIController);
 0324        fetchProjectsPromise
 325            .Then(ProjectsFetched)
 326            .Catch(ProjectsFetchedError);
 0327    }
 328
 329    internal void ProjectsFetched(ProjectData[] data)
 330    {
 1331        DataStore.i.builderInWorld.projectData.Set(data);
 1332        isFetchingProjects = false;
 1333        projectsController.SetProjects(data);
 1334        UpdateProjectsDeploymentStatus();
 1335    }
 336
 337    internal void ProjectsFetchedError(string error)
 338    {
 1339        isFetchingProjects = false;
 1340        sectionsController.SetFetchingDataEnd<SectionProjectController>();
 1341        projectsController.SetProjects(new ProjectData[] { });
 1342        BIWUtils.ShowGenericNotification(error);
 1343    }
 344
 345    private void UpdateProjectsDeploymentStatus()
 346    {
 2347        if (isFetchingLands || isFetchingProjects)
 0348            return;
 349
 2350        projectsController.UpdateDeploymentStatus();
 2351    }
 352
 353    internal void LandsFetchedError(string error)
 354    {
 1355        isFetchingLands = false;
 1356        sectionsController.SetFetchingDataEnd<SectionLandController>();
 1357        sectionsController.SetFetchingDataEnd<SectionScenesController>();
 1358        landsesController.SetLands(new LandWithAccess[] { });
 1359        scenesViewController.SetScenes(new ISceneData[] { });
 1360        Debug.LogError(error);
 1361    }
 362
 363    internal void LandsFetched(LandWithAccess[] lands)
 364    {
 1365        DataStore.i.builderInWorld.landsWithAccess.Set(lands.ToArray(), true);
 1366        sectionsController.SetFetchingDataEnd<SectionLandController>();
 1367        isFetchingLands = false;
 1368        UpdateProjectsDeploymentStatus();
 369
 370        try
 371        {
 2372            ISceneData[] places = lands.Where(land => land.scenes != null && land.scenes.Count > 0)
 2373                .Select(land => land.scenes.Where(scene => !scene.isEmpty).Select(scene => (ISceneData)new SceneData(sce
 0374                .Aggregate((i, j) => i.Concat(j))
 375                .ToArray();
 376
 0377            if (sendPlayerOpenPanelEvent)
 0378                PanelOpenEvent(lands);
 0379            landsesController.SetLands(lands);
 0380            scenesViewController.SetScenes(places);
 0381        }
 1382        catch (Exception e)
 383        {
 1384            landsesController.SetLands(lands);
 1385            scenesViewController.SetScenes(new ISceneData[] { });
 1386        }
 1387    }
 388
 389    internal void GoToCoords(Vector2Int coords)
 390    {
 1391        WebInterface.GoTo(coords.x, coords.y);
 1392        SetVisibility(false);
 1393        OnJumpInOrEdit?.Invoke();
 1394    }
 395
 0396    private void OpenUrl(string url) { WebInterface.OpenURL(url); }
 397
 398    internal void OnGoToEditScene(Vector2Int coords)
 399    {
 1400        bool isGoingToTeleport = BIWTeleportAndEdit.TeleportAndEdit(coords);
 1401        if (isGoingToTeleport)
 402        {
 1403            SetVisibility(false);
 404        }
 405
 1406        OnJumpInOrEdit?.Invoke();
 1407    }
 408
 409    private void StartFetchInterval()
 410    {
 4411        if (fetchDataInterval != null)
 412        {
 0413            StopFetchInterval();
 414        }
 415
 4416        fetchDataInterval = CoroutineStarter.Start(RefreshDataInterval());
 4417    }
 418
 419    private void StopFetchInterval()
 420    {
 20421        CoroutineStarter.Stop(fetchDataInterval);
 20422        fetchDataInterval = null;
 20423    }
 424
 425    IEnumerator RefreshDataInterval()
 426    {
 0427        while (true)
 428        {
 4429            yield return WaitForSecondsCache.Get(REFRESH_INTERVAL);
 0430            FetchPanelInfo();
 431        }
 432    }
 433
 434    private void OnSceneUnpublished(PublishSceneResultPayload current, PublishSceneResultPayload previous)
 435    {
 0436        if (current.ok)
 437        {
 0438            FetchPanelInfo(CACHE_TIME_LAND, 0);
 439        }
 0440    }
 441
 34442    private void ConfigureBuilderInFullscreenMenuChanged(Transform currentParentTransform, Transform previousParentTrans
 443}