1
0
mirror of https://github.com/ppy/osu.git synced 2024-11-16 06:27:27 +08:00
osu-lazer/osu.Game/Screens/OnlinePlay/DailyChallenge/DailyChallengeEventFeed.cs
Bartłomiej Dach b29e535ca5
Add results screen for displaying arbitrary daily challenge scores
At this point its primary usage is the daily challenge event feed, but
the leaderboard will be using this too shortly.

Because the playlists results screen that exists in `master` is
hard-coupled to showing the *local user's* best result on a given
playlist by way of hard-coupling itself to the relevant API request,
allowing show of *arbitrary* score by ID requires a whole bunch of
subclassery as things stand. Oh well.

Class naming is... best effort, due to the above.
2024-07-04 13:45:24 +02:00

134 lines
4.3 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.Collections.Generic;
using System.Linq;
using osu.Framework.Allocation;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Game.Graphics;
using osu.Game.Graphics.Containers;
using osu.Game.Graphics.UserInterface;
using osu.Game.Screens.OnlinePlay.DailyChallenge.Events;
using osu.Game.Users.Drawables;
using osuTK;
namespace osu.Game.Screens.OnlinePlay.DailyChallenge
{
public partial class DailyChallengeEventFeed : CompositeDrawable
{
private DailyChallengeEventFeedFlow flow = null!;
public Action<long>? PresentScore { get; init; }
[BackgroundDependencyLoader]
private void load()
{
InternalChildren = new Drawable[]
{
new SectionHeader("Events"),
new Container
{
RelativeSizeAxes = Axes.Both,
Padding = new MarginPadding { Top = 35 },
Child = flow = new DailyChallengeEventFeedFlow
{
RelativeSizeAxes = Axes.Both,
Direction = FillDirection.Vertical,
Origin = Anchor.BottomCentre,
Anchor = Anchor.BottomCentre,
Spacing = new Vector2(5),
Masking = true,
}
}
};
}
public void AddNewScore(NewScoreEvent newScoreEvent)
{
var row = new NewScoreEventRow(newScoreEvent)
{
Anchor = Anchor.BottomCentre,
Origin = Anchor.BottomCentre,
PresentScore = PresentScore,
};
flow.Add(row);
row.Delay(15000).Then().FadeOut(300, Easing.OutQuint).Expire();
}
protected override void Update()
{
base.Update();
for (int i = 0; i < flow.Count; ++i)
{
var row = flow[i];
if (row.Y < -flow.DrawHeight)
{
row.RemoveAndDisposeImmediately();
i -= 1;
}
}
}
private partial class DailyChallengeEventFeedFlow : FillFlowContainer
{
public override IEnumerable<Drawable> FlowingChildren => base.FlowingChildren.Reverse();
}
private partial class NewScoreEventRow : CompositeDrawable
{
private readonly NewScoreEvent newScore;
public Action<long>? PresentScore { get; init; }
public NewScoreEventRow(NewScoreEvent newScore)
{
this.newScore = newScore;
}
[BackgroundDependencyLoader]
private void load(OsuColour colours)
{
LinkFlowContainer text;
RelativeSizeAxes = Axes.X;
AutoSizeAxes = Axes.Y;
AutoSizeDuration = 300;
AutoSizeEasing = Easing.OutQuint;
InternalChildren = new Drawable[]
{
new ClickableAvatar(newScore.User)
{
Size = new Vector2(16),
Masking = true,
CornerRadius = 8,
},
text = new LinkFlowContainer(t =>
{
t.Font = OsuFont.Default.With(weight: newScore.NewRank == null ? FontWeight.Medium : FontWeight.Bold);
t.Colour = newScore.NewRank < 10 ? colours.Orange1 : Colour4.White;
})
{
RelativeSizeAxes = Axes.X,
AutoSizeAxes = Axes.Y,
Padding = new MarginPadding { Left = 21 },
}
};
text.AddUserLink(newScore.User);
text.AddText(" got ");
text.AddLink($"{newScore.TotalScore:N0} points", () => PresentScore?.Invoke(newScore.ScoreID));
if (newScore.NewRank != null)
text.AddText($" and achieved rank #{newScore.NewRank.Value:N0}");
text.AddText("!");
}
}
}
}