< 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:47
Coverable lines:205
Total lines:441
Line coverage:77% (158 of 205)
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();
 081    }
 82
 83    public void Dispose()
 84    {
 1785        StopFetchInterval();
 86
 1787        sectionsController.OnRequestOpenUrl -= OpenUrl;
 1788        sectionsController.OnRequestGoToCoords -= GoToCoords;
 1789        sectionsController.OnRequestEditSceneAtCoords -= OnGoToEditScene;
 1790        sectionsController.OnCreateProjectRequest -= newProjectFlowController.NewProject;
 91
 1792        scenesViewController.OnJumpInPressed -= GoToCoords;
 1793        scenesViewController.OnRequestOpenUrl -= OpenUrl;
 1794        scenesViewController.OnEditorPressed -= OnGoToEditScene;
 1795        projectsController.OnEditorPressed -= GetManifestToEdit;
 96
 1797        newProjectFlowController.OnNewProjectCrated -= CreateNewProject;
 98
 1799        view.OnCreateProjectPressed -= newProjectFlowController.NewProject;
 100
 17101        DataStore.i.HUDs.builderProjectsPanelVisible.OnChange -= OnVisibilityChanged;
 17102        DataStore.i.builderInWorld.unpublishSceneResult.OnChange -= OnSceneUnpublished;
 17103        view.OnClosePressed -= OnClose;
 17104        view.OnBackPressed -= OnBack;
 105
 17106        unpublishPopupController?.Dispose();
 107
 17108        fetchLandPromise?.Dispose();
 17109        fetchProjectsPromise?.Dispose();
 110
 17111        leftMenuSettingsViewHandler?.Dispose();
 17112        sectionsHandler?.Dispose();
 17113        sceneContextMenuHandler?.Dispose();
 17114        leftMenuHandler?.Dispose();
 115
 17116        sectionsController?.Dispose();
 17117        scenesViewController?.Dispose();
 118
 17119        newProjectFlowController?.Dispose();
 120
 17121        configureBuilderInFullscreenMenu.OnChange -= ConfigureBuilderInFullscreenMenuChanged;
 122
 17123        view.Dispose();
 17124    }
 125
 126    public void Initialize(IContext context)
 127    {
 0128        this.context = context;
 0129        Initialize(new SectionsController(view.GetSectionContainer()),
 130            new ScenesViewController(view.GetSceneCardViewPrefab(), view.GetTransform()),
 131            new LandsController(),
 132            new ProjectsController(view.GetProjectCardView(), view.GetTransform()),
 133            new NewProjectFlowController(),
 134            Environment.i.platform.serviceProviders.theGraph,
 135            Environment.i.platform.serviceProviders.catalyst);
 0136    }
 137
 138    internal void Initialize(ISectionsController sectionsController,
 139        IScenesViewController scenesViewController, ILandsController landsesController, IProjectsController projectsCont
 140    {
 17141        if (isInitialized)
 0142            return;
 143
 17144        isInitialized = true;
 145
 17146        this.sectionsController = sectionsController;
 17147        this.scenesViewController = scenesViewController;
 17148        this.landsesController = landsesController;
 17149        this.projectsController = projectsController;
 150
 17151        this.newProjectFlowController = newProjectFlowController;
 152
 17153        this.theGraph = theGraph;
 17154        this.catalyst = catalyst;
 155
 17156        this.unpublishPopupController = new UnpublishPopupController(view.GetUnpublishPopup());
 157
 158        // set listeners for sections, setup searchbar for section, handle request for opening a new section
 17159        sectionsHandler = new SectionsHandler(sectionsController, scenesViewController, landsesController, projectsContr
 160        // handle if main panel or settings panel should be shown in current section
 17161        leftMenuHandler = new LeftMenuHandler(view, sectionsController);
 162        // handle project scene info on the left menu panel
 17163        leftMenuSettingsViewHandler = new LeftMenuSettingsViewHandler(view.GetSettingsViewReferences(), scenesViewContro
 164        // handle scene's context menu options
 17165        sceneContextMenuHandler = new SceneContextMenuHandler(view.GetSceneCardViewContextMenu(), sectionsController, sc
 166
 17167        SetView();
 168
 17169        sectionsController.OnRequestOpenUrl += OpenUrl;
 17170        sectionsController.OnRequestGoToCoords += GoToCoords;
 17171        sectionsController.OnRequestEditSceneAtCoords += OnGoToEditScene;
 17172        sectionsController.OnCreateProjectRequest += newProjectFlowController.NewProject;
 173
 17174        scenesViewController.OnJumpInPressed += GoToCoords;
 17175        scenesViewController.OnRequestOpenUrl += OpenUrl;
 17176        scenesViewController.OnEditorPressed += OnGoToEditScene;
 17177        newProjectFlowController.OnNewProjectCrated += CreateNewProject;
 178
 17179        view.OnCreateProjectPressed += this.newProjectFlowController.NewProject;
 17180        this.projectsController.OnEditorPressed += GetManifestToEdit;
 181
 17182        DataStore.i.HUDs.builderProjectsPanelVisible.OnChange += OnVisibilityChanged;
 17183        DataStore.i.builderInWorld.unpublishSceneResult.OnChange += OnSceneUnpublished;
 17184    }
 185
 186    private void GetManifestToEdit(ProjectData data)
 187    {
 0188        Promise<Manifest> manifestPromise = context.builderAPIController.GetManifestById(data.id);
 0189        manifestPromise.Then( OpenEditorFromManifest);
 190
 0191        manifestPromise.Catch( errorString =>
 192        {
 0193            BIWUtils.ShowGenericNotification(OBTAIN_PROJECT_ERROR + errorString);
 0194        });
 0195    }
 196
 197    private void CreateNewProject(ProjectData project)
 198    {
 0199        Promise<Manifest> projectPromise = context.builderAPIController.CreateNewProject(project);
 200
 0201        projectPromise.Then( OpenEditorFromManifest);
 202
 0203        projectPromise.Catch( errorString =>
 204        {
 0205            BIWUtils.ShowGenericNotification(CREATING_PROJECT_ERROR + errorString);
 0206        });
 0207    }
 208
 0209    private void OpenEditorFromManifest(Manifest manifest) { context.sceneManager.StartEditorFromManifest(manifest); }
 210
 14211    public void SetVisibility(bool visible) { DataStore.i.HUDs.builderProjectsPanelVisible.Set(visible); }
 212
 213    private void OnVisibilityChanged(bool isVisible, bool prev)
 214    {
 7215        if (isVisible == prev)
 0216            return;
 217
 7218        view.SetVisible(isVisible);
 219
 7220        if (isVisible)
 221        {
 4222            if (DataStore.i.builderInWorld.landsWithAccess.Get() != null)
 4223                PanelOpenEvent(DataStore.i.builderInWorld.landsWithAccess.Get());
 224            else
 0225                sendPlayerOpenPanelEvent = true;
 226
 4227            FetchPanelInfo();
 4228            StartFetchInterval();
 4229            if (DataStore.i.builderInWorld.isDevBuild.Get())
 0230                sectionsController.OpenSection(SectionId.PROJECTS);
 231            else
 4232                sectionsController.OpenSection(SectionId.SCENES);
 4233        }
 234        else
 235        {
 3236            StopFetchInterval();
 237        }
 3238    }
 239
 240    private void OnClose()
 241    {
 1242        if (!view.IsVisible())
 0243            return;
 244
 1245        SetVisibility(false);
 246
 1247        LandWithAccess[] lands = landsesController.GetLands();
 1248        if (lands != null)
 249        {
 1250            Vector2Int totalLands = GetAmountOfLandsOwnedAndOperator(lands);
 1251            BIWAnalytics.PlayerClosesPanel(totalLands.x, totalLands.y);
 252        }
 1253    }
 254
 255    private void PanelOpenEvent(LandWithAccess[] lands)
 256    {
 4257        Vector2Int totalLands = GetAmountOfLandsOwnedAndOperator(lands);
 4258        BIWAnalytics.PlayerOpenPanel(totalLands.x, totalLands.y);
 4259    }
 260
 261    /// <summary>
 262    /// This counts the amount of lands that the user own and the amount of lands that the user operate
 263    /// </summary>
 264    /// <param name="lands"></param>
 265    /// <returns>Vector2: X = amount of owned lands, Y = amount of operator lands</returns>
 266    private Vector2Int GetAmountOfLandsOwnedAndOperator(LandWithAccess[] lands)
 267    {
 5268        int ownedLandsCount = 0;
 5269        int operatorLandsCount = 0;
 18270        foreach (var land in lands)
 271        {
 4272            if (land.role == LandRole.OWNER)
 4273                ownedLandsCount++;
 274            else
 0275                operatorLandsCount++;
 276        }
 277
 5278        return new Vector2Int(ownedLandsCount, operatorLandsCount);
 279    }
 280
 281    private void SetView()
 282    {
 17283        scenesViewController.AddListener((ISceneListener) view);
 17284        projectsController.AddListener((IProjectsListener) view);
 17285    }
 286
 287    private void FetchPanelInfo(float landCacheTime = CACHE_TIME_LAND, float scenesCacheTime = CACHE_TIME_SCENES)
 288    {
 4289        if (isFetchingLands || isFetchingProjects)
 0290            return;
 291
 4292        isFetchingLands = true;
 4293        isFetchingProjects = true;
 294
 4295        var address = UserProfile.GetOwnUserProfile().ethAddress;
 4296        var network = KernelConfig.i.Get().network;
 297
 298#if UNITY_EDITOR
 299        // NOTE: to be able to test in editor without getting a profile we hardcode an address here
 4300        if (string.IsNullOrEmpty(address))
 301        {
 0302            address = TESTING_ETH_ADDRESS;
 0303            network = TESTING_TLD;
 0304            DataStore.i.realm.playerRealm.Set(new CurrentRealmModel()
 305            {
 306                domain = $"https://peer-lb.decentraland.{TESTING_TLD}",
 307                contentServerUrl = $"https://peer-lb.decentraland.{TESTING_TLD}/content",
 308            });
 309        }
 310#endif
 311
 4312        sectionsController.SetFetchingDataStart();
 313
 4314        fetchLandPromise = DeployedScenesFetcher.FetchLandsFromOwner(catalyst, theGraph, address, network, landCacheTime
 4315        fetchLandPromise
 316            .Then(LandsFetched)
 317            .Catch(LandsFetchedError);
 318
 4319        if (!DataStore.i.builderInWorld.isDevBuild.Get())
 4320            return;
 0321        fetchProjectsPromise = BuilderPanelDataFetcher.FetchProjectData(context.builderAPIController);
 0322        fetchProjectsPromise
 323            .Then(ProjectsFetched)
 324            .Catch(ProjectsFetchedError);
 0325    }
 326
 327    internal void ProjectsFetched(ProjectData[] data)
 328    {
 1329        DataStore.i.builderInWorld.projectData.Set(data);
 1330        isFetchingProjects = false;
 1331        projectsController.SetProjects(data);
 1332        UpdateProjectsDeploymentStatus();
 1333    }
 334
 335    internal void ProjectsFetchedError(string error)
 336    {
 1337        isFetchingProjects = false;
 1338        sectionsController.SetFetchingDataEnd<SectionProjectController>();
 1339        projectsController.SetProjects(new ProjectData[] { });
 1340        BIWUtils.ShowGenericNotification(error);
 1341    }
 342
 343    private void UpdateProjectsDeploymentStatus()
 344    {
 2345        if (isFetchingLands || isFetchingProjects)
 0346            return;
 347
 2348        projectsController.UpdateDeploymentStatus();
 2349    }
 350
 351    internal void LandsFetchedError(string error)
 352    {
 1353        isFetchingLands = false;
 1354        sectionsController.SetFetchingDataEnd<SectionLandController>();
 1355        sectionsController.SetFetchingDataEnd<SectionScenesController>();
 1356        landsesController.SetLands(new LandWithAccess[] { });
 1357        scenesViewController.SetScenes(new ISceneData[] { });
 1358        Debug.LogError(error);
 1359    }
 360
 361    internal void LandsFetched(LandWithAccess[] lands)
 362    {
 1363        DataStore.i.builderInWorld.landsWithAccess.Set(lands.ToArray(), true);
 1364        sectionsController.SetFetchingDataEnd<SectionLandController>();
 1365        isFetchingLands = false;
 1366        UpdateProjectsDeploymentStatus();
 367
 368        try
 369        {
 2370            ISceneData[] places = lands.Where(land => land.scenes != null && land.scenes.Count > 0)
 2371                .Select(land => land.scenes.Where(scene => !scene.isEmpty).Select(scene => (ISceneData)new SceneData(sce
 0372                .Aggregate((i, j) => i.Concat(j))
 373                .ToArray();
 374
 0375            if (sendPlayerOpenPanelEvent)
 0376                PanelOpenEvent(lands);
 0377            landsesController.SetLands(lands);
 0378            scenesViewController.SetScenes(places);
 0379        }
 1380        catch (Exception e)
 381        {
 1382            landsesController.SetLands(lands);
 1383            scenesViewController.SetScenes(new ISceneData[] { });
 1384        }
 1385    }
 386
 387    internal void GoToCoords(Vector2Int coords)
 388    {
 1389        WebInterface.GoTo(coords.x, coords.y);
 1390        SetVisibility(false);
 1391        OnJumpInOrEdit?.Invoke();
 1392    }
 393
 0394    private void OpenUrl(string url) { WebInterface.OpenURL(url); }
 395
 396    internal void OnGoToEditScene(Vector2Int coords)
 397    {
 1398        bool isGoingToTeleport = BIWTeleportAndEdit.TeleportAndEdit(coords);
 1399        if (isGoingToTeleport)
 400        {
 1401            SetVisibility(false);
 402        }
 403
 1404        OnJumpInOrEdit?.Invoke();
 1405    }
 406
 407    private void StartFetchInterval()
 408    {
 4409        if (fetchDataInterval != null)
 410        {
 0411            StopFetchInterval();
 412        }
 413
 4414        fetchDataInterval = CoroutineStarter.Start(RefreshDataInterval());
 4415    }
 416
 417    private void StopFetchInterval()
 418    {
 20419        CoroutineStarter.Stop(fetchDataInterval);
 20420        fetchDataInterval = null;
 20421    }
 422
 423    IEnumerator RefreshDataInterval()
 424    {
 0425        while (true)
 426        {
 4427            yield return WaitForSecondsCache.Get(REFRESH_INTERVAL);
 0428            FetchPanelInfo();
 429        }
 430    }
 431
 432    private void OnSceneUnpublished(PublishSceneResultPayload current, PublishSceneResultPayload previous)
 433    {
 0434        if (current.ok)
 435        {
 0436            FetchPanelInfo(CACHE_TIME_LAND, 0);
 437        }
 0438    }
 439
 34440    private void ConfigureBuilderInFullscreenMenuChanged(Transform currentParentTransform, Transform previousParentTrans
 441}