Skip to content

Commit

Permalink
add recommended beatmaps
Browse files Browse the repository at this point in the history
  • Loading branch information
Flutterish committed Apr 10, 2022
1 parent b3f7014 commit 652c373
Show file tree
Hide file tree
Showing 6 changed files with 177 additions and 4 deletions.
1 change: 1 addition & 0 deletions LocalizationGenerator/Source/en.jsonc
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@
"load-error": "Could not load rurusetto-addon: Please report this to the rurusetto-addon repository NOT the osu!lazer repository: Code {0}",
"main-page": "Main",
"changelog-page": "Changelog",
"recommended-beatmaps-page": "Recommended Beatmaps",
"unknown-version": "Unknown Version",
"settings-header": "Rurusetto Addon",
"settings-api-address": "API Address",
Expand Down
15 changes: 15 additions & 0 deletions osu.Game.Rulesets.RurusettoAddon/API/APIRuleset.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
using osuTK;
using System;
using System.Collections.Generic;
using static osu.Game.Rulesets.RurusettoAddon.API.RurusettoAPI;

#nullable enable

Expand Down Expand Up @@ -172,6 +173,20 @@ public void RequestSubpage ( string subpageSlug, Action<Subpage> success, Action
}
}

public void RequestRecommendations ( RecommendationSource source, Action<List<BeatmapRecommendation>> success, Action<Exception?>? failure = null ) {
if ( Source == Source.Web && API != null && !string.IsNullOrWhiteSpace( Slug ) ) {
API.RequestBeatmapRecommendations( Slug, source, success, failure );
}
else {
failure?.Invoke( null );
}
}
public void FlushRecommendations () {
if ( Source == Source.Web && API != null && !string.IsNullOrWhiteSpace( Slug ) ) {
API.FlushBeatmapRecommendationsCache( Slug );
}
}

public void RequestDarkCover ( Action<Texture> success, Action<Exception?>? failure = null ) {
if ( API is null ) {
failure?.Invoke( null );
Expand Down
8 changes: 4 additions & 4 deletions osu.Game.Rulesets.RurusettoAddon/API/BeatmapRecommendation.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,11 @@ public record BeatmapRecommendation {

/// <summary> Beatmap's song name. </summary>
[JsonProperty( "title" )]
public LocalisableString Title { get; init; }
public string Title { get; init; }

/// <summary> Song's artist of this beatmap. </summary>
[JsonProperty( "artist" )]
public LocalisableString Artist { get; init; }
public string Artist { get; init; }

/// <summary> Song's source of this beatmap. </summary>
[JsonProperty( "source" )]
Expand All @@ -35,7 +35,7 @@ public record BeatmapRecommendation {

/// <summary> Approval state of this beatmap (4 = loved, 3 = qualified, 2 = approved, 1 = ranked, 0 = pending, -1 = WIP, -2 = graveyard) </summary>
[JsonProperty( "approved" )]
public Approval Approval { get; init; }
public BeatmapStatus Status { get; init; }

/// <summary> Star rating of this beatmap in osu! mode. </summary>
[JsonProperty( "difficultyrating" )]
Expand Down Expand Up @@ -78,7 +78,7 @@ public record BeatmapRecommendation {
public DateTime? CreatedAt { get; init; }
}

public enum Approval {
public enum BeatmapStatus {
Pending = 0,
Ranked = 1,
Approved = 2,
Expand Down
5 changes: 5 additions & 0 deletions osu.Game.Rulesets.RurusettoAddon/Localisation/Strings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -227,6 +227,11 @@ public static LocalisableString LoadError ( LocalisableString errorCode )
/// </summary>
public static LocalisableString ChangelogPage => new TranslatableString( getKey( "changelog-page" ), "Changelog" );

/// <summary>
/// Recommended Beatmaps
/// </summary>
public static LocalisableString RecommendedBeatmapsPage => new TranslatableString( getKey( "recommended-beatmaps-page" ), "Recommended Beatmaps" );

/// <summary>
/// Unknown Version
/// </summary>
Expand Down
1 change: 1 addition & 0 deletions osu.Game.Rulesets.RurusettoAddon/Localisation/Strings.resx
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ You can still try visiting it at [rurusetto]({0}).</value></data>
<data name="load-error"><value>Could not load rurusetto-addon: Please report this to the rurusetto-addon repository NOT the osu!lazer repository: Code {0}</value></data>
<data name="main-page"><value>Main</value></data>
<data name="changelog-page"><value>Changelog</value></data>
<data name="recommended-beatmaps-page"><value>Recommended Beatmaps</value></data>
<data name="unknown-version"><value>Unknown Version</value></data>
<data name="settings-header"><value>Rurusetto Addon</value></data>
<data name="settings-api-address"><value>API Address</value></data>
Expand Down
151 changes: 151 additions & 0 deletions osu.Game.Rulesets.RurusettoAddon/UI/Info/InfoTab.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,22 @@
using osu.Framework.Input.Events;
using osu.Framework.Localisation;
using osu.Framework.Platform;
using osu.Game.Beatmaps;
using osu.Game.Beatmaps.Drawables.Cards;
using osu.Game.Graphics;
using osu.Game.Graphics.Containers;
using osu.Game.Graphics.Containers.Markdown;
using osu.Game.Graphics.Sprites;
using osu.Game.Online.API;
using osu.Game.Online.API.Requests;
using osu.Game.Online.API.Requests.Responses;
using osu.Game.Overlays;
using osu.Game.Rulesets.RurusettoAddon.API;
using osu.Game.Rulesets.RurusettoAddon.UI.Users;
using osuTK;
using System;
using System.Collections.Generic;
using System.Linq;

namespace osu.Game.Rulesets.RurusettoAddon.UI.Info {
public class InfoTab : OverlayTab {
Expand Down Expand Up @@ -53,6 +60,7 @@ private void load ( OverlayColourProvider colourProvider, GameHost host, Texture

SubpageListingEntry main;
SubpageListingEntry changelog;
SubpageListingEntry recommended;
Dictionary<SubpageListingEntry, Drawable> subpageDrawables = new();

[Resolved]
Expand Down Expand Up @@ -218,12 +226,23 @@ void loadSubpages () {

void addDefaultSubpages () {
subpageTabControl.AddItem( main );
subpageTabControl.PinItem( main );

if ( ruleset.ListingEntry?.Status?.Changelog is string log && !string.IsNullOrWhiteSpace( log ) ) {
changelog = new() { Title = Localisation.Strings.ChangelogPage };
subpageTabControl.AddItem( changelog );
subpageTabControl.PinItem( changelog );
subpageDrawables.Add( changelog, createMarkdownContainer().With( d => d.Text = log ) );
}

ruleset.RequestRecommendations( RurusettoAPI.RecommendationSource.All, r => {
if ( r.Count == 0 || OnlineAPI is null )
return;

recommended = new() { Title = Localisation.Strings.RecommendedBeatmapsPage };
subpageTabControl.AddItem( recommended );
subpageTabControl.PinItem( recommended );
} );
}

ruleset.RequestSubpages( subpages => {
Expand Down Expand Up @@ -266,6 +285,10 @@ void loadCurrentPage () {
loadMainPage();
}

if ( page == recommended ) {
loadRecommendedPage();
}

if ( !subpageDrawables.TryGetValue( page, out var subpage ) ) {
var markdown = createMarkdownContainer();
var content = new FillFlowContainer {
Expand Down Expand Up @@ -326,11 +349,139 @@ void loadMainPage () {
Overlay.FinishLoadiong( this );

}, failure: e => {
// TODO RequestFailedDrawable
API.LogFailure( $"Could not retrieve detail for {ruleset}", e );
Overlay.FinishLoadiong( this );
} );
}

[Resolved( canBeNull: true )]
protected IAPIProvider OnlineAPI { get; private set; }

private void loadRecommendedPage () {
if ( subpageDrawables.ContainsKey( recommended ) )
return;

Overlay.StartLoading( this );

var container = new Container {
RelativeSizeAxes = Axes.X,
AutoSizeAxes = Axes.Y
};
subpageDrawables.Add( recommended, container );

ruleset.RequestRecommendations( RurusettoAPI.RecommendationSource.All, r => {
var all = new ReverseChildIDFillFlowContainer<Drawable> {
Direction = FillDirection.Vertical,
RelativeSizeAxes = Axes.X,
AutoSizeAxes = Axes.Y,
Spacing = new( 10 )
};
container.Child = all;

int loadedCount = 0;
foreach ( var group in r.GroupBy( x => x.Recommender.ID ).OrderBy( x => (x.Key.Value == ruleset.Owner?.ID) ? 1 : 2 ).ThenByDescending( x => x.Count() ) ) {
var list = new ReverseChildIDFillFlowContainer<Drawable> {
Direction = FillDirection.Full,
RelativeSizeAxes = Axes.X,
AutoSizeAxes = Axes.Y,
Spacing = new( 10 ),
Anchor = Anchor.TopCentre,
Origin = Anchor.TopCentre,
Margin = new() { Bottom = 20 }
};
all.Add( new GridContainer {
RelativeSizeAxes = Axes.X,
Width = 0.9f,
Height = 30,
Anchor = Anchor.TopCentre,
Origin = Anchor.TopCentre,
ColumnDimensions = new Dimension[] {
new(),
new( GridSizeMode.AutoSize ),
new()
},
Content = new Drawable[][] {
new Drawable[] {
new Circle {
Height = 3,
RelativeSizeAxes = Axes.X,
Colour = colourProvider.Colour1,
Anchor = Anchor.Centre,
Origin = Anchor.Centre
},
new DrawableRurusettoUser( Users.GetUserIdentity( group.Key.Value ), group.Key == ruleset.Owner?.ID ) {
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
Height = 30,
Margin = new MarginPadding { Horizontal = 10 }
},
new Circle {
Height = 3,
RelativeSizeAxes = Axes.X,
Colour = colourProvider.Colour1,
Anchor = Anchor.Centre,
Origin = Anchor.Centre
},
}
}
} );
all.Add( list );

foreach ( var i in group ) {
var request = new GetBeatmapSetRequest( i.BeatmapID, BeatmapSetLookupType.BeatmapId );

request.Success += v => {
v.Beatmaps = v.Beatmaps.Where( x => x.DifficultyName == i.Version ).ToArray();

list.Add( new BeatmapCardNormal( v ) {
Anchor = Anchor.TopCentre
} );

if ( ++loadedCount == r.Count ) {
Overlay.FinishLoadiong( this );
}
};
request.Failure += v => {
list.Add( new BeatmapCardNormal( new() {
Artist = i.Artist,
ArtistUnicode = i.Artist,
BPM = i.BPM,
Title = i.Title,
TitleUnicode = i.Title,
AuthorString = i.Creator,
Status = (BeatmapOnlineStatus)i.Status,
Beatmaps = new APIBeatmap[] {
new() {
BPM = i.BPM,
StarRating = i.StarDifficulty
}
}
} ) {
Anchor = Anchor.TopCentre
} );

if ( ++loadedCount == r.Count ) {
Overlay.FinishLoadiong( this );
}
};

if ( OnlineAPI is DummyAPIAccess )
request.Fail( new Exception() );
else
OnlineAPI.PerformAsync( request );
}
}
}, failure: e => {
container.Child = new RequestFailedDrawable {
ContentText = Localisation.Strings.ErrorMessageGeneric
// TODO retry
};
API.LogFailure( $"Could not retrieve recommendations for {ruleset}", e );
Overlay.FinishLoadiong( this );
} );
}

void loadHeader () {
Overlay.StartLoading( this );
ruleset.RequestDetail( detail => {
Expand Down

0 comments on commit 652c373

Please sign in to comment.