mirror of
https://github.com/ppy/osu.git
synced 2024-11-15 17:17:26 +08:00
5fa586848d
- Actually shows scores rather than playlist aggregates (which are useful... in playlists, where there is more than one item) - Actually allows scores to be shown by clicking on them - Doesn't completely break down visually on smaller window sizes The general appearance is not as polished as the old one in details but I wanted something quick that we can get out by next weekend. Also includes the naive method of refetching scores once a new top 50 score is detected. I can add a stagger if required.
176 lines
6.4 KiB
C#
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 =>
|
|
{
|
|
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 => new LeaderboardScoreV2(s, sheared: false)
|
|
{
|
|
Rank = s.Position,
|
|
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);
|
|
}
|
|
}
|
|
}
|