Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 15 additions & 11 deletions scenes/map_browser.tscn
Original file line number Diff line number Diff line change
Expand Up @@ -246,7 +246,7 @@ popup/item_0/text = "Recently added"
popup/item_0/id = 0
popup/item_1/text = "Length"
popup/item_1/id = 2
popup/item_2/text = "Notes"
popup/item_2/text = "Difficulty"
popup/item_2/id = 2

[node name="Direction" type="Button" parent="Holder/Background/Layout/TopBarBackground/Margin/TopBar/SearchBar" unique_id=1884251797]
Expand Down Expand Up @@ -275,29 +275,33 @@ layout_mode = 2
size_flags_horizontal = 3
text = "Difficulties"
flat = false
item_count = 5
popup/item_0/text = "Easy"
item_count = 6
popup/item_0/text = "N/A"
popup/item_0/checkable = 1
popup/item_0/checked = true
popup/item_0/id = 0
popup/item_1/text = "Medium"
popup/item_1/text = "Easy"
popup/item_1/checkable = 1
popup/item_1/checked = true
popup/item_1/id = 1
popup/item_2/text = "Hard"
popup/item_2/text = "Medium"
popup/item_2/checkable = 1
popup/item_2/checked = true
popup/item_2/id = 2
popup/item_3/text = "Insane"
popup/item_3/text = "Hard"
popup/item_3/checkable = 1
popup/item_3/checked = true
popup/item_3/id = 3
popup/item_4/text = "Illogical"
popup/item_4/text = "Insane"
popup/item_4/checkable = 1
popup/item_4/checked = true
popup/item_4/id = 4
popup/item_5/text = "Illogical"
popup/item_5/checkable = 1
popup/item_5/checked = true
popup/item_5/id = 5

[node name="Ranking" type="OptionButton" parent="Holder/Background/Layout/TopBarBackground/Margin/TopBar/Filters" unique_id=330241703]
[node name="Status" type="OptionButton" parent="Holder/Background/Layout/TopBarBackground/Margin/TopBar/Filters" unique_id=330241703]
layout_mode = 2
size_flags_horizontal = 3
alignment = 1
Expand All @@ -314,7 +318,7 @@ popup/item_2/id = 2
layout_mode = 2
size_flags_horizontal = 3
alignment = 1
selected = 0
selected = 2
item_count = 3
popup/item_0/text = "Online"
popup/item_0/id = 1
Expand Down Expand Up @@ -527,12 +531,12 @@ label_settings = SubResource("LabelSettings_vr0hc")
layout_mode = 2
mouse_filter = 2

[node name="RankingPill" type="PanelContainer" parent="Holder/Background/Layout/Results/RowsMargin/Rows/MapCardTemplate/Row/Map/Content/Info/Bottom" unique_id=359816098]
[node name="StatusPill" type="PanelContainer" parent="Holder/Background/Layout/Results/RowsMargin/Rows/MapCardTemplate/Row/Map/Content/Info/Bottom" unique_id=359816098]
layout_mode = 2
mouse_filter = 2
theme_override_styles/panel = SubResource("StyleBoxFlat_ikspe")

[node name="Ranking" type="Label" parent="Holder/Background/Layout/Results/RowsMargin/Rows/MapCardTemplate/Row/Map/Content/Info/Bottom/RankingPill" unique_id=1500989616]
[node name="Status" type="Label" parent="Holder/Background/Layout/Results/RowsMargin/Rows/MapCardTemplate/Row/Map/Content/Info/Bottom/StatusPill" unique_id=1500989616]
layout_mode = 2
text = "RANKED"
label_settings = SubResource("LabelSettings_10mjv")
Expand Down
2 changes: 2 additions & 0 deletions scripts/api/QueryParameters.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,6 @@ public class MapQueryParameters : QueryParameters
public string Query { get; set; }
public string Mapper { get; set; }
public string Artist { get; set; }
public int[] Difficulties { get; set; } = [];
public string[] Status { get; set; } = [];
}
4 changes: 4 additions & 0 deletions scripts/api/endpoints/Maps.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@ public static async Task<JsonDocument> Search(MapQueryParameters queryParameters
query["mapper"] = queryParameters.Mapper;
if (!string.IsNullOrEmpty(queryParameters.Artist))
query["artist"] = queryParameters.Artist;
if (queryParameters.Difficulties.Length > 0)
query["difficulty"] = string.Join(",", queryParameters.Difficulties);
if (queryParameters.Status.Length > 0)
query["status"] = string.Join(",", queryParameters.Status);

string url = $"/maps?{query}";

Expand Down
86 changes: 82 additions & 4 deletions scripts/scenes/MapBrowser.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System;
using System.Linq;
using System.Text.Json;
using System.Threading;
using System.Threading.Tasks;
Expand All @@ -16,6 +17,12 @@ public partial class MapBrowser : Control
private VBoxContainer topBar;
private HBoxContainer searchBar;
private LineEdit search;
private OptionButton sort;
private Button direction;
private Button refresh;
private MenuButton difficulty;
private OptionButton status;
private OptionButton installed;
private Timer searchTimer;
private HBoxContainer filters;
private ScrollContainer results;
Expand All @@ -32,6 +39,12 @@ public override void _Ready()
topBar = holder.GetNode<VBoxContainer>("Background/Layout/TopBarBackground/Margin/TopBar");
searchBar = topBar.GetNode<HBoxContainer>("SearchBar");
search = searchBar.GetNode<LineEdit>("Search");
sort = searchBar.GetNode<OptionButton>("Sort");
direction = searchBar.GetNode<Button>("Direction");
refresh = searchBar.GetNode<Button>("Refresh");
difficulty = topBar.GetNode<HBoxContainer>("Filters").GetNode<MenuButton>("Difficulty");
status = topBar.GetNode<HBoxContainer>("Filters").GetNode<OptionButton>("Status");
installed = topBar.GetNode<HBoxContainer>("Filters").GetNode<OptionButton>("Installed");
searchTimer = GetNode<Timer>("SearchTimer");
results = holder.GetNode<ScrollContainer>("Background/Layout/Results");
mapCardTemplate = results.GetNode<MapCard>("RowsMargin/Rows/MapCardTemplate");
Expand All @@ -43,6 +56,12 @@ public override void _Ready()

search.TextChanged += _ => searchTimer.Start();
searchTimer.Timeout += onSearchTimerTimeout;
sort.ItemSelected += _ => refreshResults();
direction.Pressed += toggleDirection;
refresh.Pressed += refreshResults;
difficulty.GetPopup().IdPressed += toggleDifficulty;
status.ItemSelected += _ => refreshResults();
installed.ItemSelected += _ => refreshResults();

hideButton.Pressed += HideMenu;
}
Expand Down Expand Up @@ -110,7 +129,7 @@ private async Task populate(MapQueryParameters queryParameters)
return;
}

foreach (var map in maps)
foreach (var map in maps.Where(matchesInstalledFilter))
{
if (mapCardTemplate.Duplicate() is not MapCard mapCard)
{
Expand All @@ -125,13 +144,72 @@ private async Task populate(MapQueryParameters queryParameters)

private void onSearchTimerTimeout()
{
clearResults();
_ = populate(buildQueryParameters());
refreshResults();
}

private void toggleDifficulty(long id)
{
PopupMenu popup = difficulty.GetPopup();
int index = popup.GetItemIndex((int)id);
if (index < 0)
return;

popup.SetItemChecked(index, !popup.IsItemChecked(index));
refreshResults();
}

private MapQueryParameters buildQueryParameters()
{
return new MapQueryParameters { Query = search.Text.Trim() };
int[] selectedDifficulties = Enumerable
.Range(0, difficulty.GetPopup().ItemCount)
.Where(index => difficulty.GetPopup().IsItemChecked(index))
.Select(index => difficulty.GetPopup().GetItemId(index))
.ToArray();

string[] statuses = status.Selected switch
{
0 => ["UNRANKED"],
1 => ["RANKED"],
_ => Array.Empty<string>(),
};

return new MapQueryParameters
{
Query = search.Text.Trim(),
SortBy = sort.Selected switch
{
1 => "length",
2 => "difficulty",
_ => "createdAt",
},
SortDirection = direction.ButtonPressed ? "asc" : "desc",
Difficulties = selectedDifficulties,
Status = statuses,
};
}

private bool matchesInstalledFilter(JsonElement map)
{
int installedFilter = installed.GetSelectedId();
if (installedFilter == 2)
return true;

bool downloaded =
map.TryGetProperty("noteHash", out var noteHash) && MapManager.Maps.Any(localMap => localMap.ObjectHash == noteHash.GetString());
return installedFilter == 0 ? downloaded : !downloaded;
}

private void toggleDirection()
{
direction.ButtonPressed = !direction.ButtonPressed;
direction.Text = direction.ButtonPressed ? "Ascending" : "Descending";
refreshResults();
}

private void refreshResults()
{
clearResults();
_ = populate(buildQueryParameters());
}

private void clearResults()
Expand Down
18 changes: 9 additions & 9 deletions scripts/scenes/MapCard.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ public partial class MapCard : PanelContainer

private PanelContainer coverHolder;
private PanelContainer blurCoverHolder;
private PanelContainer rankingPill;
private PanelContainer statusPill;
private PanelContainer notablePill;

private Panel coverDim;
Expand All @@ -32,7 +32,7 @@ public partial class MapCard : PanelContainer
private Label titleLabel;
private Label difficultyLabel;
private Label noteCountLabel;
private Label rankingLabel;
private Label statusLabel;
private Label durationLabel;

private RichTextLabel mappersLabel;
Expand Down Expand Up @@ -75,7 +75,7 @@ public override void _Ready()

coverHolder = GetNode<PanelContainer>("Row/CoverHolder");
blurCoverHolder = mapHolder.GetNode<PanelContainer>("BlurCoverHolder");
rankingPill = bottomText.GetNode<PanelContainer>("RankingPill");
statusPill = bottomText.GetNode<PanelContainer>("StatusPill");
notablePill = bottomText.GetNode<PanelContainer>("NotablePill");

coverDim = coverHolder.GetNode<Panel>("Dim");
Expand All @@ -88,7 +88,7 @@ public override void _Ready()
titleLabel = topText.GetNode<Label>("TitleHolder/Title");
difficultyLabel = topText.GetNode<Label>("Details/VBoxContainer/Difficulty");
noteCountLabel = topText.GetNode<Label>("Details/VBoxContainer/Notes");
rankingLabel = rankingPill.GetNode<Label>("Ranking");
statusLabel = statusPill.GetNode<Label>("Status");
durationLabel = bottomText.GetNode<Label>("Duration");

mappersLabel = topText.GetNode<RichTextLabel>("Details/VBoxContainer/Mapper");
Expand Down Expand Up @@ -122,11 +122,11 @@ public void Bind(JsonElement map, CancellationTokenSource source)

noteCountLabel.Text = $"{map.GetProperty("noteCount").GetInt32().ToString(CultureInfo.InvariantCulture)} notes";

bool isRanked = map.GetProperty("isRanked").GetBoolean();
var rankingPillStyle = (StyleBoxFlat)rankingPill.GetThemeStylebox("panel").Duplicate();
rankingLabel.Text = isRanked ? "RANKED" : "UNRANKED";
rankingPillStyle.BgColor = isRanked ? Constants.RANKED_COLOR : Constants.UNRANKED_COLOR;
rankingPill.AddThemeStyleboxOverride("panel", rankingPillStyle);
bool isRanked = map.GetProperty("status").GetString() == "RANKED";
var statusPillStyle = (StyleBoxFlat)statusPill.GetThemeStylebox("panel").Duplicate();
statusLabel.Text = isRanked ? "RANKED" : "UNRANKED";
statusPillStyle.BgColor = isRanked ? Constants.RANKED_COLOR : Constants.UNRANKED_COLOR;
statusPill.AddThemeStyleboxOverride("panel", statusPillStyle);

var mapLength = TimeSpan.FromMilliseconds(map.GetProperty("length").GetDouble());
durationLabel.Text =
Expand Down
Loading