1
0
mirror of https://github.com/ppy/osu.git synced 2024-11-15 13:07:24 +08:00
osu-lazer/osu.Game/Screens/OnlinePlay/DailyChallenge/DailyChallengeLeaderboard.cs
Bartłomiej Dach bf4bf4d39e
Fill daily challenge top 50 position numbers client-side
Only doing this client-side, because doing this server-side is
expensive:

	https://github.com/ppy/osu-web/pull/11354#discussion_r1689224285
2024-07-24 08:57:11 +02:00

176 lines
6.4 KiB
C#

// 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 System;
using System.Linq;
using System.Threading;
using osu.Framework.Allocation;
using osu.Framework.Bindables;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Game.Beatmaps;
using osu.Game.Graphics.Containers;
using osu.Game.Graphics.UserInterface;
using osu.Game.Online.API;
using osu.Game.Online.Rooms;
using osu.Game.Rulesets;
using osu.Game.Scoring;
using osu.Game.Screens.SelectV2.Leaderboards;
using osuTK;
namespace osu.Game.Screens.OnlinePlay.DailyChallenge
{
public partial class DailyChallengeLeaderboard : CompositeDrawable
{
public Action<long>? PresentScore { get; init; }
private readonly Room room;
private readonly PlaylistItem playlistItem;
private FillFlowContainer<LeaderboardScoreV2> scoreFlow = null!;
private Container userBestContainer = null!;
private SectionHeader userBestHeader = null!;
private LoadingLayer loadingLayer = null!;
private CancellationTokenSource? cancellationTokenSource;
[Resolved]
private IAPIProvider api { get; set; } = null!;
[Resolved]
private ScoreManager scoreManager { get; set; } = null!;
[Resolved]
private RulesetStore rulesets { get; set; } = null!;
[Resolved]
private IBindable<WorkingBeatmap> beatmap { get; set; } = null!;
public DailyChallengeLeaderboard(Room room, PlaylistItem playlistItem)
{
this.room = room;
this.playlistItem = playlistItem;
}
[BackgroundDependencyLoader]
private void load()
{
InternalChild = new GridContainer
{
RelativeSizeAxes = Axes.Both,
RowDimensions =
[
new Dimension(GridSizeMode.AutoSize),
new Dimension(),
new Dimension(GridSizeMode.AutoSize),
new Dimension(GridSizeMode.AutoSize)
],
Content = new[]
{
new Drawable[] { new SectionHeader("Leaderboard") },
new Drawable[]
{
new Container
{
RelativeSizeAxes = Axes.Both,
Children = new Drawable[]
{
new OsuScrollContainer
{
RelativeSizeAxes = Axes.Both,
Child = scoreFlow = new FillFlowContainer<LeaderboardScoreV2>
{
RelativeSizeAxes = Axes.X,
AutoSizeAxes = Axes.Y,
Padding = new MarginPadding { Right = 20, },
Direction = FillDirection.Vertical,
Spacing = new Vector2(5),
Scale = new Vector2(0.8f),
Width = 1 / 0.8f,
}
},
loadingLayer = new LoadingLayer
{
RelativeSizeAxes = Axes.Both,
},
}
}
},
new Drawable[] { userBestHeader = new SectionHeader("Personal best") { Alpha = 0, } },
new Drawable[]
{
userBestContainer = new Container
{
RelativeSizeAxes = Axes.X,
AutoSizeAxes = Axes.Y,
Padding = new MarginPadding { Right = 20, },
Scale = new Vector2(0.8f),
Width = 1 / 0.8f,
}
}
}
};
}
protected override void LoadComplete()
{
base.LoadComplete();
RefetchScores();
}
public void RefetchScores()
{
var request = new IndexPlaylistScoresRequest(room.RoomID.Value!.Value, playlistItem.ID);
request.Success += req => Schedule(() =>
{
var best = req.Scores.Select(s => s.CreateScoreInfo(scoreManager, rulesets, playlistItem, beatmap.Value.BeatmapInfo)).ToArray();
var userBest = req.UserScore?.CreateScoreInfo(scoreManager, rulesets, playlistItem, beatmap.Value.BeatmapInfo);
cancellationTokenSource?.Cancel();
cancellationTokenSource = null;
cancellationTokenSource ??= new CancellationTokenSource();
if (best.Length == 0)
{
scoreFlow.Clear();
loadingLayer.Hide();
}
else
{
LoadComponentsAsync(best.Select((s, index) => new LeaderboardScoreV2(s, sheared: false)
{
Rank = index + 1,
IsPersonalBest = s.UserID == api.LocalUser.Value.Id,
Action = () => PresentScore?.Invoke(s.OnlineID),
}), loaded =>
{
scoreFlow.Clear();
scoreFlow.AddRange(loaded);
scoreFlow.FadeTo(1, 400, Easing.OutQuint);
loadingLayer.Hide();
}, cancellationTokenSource.Token);
}
userBestContainer.Clear();
if (userBest != null)
{
userBestContainer.Add(new LeaderboardScoreV2(userBest, sheared: false)
{
Rank = userBest.Position,
IsPersonalBest = true,
Action = () => PresentScore?.Invoke(userBest.OnlineID),
});
}
userBestHeader.FadeTo(userBest == null ? 0 : 1);
});
loadingLayer.Show();
scoreFlow.FadeTo(0.5f, 400, Easing.OutQuint);
api.Queue(request);
}
}
}