1
0
mirror of https://github.com/ppy/osu.git synced 2024-11-11 15:47:26 +08:00

fixed code

This commit is contained in:
JimmyC7834 2021-06-22 13:53:21 +08:00
parent b162da5ee0
commit 0d17fb4259
3 changed files with 170 additions and 135 deletions

View File

@ -24,6 +24,8 @@ namespace osu.Game.Tests.Visual.Online
private BeatmapListingOverlay overlay; private BeatmapListingOverlay overlay;
private BeatmapListingSearchControl searchControl => overlay.ChildrenOfType<BeatmapListingSearchControl>().Single();
[BackgroundDependencyLoader] [BackgroundDependencyLoader]
private void load() private void load()
{ {
@ -70,113 +72,123 @@ namespace osu.Game.Tests.Visual.Online
} }
[Test] [Test]
public void TestSupporterOnlyFiltersPlaceholderNoBeatmaps() public void TestNonSupportUseSupporterOnlyFiltersPlaceholderNoBeatmaps()
{ {
AddStep("fetch for 0 beatmaps", () => fetchFor()); AddStep("fetch for 0 beatmaps", () => fetchFor());
AddStep("set dummy as non-supporter", () => ((DummyAPIAccess)API).LocalUser.Value.IsSupporter = false); AddStep("set dummy as non-supporter", () => ((DummyAPIAccess)API).LocalUser.Value.IsSupporter = false);
// test non-supporter on Rank Achieved filter // test non-supporter on Rank Achieved filter
toggleRandomRankFilter(); toggleRankFilter(Scoring.ScoreRank.XH);
expectedPlaceholderShown(true, false); supporterRequiredPlaceholderShown();
AddStep("Clear Rank Achieved filter", () => overlay.ChildrenOfType<BeatmapListingSearchControl>().Single().Ranks.Clear()); AddStep("Clear Rank Achieved filter", () => searchControl.Ranks.Clear());
expectedPlaceholderShown(false, true); notFoundPlaceholderShown();
// test non-supporter on Played filter // test non-supporter on Played filter
toggleRandomSupporterOnlyPlayedFilter(); toggleSupporterOnlyPlayedFilter(SearchPlayed.Played);
expectedPlaceholderShown(true, false); supporterRequiredPlaceholderShown();
AddStep("Set Played filter to Any", () => overlay.ChildrenOfType<BeatmapListingSearchControl>().Single().Played.Value = SearchPlayed.Any); AddStep("Set Played filter to Any", () => searchControl.Played.Value = SearchPlayed.Any);
expectedPlaceholderShown(false, true); notFoundPlaceholderShown();
// test non-supporter on both Rank Achieved and Played filter // test non-supporter on both Rank Achieved and Played filter
toggleRandomRankFilter(); toggleRankFilter(Scoring.ScoreRank.XH);
toggleRandomSupporterOnlyPlayedFilter(); toggleSupporterOnlyPlayedFilter(SearchPlayed.Played);
expectedPlaceholderShown(true, false); supporterRequiredPlaceholderShown();
AddStep("Clear Rank Achieved filter", () => overlay.ChildrenOfType<BeatmapListingSearchControl>().Single().Ranks.Clear()); AddStep("Clear Rank Achieved filter", () => searchControl.Ranks.Clear());
AddStep("Set Played filter to Any", () => overlay.ChildrenOfType<BeatmapListingSearchControl>().Single().Played.Value = SearchPlayed.Any); AddStep("Set Played filter to Any", () => searchControl.Played.Value = SearchPlayed.Any);
expectedPlaceholderShown(false, true); notFoundPlaceholderShown();
AddStep("set dummy as supporter", () => ((DummyAPIAccess)API).LocalUser.Value.IsSupporter = true);
// test supporter on Rank Achieved filter
toggleRandomRankFilter();
expectedPlaceholderShown(false, true);
AddStep("Clear Rank Achieved filter", () => overlay.ChildrenOfType<BeatmapListingSearchControl>().Single().Ranks.Clear());
expectedPlaceholderShown(false, true);
// test supporter on Played filter
toggleRandomSupporterOnlyPlayedFilter();
expectedPlaceholderShown(false, true);
AddStep("Set Played filter to Any", () => overlay.ChildrenOfType<BeatmapListingSearchControl>().Single().Played.Value = SearchPlayed.Any);
expectedPlaceholderShown(false, true);
// test supporter on both Rank Achieved and Played filter
toggleRandomRankFilter();
toggleRandomSupporterOnlyPlayedFilter();
expectedPlaceholderShown(false, true);
AddStep("Clear Rank Achieved filter", () => overlay.ChildrenOfType<BeatmapListingSearchControl>().Single().Ranks.Clear());
AddStep("Set Played filter to Any", () => overlay.ChildrenOfType<BeatmapListingSearchControl>().Single().Played.Value = SearchPlayed.Any);
expectedPlaceholderShown(false, true);
} }
[Test] [Test]
public void TestSupporterOnlyFiltersPlaceholderOneBeatmap() public void TestSupportUseSupporterOnlyFiltersPlaceholderNoBeatmaps()
{
AddStep("fetch for 0 beatmaps", () => fetchFor());
AddStep("set dummy as supporter", () => ((DummyAPIAccess)API).LocalUser.Value.IsSupporter = true);
// test supporter on Rank Achieved filter
toggleRankFilter(Scoring.ScoreRank.XH);
notFoundPlaceholderShown();
AddStep("Clear Rank Achieved filter", () => searchControl.Ranks.Clear());
notFoundPlaceholderShown();
// test supporter on Played filter
toggleSupporterOnlyPlayedFilter(SearchPlayed.Played);
notFoundPlaceholderShown();
AddStep("Set Played filter to Any", () => searchControl.Played.Value = SearchPlayed.Any);
notFoundPlaceholderShown();
// test supporter on both Rank Achieved and Played filter
toggleRankFilter(Scoring.ScoreRank.XH);
toggleSupporterOnlyPlayedFilter(SearchPlayed.Played);
notFoundPlaceholderShown();
AddStep("Clear Rank Achieved filter", () => searchControl.Ranks.Clear());
AddStep("Set Played filter to Any", () => searchControl.Played.Value = SearchPlayed.Any);
notFoundPlaceholderShown();
}
[Test]
public void TestNonSupporterUseSupporterOnlyFiltersPlaceholderOneBeatmap()
{ {
AddStep("fetch for 1 beatmap", () => fetchFor(CreateBeatmap(Ruleset.Value).BeatmapInfo.BeatmapSet)); AddStep("fetch for 1 beatmap", () => fetchFor(CreateBeatmap(Ruleset.Value).BeatmapInfo.BeatmapSet));
AddStep("set dummy as non-supporter", () => ((DummyAPIAccess)API).LocalUser.Value.IsSupporter = false); AddStep("set dummy as non-supporter", () => ((DummyAPIAccess)API).LocalUser.Value.IsSupporter = false);
// test non-supporter on Rank Achieved filter // test non-supporter on Rank Achieved filter
toggleRandomRankFilter(); toggleRankFilter(Scoring.ScoreRank.XH);
expectedPlaceholderShown(true, false); supporterRequiredPlaceholderShown();
AddStep("Clear Rank Achieved filter", () => overlay.ChildrenOfType<BeatmapListingSearchControl>().Single().Ranks.Clear()); AddStep("Clear Rank Achieved filter", () => searchControl.Ranks.Clear());
expectedPlaceholderShown(false, false); noPlaceholderShown();
// test non-supporter on Played filter // test non-supporter on Played filter
toggleRandomSupporterOnlyPlayedFilter(); toggleSupporterOnlyPlayedFilter(SearchPlayed.Played);
expectedPlaceholderShown(true, false); supporterRequiredPlaceholderShown();
AddStep("Set Played filter to Any", () => overlay.ChildrenOfType<BeatmapListingSearchControl>().Single().Played.Value = SearchPlayed.Any); AddStep("Set Played filter to Any", () => searchControl.Played.Value = SearchPlayed.Any);
expectedPlaceholderShown(false, false); noPlaceholderShown();
// test non-supporter on both Rank Achieved and Played filter // test non-supporter on both Rank Achieved and Played filter
toggleRandomRankFilter(); toggleRankFilter(Scoring.ScoreRank.XH);
toggleRandomSupporterOnlyPlayedFilter(); toggleSupporterOnlyPlayedFilter(SearchPlayed.Played);
expectedPlaceholderShown(true, false); supporterRequiredPlaceholderShown();
AddStep("Clear Rank Achieved filter", () => overlay.ChildrenOfType<BeatmapListingSearchControl>().Single().Ranks.Clear()); AddStep("Clear Rank Achieved filter", () => searchControl.Ranks.Clear());
AddStep("Set Played filter to Any", () => overlay.ChildrenOfType<BeatmapListingSearchControl>().Single().Played.Value = SearchPlayed.Any); AddStep("Set Played filter to Any", () => searchControl.Played.Value = SearchPlayed.Any);
expectedPlaceholderShown(false, false); noPlaceholderShown();
}
[Test]
public void TestSupporterUseSupporterOnlyFiltersPlaceholderOneBeatmap()
{
AddStep("fetch for 1 beatmap", () => fetchFor(CreateBeatmap(Ruleset.Value).BeatmapInfo.BeatmapSet));
AddStep("set dummy as supporter", () => ((DummyAPIAccess)API).LocalUser.Value.IsSupporter = true); AddStep("set dummy as supporter", () => ((DummyAPIAccess)API).LocalUser.Value.IsSupporter = true);
// test supporter on Rank Achieved filter // test supporter on Rank Achieved filter
toggleRandomRankFilter(); toggleRankFilter(Scoring.ScoreRank.XH);
expectedPlaceholderShown(false, false); noPlaceholderShown();
AddStep("Clear Rank Achieved filter", () => overlay.ChildrenOfType<BeatmapListingSearchControl>().Single().Ranks.Clear()); AddStep("Clear Rank Achieved filter", () => searchControl.Ranks.Clear());
expectedPlaceholderShown(false, false); noPlaceholderShown();
// test supporter on Played filter // test supporter on Played filter
toggleRandomSupporterOnlyPlayedFilter(); toggleSupporterOnlyPlayedFilter(SearchPlayed.Played);
expectedPlaceholderShown(false, false); noPlaceholderShown();
AddStep("Set Played filter to Any", () => overlay.ChildrenOfType<BeatmapListingSearchControl>().Single().Played.Value = SearchPlayed.Any); AddStep("Set Played filter to Any", () => searchControl.Played.Value = SearchPlayed.Any);
expectedPlaceholderShown(false, false); noPlaceholderShown();
// test supporter on both Rank Achieved and Played filter // test supporter on both Rank Achieved and Played filter
toggleRandomRankFilter(); toggleRankFilter(Scoring.ScoreRank.XH);
toggleRandomSupporterOnlyPlayedFilter(); toggleSupporterOnlyPlayedFilter(SearchPlayed.Played);
expectedPlaceholderShown(false, false); noPlaceholderShown();
AddStep("Set Played filter to Any", () => overlay.ChildrenOfType<BeatmapListingSearchControl>().Single().Played.Value = SearchPlayed.Any); AddStep("Set Played filter to Any", () => searchControl.Played.Value = SearchPlayed.Any);
AddStep("Clear Rank Achieved filter", () => overlay.ChildrenOfType<BeatmapListingSearchControl>().Single().Ranks.Clear()); AddStep("Clear Rank Achieved filter", () => searchControl.Ranks.Clear());
expectedPlaceholderShown(false, false); noPlaceholderShown();
} }
private void fetchFor(params BeatmapSetInfo[] beatmaps) private void fetchFor(params BeatmapSetInfo[] beatmaps)
@ -185,44 +197,36 @@ namespace osu.Game.Tests.Visual.Online
setsForResponse.AddRange(beatmaps.Select(b => new TestAPIBeatmapSet(b))); setsForResponse.AddRange(beatmaps.Select(b => new TestAPIBeatmapSet(b)));
// trigger arbitrary change for fetching. // trigger arbitrary change for fetching.
overlay.ChildrenOfType<BeatmapListingSearchControl>().Single().Query.TriggerChange(); searchControl.Query.TriggerChange();
} }
private void toggleRandomRankFilter() private void toggleRankFilter(Scoring.ScoreRank rank)
{ {
short r = TestContext.CurrentContext.Random.NextShort(); AddStep("toggle Rank Achieved filter", () =>
AddStep("toggle Random Rank Achieved filter", () =>
{ {
overlay.ChildrenOfType<BeatmapListingSearchControl>().Single().Ranks.Clear(); searchControl.Ranks.Clear();
overlay.ChildrenOfType<BeatmapListingSearchControl>().Single().Ranks.Add((Scoring.ScoreRank)(r % 8)); searchControl.Ranks.Add(rank);
}); });
} }
private void toggleRandomSupporterOnlyPlayedFilter() private void toggleSupporterOnlyPlayedFilter(SearchPlayed played)
{ {
short r = TestContext.CurrentContext.Random.NextShort(); AddStep("toggle Played filter", () => searchControl.Played.Value = played);
AddStep("toggle Random Played filter", () => overlay.ChildrenOfType<BeatmapListingSearchControl>().Single().Played.Value = (SearchPlayed)(r % 2 + 1));
} }
private void expectedPlaceholderShown(bool supporterRequiredShown, bool notFoundShown) private void supporterRequiredPlaceholderShown()
{ {
if (supporterRequiredShown) AddUntilStep("supporter-placeholder shown", () => overlay.ChildrenOfType<BeatmapListingOverlay.SupporterRequiredDrawable>().SingleOrDefault()?.IsPresent == true);
{ }
AddUntilStep("supporter-placeholder shown", () => overlay.ChildrenOfType<BeatmapListingOverlay.SupporterRequiredDrawable>().SingleOrDefault()?.IsPresent == true);
}
else
{
AddUntilStep("supporter-placeholder hidden", () => !overlay.ChildrenOfType<BeatmapListingOverlay.SupporterRequiredDrawable>().Any());
}
if (notFoundShown) private void notFoundPlaceholderShown()
{ {
AddUntilStep("not-found-placeholder shown", () => overlay.ChildrenOfType<BeatmapListingOverlay.NotFoundDrawable>().SingleOrDefault()?.IsPresent == true); AddUntilStep("not-found-placeholder shown", () => overlay.ChildrenOfType<BeatmapListingOverlay.NotFoundDrawable>().SingleOrDefault()?.IsPresent == true);
} }
else
{ private void noPlaceholderShown()
AddUntilStep("not-found-placeholder hidden", () => !overlay.ChildrenOfType<BeatmapListingOverlay.NotFoundDrawable>().Any()); {
} AddUntilStep("no placeholder shown", () => !overlay.ChildrenOfType<BeatmapListingOverlay.SupporterRequiredDrawable>().Any() && !overlay.ChildrenOfType<BeatmapListingOverlay.NotFoundDrawable>().Any());
} }
private class TestAPIBeatmapSet : APIBeatmapSet private class TestAPIBeatmapSet : APIBeatmapSet

View File

@ -10,11 +10,13 @@ using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Effects; using osu.Framework.Graphics.Effects;
using osu.Framework.Graphics.Shapes; using osu.Framework.Graphics.Shapes;
using osu.Framework.Localisation;
using osu.Framework.Threading; using osu.Framework.Threading;
using osu.Game.Beatmaps; using osu.Game.Beatmaps;
using osu.Game.Online.API; using osu.Game.Online.API;
using osu.Game.Online.API.Requests; using osu.Game.Online.API.Requests;
using osu.Game.Rulesets; using osu.Game.Rulesets;
using osu.Game.Resources.Localisation.Web;
using osuTK; using osuTK;
using osuTK.Graphics; using osuTK.Graphics;
@ -26,7 +28,7 @@ namespace osu.Game.Overlays.BeatmapListing
/// Fired when a search finishes. Contains only new items in the case of pagination. /// Fired when a search finishes. Contains only new items in the case of pagination.
/// Fired with BeatmapListingSearchControl when non-supporter user used supporter-only filters. /// Fired with BeatmapListingSearchControl when non-supporter user used supporter-only filters.
/// </summary> /// </summary>
public Action<List<BeatmapSetInfo>, BeatmapListingSearchControl> SearchFinished; public Action<SearchResult> SearchFinished;
/// <summary> /// <summary>
/// Fired when search criteria change. /// Fired when search criteria change.
@ -216,11 +218,19 @@ namespace osu.Game.Overlays.BeatmapListing
// check if an non-supporter user used supporter-only filters // check if an non-supporter user used supporter-only filters
if (!api.LocalUser.Value.IsSupporter && (searchControl.Ranks.Any() || searchControl.Played.Value != SearchPlayed.Any)) if (!api.LocalUser.Value.IsSupporter && (searchControl.Ranks.Any() || searchControl.Played.Value != SearchPlayed.Any))
{ {
SearchFinished?.Invoke(sets, searchControl); List<LocalisableString> filters = new List<LocalisableString>();
if (searchControl.Played.Value != SearchPlayed.Any)
filters.Add(BeatmapsStrings.ListingSearchFiltersPlayed);
if (searchControl.Ranks.Any())
filters.Add(BeatmapsStrings.ListingSearchFiltersRank);
SearchFinished?.Invoke(SearchResult.SupporterOnlyFilter(filters));
} }
else else
{ {
SearchFinished?.Invoke(sets, null); SearchFinished?.Invoke(SearchResult.ResultsReturned(sets));
} }
}; };
@ -246,5 +256,30 @@ namespace osu.Game.Overlays.BeatmapListing
base.Dispose(isDisposing); base.Dispose(isDisposing);
} }
public enum SearchResultType
{
ResultsReturned,
SupporterOnlyFilter
}
public struct SearchResult
{
public SearchResultType Type { get; private set; }
public List<BeatmapSetInfo> Results { get; private set; }
public List<LocalisableString> Filters { get; private set; }
public static SearchResult ResultsReturned(List<BeatmapSetInfo> results) => new SearchResult
{
Type = SearchResultType.ResultsReturned,
Results = results
};
public static SearchResult SupporterOnlyFilter(List<LocalisableString> filters) => new SearchResult
{
Type = SearchResultType.SupporterOnlyFilter,
Filters = filters
};
}
} }
} }

View File

@ -7,6 +7,7 @@ using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using osu.Framework.Allocation; using osu.Framework.Allocation;
using osu.Framework.Extensions.IEnumerableExtensions; using osu.Framework.Extensions.IEnumerableExtensions;
using osu.Framework.Localisation;
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.Shapes;
@ -119,28 +120,28 @@ namespace osu.Game.Overlays
private Task panelLoadDelegate; private Task panelLoadDelegate;
private void onSearchFinished(List<BeatmapSetInfo> beatmaps, BeatmapListingSearchControl searchControl) private void onSearchFinished(BeatmapListingFilterControl.SearchResult searchResult)
{ {
var newPanels = beatmaps.Select<BeatmapSetInfo, BeatmapPanel>(b => new GridBeatmapPanel(b) // non-supporter user used supporter-only filters
if (searchResult.Type == BeatmapListingFilterControl.SearchResultType.SupporterOnlyFilter)
{
supporterRequiredContent.UpdateText(searchResult.Filters);
addContentToPlaceholder(supporterRequiredContent);
return;
}
var newPanels = searchResult.Results.Select<BeatmapSetInfo, BeatmapPanel>(b => new GridBeatmapPanel(b)
{ {
Anchor = Anchor.TopCentre, Anchor = Anchor.TopCentre,
Origin = Anchor.TopCentre, Origin = Anchor.TopCentre,
}); });
// non-supporter user used supporter-only filters
if (searchControl != null)
{
supporterRequiredContent.UpdateText(searchControl.Played.Value != SearchPlayed.Any, searchControl.Ranks.Any());
LoadComponentAsync(supporterRequiredContent, addContentToPlaceholder, (cancellationToken = new CancellationTokenSource()).Token);
return;
}
if (filterControl.CurrentPage == 0) if (filterControl.CurrentPage == 0)
{ {
//No matches case //No matches case
if (!newPanels.Any()) if (!newPanels.Any())
{ {
LoadComponentAsync(notFoundContent, addContentToPlaceholder, (cancellationToken = new CancellationTokenSource()).Token); addContentToPlaceholder(notFoundContent);
return; return;
} }
@ -182,16 +183,11 @@ namespace osu.Game.Overlays
{ {
var transform = lastContent.FadeOut(100, Easing.OutQuint); var transform = lastContent.FadeOut(100, Easing.OutQuint);
if (lastContent == notFoundContent) if (lastContent == notFoundContent || lastContent == supporterRequiredContent)
{ {
// not found display may be used multiple times, so don't expire/dispose it. // the placeholder may be used multiple times, so don't expire/dispose it.
transform.Schedule(() => panelTarget.Remove(lastContent)); transform.Schedule(() => panelTarget.Remove(lastContent));
} }
else if (lastContent == supporterRequiredContent)
{
// supporter required display may be used multiple times, so don't expire/dispose it.
transform.Schedule(() => panelTarget.Remove(supporterRequiredContent));
}
else else
{ {
// Consider the case when the new content is smaller than the last content. // Consider the case when the new content is smaller than the last content.
@ -260,7 +256,7 @@ namespace osu.Game.Overlays
// using string literals as there's no proper processing for LocalizeStrings yet // using string literals as there's no proper processing for LocalizeStrings yet
public class SupporterRequiredDrawable : CompositeDrawable public class SupporterRequiredDrawable : CompositeDrawable
{ {
private OsuSpriteText supporterRequiredText; private OsuSpriteText filtersText;
public SupporterRequiredDrawable() public SupporterRequiredDrawable()
{ {
@ -289,30 +285,20 @@ namespace osu.Game.Overlays
FillMode = FillMode.Fit, FillMode = FillMode.Fit,
Texture = textures.Get(@"Online/supporter-required"), Texture = textures.Get(@"Online/supporter-required"),
}, },
supporterRequiredText = new OsuSpriteText createSupporterText(),
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
Font = OsuFont.GetFont(size: 16),
Colour = Colour4.White,
Margin = new MarginPadding { Bottom = 10 },
},
createSupporterTagLink(),
} }
}); });
} }
public void UpdateText(bool playedFilter, bool rankFilter) public void UpdateText(List<LocalisableString> filters)
{ {
List<string> filters = new List<string>(); // use string literals for now
if (playedFilter) filters.Add(BeatmapsStrings.ListingSearchFiltersPlayed.ToString()); filtersText.Text = BeatmapsStrings.ListingSearchSupporterFilterQuoteDefault(string.Join(" and ", filters), "").ToString();
if (rankFilter) filters.Add(BeatmapsStrings.ListingSearchFiltersRank.ToString());
supporterRequiredText.Text = BeatmapsStrings.ListingSearchSupporterFilterQuoteDefault(string.Join(" and ", filters), "").ToString();
} }
private Drawable createSupporterTagLink() private Drawable createSupporterText()
{ {
LinkFlowContainer supporterTagLink = new LinkFlowContainer LinkFlowContainer supporterRequiredText = new LinkFlowContainer
{ {
Anchor = Anchor.Centre, Anchor = Anchor.Centre,
Origin = Anchor.Centre, Origin = Anchor.Centre,
@ -320,8 +306,18 @@ namespace osu.Game.Overlays
Margin = new MarginPadding { Bottom = 10 }, Margin = new MarginPadding { Bottom = 10 },
}; };
supporterTagLink.AddLink(BeatmapsStrings.ListingSearchSupporterFilterQuoteLinkText.ToString(), "https://osu.ppy.sh/store/products/supporter-tag"); filtersText = (OsuSpriteText)supporterRequiredText.AddText(
return supporterTagLink; "_",
t =>
{
t.Font = OsuFont.GetFont(size: 16);
t.Colour = Colour4.White;
}
).First();
supporterRequiredText.AddLink(BeatmapsStrings.ListingSearchSupporterFilterQuoteLinkText.ToString(), @"/store/products/supporter-tag");
return supporterRequiredText;
} }
} }