Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add completion marker to daily challenge profile counter #31543

Merged
merged 5 commits into from
Jan 20, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 33 additions & 16 deletions osu.Game.Tests/Visual/Online/TestSceneUserProfileDailyChallenge.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
using osu.Framework.Bindables;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Shapes;
using osu.Framework.Testing;
using osu.Game.Online.API.Requests.Responses;
using osu.Game.Overlays;
using osu.Game.Overlays.Profile;
Expand All @@ -20,24 +21,16 @@ namespace osu.Game.Tests.Visual.Online
public partial class TestSceneUserProfileDailyChallenge : OsuManualInputManagerTestScene
{
[Cached]
public readonly Bindable<UserProfileData?> User = new Bindable<UserProfileData?>(new UserProfileData(new APIUser(), new OsuRuleset().RulesetInfo));
private readonly Bindable<UserProfileData?> userProfileData = new Bindable<UserProfileData?>(new UserProfileData(new APIUser(), new OsuRuleset().RulesetInfo));

[Cached]
private OverlayColourProvider colourProvider = new OverlayColourProvider(OverlayColourScheme.Pink);

protected override void LoadComplete()
{
base.LoadComplete();

DailyChallengeStatsDisplay display = null!;
private DailyChallengeStatsDisplay display = null!;

AddSliderStep("daily", 0, 999, 2, v => update(s => s.DailyStreakCurrent = v));
AddSliderStep("daily best", 0, 999, 2, v => update(s => s.DailyStreakBest = v));
AddSliderStep("weekly", 0, 250, 1, v => update(s => s.WeeklyStreakCurrent = v));
AddSliderStep("weekly best", 0, 250, 1, v => update(s => s.WeeklyStreakBest = v));
AddSliderStep("top 10%", 0, 999, 0, v => update(s => s.Top10PercentPlacements = v));
AddSliderStep("top 50%", 0, 999, 0, v => update(s => s.Top50PercentPlacements = v));
AddSliderStep("playcount", 0, 1500, 1, v => update(s => s.PlayCount = v));
[SetUpSteps]
public void SetUpSteps()
{
AddStep("create", () =>
{
Clear();
Expand All @@ -51,16 +44,40 @@ protected override void LoadComplete()
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
Scale = new Vector2(1f),
User = { BindTarget = User },
User = { BindTarget = userProfileData },
});
});

AddStep("set local user", () => update(s => s.UserID = API.LocalUser.Value.Id));
}

protected override void LoadComplete()
{
base.LoadComplete();

AddSliderStep("daily", 0, 999, 2, v => update(s => s.DailyStreakCurrent = v));
AddSliderStep("daily best", 0, 999, 2, v => update(s => s.DailyStreakBest = v));
AddSliderStep("weekly", 0, 250, 1, v => update(s => s.WeeklyStreakCurrent = v));
AddSliderStep("weekly best", 0, 250, 1, v => update(s => s.WeeklyStreakBest = v));
AddSliderStep("top 10%", 0, 999, 0, v => update(s => s.Top10PercentPlacements = v));
AddSliderStep("top 50%", 0, 999, 0, v => update(s => s.Top50PercentPlacements = v));
AddSliderStep("playcount", 0, 1500, 1, v => update(s => s.PlayCount = v));
}

[Test]
public void TestStates()
{
AddStep("played today", () => update(s => s.LastUpdate = DateTimeOffset.UtcNow.Date));
AddStep("played yesterday", () => update(s => s.LastUpdate = DateTimeOffset.UtcNow.Date.AddDays(-1)));
AddStep("change to non-local user", () => update(s => s.UserID = API.LocalUser.Value.Id + 1000));

AddStep("hover", () => InputManager.MoveMouseTo(display));
}

private void update(Action<APIUserDailyChallengeStatistics> change)
{
change.Invoke(User.Value!.User.DailyChallengeStatistics);
User.Value = new UserProfileData(User.Value.User, User.Value.Ruleset);
change.Invoke(userProfileData.Value!.User.DailyChallengeStatistics);
userProfileData.Value = new UserProfileData(userProfileData.Value.User, userProfileData.Value.Ruleset);
}

[Test]
Expand Down
Original file line number Diff line number Diff line change
@@ -1,18 +1,22 @@
// Copyright (c) ppy Pty Ltd <[email protected]>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.

using System;
using osu.Framework.Allocation;
using osu.Framework.Bindables;
using osu.Framework.Extensions.LocalisationExtensions;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Cursor;
using osu.Framework.Graphics.Shapes;
using osu.Framework.Graphics.Sprites;
using osu.Game.Graphics;
using osu.Game.Graphics.Containers;
using osu.Game.Graphics.Sprites;
using osu.Game.Localisation;
using osu.Game.Online.API;
using osu.Game.Online.API.Requests.Responses;
using osuTK;

namespace osu.Game.Overlays.Profile.Header.Components
{
Expand All @@ -23,6 +27,11 @@ public partial class DailyChallengeStatsDisplay : CompositeDrawable, IHasCustomT
public DailyChallengeTooltipData? TooltipContent { get; private set; }

private OsuSpriteText dailyPlayCount = null!;
private Container content = null!;
private CircularContainer completionMark = null!;

[Resolved]
private IAPIProvider api { get; set; } = null!;

[Resolved]
private OsuColour colours { get; set; } = null!;
Expand All @@ -34,58 +43,91 @@ public partial class DailyChallengeStatsDisplay : CompositeDrawable, IHasCustomT
private void load()
{
AutoSizeAxes = Axes.Both;
CornerRadius = 5;
Masking = true;

InternalChildren = new Drawable[]
{
new Box
{
RelativeSizeAxes = Axes.Both,
Colour = colourProvider.Background4,
},
new FillFlowContainer
content = new Container
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
Padding = new MarginPadding(5f),
AutoSizeAxes = Axes.Both,
Direction = FillDirection.Horizontal,
CornerRadius = 6,
BorderThickness = 2,
BorderColour = colourProvider.Background4,
Masking = true,
Children = new Drawable[]
{
new OsuTextFlowContainer(s => s.Font = OsuFont.GetFont(size: 12))
new Box
{
AutoSizeAxes = Axes.Both,
// can't use this because osu-web does weird stuff with \\n.
// Text = UsersStrings.ShowDailyChallengeTitle.,
Text = "Daily\nChallenge",
Margin = new MarginPadding { Horizontal = 5f, Bottom = 2f },
RelativeSizeAxes = Axes.Both,
Colour = colourProvider.Background4,
},
new Container
new FillFlowContainer
{
AutoSizeAxes = Axes.X,
RelativeSizeAxes = Axes.Y,
CornerRadius = 5f,
Masking = true,
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
Padding = new MarginPadding(3f),
AutoSizeAxes = Axes.Both,
Direction = FillDirection.Horizontal,
Children = new Drawable[]
{
new Box
new OsuTextFlowContainer(s => s.Font = OsuFont.GetFont(size: 12))
{
RelativeSizeAxes = Axes.Both,
Colour = colourProvider.Background6,
AutoSizeAxes = Axes.Both,
// can't use this because osu-web does weird stuff with \\n.
// Text = UsersStrings.ShowDailyChallengeTitle.,
Text = "Daily\nChallenge",
Margin = new MarginPadding { Horizontal = 5f, Bottom = 2f },
},
dailyPlayCount = new OsuSpriteText
new Container
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
UseFullGlyphHeight = false,
Colour = colourProvider.Content2,
Margin = new MarginPadding { Horizontal = 10f, Vertical = 5f },
AutoSizeAxes = Axes.X,
RelativeSizeAxes = Axes.Y,
CornerRadius = 3,
Masking = true,
Children = new Drawable[]
{
new Box
{
RelativeSizeAxes = Axes.Both,
Colour = colourProvider.Background6,
},
dailyPlayCount = new OsuSpriteText
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
UseFullGlyphHeight = false,
Colour = colourProvider.Content2,
Margin = new MarginPadding { Horizontal = 10f, Vertical = 5f },
},
}
},
}
},
}
},
completionMark = new CircularContainer
{
Alpha = 0,
Size = new Vector2(16),
Anchor = Anchor.TopRight,
Origin = Anchor.Centre,
Masking = true,
Children = new Drawable[]
{
new Box
{
RelativeSizeAxes = Axes.Both,
Colour = colours.Lime1,
},
new SpriteIcon
{
Size = new Vector2(8),
Colour = colourProvider.Background6,
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
Icon = FontAwesome.Solid.Check,
}
}
},
};
}

Expand Down Expand Up @@ -114,6 +156,29 @@ private void updateDisplay()
dailyPlayCount.Text = DailyChallengeStatsDisplayStrings.UnitDay(stats.PlayCount.ToLocalisableString("N0"));
dailyPlayCount.Colour = colours.ForRankingTier(DailyChallengeStatsTooltip.TierForPlayCount(stats.PlayCount));

bool playedToday = stats.LastUpdate?.Date == DateTimeOffset.UtcNow.Date;
bool userIsOnOwnProfile = stats.UserID == api.LocalUser.Value.Id;

if (playedToday && userIsOnOwnProfile)
{
if (completionMark.Alpha > 0.8f)
{
completionMark.ScaleTo(1.2f).ScaleTo(1, 800, Easing.OutElastic);
}
else
{
completionMark.FadeIn(500, Easing.OutExpo);
completionMark.ScaleTo(1.6f).ScaleTo(1, 500, Easing.OutExpo);
}

content.BorderColour = colours.Lime1;
}
else
{
completionMark.FadeOut(50);
content.BorderColour = colourProvider.Background4;
}

TooltipContent = new DailyChallengeTooltipData(colourProvider, stats);

Show();
Expand Down
1 change: 0 additions & 1 deletion osu.Game/Overlays/Profile/Header/Components/MainDetails.cs
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,6 @@ private void load()
AutoSizeAxes = Axes.Y,
AutoSizeDuration = 200,
AutoSizeEasing = Easing.OutQuint,
Masking = true,
Direction = FillDirection.Vertical,
Spacing = new Vector2(0, 15),
Children = new Drawable[]
Expand Down
Loading