From 2d707b2b65bb4baa189e4cb68c3e9d3bbbfeff54 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Mon, 7 Oct 2019 15:36:23 +0300 Subject: [PATCH 01/14] Implement PostBeatmapFavouriteRequest --- .../Requests/PostBeatmapFavouriteRequest.cs | 36 +++++++++++++++++++ .../BeatmapSet/Buttons/FavouriteButton.cs | 24 ++++++++++++- 2 files changed, 59 insertions(+), 1 deletion(-) create mode 100644 osu.Game/Online/API/Requests/PostBeatmapFavouriteRequest.cs diff --git a/osu.Game/Online/API/Requests/PostBeatmapFavouriteRequest.cs b/osu.Game/Online/API/Requests/PostBeatmapFavouriteRequest.cs new file mode 100644 index 0000000000..f3724230cb --- /dev/null +++ b/osu.Game/Online/API/Requests/PostBeatmapFavouriteRequest.cs @@ -0,0 +1,36 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using osu.Framework.IO.Network; +using System.Net.Http; + +namespace osu.Game.Online.API.Requests +{ + public class PostBeatmapFavouriteRequest : APIRequest + { + private readonly int id; + private readonly BeatmapFavouriteAction action; + + public PostBeatmapFavouriteRequest(int id, BeatmapFavouriteAction action) + { + this.id = id; + this.action = action; + } + + protected override WebRequest CreateWebRequest() + { + var req = base.CreateWebRequest(); + req.Method = HttpMethod.Post; + req.AddParameter(@"action", action.ToString().ToLowerInvariant()); + return req; + } + + protected override string Target => $@"beatmapsets/{id}/favourites"; + } + + public enum BeatmapFavouriteAction + { + Favourite, + UnFavourite + } +} diff --git a/osu.Game/Overlays/BeatmapSet/Buttons/FavouriteButton.cs b/osu.Game/Overlays/BeatmapSet/Buttons/FavouriteButton.cs index 11f56bc163..23325b8765 100644 --- a/osu.Game/Overlays/BeatmapSet/Buttons/FavouriteButton.cs +++ b/osu.Game/Overlays/BeatmapSet/Buttons/FavouriteButton.cs @@ -10,6 +10,9 @@ using osu.Framework.Graphics.Sprites; using osu.Game.Beatmaps; using osu.Game.Graphics; using osu.Game.Graphics.Backgrounds; +using osu.Game.Graphics.UserInterface; +using osu.Game.Online.API; +using osu.Game.Online.API.Requests; using osuTK; namespace osu.Game.Overlays.BeatmapSet.Buttons @@ -20,8 +23,11 @@ namespace osu.Game.Overlays.BeatmapSet.Buttons private readonly Bindable favourited = new Bindable(); + private PostBeatmapFavouriteRequest request; + private DimmedLoadingLayer loading; + [BackgroundDependencyLoader] - private void load() + private void load(IAPIProvider api) { Container pink; SpriteIcon icon; @@ -55,6 +61,7 @@ namespace osu.Game.Overlays.BeatmapSet.Buttons Size = new Vector2(18), Shadow = false, }, + loading = new DimmedLoadingLayer(), }); BeatmapSet.BindValueChanged(setInfo => @@ -67,6 +74,8 @@ namespace osu.Game.Overlays.BeatmapSet.Buttons favourited.ValueChanged += favourited => { + loading.Hide(); + if (favourited.NewValue) { pink.FadeIn(200); @@ -78,6 +87,19 @@ namespace osu.Game.Overlays.BeatmapSet.Buttons icon.Icon = FontAwesome.Regular.Heart; } }; + + Action = () => + { + if (loading.State.Value == Visibility.Visible) + return; + + loading.Show(); + + request?.Cancel(); + request = new PostBeatmapFavouriteRequest(BeatmapSet.Value?.OnlineBeatmapSetID ?? 0, favourited.Value ? BeatmapFavouriteAction.UnFavourite : BeatmapFavouriteAction.Favourite); + request.Success += () => favourited.Value = !favourited.Value; + api.Queue(request); + }; } protected override void UpdateAfterChildren() From a7dc9bb582682c0b87ea047f1da9aa6b40a45ea0 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Mon, 7 Oct 2019 15:41:05 +0300 Subject: [PATCH 02/14] Add tooltip and remove pink layer --- .../BeatmapSet/Buttons/FavouriteButton.cs | 40 +++---------------- 1 file changed, 5 insertions(+), 35 deletions(-) diff --git a/osu.Game/Overlays/BeatmapSet/Buttons/FavouriteButton.cs b/osu.Game/Overlays/BeatmapSet/Buttons/FavouriteButton.cs index 23325b8765..fcea20ef11 100644 --- a/osu.Game/Overlays/BeatmapSet/Buttons/FavouriteButton.cs +++ b/osu.Game/Overlays/BeatmapSet/Buttons/FavouriteButton.cs @@ -5,11 +5,9 @@ using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; -using osu.Framework.Graphics.Shapes; +using osu.Framework.Graphics.Cursor; using osu.Framework.Graphics.Sprites; using osu.Game.Beatmaps; -using osu.Game.Graphics; -using osu.Game.Graphics.Backgrounds; using osu.Game.Graphics.UserInterface; using osu.Game.Online.API; using osu.Game.Online.API.Requests; @@ -17,7 +15,7 @@ using osuTK; namespace osu.Game.Overlays.BeatmapSet.Buttons { - public class FavouriteButton : HeaderButton + public class FavouriteButton : HeaderButton, IHasTooltip { public readonly Bindable BeatmapSet = new Bindable(); @@ -26,33 +24,14 @@ namespace osu.Game.Overlays.BeatmapSet.Buttons private PostBeatmapFavouriteRequest request; private DimmedLoadingLayer loading; + public string TooltipText => (favourited.Value ? "Unfavourite" : "Favourite") + " this beatmapset"; + [BackgroundDependencyLoader] private void load(IAPIProvider api) { - Container pink; SpriteIcon icon; AddRange(new Drawable[] { - pink = new Container - { - RelativeSizeAxes = Axes.Both, - Alpha = 0f, - Children = new Drawable[] - { - new Box - { - RelativeSizeAxes = Axes.Both, - Colour = OsuColour.FromHex(@"9f015f"), - }, - new Triangles - { - RelativeSizeAxes = Axes.Both, - ColourLight = OsuColour.FromHex(@"cb2187"), - ColourDark = OsuColour.FromHex(@"9f015f"), - TriangleScale = 1.5f, - }, - }, - }, icon = new SpriteIcon { Anchor = Anchor.Centre, @@ -76,16 +55,7 @@ namespace osu.Game.Overlays.BeatmapSet.Buttons { loading.Hide(); - if (favourited.NewValue) - { - pink.FadeIn(200); - icon.Icon = FontAwesome.Solid.Heart; - } - else - { - pink.FadeOut(200); - icon.Icon = FontAwesome.Regular.Heart; - } + icon.Icon = favourited.NewValue ? FontAwesome.Solid.Heart : FontAwesome.Regular.Heart; }; Action = () => From 2dac3a6efe89934faa8cc354e5581a83bd182bd3 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Wed, 16 Oct 2019 13:58:29 +0300 Subject: [PATCH 03/14] Handle hitting the maximum allowed number of favourited beatmaps --- .../BeatmapSet/Buttons/FavouriteButton.cs | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/osu.Game/Overlays/BeatmapSet/Buttons/FavouriteButton.cs b/osu.Game/Overlays/BeatmapSet/Buttons/FavouriteButton.cs index fcea20ef11..e2bc1ee008 100644 --- a/osu.Game/Overlays/BeatmapSet/Buttons/FavouriteButton.cs +++ b/osu.Game/Overlays/BeatmapSet/Buttons/FavouriteButton.cs @@ -11,6 +11,7 @@ using osu.Game.Beatmaps; using osu.Game.Graphics.UserInterface; using osu.Game.Online.API; using osu.Game.Online.API.Requests; +using osu.Game.Overlays.Notifications; using osuTK; namespace osu.Game.Overlays.BeatmapSet.Buttons @@ -26,8 +27,8 @@ namespace osu.Game.Overlays.BeatmapSet.Buttons public string TooltipText => (favourited.Value ? "Unfavourite" : "Favourite") + " this beatmapset"; - [BackgroundDependencyLoader] - private void load(IAPIProvider api) + [BackgroundDependencyLoader(true)] + private void load(IAPIProvider api, NotificationOverlay notifications) { SpriteIcon icon; AddRange(new Drawable[] @@ -68,6 +69,18 @@ namespace osu.Game.Overlays.BeatmapSet.Buttons request?.Cancel(); request = new PostBeatmapFavouriteRequest(BeatmapSet.Value?.OnlineBeatmapSetID ?? 0, favourited.Value ? BeatmapFavouriteAction.UnFavourite : BeatmapFavouriteAction.Favourite); request.Success += () => favourited.Value = !favourited.Value; + request.Failure += exception => + { + if (exception.Message == "UnprocessableEntity") + { + notifications.Post(new SimpleNotification + { + Text = @"You have too many favourited beatmaps! Please unfavourite some before trying again.", + Icon = FontAwesome.Solid.Times, + }); + loading.Hide(); + } + }; api.Queue(request); }; } From 58df6930b279791e6cad547718d4182bd91aa22c Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 12 Nov 2019 19:34:20 +0900 Subject: [PATCH 04/14] Get error message from server --- osu.Game/Online/API/APIRequest.cs | 23 +++++++++++++++++++ .../BeatmapSet/Buttons/FavouriteButton.cs | 13 ++++------- 2 files changed, 28 insertions(+), 8 deletions(-) diff --git a/osu.Game/Online/API/APIRequest.cs b/osu.Game/Online/API/APIRequest.cs index 4f613d5c3c..ea0d50511f 100644 --- a/osu.Game/Online/API/APIRequest.cs +++ b/osu.Game/Online/API/APIRequest.cs @@ -2,6 +2,7 @@ // See the LICENCE file in the repository root for full licence text. using System; +using Newtonsoft.Json; using osu.Framework.IO.Network; using osu.Framework.Logging; @@ -112,6 +113,22 @@ namespace osu.Game.Online.API cancelled = true; WebRequest?.Abort(); + string responseString = WebRequest?.ResponseString; + + if (!string.IsNullOrEmpty(responseString)) + { + try + { + // attempt to decode a displayable error string. + var error = JsonConvert.DeserializeObject(responseString); + if (error != null) + e = new Exception(error.ErrorMessage, e); + } + catch + { + } + } + Logger.Log($@"Failing request {this} ({e})", LoggingTarget.Network); pendingFailure = () => Failure?.Invoke(e); checkAndScheduleFailure(); @@ -129,6 +146,12 @@ namespace osu.Game.Online.API pendingFailure = null; return true; } + + private class DisplayableError + { + [JsonProperty("error")] + public string ErrorMessage; + } } public delegate void APIFailureHandler(Exception e); diff --git a/osu.Game/Overlays/BeatmapSet/Buttons/FavouriteButton.cs b/osu.Game/Overlays/BeatmapSet/Buttons/FavouriteButton.cs index e2bc1ee008..f059e06214 100644 --- a/osu.Game/Overlays/BeatmapSet/Buttons/FavouriteButton.cs +++ b/osu.Game/Overlays/BeatmapSet/Buttons/FavouriteButton.cs @@ -71,15 +71,12 @@ namespace osu.Game.Overlays.BeatmapSet.Buttons request.Success += () => favourited.Value = !favourited.Value; request.Failure += exception => { - if (exception.Message == "UnprocessableEntity") + notifications.Post(new SimpleNotification { - notifications.Post(new SimpleNotification - { - Text = @"You have too many favourited beatmaps! Please unfavourite some before trying again.", - Icon = FontAwesome.Solid.Times, - }); - loading.Hide(); - } + Text = exception.Message, + Icon = FontAwesome.Solid.Times, + }); + loading.Hide(); }; api.Queue(request); }; From 61464c5c89723cbfe06dc975e760d207c2d8dc8b Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 12 Nov 2019 21:27:15 +0900 Subject: [PATCH 05/14] Fix potential nullref in unrelated test --- osu.Game/Online/API/Requests/SearchBeatmapSetsRequest.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Online/API/Requests/SearchBeatmapSetsRequest.cs b/osu.Game/Online/API/Requests/SearchBeatmapSetsRequest.cs index c8c36789c4..5652b8d2bd 100644 --- a/osu.Game/Online/API/Requests/SearchBeatmapSetsRequest.cs +++ b/osu.Game/Online/API/Requests/SearchBeatmapSetsRequest.cs @@ -19,7 +19,7 @@ namespace osu.Game.Online.API.Requests public SearchBeatmapSetsRequest(string query, RulesetInfo ruleset, BeatmapSearchCategory searchCategory = BeatmapSearchCategory.Any, DirectSortCriteria sortCriteria = DirectSortCriteria.Ranked, SortDirection direction = SortDirection.Descending) { - this.query = System.Uri.EscapeDataString(query); + this.query = string.IsNullOrEmpty(query) ? string.Empty : System.Uri.EscapeDataString(query); this.ruleset = ruleset; this.searchCategory = searchCategory; this.sortCriteria = sortCriteria; From 5110ae82a1cd76a970ef11bfebf7559dea0c9514 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 12 Nov 2019 21:38:08 +0900 Subject: [PATCH 06/14] Tidy up implementation --- .../BeatmapSet/Buttons/FavouriteButton.cs | 42 +++++++++++-------- 1 file changed, 24 insertions(+), 18 deletions(-) diff --git a/osu.Game/Overlays/BeatmapSet/Buttons/FavouriteButton.cs b/osu.Game/Overlays/BeatmapSet/Buttons/FavouriteButton.cs index f059e06214..33df1fa485 100644 --- a/osu.Game/Overlays/BeatmapSet/Buttons/FavouriteButton.cs +++ b/osu.Game/Overlays/BeatmapSet/Buttons/FavouriteButton.cs @@ -1,6 +1,7 @@ -// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. +using System.Diagnostics; using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Graphics; @@ -20,7 +21,7 @@ namespace osu.Game.Overlays.BeatmapSet.Buttons { public readonly Bindable BeatmapSet = new Bindable(); - private readonly Bindable favourited = new Bindable(); + private readonly BindableBool favourited = new BindableBool(); private PostBeatmapFavouriteRequest request; private DimmedLoadingLayer loading; @@ -44,40 +45,45 @@ namespace osu.Game.Overlays.BeatmapSet.Buttons loading = new DimmedLoadingLayer(), }); + favourited.ValueChanged += favourited => icon.Icon = favourited.NewValue ? FontAwesome.Solid.Heart : FontAwesome.Regular.Heart; + BeatmapSet.BindValueChanged(setInfo => { - if (setInfo.NewValue?.OnlineInfo?.HasFavourited == null) - return; - - favourited.Value = setInfo.NewValue.OnlineInfo.HasFavourited; - }); - - favourited.ValueChanged += favourited => - { - loading.Hide(); - - icon.Icon = favourited.NewValue ? FontAwesome.Solid.Heart : FontAwesome.Regular.Heart; - }; + Enabled.Value = BeatmapSet.Value?.OnlineBeatmapSetID > 0; + favourited.Value = setInfo.NewValue?.OnlineInfo?.HasFavourited ?? false; + }, true); Action = () => { if (loading.State.Value == Visibility.Visible) return; + // guaranteed by disabled state abvove. + Debug.Assert(BeatmapSet.Value.OnlineBeatmapSetID != null); + loading.Show(); request?.Cancel(); - request = new PostBeatmapFavouriteRequest(BeatmapSet.Value?.OnlineBeatmapSetID ?? 0, favourited.Value ? BeatmapFavouriteAction.UnFavourite : BeatmapFavouriteAction.Favourite); - request.Success += () => favourited.Value = !favourited.Value; - request.Failure += exception => + + request = new PostBeatmapFavouriteRequest(BeatmapSet.Value.OnlineBeatmapSetID.Value, favourited.Value ? BeatmapFavouriteAction.UnFavourite : BeatmapFavouriteAction.Favourite); + + request.Success += () => + { + favourited.Toggle(); + loading.Hide(); + }; + + request.Failure += e => { notifications.Post(new SimpleNotification { - Text = exception.Message, + Text = e.Message, Icon = FontAwesome.Solid.Times, }); + loading.Hide(); }; + api.Queue(request); }; } From da819261e0063b6f3a98ed5c28821696c662dcdf Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 12 Nov 2019 21:38:16 +0900 Subject: [PATCH 07/14] Shrink and darken loading layer to better suit button --- osu.Game/Graphics/UserInterface/DimmedLoadingLayer.cs | 7 ++++--- osu.Game/Overlays/BeatmapSet/Buttons/FavouriteButton.cs | 4 ++-- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/osu.Game/Graphics/UserInterface/DimmedLoadingLayer.cs b/osu.Game/Graphics/UserInterface/DimmedLoadingLayer.cs index b7d2222f33..f7138827cc 100644 --- a/osu.Game/Graphics/UserInterface/DimmedLoadingLayer.cs +++ b/osu.Game/Graphics/UserInterface/DimmedLoadingLayer.cs @@ -6,6 +6,7 @@ using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; using osu.Framework.Extensions.Color4Extensions; +using osuTK; namespace osu.Game.Graphics.UserInterface { @@ -15,7 +16,7 @@ namespace osu.Game.Graphics.UserInterface private readonly LoadingAnimation loading; - public DimmedLoadingLayer() + public DimmedLoadingLayer(float dimAmount = 0.5f, float iconScale = 1f) { RelativeSizeAxes = Axes.Both; Children = new Drawable[] @@ -23,9 +24,9 @@ namespace osu.Game.Graphics.UserInterface new Box { RelativeSizeAxes = Axes.Both, - Colour = Color4.Black.Opacity(0.5f), + Colour = Color4.Black.Opacity(dimAmount), }, - loading = new LoadingAnimation(), + loading = new LoadingAnimation { Scale = new Vector2(iconScale) }, }; } diff --git a/osu.Game/Overlays/BeatmapSet/Buttons/FavouriteButton.cs b/osu.Game/Overlays/BeatmapSet/Buttons/FavouriteButton.cs index 33df1fa485..cfb34e4adf 100644 --- a/osu.Game/Overlays/BeatmapSet/Buttons/FavouriteButton.cs +++ b/osu.Game/Overlays/BeatmapSet/Buttons/FavouriteButton.cs @@ -1,4 +1,4 @@ -// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. using System.Diagnostics; @@ -42,7 +42,7 @@ namespace osu.Game.Overlays.BeatmapSet.Buttons Size = new Vector2(18), Shadow = false, }, - loading = new DimmedLoadingLayer(), + loading = new DimmedLoadingLayer(0.8f, 0.5f), }); favourited.ValueChanged += favourited => icon.Icon = favourited.NewValue ? FontAwesome.Solid.Heart : FontAwesome.Regular.Heart; From 70a02d27a99e86f4308f62aac12dbe10f75fa5bf Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 12 Nov 2019 22:53:01 +0900 Subject: [PATCH 08/14] Update solution paths --- fastlane/Fastfile | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/fastlane/Fastfile b/fastlane/Fastfile index 7adf42a1eb..28a83fbbae 100644 --- a/fastlane/Fastfile +++ b/fastlane/Fastfile @@ -49,12 +49,12 @@ desc 'Deploy to play store' desc 'Compile the project' lane :build do |options| nuget_restore( - project_path: 'osu.Android.sln' + project_path: 'osu.sln' ) souyuz( build_configuration: 'Release', - solution_path: 'osu.Android.sln', + solution_path: 'osu.sln', platform: "android", output_path: "osu.Android/bin/Release/", keystore_path: options[:keystore_path], @@ -70,7 +70,7 @@ desc 'Deploy to play store' android_build = split.join('') app_version( - solution_path: 'osu.Android.sln', + solution_path: 'osu.sln', version: options[:version], build: android_build, ) @@ -106,7 +106,7 @@ platform :ios do desc 'Compile the project' lane :build do nuget_restore( - project_path: 'osu.iOS.sln' + project_path: 'osu.sln' ) souyuz( From dfd5c8807515bf6f5aec86610ff116e439b99d50 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Wed, 13 Nov 2019 00:00:08 +0300 Subject: [PATCH 09/14] Typo fix --- osu.Game/Overlays/BeatmapSet/Buttons/FavouriteButton.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Overlays/BeatmapSet/Buttons/FavouriteButton.cs b/osu.Game/Overlays/BeatmapSet/Buttons/FavouriteButton.cs index cfb34e4adf..4c2a8652f3 100644 --- a/osu.Game/Overlays/BeatmapSet/Buttons/FavouriteButton.cs +++ b/osu.Game/Overlays/BeatmapSet/Buttons/FavouriteButton.cs @@ -58,7 +58,7 @@ namespace osu.Game.Overlays.BeatmapSet.Buttons if (loading.State.Value == Visibility.Visible) return; - // guaranteed by disabled state abvove. + // guaranteed by disabled state above. Debug.Assert(BeatmapSet.Value.OnlineBeatmapSetID != null); loading.Show(); From 3903e59f2fecca4c63de60897a66279763973936 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Wed, 13 Nov 2019 00:01:13 +0300 Subject: [PATCH 10/14] Add null check for notification overlay --- osu.Game/Overlays/BeatmapSet/Buttons/FavouriteButton.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Overlays/BeatmapSet/Buttons/FavouriteButton.cs b/osu.Game/Overlays/BeatmapSet/Buttons/FavouriteButton.cs index 4c2a8652f3..163251d798 100644 --- a/osu.Game/Overlays/BeatmapSet/Buttons/FavouriteButton.cs +++ b/osu.Game/Overlays/BeatmapSet/Buttons/FavouriteButton.cs @@ -75,7 +75,7 @@ namespace osu.Game.Overlays.BeatmapSet.Buttons request.Failure += e => { - notifications.Post(new SimpleNotification + notifications?.Post(new SimpleNotification { Text = e.Message, Icon = FontAwesome.Solid.Times, From 2b8a105ec5cab7296966efab2cc87fcc2d01347e Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 13 Nov 2019 11:49:36 +0900 Subject: [PATCH 11/14] Fix osu!direct test fail Unsure how this occurred only now; may warrant further investigation. --- osu.Game/Online/API/Requests/SearchBeatmapSetsRequest.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Online/API/Requests/SearchBeatmapSetsRequest.cs b/osu.Game/Online/API/Requests/SearchBeatmapSetsRequest.cs index c8c36789c4..5652b8d2bd 100644 --- a/osu.Game/Online/API/Requests/SearchBeatmapSetsRequest.cs +++ b/osu.Game/Online/API/Requests/SearchBeatmapSetsRequest.cs @@ -19,7 +19,7 @@ namespace osu.Game.Online.API.Requests public SearchBeatmapSetsRequest(string query, RulesetInfo ruleset, BeatmapSearchCategory searchCategory = BeatmapSearchCategory.Any, DirectSortCriteria sortCriteria = DirectSortCriteria.Ranked, SortDirection direction = SortDirection.Descending) { - this.query = System.Uri.EscapeDataString(query); + this.query = string.IsNullOrEmpty(query) ? string.Empty : System.Uri.EscapeDataString(query); this.ruleset = ruleset; this.searchCategory = searchCategory; this.sortCriteria = sortCriteria; From 3c5008f94c20a968e6248dd0e5dcad74c649722d Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 13 Nov 2019 11:59:03 +0900 Subject: [PATCH 12/14] Add test --- .../Visual/Online/TestSceneFavouriteButton.cs | 46 +++++++++++++++++++ 1 file changed, 46 insertions(+) create mode 100644 osu.Game.Tests/Visual/Online/TestSceneFavouriteButton.cs diff --git a/osu.Game.Tests/Visual/Online/TestSceneFavouriteButton.cs b/osu.Game.Tests/Visual/Online/TestSceneFavouriteButton.cs new file mode 100644 index 0000000000..ae21245b59 --- /dev/null +++ b/osu.Game.Tests/Visual/Online/TestSceneFavouriteButton.cs @@ -0,0 +1,46 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using NUnit.Framework; +using osu.Framework.Testing; +using osu.Game.Beatmaps; +using osu.Game.Overlays.BeatmapSet.Buttons; + +namespace osu.Game.Tests.Visual.Online +{ + public class TestSceneFavouriteButton : OsuTestScene + { + private FavouriteButton favourite; + + [SetUpSteps] + public void SetUpSteps() + { + AddStep("create button", () => Child = favourite = new FavouriteButton()); + } + + [Test] + public void TestLoggedOutIn() + { + AddStep("set valid beatmap", () => favourite.BeatmapSet.Value = new BeatmapSetInfo { OnlineBeatmapSetID = 88 }); + AddStep("log out", () => API.Logout()); + checkEnabled(false); + AddStep("log in", () => API.Login("test", "test")); + checkEnabled(true); + } + + [Test] + public void TestBeatmapChange() + { + AddStep("log in", () => API.Login("test", "test")); + AddStep("set valid beatmap", () => favourite.BeatmapSet.Value = new BeatmapSetInfo { OnlineBeatmapSetID = 88 }); + checkEnabled(true); + AddStep("set invalid beatmap", () => favourite.BeatmapSet.Value = new BeatmapSetInfo()); + checkEnabled(true); + } + + private void checkEnabled(bool expected) + { + AddAssert("is " + (expected ? "enabled" : "disabled"), () => favourite.Enabled.Value == expected); + } + } +} From f18263aa70dc215af08e6b008c74a5be7a700d39 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 13 Nov 2019 12:09:18 +0900 Subject: [PATCH 13/14] Add tests --- .../Visual/Online/TestSceneFavouriteButton.cs | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/osu.Game.Tests/Visual/Online/TestSceneFavouriteButton.cs b/osu.Game.Tests/Visual/Online/TestSceneFavouriteButton.cs index ae21245b59..8e2ee4e28d 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneFavouriteButton.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneFavouriteButton.cs @@ -2,9 +2,11 @@ // See the LICENCE file in the repository root for full licence text. using NUnit.Framework; +using osu.Framework.Graphics; using osu.Framework.Testing; using osu.Game.Beatmaps; using osu.Game.Overlays.BeatmapSet.Buttons; +using osuTK; namespace osu.Game.Tests.Visual.Online { @@ -15,7 +17,13 @@ namespace osu.Game.Tests.Visual.Online [SetUpSteps] public void SetUpSteps() { - AddStep("create button", () => Child = favourite = new FavouriteButton()); + AddStep("create button", () => Child = favourite = new FavouriteButton + { + RelativeSizeAxes = Axes.None, + Size = new Vector2(50), + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + }); } [Test] @@ -35,7 +43,7 @@ namespace osu.Game.Tests.Visual.Online AddStep("set valid beatmap", () => favourite.BeatmapSet.Value = new BeatmapSetInfo { OnlineBeatmapSetID = 88 }); checkEnabled(true); AddStep("set invalid beatmap", () => favourite.BeatmapSet.Value = new BeatmapSetInfo()); - checkEnabled(true); + checkEnabled(false); } private void checkEnabled(bool expected) From c751328665b1c5e1ff2b51f7aa359570518d6f8d Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 13 Nov 2019 12:13:33 +0900 Subject: [PATCH 14/14] Disable button when not logged in --- .../BeatmapSet/Buttons/FavouriteButton.cs | 36 ++++++++++++++----- 1 file changed, 27 insertions(+), 9 deletions(-) diff --git a/osu.Game/Overlays/BeatmapSet/Buttons/FavouriteButton.cs b/osu.Game/Overlays/BeatmapSet/Buttons/FavouriteButton.cs index 163251d798..af0987d183 100644 --- a/osu.Game/Overlays/BeatmapSet/Buttons/FavouriteButton.cs +++ b/osu.Game/Overlays/BeatmapSet/Buttons/FavouriteButton.cs @@ -13,6 +13,7 @@ using osu.Game.Graphics.UserInterface; using osu.Game.Online.API; using osu.Game.Online.API.Requests; using osu.Game.Overlays.Notifications; +using osu.Game.Users; using osuTK; namespace osu.Game.Overlays.BeatmapSet.Buttons @@ -26,12 +27,23 @@ namespace osu.Game.Overlays.BeatmapSet.Buttons private PostBeatmapFavouriteRequest request; private DimmedLoadingLayer loading; - public string TooltipText => (favourited.Value ? "Unfavourite" : "Favourite") + " this beatmapset"; + private readonly Bindable localUser = new Bindable(); + + public string TooltipText + { + get + { + if (!Enabled.Value) return string.Empty; + + return (favourited.Value ? "Unfavourite" : "Favourite") + " this beatmapset"; + } + } [BackgroundDependencyLoader(true)] private void load(IAPIProvider api, NotificationOverlay notifications) { SpriteIcon icon; + AddRange(new Drawable[] { icon = new SpriteIcon @@ -45,14 +57,6 @@ namespace osu.Game.Overlays.BeatmapSet.Buttons loading = new DimmedLoadingLayer(0.8f, 0.5f), }); - favourited.ValueChanged += favourited => icon.Icon = favourited.NewValue ? FontAwesome.Solid.Heart : FontAwesome.Regular.Heart; - - BeatmapSet.BindValueChanged(setInfo => - { - Enabled.Value = BeatmapSet.Value?.OnlineBeatmapSetID > 0; - favourited.Value = setInfo.NewValue?.OnlineInfo?.HasFavourited ?? false; - }, true); - Action = () => { if (loading.State.Value == Visibility.Visible) @@ -86,8 +90,22 @@ namespace osu.Game.Overlays.BeatmapSet.Buttons api.Queue(request); }; + + favourited.ValueChanged += favourited => icon.Icon = favourited.NewValue ? FontAwesome.Solid.Heart : FontAwesome.Regular.Heart; + + localUser.BindTo(api.LocalUser); + localUser.BindValueChanged(_ => updateEnabled()); + + // must be run after setting the Action to ensure correct enabled state (setting an Action forces a button to be enabled). + BeatmapSet.BindValueChanged(setInfo => + { + updateEnabled(); + favourited.Value = setInfo.NewValue?.OnlineInfo?.HasFavourited ?? false; + }, true); } + private void updateEnabled() => Enabled.Value = !(localUser.Value is GuestUser) && BeatmapSet.Value?.OnlineBeatmapSetID > 0; + protected override void UpdateAfterChildren() { base.UpdateAfterChildren();