| | 1 | | using System; |
| | 2 | | using System.Collections.Generic; |
| | 3 | | using System.Linq; |
| | 4 | | using DCL.Helpers; |
| | 5 | | using DCL.Interface; |
| | 6 | | using UnityEngine; |
| | 7 | | using Object = UnityEngine.Object; |
| | 8 | |
|
| | 9 | | namespace DCL.Builder |
| | 10 | | { |
| | 11 | | internal class SectionLandController : SectionBase, ILandsListener, ISectionOpenURLRequester, ISectionGotoCoordsRequ |
| | 12 | | { |
| | 13 | | public const string VIEW_PREFAB_PATH = "BuilderProjectsPanelMenuSections/SectionLandsView"; |
| | 14 | |
|
| | 15 | | private const string BUILDER_LAND_URL_FORMAT = "https://builder.decentraland.org/land/{0}"; |
| | 16 | | private const string MARKETPLACE_URL = "https://market.decentraland.org/"; |
| | 17 | |
|
| | 18 | | public event Action<string> OnRequestOpenUrl; |
| | 19 | | public event Action<Vector2Int> OnRequestGoToCoords; |
| | 20 | | public event Action<Vector2Int> OnRequestEditSceneAtCoords; |
| | 21 | |
|
| 0 | 22 | | public override ISectionSearchHandler searchHandler => landSearchHandler; |
| | 23 | |
|
| | 24 | | private readonly SectionLandView view; |
| | 25 | |
|
| 3 | 26 | | private readonly ISectionSearchHandler landSearchHandler = new SectionSearchHandler(); |
| 3 | 27 | | private readonly Dictionary<string, LandElementView> landElementViews = new Dictionary<string, LandElementView>( |
| 3 | 28 | | private readonly Queue<LandElementView> landElementViewsPool = new Queue<LandElementView>(); |
| | 29 | |
|
| 0 | 30 | | public SectionLandController() : this( |
| | 31 | | Object.Instantiate(Resources.Load<SectionLandView>(VIEW_PREFAB_PATH)) |
| 0 | 32 | | ) { } |
| | 33 | |
|
| 3 | 34 | | public SectionLandController(SectionLandView view) |
| | 35 | | { |
| 3 | 36 | | this.view = view; |
| 3 | 37 | | PoolView(view.GetLandElementeBaseView()); |
| | 38 | |
|
| 3 | 39 | | view.OnOpenMarketplaceRequested += OnOpenMarketplacePressed; |
| 3 | 40 | | landSearchHandler.OnResult += OnSearchResult; |
| 3 | 41 | | } |
| | 42 | |
|
| 0 | 43 | | public override void SetViewContainer(Transform viewContainer) { view.SetParent(viewContainer); } |
| | 44 | |
|
| | 45 | | public override void Dispose() |
| | 46 | | { |
| 3 | 47 | | view.OnOpenMarketplaceRequested -= OnOpenMarketplacePressed; |
| 3 | 48 | | landSearchHandler.OnResult -= OnSearchResult; |
| | 49 | |
|
| 3 | 50 | | using (var iterator = landElementViews.GetEnumerator()) |
| | 51 | | { |
| 4 | 52 | | while (iterator.MoveNext()) |
| | 53 | | { |
| 1 | 54 | | iterator.Dispose(); |
| | 55 | | } |
| 3 | 56 | | } |
| | 57 | |
|
| 6 | 58 | | while (landElementViewsPool.Count > 0) |
| | 59 | | { |
| 3 | 60 | | landElementViewsPool.Dequeue().Dispose(); |
| | 61 | | } |
| | 62 | |
|
| 3 | 63 | | view.Dispose(); |
| 3 | 64 | | } |
| | 65 | |
|
| 4 | 66 | | protected override void OnShow() { view.SetActive(true); } |
| | 67 | |
|
| 2 | 68 | | protected override void OnHide() { view.SetActive(false); } |
| | 69 | |
|
| | 70 | | void ILandsListener.OnSetLands(LandWithAccess[] lands) |
| | 71 | | { |
| 5 | 72 | | if (lands == null || lands.Length == 0) |
| | 73 | | { |
| 1 | 74 | | SetEmptyOrLoading(); |
| | 75 | | } |
| | 76 | |
|
| 5 | 77 | | if (lands == null) |
| 0 | 78 | | return; |
| | 79 | |
|
| 5 | 80 | | List<LandElementView> toRemove = landElementViews.Values |
| 7 | 81 | | .Where(landElementView => lands.All(land => land.id != land |
| | 82 | | .ToList(); |
| | 83 | |
|
| 14 | 84 | | for (int i = 0; i < toRemove.Count; i++) |
| | 85 | | { |
| 2 | 86 | | landElementViews.Remove(toRemove[i].GetId()); |
| 2 | 87 | | PoolView(toRemove[i]); |
| | 88 | | } |
| | 89 | |
|
| 20 | 90 | | for (int i = 0; i < lands.Length; i++) |
| | 91 | | { |
| 5 | 92 | | if (!landElementViews.TryGetValue(lands[i].id, out LandElementView landElementView)) |
| | 93 | | { |
| 3 | 94 | | landElementView = GetPooledView(); |
| 3 | 95 | | landElementViews.Add(lands[i].id, landElementView); |
| | 96 | | } |
| | 97 | |
|
| 5 | 98 | | bool isEstate = lands[i].type == LandType.ESTATE; |
| 5 | 99 | | landElementView.Setup(lands[i]); |
| 5 | 100 | | landElementView.SetThumbnail(GetLandThumbnailUrl(lands[i], isEstate)); |
| | 101 | | } |
| | 102 | |
|
| 10 | 103 | | landSearchHandler.SetSearchableList(landElementViews.Values.Select(scene => scene.searchInfo).ToList()); |
| 5 | 104 | | } |
| | 105 | |
|
| | 106 | | private void OnSearchResult(List<ISearchInfo> searchInfoLands) |
| | 107 | | { |
| 5 | 108 | | if (landElementViews == null) |
| 0 | 109 | | return; |
| | 110 | |
|
| 5 | 111 | | using (var iterator = landElementViews.GetEnumerator()) |
| | 112 | | { |
| 10 | 113 | | while (iterator.MoveNext()) |
| | 114 | | { |
| 5 | 115 | | iterator.Current.Value.SetParent(view.GetLandElementsContainer()); |
| 5 | 116 | | iterator.Current.Value.gameObject.SetActive(false); |
| | 117 | | } |
| 5 | 118 | | } |
| | 119 | |
|
| 20 | 120 | | for (int i = 0; i < searchInfoLands.Count; i++) |
| | 121 | | { |
| 5 | 122 | | if (!landElementViews.TryGetValue(searchInfoLands[i].id, out LandElementView landView)) |
| | 123 | | continue; |
| | 124 | |
|
| 5 | 125 | | landView.gameObject.SetActive(true); |
| 5 | 126 | | landView.transform.SetSiblingIndex(i); |
| | 127 | | } |
| | 128 | |
|
| 5 | 129 | | if (landElementViews.Count == 0) |
| | 130 | | { |
| 1 | 131 | | SetEmptyOrLoading(); |
| 1 | 132 | | } |
| 4 | 133 | | else if (searchInfoLands.Count == 0) |
| | 134 | | { |
| 0 | 135 | | view.SetNoSearchResult(); |
| 0 | 136 | | } |
| | 137 | | else |
| | 138 | | { |
| 4 | 139 | | view.SetFilled(); |
| | 140 | | } |
| 4 | 141 | | } |
| | 142 | |
|
| | 143 | | private void PoolView(LandElementView landView) |
| | 144 | | { |
| 5 | 145 | | landView.OnSettingsPressed -= OnSettingsPressed; |
| 5 | 146 | | landView.OnJumpInPressed -= OnJumpInPressed; |
| 5 | 147 | | landView.OnOpenInDappPressed -= OnOpenInDappPressed; |
| 5 | 148 | | landView.OnEditorPressed -= OnEditPressed; |
| | 149 | |
|
| 5 | 150 | | landView.SetActive(false); |
| 5 | 151 | | landElementViewsPool.Enqueue(landView); |
| 5 | 152 | | } |
| | 153 | |
|
| | 154 | | private LandElementView GetPooledView() |
| | 155 | | { |
| | 156 | | LandElementView landView; |
| | 157 | |
|
| 3 | 158 | | if (landElementViewsPool.Count > 0) |
| | 159 | | { |
| 2 | 160 | | landView = landElementViewsPool.Dequeue(); |
| 2 | 161 | | } |
| | 162 | | else |
| | 163 | | { |
| 1 | 164 | | landView = Object.Instantiate(view.GetLandElementeBaseView(), view.GetLandElementsContainer()); |
| | 165 | | } |
| | 166 | |
|
| 3 | 167 | | landView.OnSettingsPressed += OnSettingsPressed; |
| 3 | 168 | | landView.OnJumpInPressed += OnJumpInPressed; |
| 3 | 169 | | landView.OnOpenInDappPressed += OnOpenInDappPressed; |
| 3 | 170 | | landView.OnEditorPressed += OnEditPressed; |
| | 171 | |
|
| 3 | 172 | | return landView; |
| | 173 | | } |
| | 174 | |
|
| | 175 | | private void SetEmptyOrLoading() |
| | 176 | | { |
| 2 | 177 | | if (isLoading) |
| | 178 | | { |
| 0 | 179 | | view.SetLoading(); |
| 0 | 180 | | } |
| | 181 | | else |
| | 182 | | { |
| 2 | 183 | | view.SetEmpty(); |
| | 184 | | } |
| 2 | 185 | | } |
| | 186 | |
|
| | 187 | | private string GetLandThumbnailUrl(LandWithAccess land, bool isEstate) |
| | 188 | | { |
| 5 | 189 | | if (land == null) |
| 0 | 190 | | return null; |
| | 191 | |
|
| | 192 | | const int width = 100; |
| | 193 | | const int height = 100; |
| | 194 | | const int sizeFactorParcel = 15; |
| | 195 | | const int sizeFactorEstate = 35; |
| | 196 | |
|
| 5 | 197 | | if (!isEstate) |
| | 198 | | { |
| 5 | 199 | | return MapUtils.GetMarketPlaceThumbnailUrl(new[] { land.baseCoords }, width, height, sizeFactorParcel); |
| | 200 | | } |
| | 201 | |
|
| 0 | 202 | | return MapUtils.GetMarketPlaceThumbnailUrl(land.parcels, width, height, sizeFactorEstate); |
| | 203 | | } |
| | 204 | |
|
| | 205 | | private void OnSettingsPressed(string landId) |
| | 206 | | { |
| | 207 | | //NOTE: for MVP we are redirecting user to Builder's page |
| 0 | 208 | | WebInterface.OpenURL(string.Format(BUILDER_LAND_URL_FORMAT, landId)); |
| 0 | 209 | | } |
| | 210 | |
|
| 0 | 211 | | private void OnOpenInDappPressed(string landId) { OnRequestOpenUrl?.Invoke(string.Format(BUILDER_LAND_URL_FORMAT |
| | 212 | |
|
| 0 | 213 | | private void OnJumpInPressed(Vector2Int coords) { OnRequestGoToCoords?.Invoke(coords); } |
| | 214 | |
|
| 0 | 215 | | private void OnOpenMarketplacePressed() { OnRequestOpenUrl?.Invoke(MARKETPLACE_URL); } |
| | 216 | |
|
| 0 | 217 | | private void OnEditPressed(Vector2Int coords) { OnRequestEditSceneAtCoords?.Invoke(coords); } |
| | 218 | | } |
| | 219 | | } |