Skip to content

Commit 5475612

Browse files
feat: add worlds in discovery panel (#5617)
* Feat: add events in discovery panel * Polish UI common buttons * Polish UI realm selector * Polish nav bar, search bar and discover bar UI * Rename and update like/dislike icons * Polish UI place card * Polish place subsection and card * Polish UI search subsection * Added retrieval of worlds in search * Added worlds sub section in discover panel * Minor changes to worlds subsection * Add background container to places card * Polish worlds button. Add icon. * Update Tooltip.prefab * Enhance color animations in header buttons * Enhance hover animation in place card buttons * Polish Place Card modal UI * Polish worlds subsection. Create folder for textures. * Minor UI fixes for explore v2 * Polish favourites subsection and card * Normalise show more button position in every subsection * Update favorites subsection * Polish event subsection * Fixed search section * Minor test fix * Added worlds subsection view tests * Fixed search tab test * Added worlds test for search subsection * Additional tests and code cleanup * Rebuild discover header UI * Polish UI search sub section. Fix left alignment. * Add content size fitter and vertical layout to search subsections rows. Add icons next to each title. * Fix color hover animation in dropdowns * Fix margins and paddings * Add content size fitter to cards containers * Increase cards' containers horizontal gap. * Fixed jump in for worlds * Move icons from titles next to subtitles. * Update favorites empty state. Rename-update textures * Added feature flag * Fixed analytics * Additional changes for worlds analytics * Fixed search worlds analytics * Temporarly ignored tests --------- Signed-off-by: davidejensen <davidejensen@live.it> Co-authored-by: Romina Marchetti <rma.marchetti@gmail.com>
1 parent 68758f4 commit 5475612

File tree

101 files changed

+30933
-23918
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

101 files changed

+30933
-23918
lines changed

unity-renderer/Assets/DCLServices/PlacesAPIService/PlacesAnalytics.cs

Lines changed: 31 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -24,13 +24,14 @@ public enum SortingType
2424
Best
2525
}
2626

27-
void AddFavorite(string placeUUID, ActionSource source);
28-
void RemoveFavorite(string placeUUID, ActionSource source);
29-
void Like(string placeUUID, IPlacesAnalytics.ActionSource source);
30-
void Dislike(string placeUUID, IPlacesAnalytics.ActionSource source);
31-
void RemoveVote(string placeUUID, IPlacesAnalytics.ActionSource source);
27+
void AddFavorite(string placeUUID, ActionSource source, bool isWorld = false);
28+
void RemoveFavorite(string placeUUID, ActionSource source, bool isWorld = false);
29+
void Like(string placeUUID, IPlacesAnalytics.ActionSource source, bool isWorld = false);
30+
void Dislike(string placeUUID, IPlacesAnalytics.ActionSource source, bool isWorld = false);
31+
void RemoveVote(string placeUUID, IPlacesAnalytics.ActionSource source, bool isWorld = false);
3232
void Filter(FilterType filterType);
3333
void Sort(IPlacesAnalytics.SortingType sortingType);
34+
void SortWorlds(IPlacesAnalytics.SortingType sortingType);
3435
}
3536

3637
public class PlacesAnalytics : IPlacesAnalytics
@@ -42,53 +43,59 @@ public class PlacesAnalytics : IPlacesAnalytics
4243
private const string REMOVE_VOTE_PLACE = "player_remove_vote_place";
4344
private const string FILTER_PLACES = "player_filter_places";
4445
private const string SORT_PLACES = "player_sort_places";
46+
private const string SORT_WORLDS = "player_sort_worlds";
4547

46-
public void AddFavorite(string placeUUID, IPlacesAnalytics.ActionSource source)
48+
public void AddFavorite(string placeUUID, IPlacesAnalytics.ActionSource source, bool isWorld = false)
4749
{
4850
var data = new Dictionary<string, string>
4951
{
5052
["place_id"] = placeUUID,
51-
["source"] = source.ToString()
53+
["source"] = source.ToString(),
54+
["is_world"] = isWorld.ToString()
5255
};
5356
GenericAnalytics.SendAnalytic(ADD_FAVORITE_PLACE, data);
5457
}
5558

56-
public void RemoveFavorite(string placeUUID, IPlacesAnalytics.ActionSource source)
59+
public void RemoveFavorite(string placeUUID, IPlacesAnalytics.ActionSource source, bool isWorld = false)
5760
{
5861
var data = new Dictionary<string, string>
5962
{
6063
["place_id"] = placeUUID,
61-
["source"] = source.ToString()
64+
["source"] = source.ToString(),
65+
["is_world"] = isWorld.ToString()
6266
};
6367
GenericAnalytics.SendAnalytic(REMOVE_FAVORITE_PLACE, data);
6468
}
6569

66-
public void Like(string placeUUID, IPlacesAnalytics.ActionSource source)
70+
public void Like(string placeUUID, IPlacesAnalytics.ActionSource source, bool isWorld = false)
6771
{
6872
var data = new Dictionary<string, string>
6973
{
7074
["place_id"] = placeUUID,
71-
["source"] = source.ToString()
75+
["source"] = source.ToString(),
76+
["is_world"] = isWorld.ToString()
7277
};
7378
GenericAnalytics.SendAnalytic(LIKE_PLACE, data);
7479
}
7580

76-
public void Dislike(string placeUUID, IPlacesAnalytics.ActionSource source)
81+
public void Dislike(string placeUUID, IPlacesAnalytics.ActionSource source, bool isWorld = false)
7782
{
7883
var data = new Dictionary<string, string>
7984
{
8085
["place_id"] = placeUUID,
81-
["source"] = source.ToString()
86+
["source"] = source.ToString(),
87+
["is_world"] = isWorld.ToString()
8288
};
8389
GenericAnalytics.SendAnalytic(DISLIKE_PLACE, data);
8490
}
8591

86-
public void RemoveVote(string placeUUID, IPlacesAnalytics.ActionSource source)
92+
public void RemoveVote(string placeUUID, IPlacesAnalytics.ActionSource source, bool isWorld = false)
8793
{
8894
var data = new Dictionary<string, string>
8995
{
9096
["place_id"] = placeUUID,
91-
["source"] = source.ToString()
97+
["source"] = source.ToString(),
98+
["is_world"] = isWorld.ToString()
9299
};
93100
GenericAnalytics.SendAnalytic(REMOVE_VOTE_PLACE, data);
94101
}
@@ -110,5 +117,14 @@ public void Sort(IPlacesAnalytics.SortingType sortingType)
110117
};
111118
GenericAnalytics.SendAnalytic(SORT_PLACES, data);
112119
}
120+
121+
public void SortWorlds(IPlacesAnalytics.SortingType sortingType)
122+
{
123+
var data = new Dictionary<string, string>
124+
{
125+
["type"] = sortingType.ToString()
126+
};
127+
GenericAnalytics.SendAnalytic(SORT_WORLDS, data);
128+
}
113129
}
114130
}

unity-renderer/Assets/DCLServices/WorldsAPIService.meta

Lines changed: 8 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
using Cysharp.Threading.Tasks;
2+
using DCL;
3+
using DCL.Helpers;
4+
using MainScripts.DCL.Controllers.HotScenes;
5+
using System;
6+
using System.Collections.Generic;
7+
using System.Threading;
8+
using UnityEngine;
9+
using UnityEngine.Networking;
10+
11+
namespace DCLServices.WorldsAPIService
12+
{
13+
public interface IWorldsAPIClient
14+
{
15+
UniTask<WorldsResponse.WorldsAPIResponse> SearchWorlds(string searchString, int pageNumber, int pageSize, CancellationToken ct);
16+
17+
UniTask<WorldsResponse.WorldsAPIResponse> GetWorlds(int pageNumber, int pageSize, string filter = "", string sort = "", CancellationToken ct = default);
18+
}
19+
20+
public class WorldsAPIClient : IWorldsAPIClient
21+
{
22+
private const string BASE_URL = "https://places.decentraland.org/api/worlds";
23+
24+
private readonly IWebRequestController webRequestController;
25+
26+
public WorldsAPIClient(IWebRequestController webRequestController)
27+
{
28+
this.webRequestController = webRequestController;
29+
}
30+
31+
public async UniTask<WorldsResponse.WorldsAPIResponse> SearchWorlds(string searchString, int pageNumber, int pageSize, CancellationToken ct)
32+
{
33+
const string URL = BASE_URL + "?with_realms_detail=true&search={0}&offset={1}&limit={2}";
34+
var result = await webRequestController.GetAsync(string.Format(URL, searchString.Replace(" ", "+"), pageNumber * pageSize, pageSize), cancellationToken: ct, isSigned: true);
35+
36+
if (result.result != UnityWebRequest.Result.Success)
37+
throw new Exception($"Error fetching worlds info:\n{result.error}");
38+
39+
var response = Utils.SafeFromJson<WorldsResponse.WorldsAPIResponse>(result.downloadHandler.text);
40+
41+
if (response == null)
42+
throw new Exception($"Error parsing world info:\n{result.downloadHandler.text}");
43+
44+
if (response.data == null)
45+
throw new Exception($"No world info retrieved:\n{result.downloadHandler.text}");
46+
47+
return response;
48+
}
49+
50+
public async UniTask<WorldsResponse.WorldsAPIResponse> GetWorlds(int pageNumber, int pageSize, string filter = "", string sort = "", CancellationToken ct = default)
51+
{
52+
const string URL = BASE_URL + "?order_by={3}&order=desc&with_realms_detail=true&offset={0}&limit={1}&{2}";
53+
var result = await webRequestController.GetAsync(string.Format(URL, pageNumber * pageSize, pageSize, filter, sort), cancellationToken: ct, isSigned: true);
54+
55+
if (result.result != UnityWebRequest.Result.Success)
56+
throw new Exception($"Error fetching worlds info:\n{result.error}");
57+
58+
var response = Utils.SafeFromJson<WorldsResponse.WorldsAPIResponse>(result.downloadHandler.text);
59+
60+
if (response == null)
61+
throw new Exception($"Error parsing word info:\n{result.downloadHandler.text}");
62+
63+
if (response.data == null)
64+
throw new Exception($"No world info retrieved:\n{result.downloadHandler.text}");
65+
66+
return response;
67+
}
68+
}
69+
}

unity-renderer/Assets/DCLServices/WorldsAPIService/WorldsAPIClient.cs.meta

Lines changed: 3 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
{
2+
"name": "WorldsAPIService",
3+
"rootNamespace": "",
4+
"references": [
5+
"GUID:3b80b0b562b1cbc489513f09fc1b8f69",
6+
"GUID:f51ebe6a0ceec4240a699833d6309b23",
7+
"GUID:b8662e798190944f4b638fbeb48e84f0",
8+
"GUID:68069f49d86442cd9618861b4d74b1aa",
9+
"GUID:4d3366a36e77f41cfb7436340334e236",
10+
"GUID:ee6523961ef177343ad763fcd55c7c46",
11+
"GUID:b1087c5731ff68448a0a9c625bb7e52d",
12+
"GUID:0663fad624d836944b40ae27c3414652",
13+
"GUID:2fe81fa47ac9ca345860b544ce917241"
14+
],
15+
"includePlatforms": [],
16+
"excludePlatforms": [],
17+
"allowUnsafeCode": false,
18+
"overrideReferences": false,
19+
"precompiledReferences": [],
20+
"autoReferenced": true,
21+
"defineConstraints": [],
22+
"versionDefines": [],
23+
"noEngineReferences": false
24+
}

unity-renderer/Assets/DCLServices/WorldsAPIService/WorldsAPIService.asmdef.meta

Lines changed: 7 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
using Cysharp.Threading.Tasks;
2+
using DCL;
3+
using DCL.Tasks;
4+
using DCLServices.Lambdas;
5+
using System;
6+
using System.Collections.Generic;
7+
using System.Threading;
8+
9+
namespace DCLServices.WorldsAPIService
10+
{
11+
12+
public interface IWorldsAPIService : IService
13+
{
14+
UniTask<(IReadOnlyList<WorldsResponse.WorldInfo> worlds, int total)> SearchWorlds(string searchText, int pageNumber, int pageSize, CancellationToken ct, bool renewCache = false);
15+
UniTask<(IReadOnlyList<WorldsResponse.WorldInfo> worlds, int total)> GetWorlds(int pageNumber, int pageSize, string filter = "", string sort = "", CancellationToken ct = default, bool renewCache = false);
16+
}
17+
18+
public class WorldsAPIService : IWorldsAPIService, ILambdaServiceConsumer<WorldsResponse.WorldsAPIResponse>
19+
{
20+
private IWorldsAPIClient client;
21+
private readonly CancellationTokenSource disposeCts = new ();
22+
internal readonly Dictionary<string, LambdaResponsePagePointer<WorldsResponse.WorldsAPIResponse>> activeWorldsPagePointers = new ();
23+
24+
public WorldsAPIService(IWorldsAPIClient client)
25+
{
26+
this.client = client;
27+
}
28+
public void Initialize() { }
29+
30+
public async UniTask<(IReadOnlyList<WorldsResponse.WorldInfo> worlds, int total)> SearchWorlds(string searchText, int pageNumber, int pageSize, CancellationToken ct, bool renewCache = false)
31+
{
32+
WorldsResponse.WorldsAPIResponse worldsAPIResponse = await client.SearchWorlds(searchText, pageNumber, pageSize, ct);
33+
return (worldsAPIResponse.data, worldsAPIResponse.total);
34+
}
35+
36+
public async UniTask<(IReadOnlyList<WorldsResponse.WorldInfo> worlds, int total)> GetWorlds(int pageNumber, int pageSize, string filter = "", string sort = "", CancellationToken ct = default,
37+
bool renewCache = false)
38+
{
39+
var createNewPointer = false;
40+
41+
if (!activeWorldsPagePointers.TryGetValue($"{pageSize}_{filter}_{sort}", out var pagePointer)) { createNewPointer = true; }
42+
else if (renewCache)
43+
{
44+
pagePointer.Dispose();
45+
activeWorldsPagePointers.Remove($"{pageSize}_{filter}_{sort}");
46+
createNewPointer = true;
47+
}
48+
49+
if (createNewPointer)
50+
{
51+
activeWorldsPagePointers[$"{pageSize}_{filter}_{sort}"] = pagePointer = new LambdaResponsePagePointer<WorldsResponse.WorldsAPIResponse>(
52+
$"", // not needed, the consumer will compose the URL
53+
pageSize, disposeCts.Token, this, TimeSpan.FromSeconds(30));
54+
}
55+
56+
(WorldsResponse.WorldsAPIResponse response, bool _) = await pagePointer.GetPageAsync(pageNumber, ct, new Dictionary<string, string>(){{"filter", filter},{"sort", sort}});
57+
58+
return (response.data, response.total);
59+
}
60+
61+
public async UniTask<(WorldsResponse.WorldsAPIResponse response, bool success)> CreateRequest(string endPoint, int pageSize, int pageNumber, Dictionary<string,string> additionalData, CancellationToken ct = default)
62+
{
63+
var response = await client.GetWorlds(pageNumber, pageSize,additionalData["filter"],additionalData["sort"], ct);
64+
// Client will handle most of the error handling and throw if needed
65+
return (response, true);
66+
}
67+
68+
public void Dispose()
69+
{
70+
disposeCts.SafeCancelAndDispose();
71+
}
72+
}
73+
}

unity-renderer/Assets/DCLServices/WorldsAPIService/WorldsAPIService.cs.meta

Lines changed: 3 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)