mirror of
https://github.com/ppy/osu.git
synced 2024-12-15 18:53:51 +08:00
Merge branch 'master' into fallback-to-skin-combo-colours
This commit is contained in:
commit
dfc6973d70
@ -49,12 +49,12 @@ desc 'Deploy to play store'
|
|||||||
desc 'Compile the project'
|
desc 'Compile the project'
|
||||||
lane :build do |options|
|
lane :build do |options|
|
||||||
nuget_restore(
|
nuget_restore(
|
||||||
project_path: 'osu.Android.sln'
|
project_path: 'osu.sln'
|
||||||
)
|
)
|
||||||
|
|
||||||
souyuz(
|
souyuz(
|
||||||
build_configuration: 'Release',
|
build_configuration: 'Release',
|
||||||
solution_path: 'osu.Android.sln',
|
solution_path: 'osu.sln',
|
||||||
platform: "android",
|
platform: "android",
|
||||||
output_path: "osu.Android/bin/Release/",
|
output_path: "osu.Android/bin/Release/",
|
||||||
keystore_path: options[:keystore_path],
|
keystore_path: options[:keystore_path],
|
||||||
@ -70,7 +70,7 @@ desc 'Deploy to play store'
|
|||||||
android_build = split.join('')
|
android_build = split.join('')
|
||||||
|
|
||||||
app_version(
|
app_version(
|
||||||
solution_path: 'osu.Android.sln',
|
solution_path: 'osu.sln',
|
||||||
version: options[:version],
|
version: options[:version],
|
||||||
build: android_build,
|
build: android_build,
|
||||||
)
|
)
|
||||||
@ -106,7 +106,7 @@ platform :ios do
|
|||||||
desc 'Compile the project'
|
desc 'Compile the project'
|
||||||
lane :build do
|
lane :build do
|
||||||
nuget_restore(
|
nuget_restore(
|
||||||
project_path: 'osu.iOS.sln'
|
project_path: 'osu.sln'
|
||||||
)
|
)
|
||||||
|
|
||||||
souyuz(
|
souyuz(
|
||||||
|
54
osu.Game.Tests/Visual/Online/TestSceneFavouriteButton.cs
Normal file
54
osu.Game.Tests/Visual/Online/TestSceneFavouriteButton.cs
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||||
|
// 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
|
||||||
|
{
|
||||||
|
public class TestSceneFavouriteButton : OsuTestScene
|
||||||
|
{
|
||||||
|
private FavouriteButton favourite;
|
||||||
|
|
||||||
|
[SetUpSteps]
|
||||||
|
public void SetUpSteps()
|
||||||
|
{
|
||||||
|
AddStep("create button", () => Child = favourite = new FavouriteButton
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.None,
|
||||||
|
Size = new Vector2(50),
|
||||||
|
Anchor = Anchor.Centre,
|
||||||
|
Origin = Anchor.Centre,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
[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(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void checkEnabled(bool expected)
|
||||||
|
{
|
||||||
|
AddAssert("is " + (expected ? "enabled" : "disabled"), () => favourite.Enabled.Value == expected);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -6,6 +6,7 @@ using osu.Framework.Graphics;
|
|||||||
using osu.Framework.Graphics.Containers;
|
using osu.Framework.Graphics.Containers;
|
||||||
using osu.Framework.Graphics.Shapes;
|
using osu.Framework.Graphics.Shapes;
|
||||||
using osu.Framework.Extensions.Color4Extensions;
|
using osu.Framework.Extensions.Color4Extensions;
|
||||||
|
using osuTK;
|
||||||
|
|
||||||
namespace osu.Game.Graphics.UserInterface
|
namespace osu.Game.Graphics.UserInterface
|
||||||
{
|
{
|
||||||
@ -15,7 +16,7 @@ namespace osu.Game.Graphics.UserInterface
|
|||||||
|
|
||||||
private readonly LoadingAnimation loading;
|
private readonly LoadingAnimation loading;
|
||||||
|
|
||||||
public DimmedLoadingLayer()
|
public DimmedLoadingLayer(float dimAmount = 0.5f, float iconScale = 1f)
|
||||||
{
|
{
|
||||||
RelativeSizeAxes = Axes.Both;
|
RelativeSizeAxes = Axes.Both;
|
||||||
Children = new Drawable[]
|
Children = new Drawable[]
|
||||||
@ -23,9 +24,9 @@ namespace osu.Game.Graphics.UserInterface
|
|||||||
new Box
|
new Box
|
||||||
{
|
{
|
||||||
RelativeSizeAxes = Axes.Both,
|
RelativeSizeAxes = Axes.Both,
|
||||||
Colour = Color4.Black.Opacity(0.5f),
|
Colour = Color4.Black.Opacity(dimAmount),
|
||||||
},
|
},
|
||||||
loading = new LoadingAnimation(),
|
loading = new LoadingAnimation { Scale = new Vector2(iconScale) },
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
// See the LICENCE file in the repository root for full licence text.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
|
using Newtonsoft.Json;
|
||||||
using osu.Framework.IO.Network;
|
using osu.Framework.IO.Network;
|
||||||
using osu.Framework.Logging;
|
using osu.Framework.Logging;
|
||||||
|
|
||||||
@ -112,6 +113,22 @@ namespace osu.Game.Online.API
|
|||||||
cancelled = true;
|
cancelled = true;
|
||||||
WebRequest?.Abort();
|
WebRequest?.Abort();
|
||||||
|
|
||||||
|
string responseString = WebRequest?.ResponseString;
|
||||||
|
|
||||||
|
if (!string.IsNullOrEmpty(responseString))
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// attempt to decode a displayable error string.
|
||||||
|
var error = JsonConvert.DeserializeObject<DisplayableError>(responseString);
|
||||||
|
if (error != null)
|
||||||
|
e = new Exception(error.ErrorMessage, e);
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Logger.Log($@"Failing request {this} ({e})", LoggingTarget.Network);
|
Logger.Log($@"Failing request {this} ({e})", LoggingTarget.Network);
|
||||||
pendingFailure = () => Failure?.Invoke(e);
|
pendingFailure = () => Failure?.Invoke(e);
|
||||||
checkAndScheduleFailure();
|
checkAndScheduleFailure();
|
||||||
@ -129,6 +146,12 @@ namespace osu.Game.Online.API
|
|||||||
pendingFailure = null;
|
pendingFailure = null;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private class DisplayableError
|
||||||
|
{
|
||||||
|
[JsonProperty("error")]
|
||||||
|
public string ErrorMessage;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public delegate void APIFailureHandler(Exception e);
|
public delegate void APIFailureHandler(Exception e);
|
||||||
|
36
osu.Game/Online/API/Requests/PostBeatmapFavouriteRequest.cs
Normal file
36
osu.Game/Online/API/Requests/PostBeatmapFavouriteRequest.cs
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. 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
|
||||||
|
}
|
||||||
|
}
|
@ -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)
|
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.ruleset = ruleset;
|
||||||
this.searchCategory = searchCategory;
|
this.searchCategory = searchCategory;
|
||||||
this.sortCriteria = sortCriteria;
|
this.sortCriteria = sortCriteria;
|
||||||
|
@ -1,52 +1,51 @@
|
|||||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||||
// See the LICENCE file in the repository root for full licence text.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
|
using System.Diagnostics;
|
||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
using osu.Framework.Bindables;
|
using osu.Framework.Bindables;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Graphics.Containers;
|
using osu.Framework.Graphics.Containers;
|
||||||
using osu.Framework.Graphics.Shapes;
|
using osu.Framework.Graphics.Cursor;
|
||||||
using osu.Framework.Graphics.Sprites;
|
using osu.Framework.Graphics.Sprites;
|
||||||
using osu.Game.Beatmaps;
|
using osu.Game.Beatmaps;
|
||||||
using osu.Game.Graphics;
|
using osu.Game.Graphics.UserInterface;
|
||||||
using osu.Game.Graphics.Backgrounds;
|
using osu.Game.Online.API;
|
||||||
|
using osu.Game.Online.API.Requests;
|
||||||
|
using osu.Game.Overlays.Notifications;
|
||||||
|
using osu.Game.Users;
|
||||||
using osuTK;
|
using osuTK;
|
||||||
|
|
||||||
namespace osu.Game.Overlays.BeatmapSet.Buttons
|
namespace osu.Game.Overlays.BeatmapSet.Buttons
|
||||||
{
|
{
|
||||||
public class FavouriteButton : HeaderButton
|
public class FavouriteButton : HeaderButton, IHasTooltip
|
||||||
{
|
{
|
||||||
public readonly Bindable<BeatmapSetInfo> BeatmapSet = new Bindable<BeatmapSetInfo>();
|
public readonly Bindable<BeatmapSetInfo> BeatmapSet = new Bindable<BeatmapSetInfo>();
|
||||||
|
|
||||||
private readonly Bindable<bool> favourited = new Bindable<bool>();
|
private readonly BindableBool favourited = new BindableBool();
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
private PostBeatmapFavouriteRequest request;
|
||||||
private void load()
|
private DimmedLoadingLayer loading;
|
||||||
|
|
||||||
|
private readonly Bindable<User> localUser = new Bindable<User>();
|
||||||
|
|
||||||
|
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)
|
||||||
{
|
{
|
||||||
Container pink;
|
|
||||||
SpriteIcon icon;
|
SpriteIcon icon;
|
||||||
|
|
||||||
AddRange(new Drawable[]
|
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
|
icon = new SpriteIcon
|
||||||
{
|
{
|
||||||
Anchor = Anchor.Centre,
|
Anchor = Anchor.Centre,
|
||||||
@ -55,31 +54,58 @@ namespace osu.Game.Overlays.BeatmapSet.Buttons
|
|||||||
Size = new Vector2(18),
|
Size = new Vector2(18),
|
||||||
Shadow = false,
|
Shadow = false,
|
||||||
},
|
},
|
||||||
|
loading = new DimmedLoadingLayer(0.8f, 0.5f),
|
||||||
});
|
});
|
||||||
|
|
||||||
BeatmapSet.BindValueChanged(setInfo =>
|
Action = () =>
|
||||||
{
|
{
|
||||||
if (setInfo.NewValue?.OnlineInfo?.HasFavourited == null)
|
if (loading.State.Value == Visibility.Visible)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
favourited.Value = setInfo.NewValue.OnlineInfo.HasFavourited;
|
// guaranteed by disabled state above.
|
||||||
|
Debug.Assert(BeatmapSet.Value.OnlineBeatmapSetID != null);
|
||||||
|
|
||||||
|
loading.Show();
|
||||||
|
|
||||||
|
request?.Cancel();
|
||||||
|
|
||||||
|
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 = e.Message,
|
||||||
|
Icon = FontAwesome.Solid.Times,
|
||||||
});
|
});
|
||||||
|
|
||||||
favourited.ValueChanged += favourited =>
|
loading.Hide();
|
||||||
{
|
|
||||||
if (favourited.NewValue)
|
|
||||||
{
|
|
||||||
pink.FadeIn(200);
|
|
||||||
icon.Icon = FontAwesome.Solid.Heart;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
pink.FadeOut(200);
|
|
||||||
icon.Icon = FontAwesome.Regular.Heart;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
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()
|
protected override void UpdateAfterChildren()
|
||||||
{
|
{
|
||||||
base.UpdateAfterChildren();
|
base.UpdateAfterChildren();
|
||||||
|
Loading…
Reference in New Issue
Block a user