mirror of
https://github.com/ppy/osu.git
synced 2024-11-11 17:47:29 +08:00
Merge branch 'master' into overlay-ruleset-selector
This commit is contained in:
commit
fae5bf0f18
@ -54,6 +54,6 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="ppy.osu.Game.Resources" Version="2019.1230.0" />
|
<PackageReference Include="ppy.osu.Game.Resources" Version="2019.1230.0" />
|
||||||
<PackageReference Include="ppy.osu.Framework.Android" Version="2020.125.0" />
|
<PackageReference Include="ppy.osu.Framework.Android" Version="2020.131.0" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
||||||
|
@ -7,12 +7,10 @@ using System.Linq;
|
|||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
using osu.Framework.Audio;
|
using osu.Framework.Audio;
|
||||||
using osu.Framework.Graphics;
|
|
||||||
using osu.Framework.IO.Stores;
|
using osu.Framework.IO.Stores;
|
||||||
using osu.Framework.Testing;
|
using osu.Framework.Testing;
|
||||||
using osu.Game.Beatmaps;
|
using osu.Game.Beatmaps;
|
||||||
using osu.Game.Rulesets.Osu.Objects;
|
using osu.Game.Rulesets.Osu.Objects;
|
||||||
using osu.Game.Screens;
|
|
||||||
using osu.Game.Screens.Play;
|
using osu.Game.Screens.Play;
|
||||||
using osu.Game.Skinning;
|
using osu.Game.Skinning;
|
||||||
using osu.Game.Tests.Visual;
|
using osu.Game.Tests.Visual;
|
||||||
@ -21,7 +19,7 @@ using osuTK.Graphics;
|
|||||||
|
|
||||||
namespace osu.Game.Rulesets.Osu.Tests
|
namespace osu.Game.Rulesets.Osu.Tests
|
||||||
{
|
{
|
||||||
public class TestSceneLegacyBeatmapSkin : OsuTestScene
|
public class TestSceneLegacyBeatmapSkin : ScreenTestScene
|
||||||
{
|
{
|
||||||
[Resolved]
|
[Resolved]
|
||||||
private AudioManager audio { get; set; }
|
private AudioManager audio { get; set; }
|
||||||
@ -65,7 +63,8 @@ namespace osu.Game.Rulesets.Osu.Tests
|
|||||||
ExposedPlayer player;
|
ExposedPlayer player;
|
||||||
|
|
||||||
Beatmap.Value = new CustomSkinWorkingBeatmap(audio, beatmapHasColours);
|
Beatmap.Value = new CustomSkinWorkingBeatmap(audio, beatmapHasColours);
|
||||||
Child = new OsuScreenStack(player = new ExposedPlayer(userHasCustomColours)) { RelativeSizeAxes = Axes.Both };
|
|
||||||
|
LoadScreen(player = new ExposedPlayer(userHasCustomColours));
|
||||||
|
|
||||||
return player;
|
return player;
|
||||||
}
|
}
|
||||||
|
@ -44,6 +44,7 @@ namespace osu.Game.Rulesets.Osu.Tests
|
|||||||
private const double time_during_slide_2 = 3000;
|
private const double time_during_slide_2 = 3000;
|
||||||
private const double time_during_slide_3 = 3500;
|
private const double time_during_slide_3 = 3500;
|
||||||
private const double time_during_slide_4 = 3800;
|
private const double time_during_slide_4 = 3800;
|
||||||
|
private const double time_slider_end = 4000;
|
||||||
|
|
||||||
private List<JudgementResult> judgementResults;
|
private List<JudgementResult> judgementResults;
|
||||||
private bool allJudgedFired;
|
private bool allJudgedFired;
|
||||||
@ -284,6 +285,48 @@ namespace osu.Game.Rulesets.Osu.Tests
|
|||||||
AddAssert("Tracking acquired", assertMidSliderJudgements);
|
AddAssert("Tracking acquired", assertMidSliderJudgements);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Scenario:
|
||||||
|
/// - Press a key on the slider head
|
||||||
|
/// - While holding the key, move cursor close to the edge of tracking area
|
||||||
|
/// - Keep the cursor on the edge of tracking area until the slider ends
|
||||||
|
/// Expected Result:
|
||||||
|
/// A passing test case will have the slider track the cursor throughout the whole test.
|
||||||
|
/// </summary>
|
||||||
|
[Test]
|
||||||
|
public void TestTrackingAreaEdge()
|
||||||
|
{
|
||||||
|
performTest(new List<ReplayFrame>
|
||||||
|
{
|
||||||
|
new OsuReplayFrame { Position = new Vector2(0, 0), Actions = { OsuAction.LeftButton }, Time = time_slider_start },
|
||||||
|
new OsuReplayFrame { Position = new Vector2(0, OsuHitObject.OBJECT_RADIUS * 1.19f), Actions = { OsuAction.LeftButton }, Time = time_slider_start + 100 },
|
||||||
|
new OsuReplayFrame { Position = new Vector2(slider_path_length, OsuHitObject.OBJECT_RADIUS * 1.199f), Actions = { OsuAction.LeftButton }, Time = time_slider_end },
|
||||||
|
});
|
||||||
|
|
||||||
|
AddAssert("Tracking kept", assertGreatJudge);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Scenario:
|
||||||
|
/// - Press a key on the slider head
|
||||||
|
/// - While holding the key, move cursor just outside the tracking area
|
||||||
|
/// - Keep the cursor just outside the tracking area until the slider ends
|
||||||
|
/// Expected Result:
|
||||||
|
/// A passing test case will have the slider drop the tracking on frame 2.
|
||||||
|
/// </summary>
|
||||||
|
[Test]
|
||||||
|
public void TestTrackingAreaOutsideEdge()
|
||||||
|
{
|
||||||
|
performTest(new List<ReplayFrame>
|
||||||
|
{
|
||||||
|
new OsuReplayFrame { Position = new Vector2(0, 0), Actions = { OsuAction.LeftButton }, Time = time_slider_start },
|
||||||
|
new OsuReplayFrame { Position = new Vector2(0, OsuHitObject.OBJECT_RADIUS * 1.21f), Actions = { OsuAction.LeftButton }, Time = time_slider_start + 100 },
|
||||||
|
new OsuReplayFrame { Position = new Vector2(slider_path_length, OsuHitObject.OBJECT_RADIUS * 1.201f), Actions = { OsuAction.LeftButton }, Time = time_slider_end },
|
||||||
|
});
|
||||||
|
|
||||||
|
AddAssert("Tracking dropped", assertMidSliderJudgementFail);
|
||||||
|
}
|
||||||
|
|
||||||
private bool assertGreatJudge() => judgementResults.Last().Type == HitResult.Great;
|
private bool assertGreatJudge() => judgementResults.Last().Type == HitResult.Great;
|
||||||
|
|
||||||
private bool assertHeadMissTailTracked() => judgementResults[^2].Type == HitResult.Great && judgementResults.First().Type == HitResult.Miss;
|
private bool assertHeadMissTailTracked() => judgementResults[^2].Type == HitResult.Great && judgementResults.First().Type == HitResult.Miss;
|
||||||
@ -294,6 +337,8 @@ namespace osu.Game.Rulesets.Osu.Tests
|
|||||||
|
|
||||||
private ScoreAccessibleReplayPlayer currentPlayer;
|
private ScoreAccessibleReplayPlayer currentPlayer;
|
||||||
|
|
||||||
|
private const float slider_path_length = 25;
|
||||||
|
|
||||||
private void performTest(List<ReplayFrame> frames)
|
private void performTest(List<ReplayFrame> frames)
|
||||||
{
|
{
|
||||||
AddStep("load player", () =>
|
AddStep("load player", () =>
|
||||||
@ -309,8 +354,8 @@ namespace osu.Game.Rulesets.Osu.Tests
|
|||||||
Path = new SliderPath(PathType.PerfectCurve, new[]
|
Path = new SliderPath(PathType.PerfectCurve, new[]
|
||||||
{
|
{
|
||||||
Vector2.Zero,
|
Vector2.Zero,
|
||||||
new Vector2(25, 0),
|
new Vector2(slider_path_length, 0),
|
||||||
}, 25),
|
}, slider_path_length),
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
BeatmapInfo =
|
BeatmapInfo =
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
<PackageReference Include="Appveyor.TestLogger" Version="2.0.0" />
|
<PackageReference Include="Appveyor.TestLogger" Version="2.0.0" />
|
||||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.4.0" />
|
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.4.0" />
|
||||||
<PackageReference Include="NUnit" Version="3.12.0" />
|
<PackageReference Include="NUnit" Version="3.12.0" />
|
||||||
<PackageReference Include="NUnit3TestAdapter" Version="3.16.0" />
|
<PackageReference Include="NUnit3TestAdapter" Version="3.15.1" />
|
||||||
<PackageReference Update="Microsoft.EntityFrameworkCore.Sqlite" Version="2.1.4" />
|
<PackageReference Update="Microsoft.EntityFrameworkCore.Sqlite" Version="2.1.4" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<PropertyGroup Label="Project">
|
<PropertyGroup Label="Project">
|
||||||
|
@ -23,7 +23,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Connections
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// The start time of <see cref="Start"/>.
|
/// The start time of <see cref="Start"/>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public readonly Bindable<double> StartTime = new Bindable<double>();
|
public readonly Bindable<double> StartTime = new BindableDouble();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The <see cref="DrawableOsuHitObject"/> which <see cref="FollowPoint"/>s will exit from.
|
/// The <see cref="DrawableOsuHitObject"/> which <see cref="FollowPoint"/>s will exit from.
|
||||||
|
@ -22,7 +22,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
|
|||||||
|
|
||||||
private readonly IBindable<Vector2> positionBindable = new Bindable<Vector2>();
|
private readonly IBindable<Vector2> positionBindable = new Bindable<Vector2>();
|
||||||
private readonly IBindable<int> stackHeightBindable = new Bindable<int>();
|
private readonly IBindable<int> stackHeightBindable = new Bindable<int>();
|
||||||
private readonly IBindable<float> scaleBindable = new Bindable<float>();
|
private readonly IBindable<float> scaleBindable = new BindableFloat();
|
||||||
|
|
||||||
public OsuAction? HitAction => HitArea.HitAction;
|
public OsuAction? HitAction => HitArea.HitAction;
|
||||||
|
|
||||||
|
@ -37,7 +37,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
|
|||||||
InternalChild = scaleContainer = new ReverseArrowPiece();
|
InternalChild = scaleContainer = new ReverseArrowPiece();
|
||||||
}
|
}
|
||||||
|
|
||||||
private readonly IBindable<float> scaleBindable = new Bindable<float>();
|
private readonly IBindable<float> scaleBindable = new BindableFloat();
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader]
|
||||||
private void load()
|
private void load()
|
||||||
|
@ -37,7 +37,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
|
|||||||
|
|
||||||
private readonly IBindable<Vector2> positionBindable = new Bindable<Vector2>();
|
private readonly IBindable<Vector2> positionBindable = new Bindable<Vector2>();
|
||||||
private readonly IBindable<int> stackHeightBindable = new Bindable<int>();
|
private readonly IBindable<int> stackHeightBindable = new Bindable<int>();
|
||||||
private readonly IBindable<float> scaleBindable = new Bindable<float>();
|
private readonly IBindable<float> scaleBindable = new BindableFloat();
|
||||||
|
|
||||||
public DrawableSlider(Slider s)
|
public DrawableSlider(Slider s)
|
||||||
: base(s)
|
: base(s)
|
||||||
|
@ -52,7 +52,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
private readonly IBindable<float> scaleBindable = new Bindable<float>();
|
private readonly IBindable<float> scaleBindable = new BindableFloat();
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader]
|
||||||
private void load()
|
private void load()
|
||||||
|
@ -23,7 +23,8 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces
|
|||||||
public Func<OsuAction?> GetInitialHitAction;
|
public Func<OsuAction?> GetInitialHitAction;
|
||||||
|
|
||||||
private readonly Slider slider;
|
private readonly Slider slider;
|
||||||
public readonly Drawable FollowCircle;
|
private readonly Drawable followCircle;
|
||||||
|
private readonly Drawable trackingArea;
|
||||||
private readonly DrawableSlider drawableSlider;
|
private readonly DrawableSlider drawableSlider;
|
||||||
|
|
||||||
public SliderBall(Slider slider, DrawableSlider drawableSlider = null)
|
public SliderBall(Slider slider, DrawableSlider drawableSlider = null)
|
||||||
@ -38,7 +39,14 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces
|
|||||||
|
|
||||||
Children = new[]
|
Children = new[]
|
||||||
{
|
{
|
||||||
FollowCircle = new FollowCircleContainer
|
// This is separate from the visible followcircle to ensure consistent internal tracking area (needed to match osu-stable)
|
||||||
|
trackingArea = new CircularContainer
|
||||||
|
{
|
||||||
|
Origin = Anchor.Centre,
|
||||||
|
Anchor = Anchor.Centre,
|
||||||
|
RelativeSizeAxes = Axes.Both
|
||||||
|
},
|
||||||
|
followCircle = new FollowCircleContainer
|
||||||
{
|
{
|
||||||
Origin = Anchor.Centre,
|
Origin = Anchor.Centre,
|
||||||
Anchor = Anchor.Centre,
|
Anchor = Anchor.Centre,
|
||||||
@ -95,8 +103,10 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces
|
|||||||
|
|
||||||
tracking = value;
|
tracking = value;
|
||||||
|
|
||||||
FollowCircle.ScaleTo(tracking ? 2f : 1, 300, Easing.OutQuint);
|
// Tracking area is bigger than the visible followcircle and scales instantly to match osu-stable
|
||||||
FollowCircle.FadeTo(tracking ? 1f : 0, 300, Easing.OutQuint);
|
trackingArea.ScaleTo(tracking ? 2.4f : 1f);
|
||||||
|
followCircle.ScaleTo(tracking ? 2f : 1f, 300, Easing.OutQuint);
|
||||||
|
followCircle.FadeTo(tracking ? 1f : 0, 300, Easing.OutQuint);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -149,7 +159,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces
|
|||||||
// in valid time range
|
// in valid time range
|
||||||
Time.Current >= slider.StartTime && Time.Current < slider.EndTime &&
|
Time.Current >= slider.StartTime && Time.Current < slider.EndTime &&
|
||||||
// in valid position range
|
// in valid position range
|
||||||
lastScreenSpaceMousePosition.HasValue && FollowCircle.ReceivePositionalInputAt(lastScreenSpaceMousePosition.Value) &&
|
lastScreenSpaceMousePosition.HasValue && trackingArea.ReceivePositionalInputAt(lastScreenSpaceMousePosition.Value) &&
|
||||||
// valid action
|
// valid action
|
||||||
(actions?.Any(isValidTrackingAction) ?? false);
|
(actions?.Any(isValidTrackingAction) ?? false);
|
||||||
}
|
}
|
||||||
|
@ -57,7 +57,7 @@ namespace osu.Game.Rulesets.Osu.Objects
|
|||||||
|
|
||||||
public double Radius => OBJECT_RADIUS * Scale;
|
public double Radius => OBJECT_RADIUS * Scale;
|
||||||
|
|
||||||
public readonly Bindable<float> ScaleBindable = new Bindable<float>(1);
|
public readonly Bindable<float> ScaleBindable = new BindableFloat(1);
|
||||||
|
|
||||||
public float Scale
|
public float Scale
|
||||||
{
|
{
|
||||||
|
@ -57,7 +57,7 @@ namespace osu.Game.Rulesets.Osu.UI.Cursor
|
|||||||
autoCursorScale = config.GetBindable<bool>(OsuSetting.AutoCursorSize);
|
autoCursorScale = config.GetBindable<bool>(OsuSetting.AutoCursorSize);
|
||||||
autoCursorScale.ValueChanged += _ => calculateScale();
|
autoCursorScale.ValueChanged += _ => calculateScale();
|
||||||
|
|
||||||
CursorScale = new Bindable<float>();
|
CursorScale = new BindableFloat();
|
||||||
CursorScale.ValueChanged += e => ActiveCursor.Scale = cursorTrail.Scale = new Vector2(e.NewValue);
|
CursorScale.ValueChanged += e => ActiveCursor.Scale = cursorTrail.Scale = new Vector2(e.NewValue);
|
||||||
|
|
||||||
calculateScale();
|
calculateScale();
|
||||||
|
@ -50,7 +50,7 @@ namespace osu.Game.Rulesets.Osu.UI
|
|||||||
{
|
{
|
||||||
Add(localCursorContainer = new OsuCursorContainer());
|
Add(localCursorContainer = new OsuCursorContainer());
|
||||||
|
|
||||||
localCursorScale = new Bindable<float>();
|
localCursorScale = new BindableFloat();
|
||||||
localCursorScale.BindTo(localCursorContainer.CursorScale);
|
localCursorScale.BindTo(localCursorContainer.CursorScale);
|
||||||
localCursorScale.BindValueChanged(scale => cursorScaleContainer.Scale = new Vector2(scale.NewValue), true);
|
localCursorScale.BindValueChanged(scale => cursorScaleContainer.Scale = new Vector2(scale.NewValue), true);
|
||||||
}
|
}
|
||||||
|
@ -302,8 +302,8 @@ namespace osu.Game.Tests.Visual.Background
|
|||||||
}
|
}
|
||||||
|
|
||||||
public readonly Bindable<bool> DimEnabled = new Bindable<bool>();
|
public readonly Bindable<bool> DimEnabled = new Bindable<bool>();
|
||||||
public readonly Bindable<double> DimLevel = new Bindable<double>();
|
public readonly Bindable<double> DimLevel = new BindableDouble();
|
||||||
public readonly Bindable<double> BlurLevel = new Bindable<double>();
|
public readonly Bindable<double> BlurLevel = new BindableDouble();
|
||||||
|
|
||||||
public new BeatmapCarousel Carousel => base.Carousel;
|
public new BeatmapCarousel Carousel => base.Carousel;
|
||||||
|
|
||||||
|
@ -2,30 +2,52 @@
|
|||||||
// See the LICENCE file in the repository root for full licence text.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using NUnit.Framework;
|
||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
using osu.Framework.Screens;
|
using osu.Framework.Screens;
|
||||||
using osu.Game.Configuration;
|
using osu.Game.Configuration;
|
||||||
using osu.Game.Rulesets;
|
using osu.Game.Rulesets;
|
||||||
|
using osu.Game.Rulesets.Catch;
|
||||||
|
using osu.Game.Rulesets.Mania;
|
||||||
using osu.Game.Rulesets.Mods;
|
using osu.Game.Rulesets.Mods;
|
||||||
|
using osu.Game.Rulesets.Osu;
|
||||||
|
using osu.Game.Rulesets.Taiko;
|
||||||
using osu.Game.Screens.Play;
|
using osu.Game.Screens.Play;
|
||||||
|
|
||||||
namespace osu.Game.Tests.Visual
|
namespace osu.Game.Tests.Visual.Gameplay
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// A base class which runs <see cref="Player"/> test for all available rulesets.
|
/// A base class which runs <see cref="Player"/> test for all available rulesets.
|
||||||
/// Steps to be run for each ruleset should be added via <see cref="AddCheckSteps"/>.
|
/// Steps to be run for each ruleset should be added via <see cref="AddCheckSteps"/>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public abstract class AllPlayersTestScene : RateAdjustedBeatmapTestScene
|
public abstract class TestSceneAllRulesetPlayers : RateAdjustedBeatmapTestScene
|
||||||
{
|
{
|
||||||
protected Player Player;
|
protected Player Player;
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader]
|
||||||
private void load(RulesetStore rulesets)
|
private void load(RulesetStore rulesets)
|
||||||
{
|
{
|
||||||
foreach (var r in rulesets.AvailableRulesets)
|
OsuConfigManager manager;
|
||||||
|
Dependencies.Cache(manager = new OsuConfigManager(LocalStorage));
|
||||||
|
manager.GetBindable<double>(OsuSetting.DimLevel).Value = 1.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestOsu() => runForRuleset(new OsuRuleset().RulesetInfo);
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestTaiko() => runForRuleset(new TaikoRuleset().RulesetInfo);
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestCatch() => runForRuleset(new CatchRuleset().RulesetInfo);
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestMania() => runForRuleset(new ManiaRuleset().RulesetInfo);
|
||||||
|
|
||||||
|
private void runForRuleset(RulesetInfo ruleset)
|
||||||
{
|
{
|
||||||
Player p = null;
|
Player p = null;
|
||||||
AddStep(r.Name, () => p = loadPlayerFor(r));
|
AddStep($"load {ruleset.Name} player", () => p = loadPlayerFor(ruleset));
|
||||||
AddUntilStep("player loaded", () =>
|
AddUntilStep("player loaded", () =>
|
||||||
{
|
{
|
||||||
if (p?.IsLoaded == true)
|
if (p?.IsLoaded == true)
|
||||||
@ -40,11 +62,6 @@ namespace osu.Game.Tests.Visual
|
|||||||
AddCheckSteps();
|
AddCheckSteps();
|
||||||
}
|
}
|
||||||
|
|
||||||
OsuConfigManager manager;
|
|
||||||
Dependencies.Cache(manager = new OsuConfigManager(LocalStorage));
|
|
||||||
manager.GetBindable<double>(OsuSetting.DimLevel).Value = 1.0;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected abstract void AddCheckSteps();
|
protected abstract void AddCheckSteps();
|
||||||
|
|
||||||
private Player loadPlayerFor(RulesetInfo rulesetInfo)
|
private Player loadPlayerFor(RulesetInfo rulesetInfo)
|
@ -12,7 +12,7 @@ using osu.Game.Storyboards;
|
|||||||
namespace osu.Game.Tests.Visual.Gameplay
|
namespace osu.Game.Tests.Visual.Gameplay
|
||||||
{
|
{
|
||||||
[Description("Player instantiated with an autoplay mod.")]
|
[Description("Player instantiated with an autoplay mod.")]
|
||||||
public class TestSceneAutoplay : AllPlayersTestScene
|
public class TestSceneAutoplay : TestSceneAllRulesetPlayers
|
||||||
{
|
{
|
||||||
private ClockBackedTestWorkingBeatmap.TrackVirtualManual track;
|
private ClockBackedTestWorkingBeatmap.TrackVirtualManual track;
|
||||||
|
|
||||||
|
@ -10,7 +10,7 @@ using osu.Game.Screens.Play;
|
|||||||
|
|
||||||
namespace osu.Game.Tests.Visual.Gameplay
|
namespace osu.Game.Tests.Visual.Gameplay
|
||||||
{
|
{
|
||||||
public class TestSceneFailAnimation : AllPlayersTestScene
|
public class TestSceneFailAnimation : TestSceneAllRulesetPlayers
|
||||||
{
|
{
|
||||||
protected override Player CreatePlayer(Ruleset ruleset)
|
protected override Player CreatePlayer(Ruleset ruleset)
|
||||||
{
|
{
|
||||||
@ -20,7 +20,7 @@ namespace osu.Game.Tests.Visual.Gameplay
|
|||||||
|
|
||||||
public override IReadOnlyList<Type> RequiredTypes => new[]
|
public override IReadOnlyList<Type> RequiredTypes => new[]
|
||||||
{
|
{
|
||||||
typeof(AllPlayersTestScene),
|
typeof(TestSceneAllRulesetPlayers),
|
||||||
typeof(TestPlayer),
|
typeof(TestPlayer),
|
||||||
typeof(Player),
|
typeof(Player),
|
||||||
};
|
};
|
||||||
|
@ -10,7 +10,7 @@ using osu.Game.Screens.Play;
|
|||||||
|
|
||||||
namespace osu.Game.Tests.Visual.Gameplay
|
namespace osu.Game.Tests.Visual.Gameplay
|
||||||
{
|
{
|
||||||
public class TestSceneFailJudgement : AllPlayersTestScene
|
public class TestSceneFailJudgement : TestSceneAllRulesetPlayers
|
||||||
{
|
{
|
||||||
protected override Player CreatePlayer(Ruleset ruleset)
|
protected override Player CreatePlayer(Ruleset ruleset)
|
||||||
{
|
{
|
||||||
|
@ -36,6 +36,7 @@ namespace osu.Game.Tests.Visual.Gameplay
|
|||||||
public override void SetUpSteps()
|
public override void SetUpSteps()
|
||||||
{
|
{
|
||||||
base.SetUpSteps();
|
base.SetUpSteps();
|
||||||
|
|
||||||
AddStep("resume player", () => Player.GameplayClockContainer.Start());
|
AddStep("resume player", () => Player.GameplayClockContainer.Start());
|
||||||
confirmClockRunning(true);
|
confirmClockRunning(true);
|
||||||
}
|
}
|
||||||
|
@ -10,7 +10,7 @@ using osu.Game.Storyboards;
|
|||||||
|
|
||||||
namespace osu.Game.Tests.Visual.Gameplay
|
namespace osu.Game.Tests.Visual.Gameplay
|
||||||
{
|
{
|
||||||
public class TestScenePlayerReferenceLeaking : AllPlayersTestScene
|
public class TestScenePlayerReferenceLeaking : TestSceneAllRulesetPlayers
|
||||||
{
|
{
|
||||||
private readonly WeakList<WorkingBeatmap> workingWeakReferences = new WeakList<WorkingBeatmap>();
|
private readonly WeakList<WorkingBeatmap> workingWeakReferences = new WeakList<WorkingBeatmap>();
|
||||||
|
|
||||||
|
@ -13,7 +13,7 @@ using osu.Game.Screens.Play;
|
|||||||
namespace osu.Game.Tests.Visual.Gameplay
|
namespace osu.Game.Tests.Visual.Gameplay
|
||||||
{
|
{
|
||||||
[Description("Player instantiated with a replay.")]
|
[Description("Player instantiated with a replay.")]
|
||||||
public class TestSceneReplay : AllPlayersTestScene
|
public class TestSceneReplay : TestSceneAllRulesetPlayers
|
||||||
{
|
{
|
||||||
protected override Player CreatePlayer(Ruleset ruleset)
|
protected override Player CreatePlayer(Ruleset ruleset)
|
||||||
{
|
{
|
||||||
|
@ -3,12 +3,15 @@
|
|||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
using osu.Framework.Bindables;
|
using osu.Framework.Bindables;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Graphics.Containers;
|
using osu.Framework.Graphics.Containers;
|
||||||
using osu.Framework.Graphics.UserInterface;
|
using osu.Framework.Graphics.UserInterface;
|
||||||
|
using osu.Framework.Testing;
|
||||||
|
using osu.Game.Graphics.UserInterface;
|
||||||
using osu.Game.Online.Chat;
|
using osu.Game.Online.Chat;
|
||||||
using osu.Game.Overlays;
|
using osu.Game.Overlays;
|
||||||
using osu.Game.Overlays.Chat;
|
using osu.Game.Overlays.Chat;
|
||||||
@ -35,8 +38,21 @@ namespace osu.Game.Tests.Visual.Online
|
|||||||
private TestChatOverlay chatOverlay;
|
private TestChatOverlay chatOverlay;
|
||||||
private ChannelManager channelManager;
|
private ChannelManager channelManager;
|
||||||
|
|
||||||
private readonly Channel channel1 = new Channel(new User()) { Name = "test really long username" };
|
private readonly List<Channel> channels;
|
||||||
private readonly Channel channel2 = new Channel(new User()) { Name = "test2" };
|
|
||||||
|
private Channel channel1 => channels[0];
|
||||||
|
private Channel channel2 => channels[1];
|
||||||
|
|
||||||
|
public TestSceneChatOverlay()
|
||||||
|
{
|
||||||
|
channels = Enumerable.Range(1, 10)
|
||||||
|
.Select(index => new Channel(new User())
|
||||||
|
{
|
||||||
|
Name = $"Channel no. {index}",
|
||||||
|
Topic = index == 3 ? null : $"We talk about the number {index} here"
|
||||||
|
})
|
||||||
|
.ToList();
|
||||||
|
}
|
||||||
|
|
||||||
[SetUp]
|
[SetUp]
|
||||||
public void Setup()
|
public void Setup()
|
||||||
@ -45,7 +61,7 @@ namespace osu.Game.Tests.Visual.Online
|
|||||||
{
|
{
|
||||||
ChannelManagerContainer container;
|
ChannelManagerContainer container;
|
||||||
|
|
||||||
Child = container = new ChannelManagerContainer(new List<Channel> { channel1, channel2 })
|
Child = container = new ChannelManagerContainer(channels)
|
||||||
{
|
{
|
||||||
RelativeSizeAxes = Axes.Both,
|
RelativeSizeAxes = Axes.Both,
|
||||||
};
|
};
|
||||||
@ -96,6 +112,47 @@ namespace osu.Game.Tests.Visual.Online
|
|||||||
AddAssert("Selector is visible", () => chatOverlay.SelectionOverlayState == Visibility.Visible);
|
AddAssert("Selector is visible", () => chatOverlay.SelectionOverlayState == Visibility.Visible);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestSearchInSelector()
|
||||||
|
{
|
||||||
|
AddStep("search for 'no. 2'", () => chatOverlay.ChildrenOfType<SearchTextBox>().First().Text = "no. 2");
|
||||||
|
AddUntilStep("only channel 2 visible", () =>
|
||||||
|
{
|
||||||
|
var listItems = chatOverlay.ChildrenOfType<ChannelListItem>().Where(c => c.IsPresent);
|
||||||
|
return listItems.Count() == 1 && listItems.Single().Channel == channel2;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestChannelShortcutKeys()
|
||||||
|
{
|
||||||
|
AddStep("join 10 channels", () => channels.ForEach(channel => channelManager.JoinChannel(channel)));
|
||||||
|
AddStep("close channel selector", () =>
|
||||||
|
{
|
||||||
|
InputManager.PressKey(Key.Escape);
|
||||||
|
InputManager.ReleaseKey(Key.Escape);
|
||||||
|
});
|
||||||
|
AddUntilStep("wait for close", () => chatOverlay.SelectionOverlayState == Visibility.Hidden);
|
||||||
|
|
||||||
|
for (int zeroBasedIndex = 0; zeroBasedIndex < 10; ++zeroBasedIndex)
|
||||||
|
{
|
||||||
|
var oneBasedIndex = zeroBasedIndex + 1;
|
||||||
|
var targetNumberKey = oneBasedIndex % 10;
|
||||||
|
var targetChannel = channels[zeroBasedIndex];
|
||||||
|
AddStep($"press Alt+{targetNumberKey}", () => pressChannelHotkey(targetNumberKey));
|
||||||
|
AddAssert($"channel #{oneBasedIndex} is selected", () => channelManager.CurrentChannel.Value == targetChannel);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void pressChannelHotkey(int number)
|
||||||
|
{
|
||||||
|
var channelKey = Key.Number0 + number;
|
||||||
|
InputManager.PressKey(Key.AltLeft);
|
||||||
|
InputManager.PressKey(channelKey);
|
||||||
|
InputManager.ReleaseKey(Key.AltLeft);
|
||||||
|
InputManager.ReleaseKey(channelKey);
|
||||||
|
}
|
||||||
|
|
||||||
private void clickDrawable(Drawable d)
|
private void clickDrawable(Drawable d)
|
||||||
{
|
{
|
||||||
InputManager.MoveMouseTo(d);
|
InputManager.MoveMouseTo(d);
|
||||||
|
@ -25,7 +25,8 @@ namespace osu.Game.Tests.Visual.Online
|
|||||||
typeof(SortTabControl),
|
typeof(SortTabControl),
|
||||||
typeof(ShowChildrenButton),
|
typeof(ShowChildrenButton),
|
||||||
typeof(DeletedCommentsCounter),
|
typeof(DeletedCommentsCounter),
|
||||||
typeof(VotePill)
|
typeof(VotePill),
|
||||||
|
typeof(CommentsPage),
|
||||||
};
|
};
|
||||||
|
|
||||||
protected override bool UseOnlineAPI => true;
|
protected override bool UseOnlineAPI => true;
|
||||||
|
162
osu.Game.Tests/Visual/Online/TestSceneCommentsPage.cs
Normal file
162
osu.Game.Tests/Visual/Online/TestSceneCommentsPage.cs
Normal file
@ -0,0 +1,162 @@
|
|||||||
|
// 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 osu.Game.Overlays.Comments;
|
||||||
|
using osu.Game.Overlays;
|
||||||
|
using osu.Framework.Allocation;
|
||||||
|
using osu.Game.Online.API.Requests.Responses;
|
||||||
|
using osu.Game.Users;
|
||||||
|
using osu.Game.Graphics.UserInterface;
|
||||||
|
using osu.Framework.Bindables;
|
||||||
|
using osu.Framework.Graphics.Containers;
|
||||||
|
using osu.Framework.Graphics;
|
||||||
|
using osuTK;
|
||||||
|
|
||||||
|
namespace osu.Game.Tests.Visual.Online
|
||||||
|
{
|
||||||
|
public class TestSceneCommentsPage : OsuTestScene
|
||||||
|
{
|
||||||
|
public override IReadOnlyList<Type> RequiredTypes => new[]
|
||||||
|
{
|
||||||
|
typeof(DrawableComment),
|
||||||
|
typeof(CommentsPage),
|
||||||
|
};
|
||||||
|
|
||||||
|
[Cached]
|
||||||
|
private readonly OverlayColourProvider colourProvider = new OverlayColourProvider(OverlayColourScheme.Purple);
|
||||||
|
|
||||||
|
private readonly BindableBool showDeleted = new BindableBool();
|
||||||
|
private readonly Container content;
|
||||||
|
|
||||||
|
public TestSceneCommentsPage()
|
||||||
|
{
|
||||||
|
Add(new FillFlowContainer
|
||||||
|
{
|
||||||
|
AutoSizeAxes = Axes.Y,
|
||||||
|
RelativeSizeAxes = Axes.X,
|
||||||
|
Direction = FillDirection.Vertical,
|
||||||
|
Spacing = new Vector2(0, 10),
|
||||||
|
Children = new Drawable[]
|
||||||
|
{
|
||||||
|
new Container
|
||||||
|
{
|
||||||
|
AutoSizeAxes = Axes.Y,
|
||||||
|
Width = 200,
|
||||||
|
Child = new OsuCheckbox
|
||||||
|
{
|
||||||
|
Current = showDeleted,
|
||||||
|
LabelText = @"Show Deleted"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
content = new Container
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.X,
|
||||||
|
AutoSizeAxes = Axes.Y,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
AddStep("load comments", () => createPage(comment_bundle));
|
||||||
|
AddStep("load empty comments", () => createPage(empty_comment_bundle));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void createPage(CommentBundle commentBundle)
|
||||||
|
{
|
||||||
|
content.Clear();
|
||||||
|
content.Add(new CommentsPage(commentBundle)
|
||||||
|
{
|
||||||
|
ShowDeleted = { BindTarget = showDeleted }
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private static readonly CommentBundle empty_comment_bundle = new CommentBundle
|
||||||
|
{
|
||||||
|
Comments = new List<Comment>(),
|
||||||
|
Total = 0,
|
||||||
|
};
|
||||||
|
|
||||||
|
private static readonly CommentBundle comment_bundle = new CommentBundle
|
||||||
|
{
|
||||||
|
Comments = new List<Comment>
|
||||||
|
{
|
||||||
|
new Comment
|
||||||
|
{
|
||||||
|
Id = 1,
|
||||||
|
Message = "Simple test comment",
|
||||||
|
LegacyName = "TestUser1",
|
||||||
|
CreatedAt = DateTimeOffset.Now,
|
||||||
|
VotesCount = 5
|
||||||
|
},
|
||||||
|
new Comment
|
||||||
|
{
|
||||||
|
Id = 2,
|
||||||
|
Message = "This comment has been deleted :( but visible for admins",
|
||||||
|
LegacyName = "TestUser2",
|
||||||
|
CreatedAt = DateTimeOffset.Now,
|
||||||
|
DeletedAt = DateTimeOffset.Now,
|
||||||
|
VotesCount = 5
|
||||||
|
},
|
||||||
|
new Comment
|
||||||
|
{
|
||||||
|
Id = 3,
|
||||||
|
Message = "This comment is a top level",
|
||||||
|
LegacyName = "TestUser3",
|
||||||
|
CreatedAt = DateTimeOffset.Now,
|
||||||
|
RepliesCount = 2,
|
||||||
|
},
|
||||||
|
new Comment
|
||||||
|
{
|
||||||
|
Id = 4,
|
||||||
|
ParentId = 3,
|
||||||
|
Message = "And this is a reply",
|
||||||
|
RepliesCount = 1,
|
||||||
|
LegacyName = "TestUser1",
|
||||||
|
CreatedAt = DateTimeOffset.Now,
|
||||||
|
},
|
||||||
|
new Comment
|
||||||
|
{
|
||||||
|
Id = 15,
|
||||||
|
ParentId = 4,
|
||||||
|
Message = "Reply to reply",
|
||||||
|
LegacyName = "TestUser1",
|
||||||
|
CreatedAt = DateTimeOffset.Now,
|
||||||
|
},
|
||||||
|
new Comment
|
||||||
|
{
|
||||||
|
Id = 6,
|
||||||
|
ParentId = 3,
|
||||||
|
LegacyName = "TestUser11515",
|
||||||
|
CreatedAt = DateTimeOffset.Now,
|
||||||
|
DeletedAt = DateTimeOffset.Now,
|
||||||
|
},
|
||||||
|
new Comment
|
||||||
|
{
|
||||||
|
Id = 5,
|
||||||
|
Message = "This comment is voted and edited",
|
||||||
|
LegacyName = "BigBrainUser",
|
||||||
|
CreatedAt = DateTimeOffset.Now,
|
||||||
|
EditedAt = DateTimeOffset.Now,
|
||||||
|
VotesCount = 1000,
|
||||||
|
EditedById = 1,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
IncludedComments = new List<Comment>(),
|
||||||
|
UserVotes = new List<long>
|
||||||
|
{
|
||||||
|
5
|
||||||
|
},
|
||||||
|
Users = new List<User>
|
||||||
|
{
|
||||||
|
new User
|
||||||
|
{
|
||||||
|
Id = 1,
|
||||||
|
Username = "Good_Admin"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
TopLevelCount = 4,
|
||||||
|
Total = 7
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
@ -26,7 +26,6 @@ namespace osu.Game.Tests.Visual.Online
|
|||||||
typeof(HistoricalSection),
|
typeof(HistoricalSection),
|
||||||
typeof(PaginatedMostPlayedBeatmapContainer),
|
typeof(PaginatedMostPlayedBeatmapContainer),
|
||||||
typeof(DrawableMostPlayedBeatmap),
|
typeof(DrawableMostPlayedBeatmap),
|
||||||
typeof(DrawableProfileRow)
|
|
||||||
};
|
};
|
||||||
|
|
||||||
[Cached]
|
[Cached]
|
||||||
|
@ -4,11 +4,13 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
|
using osu.Framework.Allocation;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Graphics.Containers;
|
using osu.Framework.Graphics.Containers;
|
||||||
using osu.Framework.Graphics.Shapes;
|
using osu.Framework.Graphics.Shapes;
|
||||||
using osu.Game.Graphics;
|
using osu.Game.Graphics;
|
||||||
using osu.Game.Graphics.UserInterface;
|
using osu.Game.Graphics.UserInterface;
|
||||||
|
using osu.Game.Overlays;
|
||||||
using osu.Game.Overlays.Profile.Header.Components;
|
using osu.Game.Overlays.Profile.Header.Components;
|
||||||
using osu.Game.Users;
|
using osu.Game.Users;
|
||||||
using osuTK;
|
using osuTK;
|
||||||
@ -24,6 +26,9 @@ namespace osu.Game.Tests.Visual.Online
|
|||||||
typeof(LineGraph)
|
typeof(LineGraph)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
[Cached]
|
||||||
|
private readonly OverlayColourProvider colourProvider = new OverlayColourProvider(OverlayColourScheme.Pink);
|
||||||
|
|
||||||
public TestSceneRankGraph()
|
public TestSceneRankGraph()
|
||||||
{
|
{
|
||||||
RankGraph graph;
|
RankGraph graph;
|
||||||
|
@ -5,6 +5,7 @@ using System;
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
|
using osu.Framework.Allocation;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Graphics.Containers;
|
using osu.Framework.Graphics.Containers;
|
||||||
using osu.Framework.Graphics.Shapes;
|
using osu.Framework.Graphics.Shapes;
|
||||||
@ -12,6 +13,7 @@ using osu.Game.Graphics;
|
|||||||
using osu.Game.Graphics.Containers;
|
using osu.Game.Graphics.Containers;
|
||||||
using osu.Game.Online.API.Requests;
|
using osu.Game.Online.API.Requests;
|
||||||
using osu.Game.Online.API.Requests.Responses;
|
using osu.Game.Online.API.Requests.Responses;
|
||||||
|
using osu.Game.Overlays;
|
||||||
using osu.Game.Overlays.Profile.Sections;
|
using osu.Game.Overlays.Profile.Sections;
|
||||||
using osu.Game.Overlays.Profile.Sections.Recent;
|
using osu.Game.Overlays.Profile.Sections.Recent;
|
||||||
|
|
||||||
@ -28,6 +30,9 @@ namespace osu.Game.Tests.Visual.Online
|
|||||||
typeof(MedalIcon)
|
typeof(MedalIcon)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
[Cached]
|
||||||
|
private readonly OverlayColourProvider colourProvider = new OverlayColourProvider(OverlayColourScheme.Green);
|
||||||
|
|
||||||
public TestSceneUserProfileRecentSection()
|
public TestSceneUserProfileRecentSection()
|
||||||
{
|
{
|
||||||
Children = new Drawable[]
|
Children = new Drawable[]
|
||||||
@ -131,6 +136,22 @@ namespace osu.Game.Tests.Visual.Online
|
|||||||
Beatmap = dummyBeatmap,
|
Beatmap = dummyBeatmap,
|
||||||
},
|
},
|
||||||
new APIRecentActivity
|
new APIRecentActivity
|
||||||
|
{
|
||||||
|
User = dummyUser,
|
||||||
|
Type = RecentActivityType.Rank,
|
||||||
|
Rank = 1,
|
||||||
|
Mode = "vitaru",
|
||||||
|
Beatmap = dummyBeatmap,
|
||||||
|
},
|
||||||
|
new APIRecentActivity
|
||||||
|
{
|
||||||
|
User = dummyUser,
|
||||||
|
Type = RecentActivityType.Rank,
|
||||||
|
Rank = 1,
|
||||||
|
Mode = "fruits",
|
||||||
|
Beatmap = dummyBeatmap,
|
||||||
|
},
|
||||||
|
new APIRecentActivity
|
||||||
{
|
{
|
||||||
User = dummyUser,
|
User = dummyUser,
|
||||||
Type = RecentActivityType.RankLost,
|
Type = RecentActivityType.RankLost,
|
||||||
|
175
osu.Game.Tests/Visual/SongSelect/TestSceneAdvancedStats.cs
Normal file
175
osu.Game.Tests/Visual/SongSelect/TestSceneAdvancedStats.cs
Normal file
@ -0,0 +1,175 @@
|
|||||||
|
// 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 NUnit.Framework;
|
||||||
|
using osu.Framework.Allocation;
|
||||||
|
using osu.Framework.Graphics.Sprites;
|
||||||
|
using osu.Framework.Testing;
|
||||||
|
using osu.Game.Beatmaps;
|
||||||
|
using osu.Game.Graphics;
|
||||||
|
using osu.Game.Rulesets;
|
||||||
|
using osu.Game.Rulesets.Mods;
|
||||||
|
using osu.Game.Screens.Select.Details;
|
||||||
|
using osuTK.Graphics;
|
||||||
|
|
||||||
|
namespace osu.Game.Tests.Visual.SongSelect
|
||||||
|
{
|
||||||
|
[System.ComponentModel.Description("Advanced beatmap statistics display")]
|
||||||
|
public class TestSceneAdvancedStats : OsuTestScene
|
||||||
|
{
|
||||||
|
private TestAdvancedStats advancedStats;
|
||||||
|
|
||||||
|
[Resolved]
|
||||||
|
private RulesetStore rulesets { get; set; }
|
||||||
|
|
||||||
|
[Resolved]
|
||||||
|
private OsuColour colours { get; set; }
|
||||||
|
|
||||||
|
[SetUp]
|
||||||
|
public void Setup() => Schedule(() => Child = advancedStats = new TestAdvancedStats
|
||||||
|
{
|
||||||
|
Width = 500
|
||||||
|
});
|
||||||
|
|
||||||
|
private BeatmapInfo exampleBeatmapInfo => new BeatmapInfo
|
||||||
|
{
|
||||||
|
RulesetID = 0,
|
||||||
|
Ruleset = rulesets.AvailableRulesets.First(),
|
||||||
|
BaseDifficulty = new BeatmapDifficulty
|
||||||
|
{
|
||||||
|
CircleSize = 7.2f,
|
||||||
|
DrainRate = 3,
|
||||||
|
OverallDifficulty = 5.7f,
|
||||||
|
ApproachRate = 3.5f
|
||||||
|
},
|
||||||
|
StarDifficulty = 4.5f
|
||||||
|
};
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestNoMod()
|
||||||
|
{
|
||||||
|
AddStep("set beatmap", () => advancedStats.Beatmap = exampleBeatmapInfo);
|
||||||
|
|
||||||
|
AddStep("no mods selected", () => SelectedMods.Value = Array.Empty<Mod>());
|
||||||
|
|
||||||
|
AddAssert("first bar text is Circle Size", () => advancedStats.ChildrenOfType<SpriteText>().First().Text == "Circle Size");
|
||||||
|
AddAssert("circle size bar is white", () => barIsWhite(advancedStats.FirstValue));
|
||||||
|
AddAssert("HP drain bar is white", () => barIsWhite(advancedStats.HpDrain));
|
||||||
|
AddAssert("accuracy bar is white", () => barIsWhite(advancedStats.Accuracy));
|
||||||
|
AddAssert("approach rate bar is white", () => barIsWhite(advancedStats.ApproachRate));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestManiaFirstBarText()
|
||||||
|
{
|
||||||
|
AddStep("set beatmap", () => advancedStats.Beatmap = new BeatmapInfo
|
||||||
|
{
|
||||||
|
Ruleset = rulesets.GetRuleset(3),
|
||||||
|
BaseDifficulty = new BeatmapDifficulty
|
||||||
|
{
|
||||||
|
CircleSize = 5,
|
||||||
|
DrainRate = 4.3f,
|
||||||
|
OverallDifficulty = 4.5f,
|
||||||
|
ApproachRate = 3.1f
|
||||||
|
},
|
||||||
|
StarDifficulty = 8
|
||||||
|
});
|
||||||
|
|
||||||
|
AddAssert("first bar text is Key Count", () => advancedStats.ChildrenOfType<SpriteText>().First().Text == "Key Count");
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestEasyMod()
|
||||||
|
{
|
||||||
|
AddStep("set beatmap", () => advancedStats.Beatmap = exampleBeatmapInfo);
|
||||||
|
|
||||||
|
AddStep("select EZ mod", () =>
|
||||||
|
{
|
||||||
|
var ruleset = advancedStats.Beatmap.Ruleset.CreateInstance();
|
||||||
|
SelectedMods.Value = new[] { ruleset.GetAllMods().OfType<ModEasy>().Single() };
|
||||||
|
});
|
||||||
|
|
||||||
|
AddAssert("circle size bar is blue", () => barIsBlue(advancedStats.FirstValue));
|
||||||
|
AddAssert("HP drain bar is blue", () => barIsBlue(advancedStats.HpDrain));
|
||||||
|
AddAssert("accuracy bar is blue", () => barIsBlue(advancedStats.Accuracy));
|
||||||
|
AddAssert("approach rate bar is blue", () => barIsBlue(advancedStats.ApproachRate));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestHardRockMod()
|
||||||
|
{
|
||||||
|
AddStep("set beatmap", () => advancedStats.Beatmap = exampleBeatmapInfo);
|
||||||
|
|
||||||
|
AddStep("select HR mod", () =>
|
||||||
|
{
|
||||||
|
var ruleset = advancedStats.Beatmap.Ruleset.CreateInstance();
|
||||||
|
SelectedMods.Value = new[] { ruleset.GetAllMods().OfType<ModHardRock>().Single() };
|
||||||
|
});
|
||||||
|
|
||||||
|
AddAssert("circle size bar is red", () => barIsRed(advancedStats.FirstValue));
|
||||||
|
AddAssert("HP drain bar is red", () => barIsRed(advancedStats.HpDrain));
|
||||||
|
AddAssert("accuracy bar is red", () => barIsRed(advancedStats.Accuracy));
|
||||||
|
AddAssert("approach rate bar is red", () => barIsRed(advancedStats.ApproachRate));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestUnchangedDifficultyAdjustMod()
|
||||||
|
{
|
||||||
|
AddStep("set beatmap", () => advancedStats.Beatmap = exampleBeatmapInfo);
|
||||||
|
|
||||||
|
AddStep("select unchanged Difficulty Adjust mod", () =>
|
||||||
|
{
|
||||||
|
var ruleset = advancedStats.Beatmap.Ruleset.CreateInstance();
|
||||||
|
var difficultyAdjustMod = ruleset.GetAllMods().OfType<ModDifficultyAdjust>().Single();
|
||||||
|
difficultyAdjustMod.ReadFromDifficulty(advancedStats.Beatmap.BaseDifficulty);
|
||||||
|
SelectedMods.Value = new[] { difficultyAdjustMod };
|
||||||
|
});
|
||||||
|
|
||||||
|
AddAssert("circle size bar is white", () => barIsWhite(advancedStats.FirstValue));
|
||||||
|
AddAssert("HP drain bar is white", () => barIsWhite(advancedStats.HpDrain));
|
||||||
|
AddAssert("accuracy bar is white", () => barIsWhite(advancedStats.Accuracy));
|
||||||
|
AddAssert("approach rate bar is white", () => barIsWhite(advancedStats.ApproachRate));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestChangedDifficultyAdjustMod()
|
||||||
|
{
|
||||||
|
AddStep("set beatmap", () => advancedStats.Beatmap = exampleBeatmapInfo);
|
||||||
|
|
||||||
|
AddStep("select changed Difficulty Adjust mod", () =>
|
||||||
|
{
|
||||||
|
var ruleset = advancedStats.Beatmap.Ruleset.CreateInstance();
|
||||||
|
var difficultyAdjustMod = ruleset.GetAllMods().OfType<ModDifficultyAdjust>().Single();
|
||||||
|
var originalDifficulty = advancedStats.Beatmap.BaseDifficulty;
|
||||||
|
var adjustedDifficulty = new BeatmapDifficulty
|
||||||
|
{
|
||||||
|
CircleSize = originalDifficulty.CircleSize,
|
||||||
|
DrainRate = originalDifficulty.DrainRate - 0.5f,
|
||||||
|
OverallDifficulty = originalDifficulty.OverallDifficulty,
|
||||||
|
ApproachRate = originalDifficulty.ApproachRate + 2.2f,
|
||||||
|
};
|
||||||
|
difficultyAdjustMod.ReadFromDifficulty(adjustedDifficulty);
|
||||||
|
SelectedMods.Value = new[] { difficultyAdjustMod };
|
||||||
|
});
|
||||||
|
|
||||||
|
AddAssert("circle size bar is white", () => barIsWhite(advancedStats.FirstValue));
|
||||||
|
AddAssert("drain rate bar is blue", () => barIsBlue(advancedStats.HpDrain));
|
||||||
|
AddAssert("accuracy bar is white", () => barIsWhite(advancedStats.Accuracy));
|
||||||
|
AddAssert("approach rate bar is red", () => barIsRed(advancedStats.ApproachRate));
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool barIsWhite(AdvancedStats.StatisticRow row) => row.ModBar.AccentColour == Color4.White;
|
||||||
|
private bool barIsBlue(AdvancedStats.StatisticRow row) => row.ModBar.AccentColour == colours.BlueDark;
|
||||||
|
private bool barIsRed(AdvancedStats.StatisticRow row) => row.ModBar.AccentColour == colours.Red;
|
||||||
|
|
||||||
|
private class TestAdvancedStats : AdvancedStats
|
||||||
|
{
|
||||||
|
public new StatisticRow FirstValue => base.FirstValue;
|
||||||
|
public new StatisticRow HpDrain => base.HpDrain;
|
||||||
|
public new StatisticRow Accuracy => base.Accuracy;
|
||||||
|
public new StatisticRow ApproachRate => base.ApproachRate;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -3,14 +3,8 @@
|
|||||||
|
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
using osu.Framework.Allocation;
|
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Testing;
|
|
||||||
using osu.Game.Beatmaps;
|
using osu.Game.Beatmaps;
|
||||||
using osu.Game.Graphics;
|
|
||||||
using osu.Game.Graphics.UserInterface;
|
|
||||||
using osu.Game.Rulesets;
|
|
||||||
using osu.Game.Rulesets.Mods;
|
|
||||||
using osu.Game.Screens.Select;
|
using osu.Game.Screens.Select;
|
||||||
|
|
||||||
namespace osu.Game.Tests.Visual.SongSelect
|
namespace osu.Game.Tests.Visual.SongSelect
|
||||||
@ -180,27 +174,5 @@ namespace osu.Game.Tests.Visual.SongSelect
|
|||||||
OnlineBeatmapID = 162,
|
OnlineBeatmapID = 162,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
[Resolved]
|
|
||||||
private RulesetStore rulesets { get; set; }
|
|
||||||
|
|
||||||
[Resolved]
|
|
||||||
private OsuColour colours { get; set; }
|
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void TestModAdjustments()
|
|
||||||
{
|
|
||||||
TestAllMetrics();
|
|
||||||
|
|
||||||
Ruleset ruleset = rulesets.AvailableRulesets.First().CreateInstance();
|
|
||||||
|
|
||||||
AddStep("with EZ mod", () => SelectedMods.Value = new[] { ruleset.GetAllMods().First(m => m is ModEasy) });
|
|
||||||
|
|
||||||
AddAssert("first bar coloured blue", () => details.ChildrenOfType<Bar>().Skip(1).First().AccentColour == colours.BlueDark);
|
|
||||||
|
|
||||||
AddStep("with HR mod", () => SelectedMods.Value = new[] { ruleset.GetAllMods().First(m => m is ModHardRock) });
|
|
||||||
|
|
||||||
AddAssert("first bar coloured red", () => details.ChildrenOfType<Bar>().Skip(1).First().AccentColour == colours.Red);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -72,19 +72,24 @@ namespace osu.Game.Tests.Visual.SongSelect
|
|||||||
// required to get bindables attached
|
// required to get bindables attached
|
||||||
Add(music);
|
Add(music);
|
||||||
|
|
||||||
Beatmap.SetDefault();
|
|
||||||
|
|
||||||
Dependencies.Cache(config = new OsuConfigManager(LocalStorage));
|
Dependencies.Cache(config = new OsuConfigManager(LocalStorage));
|
||||||
}
|
}
|
||||||
|
|
||||||
private OsuConfigManager config;
|
private OsuConfigManager config;
|
||||||
|
|
||||||
[SetUp]
|
[SetUpSteps]
|
||||||
public virtual void SetUp() => Schedule(() =>
|
public override void SetUpSteps()
|
||||||
|
{
|
||||||
|
base.SetUpSteps();
|
||||||
|
|
||||||
|
AddStep("delete all beatmaps", () =>
|
||||||
{
|
{
|
||||||
Ruleset.Value = new OsuRuleset().RulesetInfo;
|
Ruleset.Value = new OsuRuleset().RulesetInfo;
|
||||||
manager?.Delete(manager.GetAllUsableBeatmapSets());
|
manager?.Delete(manager.GetAllUsableBeatmapSets());
|
||||||
|
|
||||||
|
Beatmap.SetDefault();
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void TestSingleFilterOnEnter()
|
public void TestSingleFilterOnEnter()
|
||||||
@ -120,9 +125,6 @@ namespace osu.Game.Tests.Visual.SongSelect
|
|||||||
|
|
||||||
AddUntilStep("wait for not current", () => !songSelect.IsCurrentScreen());
|
AddUntilStep("wait for not current", () => !songSelect.IsCurrentScreen());
|
||||||
AddAssert("ensure selection changed", () => selected != Beatmap.Value);
|
AddAssert("ensure selection changed", () => selected != Beatmap.Value);
|
||||||
|
|
||||||
AddUntilStep("wait for return to song select", () => songSelect.IsCurrentScreen());
|
|
||||||
AddUntilStep("bindable lease returned", () => !Beatmap.Disabled);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
@ -148,9 +150,6 @@ namespace osu.Game.Tests.Visual.SongSelect
|
|||||||
|
|
||||||
AddUntilStep("wait for not current", () => !songSelect.IsCurrentScreen());
|
AddUntilStep("wait for not current", () => !songSelect.IsCurrentScreen());
|
||||||
AddAssert("ensure selection didn't change", () => selected == Beatmap.Value);
|
AddAssert("ensure selection didn't change", () => selected == Beatmap.Value);
|
||||||
|
|
||||||
AddUntilStep("wait for return to song select", () => songSelect.IsCurrentScreen());
|
|
||||||
AddUntilStep("bindable lease returned", () => !Beatmap.Disabled);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
@ -180,9 +179,6 @@ namespace osu.Game.Tests.Visual.SongSelect
|
|||||||
|
|
||||||
AddUntilStep("wait for not current", () => !songSelect.IsCurrentScreen());
|
AddUntilStep("wait for not current", () => !songSelect.IsCurrentScreen());
|
||||||
AddAssert("ensure selection changed", () => selected != Beatmap.Value);
|
AddAssert("ensure selection changed", () => selected != Beatmap.Value);
|
||||||
|
|
||||||
AddUntilStep("wait for return to song select", () => songSelect.IsCurrentScreen());
|
|
||||||
AddUntilStep("bindable lease returned", () => !Beatmap.Disabled);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
@ -213,9 +209,6 @@ namespace osu.Game.Tests.Visual.SongSelect
|
|||||||
|
|
||||||
AddUntilStep("wait for not current", () => !songSelect.IsCurrentScreen());
|
AddUntilStep("wait for not current", () => !songSelect.IsCurrentScreen());
|
||||||
AddAssert("ensure selection didn't change", () => selected == Beatmap.Value);
|
AddAssert("ensure selection didn't change", () => selected == Beatmap.Value);
|
||||||
|
|
||||||
AddUntilStep("wait for return to song select", () => songSelect.IsCurrentScreen());
|
|
||||||
AddUntilStep("bindable lease returned", () => !Beatmap.Disabled);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
|
@ -29,9 +29,9 @@ namespace osu.Game.Graphics
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public DrawableDate(DateTimeOffset date, float textSize = OsuFont.DEFAULT_FONT_SIZE)
|
public DrawableDate(DateTimeOffset date, float textSize = OsuFont.DEFAULT_FONT_SIZE, bool italic = true)
|
||||||
{
|
{
|
||||||
Font = OsuFont.GetFont(weight: FontWeight.Regular, size: textSize, italics: true);
|
Font = OsuFont.GetFont(weight: FontWeight.Regular, size: textSize, italics: italic);
|
||||||
Date = date;
|
Date = date;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -40,13 +40,14 @@ namespace osu.Game.Graphics.UserInterface
|
|||||||
|
|
||||||
public ShowMoreButton()
|
public ShowMoreButton()
|
||||||
{
|
{
|
||||||
AutoSizeAxes = Axes.Both;
|
Height = 30;
|
||||||
|
Width = 140;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override Drawable CreateContent() => new CircularContainer
|
protected override Drawable CreateContent() => new CircularContainer
|
||||||
{
|
{
|
||||||
Masking = true,
|
Masking = true,
|
||||||
Size = new Vector2(140, 30),
|
RelativeSizeAxes = Axes.Both,
|
||||||
Children = new Drawable[]
|
Children = new Drawable[]
|
||||||
{
|
{
|
||||||
background = new Box
|
background = new Box
|
||||||
|
@ -6,8 +6,6 @@ using osu.Game.Users;
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Net;
|
|
||||||
using System.Text.RegularExpressions;
|
|
||||||
|
|
||||||
namespace osu.Game.Online.API.Requests.Responses
|
namespace osu.Game.Online.API.Requests.Responses
|
||||||
{
|
{
|
||||||
@ -70,12 +68,10 @@ namespace osu.Game.Online.API.Requests.Responses
|
|||||||
|
|
||||||
public bool IsDeleted => DeletedAt.HasValue;
|
public bool IsDeleted => DeletedAt.HasValue;
|
||||||
|
|
||||||
public bool HasMessage => !string.IsNullOrEmpty(MessageHtml);
|
public bool HasMessage => !string.IsNullOrEmpty(Message);
|
||||||
|
|
||||||
public bool IsVoted { get; set; }
|
public bool IsVoted { get; set; }
|
||||||
|
|
||||||
public string GetMessage => HasMessage ? WebUtility.HtmlDecode(Regex.Replace(MessageHtml, @"<(.|\n)*?>", string.Empty)) : string.Empty;
|
|
||||||
|
|
||||||
public int DeletedChildrenCount => ChildComments.Count(c => c.IsDeleted);
|
public int DeletedChildrenCount => ChildComments.Count(c => c.IsDeleted);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -47,17 +47,18 @@ namespace osu.Game.Online.API.Requests.Responses
|
|||||||
[JsonProperty(@"included_comments")]
|
[JsonProperty(@"included_comments")]
|
||||||
public List<Comment> IncludedComments { get; set; }
|
public List<Comment> IncludedComments { get; set; }
|
||||||
|
|
||||||
|
private List<long> userVotes;
|
||||||
|
|
||||||
[JsonProperty(@"user_votes")]
|
[JsonProperty(@"user_votes")]
|
||||||
private List<long> userVotes
|
public List<long> UserVotes
|
||||||
{
|
{
|
||||||
set => value.ForEach(v =>
|
get => userVotes;
|
||||||
|
set
|
||||||
{
|
{
|
||||||
Comments.ForEach(c =>
|
userVotes = value;
|
||||||
{
|
|
||||||
if (v == c.Id)
|
Comments.ForEach(c => c.IsVoted = value.Contains(c.Id));
|
||||||
c.IsVoted = true;
|
}
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<User> users;
|
private List<User> users;
|
||||||
|
@ -25,7 +25,7 @@ namespace osu.Game.Overlays.Chat.Selection
|
|||||||
private const float text_size = 15;
|
private const float text_size = 15;
|
||||||
private const float transition_duration = 100;
|
private const float transition_duration = 100;
|
||||||
|
|
||||||
private readonly Channel channel;
|
public readonly Channel Channel;
|
||||||
|
|
||||||
private readonly Bindable<bool> joinedBind = new Bindable<bool>();
|
private readonly Bindable<bool> joinedBind = new Bindable<bool>();
|
||||||
private readonly OsuSpriteText name;
|
private readonly OsuSpriteText name;
|
||||||
@ -36,7 +36,7 @@ namespace osu.Game.Overlays.Chat.Selection
|
|||||||
private Color4 topicColour;
|
private Color4 topicColour;
|
||||||
private Color4 hoverColour;
|
private Color4 hoverColour;
|
||||||
|
|
||||||
public IEnumerable<string> FilterTerms => new[] { channel.Name, channel.Topic };
|
public IEnumerable<string> FilterTerms => new[] { Channel.Name, Channel.Topic ?? string.Empty };
|
||||||
|
|
||||||
public bool MatchingFilter
|
public bool MatchingFilter
|
||||||
{
|
{
|
||||||
@ -50,7 +50,7 @@ namespace osu.Game.Overlays.Chat.Selection
|
|||||||
|
|
||||||
public ChannelListItem(Channel channel)
|
public ChannelListItem(Channel channel)
|
||||||
{
|
{
|
||||||
this.channel = channel;
|
Channel = channel;
|
||||||
|
|
||||||
RelativeSizeAxes = Axes.X;
|
RelativeSizeAxes = Axes.X;
|
||||||
AutoSizeAxes = Axes.Y;
|
AutoSizeAxes = Axes.Y;
|
||||||
@ -148,7 +148,7 @@ namespace osu.Game.Overlays.Chat.Selection
|
|||||||
hoverColour = colours.Yellow;
|
hoverColour = colours.Yellow;
|
||||||
|
|
||||||
joinedBind.ValueChanged += joined => updateColour(joined.NewValue);
|
joinedBind.ValueChanged += joined => updateColour(joined.NewValue);
|
||||||
joinedBind.BindTo(channel.Joined);
|
joinedBind.BindTo(Channel.Joined);
|
||||||
|
|
||||||
joinedBind.TriggerChange();
|
joinedBind.TriggerChange();
|
||||||
FinishTransforms(true);
|
FinishTransforms(true);
|
||||||
@ -156,7 +156,7 @@ namespace osu.Game.Overlays.Chat.Selection
|
|||||||
|
|
||||||
protected override bool OnHover(HoverEvent e)
|
protected override bool OnHover(HoverEvent e)
|
||||||
{
|
{
|
||||||
if (!channel.Joined.Value)
|
if (!Channel.Joined.Value)
|
||||||
name.FadeColour(hoverColour, 50, Easing.OutQuint);
|
name.FadeColour(hoverColour, 50, Easing.OutQuint);
|
||||||
|
|
||||||
return base.OnHover(e);
|
return base.OnHover(e);
|
||||||
@ -164,7 +164,7 @@ namespace osu.Game.Overlays.Chat.Selection
|
|||||||
|
|
||||||
protected override void OnHoverLost(HoverLostEvent e)
|
protected override void OnHoverLost(HoverLostEvent e)
|
||||||
{
|
{
|
||||||
if (!channel.Joined.Value)
|
if (!Channel.Joined.Value)
|
||||||
name.FadeColour(Color4.White, transition_duration);
|
name.FadeColour(Color4.White, transition_duration);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -321,8 +321,10 @@ namespace osu.Game.Overlays
|
|||||||
|
|
||||||
private void selectTab(int index)
|
private void selectTab(int index)
|
||||||
{
|
{
|
||||||
var channel = ChannelTabControl.Items.Skip(index).FirstOrDefault();
|
var channel = ChannelTabControl.Items
|
||||||
if (channel != null && !(channel is ChannelSelectorTabItem.ChannelSelectorTabChannel))
|
.Where(tab => !(tab is ChannelSelectorTabItem.ChannelSelectorTabChannel))
|
||||||
|
.ElementAtOrDefault(index);
|
||||||
|
if (channel != null)
|
||||||
ChannelTabControl.Current.Value = channel;
|
ChannelTabControl.Current.Value = channel;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -68,6 +68,7 @@ namespace osu.Game.Overlays.Comments
|
|||||||
},
|
},
|
||||||
new Container
|
new Container
|
||||||
{
|
{
|
||||||
|
Name = @"Footer",
|
||||||
RelativeSizeAxes = Axes.X,
|
RelativeSizeAxes = Axes.X,
|
||||||
AutoSizeAxes = Axes.Y,
|
AutoSizeAxes = Axes.Y,
|
||||||
Children = new Drawable[]
|
Children = new Drawable[]
|
||||||
@ -154,6 +155,7 @@ namespace osu.Game.Overlays.Comments
|
|||||||
{
|
{
|
||||||
currentPage = 1;
|
currentPage = 1;
|
||||||
deletedCommentsCounter.Count.Value = 0;
|
deletedCommentsCounter.Count.Value = 0;
|
||||||
|
moreButton.Show();
|
||||||
moreButton.IsLoading = true;
|
moreButton.IsLoading = true;
|
||||||
content.Clear();
|
content.Clear();
|
||||||
}
|
}
|
||||||
@ -162,25 +164,10 @@ namespace osu.Game.Overlays.Comments
|
|||||||
{
|
{
|
||||||
loadCancellation = new CancellationTokenSource();
|
loadCancellation = new CancellationTokenSource();
|
||||||
|
|
||||||
var page = new FillFlowContainer
|
LoadComponentAsync(new CommentsPage(response)
|
||||||
{
|
|
||||||
RelativeSizeAxes = Axes.X,
|
|
||||||
AutoSizeAxes = Axes.Y,
|
|
||||||
Direction = FillDirection.Vertical,
|
|
||||||
};
|
|
||||||
|
|
||||||
foreach (var c in response.Comments)
|
|
||||||
{
|
|
||||||
if (c.IsTopLevel)
|
|
||||||
{
|
|
||||||
page.Add(new DrawableComment(c)
|
|
||||||
{
|
{
|
||||||
ShowDeleted = { BindTarget = ShowDeleted }
|
ShowDeleted = { BindTarget = ShowDeleted }
|
||||||
});
|
}, loaded =>
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
LoadComponentAsync(page, loaded =>
|
|
||||||
{
|
{
|
||||||
content.Add(loaded);
|
content.Add(loaded);
|
||||||
|
|
||||||
@ -194,10 +181,12 @@ namespace osu.Game.Overlays.Comments
|
|||||||
moreButton.Current.Value = response.TopLevelCount - loadedTopLevelComments;
|
moreButton.Current.Value = response.TopLevelCount - loadedTopLevelComments;
|
||||||
moreButton.IsLoading = false;
|
moreButton.IsLoading = false;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
moreButton.Hide();
|
||||||
|
}
|
||||||
|
|
||||||
commentCounter.Current.Value = response.Total;
|
commentCounter.Current.Value = response.Total;
|
||||||
|
|
||||||
moreButton.FadeTo(response.HasMore ? 1 : 0);
|
|
||||||
}, loadCancellation.Token);
|
}, loadCancellation.Token);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
92
osu.Game/Overlays/Comments/CommentsPage.cs
Normal file
92
osu.Game/Overlays/Comments/CommentsPage.cs
Normal file
@ -0,0 +1,92 @@
|
|||||||
|
// 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 osu.Framework.Allocation;
|
||||||
|
using osu.Framework.Graphics.Containers;
|
||||||
|
using osu.Framework.Graphics;
|
||||||
|
using osu.Framework.Bindables;
|
||||||
|
using osu.Game.Online.API.Requests.Responses;
|
||||||
|
using osu.Framework.Graphics.Shapes;
|
||||||
|
using osu.Game.Graphics.Sprites;
|
||||||
|
using System.Linq;
|
||||||
|
|
||||||
|
namespace osu.Game.Overlays.Comments
|
||||||
|
{
|
||||||
|
public class CommentsPage : CompositeDrawable
|
||||||
|
{
|
||||||
|
public readonly BindableBool ShowDeleted = new BindableBool();
|
||||||
|
|
||||||
|
private readonly CommentBundle commentBundle;
|
||||||
|
|
||||||
|
public CommentsPage(CommentBundle commentBundle)
|
||||||
|
{
|
||||||
|
this.commentBundle = commentBundle;
|
||||||
|
}
|
||||||
|
|
||||||
|
[BackgroundDependencyLoader]
|
||||||
|
private void load(OverlayColourProvider colourProvider)
|
||||||
|
{
|
||||||
|
FillFlowContainer flow;
|
||||||
|
|
||||||
|
RelativeSizeAxes = Axes.X;
|
||||||
|
AutoSizeAxes = Axes.Y;
|
||||||
|
|
||||||
|
AddRangeInternal(new Drawable[]
|
||||||
|
{
|
||||||
|
new Box
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.Both,
|
||||||
|
Colour = colourProvider.Background5
|
||||||
|
},
|
||||||
|
flow = new FillFlowContainer
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.X,
|
||||||
|
AutoSizeAxes = Axes.Y,
|
||||||
|
Direction = FillDirection.Vertical,
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!commentBundle.Comments.Any())
|
||||||
|
{
|
||||||
|
flow.Add(new NoCommentsPlaceholder());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (var c in commentBundle.Comments)
|
||||||
|
{
|
||||||
|
if (c.IsTopLevel)
|
||||||
|
{
|
||||||
|
flow.Add(new DrawableComment(c)
|
||||||
|
{
|
||||||
|
ShowDeleted = { BindTarget = ShowDeleted }
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private class NoCommentsPlaceholder : CompositeDrawable
|
||||||
|
{
|
||||||
|
[BackgroundDependencyLoader]
|
||||||
|
private void load(OverlayColourProvider colourProvider)
|
||||||
|
{
|
||||||
|
Height = 80;
|
||||||
|
RelativeSizeAxes = Axes.X;
|
||||||
|
AddRangeInternal(new Drawable[]
|
||||||
|
{
|
||||||
|
new Box
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.Both,
|
||||||
|
Colour = colourProvider.Background4
|
||||||
|
},
|
||||||
|
new OsuSpriteText
|
||||||
|
{
|
||||||
|
Anchor = Anchor.CentreLeft,
|
||||||
|
Origin = Anchor.CentreLeft,
|
||||||
|
Margin = new MarginPadding { Left = 50 },
|
||||||
|
Text = @"No comments yet."
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -14,6 +14,8 @@ namespace osu.Game.Overlays.Comments
|
|||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader]
|
||||||
private void load(OverlayColourProvider colourProvider)
|
private void load(OverlayColourProvider colourProvider)
|
||||||
{
|
{
|
||||||
|
Height = 20;
|
||||||
|
|
||||||
IdleColour = colourProvider.Background2;
|
IdleColour = colourProvider.Background2;
|
||||||
HoverColour = colourProvider.Background1;
|
HoverColour = colourProvider.Background1;
|
||||||
ChevronIconColour = colourProvider.Foreground1;
|
ChevronIconColour = colourProvider.Foreground1;
|
||||||
|
@ -213,7 +213,7 @@ namespace osu.Game.Overlays.Comments
|
|||||||
|
|
||||||
if (comment.HasMessage)
|
if (comment.HasMessage)
|
||||||
{
|
{
|
||||||
var formattedSource = MessageFormatter.FormatText(comment.GetMessage);
|
var formattedSource = MessageFormatter.FormatText(comment.Message);
|
||||||
message.AddLinks(formattedSource.Text, formattedSource.Links);
|
message.AddLinks(formattedSource.Text, formattedSource.Links);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -343,7 +343,7 @@ namespace osu.Game.Overlays.Comments
|
|||||||
if (parentComment == null)
|
if (parentComment == null)
|
||||||
return string.Empty;
|
return string.Empty;
|
||||||
|
|
||||||
return parentComment.HasMessage ? parentComment.GetMessage : parentComment.IsDeleted ? @"deleted" : string.Empty;
|
return parentComment.HasMessage ? parentComment.Message : parentComment.IsDeleted ? @"deleted" : string.Empty;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -196,7 +196,7 @@ namespace osu.Game.Overlays
|
|||||||
if (!instant)
|
if (!instant)
|
||||||
queuedDirection = TrackChangeDirection.Next;
|
queuedDirection = TrackChangeDirection.Next;
|
||||||
|
|
||||||
var playable = BeatmapSets.SkipWhile(i => i.ID != current.BeatmapSetInfo.ID).Skip(1).FirstOrDefault() ?? BeatmapSets.FirstOrDefault();
|
var playable = BeatmapSets.SkipWhile(i => i.ID != current.BeatmapSetInfo.ID).ElementAtOrDefault(1) ?? BeatmapSets.FirstOrDefault();
|
||||||
|
|
||||||
if (playable != null)
|
if (playable != null)
|
||||||
{
|
{
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
// 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.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
@ -82,7 +82,7 @@ namespace osu.Game.Overlays.Profile.Header
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
topLinkContainer.AddText("Joined ");
|
topLinkContainer.AddText("Joined ");
|
||||||
topLinkContainer.AddText(new DrawableDate(user.JoinDate), embolden);
|
topLinkContainer.AddText(new DrawableDate(user.JoinDate, italic: false), embolden);
|
||||||
}
|
}
|
||||||
|
|
||||||
addSpacer(topLinkContainer);
|
addSpacer(topLinkContainer);
|
||||||
@ -95,7 +95,7 @@ namespace osu.Game.Overlays.Profile.Header
|
|||||||
else if (user.LastVisit.HasValue)
|
else if (user.LastVisit.HasValue)
|
||||||
{
|
{
|
||||||
topLinkContainer.AddText("Last seen ");
|
topLinkContainer.AddText("Last seen ");
|
||||||
topLinkContainer.AddText(new DrawableDate(user.LastVisit.Value), embolden);
|
topLinkContainer.AddText(new DrawableDate(user.LastVisit.Value, italic: false), embolden);
|
||||||
|
|
||||||
addSpacer(topLinkContainer);
|
addSpacer(topLinkContainer);
|
||||||
}
|
}
|
||||||
@ -111,34 +111,42 @@ namespace osu.Game.Overlays.Profile.Header
|
|||||||
topLinkContainer.AddText("Contributed ");
|
topLinkContainer.AddText("Contributed ");
|
||||||
topLinkContainer.AddLink($@"{user.PostCount:#,##0} forum posts", $"https://osu.ppy.sh/users/{user.Id}/posts", creationParameters: embolden);
|
topLinkContainer.AddLink($@"{user.PostCount:#,##0} forum posts", $"https://osu.ppy.sh/users/{user.Id}/posts", creationParameters: embolden);
|
||||||
|
|
||||||
string websiteWithoutProtcol = user.Website;
|
string websiteWithoutProtocol = user.Website;
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(websiteWithoutProtcol))
|
if (!string.IsNullOrEmpty(websiteWithoutProtocol))
|
||||||
{
|
{
|
||||||
if (Uri.TryCreate(websiteWithoutProtcol, UriKind.Absolute, out var uri))
|
if (Uri.TryCreate(websiteWithoutProtocol, UriKind.Absolute, out var uri))
|
||||||
{
|
{
|
||||||
websiteWithoutProtcol = uri.Host + uri.PathAndQuery + uri.Fragment;
|
websiteWithoutProtocol = uri.Host + uri.PathAndQuery + uri.Fragment;
|
||||||
websiteWithoutProtcol = websiteWithoutProtcol.TrimEnd('/');
|
websiteWithoutProtocol = websiteWithoutProtocol.TrimEnd('/');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
tryAddInfo(FontAwesome.Solid.MapMarker, user.Location);
|
bool anyInfoAdded = false;
|
||||||
tryAddInfo(OsuIcon.Heart, user.Interests);
|
|
||||||
tryAddInfo(FontAwesome.Solid.Suitcase, user.Occupation);
|
anyInfoAdded |= tryAddInfo(FontAwesome.Solid.MapMarker, user.Location);
|
||||||
|
anyInfoAdded |= tryAddInfo(OsuIcon.Heart, user.Interests);
|
||||||
|
anyInfoAdded |= tryAddInfo(FontAwesome.Solid.Suitcase, user.Occupation);
|
||||||
|
|
||||||
|
if (anyInfoAdded)
|
||||||
bottomLinkContainer.NewLine();
|
bottomLinkContainer.NewLine();
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(user.Twitter))
|
if (!string.IsNullOrEmpty(user.Twitter))
|
||||||
tryAddInfo(FontAwesome.Brands.Twitter, "@" + user.Twitter, $@"https://twitter.com/{user.Twitter}");
|
anyInfoAdded |= tryAddInfo(FontAwesome.Brands.Twitter, "@" + user.Twitter, $@"https://twitter.com/{user.Twitter}");
|
||||||
tryAddInfo(FontAwesome.Brands.Discord, user.Discord);
|
anyInfoAdded |= tryAddInfo(FontAwesome.Brands.Discord, user.Discord);
|
||||||
tryAddInfo(FontAwesome.Brands.Skype, user.Skype, @"skype:" + user.Skype + @"?chat");
|
anyInfoAdded |= tryAddInfo(FontAwesome.Brands.Skype, user.Skype, @"skype:" + user.Skype + @"?chat");
|
||||||
tryAddInfo(FontAwesome.Brands.Lastfm, user.Lastfm, $@"https://last.fm/users/{user.Lastfm}");
|
anyInfoAdded |= tryAddInfo(FontAwesome.Brands.Lastfm, user.Lastfm, $@"https://last.fm/users/{user.Lastfm}");
|
||||||
tryAddInfo(FontAwesome.Solid.Link, websiteWithoutProtcol, user.Website);
|
anyInfoAdded |= tryAddInfo(FontAwesome.Solid.Link, websiteWithoutProtocol, user.Website);
|
||||||
|
|
||||||
|
// If no information was added to the bottomLinkContainer, hide it to avoid unwanted padding
|
||||||
|
bottomLinkContainer.Alpha = anyInfoAdded ? 1 : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addSpacer(OsuTextFlowContainer textFlow) => textFlow.AddArbitraryDrawable(new Container { Width = 15 });
|
private void addSpacer(OsuTextFlowContainer textFlow) => textFlow.AddArbitraryDrawable(new Container { Width = 15 });
|
||||||
|
|
||||||
private void tryAddInfo(IconUsage icon, string content, string link = null)
|
private bool tryAddInfo(IconUsage icon, string content, string link = null)
|
||||||
{
|
{
|
||||||
if (string.IsNullOrEmpty(content)) return;
|
if (string.IsNullOrEmpty(content)) return false;
|
||||||
|
|
||||||
// newlines could be contained in API returned user content.
|
// newlines could be contained in API returned user content.
|
||||||
content = content.Replace("\n", " ");
|
content = content.Replace("\n", " ");
|
||||||
@ -155,6 +163,7 @@ namespace osu.Game.Overlays.Profile.Header
|
|||||||
bottomLinkContainer.AddText(" " + content, embolden);
|
bottomLinkContainer.AddText(" " + content, embolden);
|
||||||
|
|
||||||
addSpacer(bottomLinkContainer);
|
addSpacer(bottomLinkContainer);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void embolden(SpriteText text) => text.Font = text.Font.With(weight: FontWeight.Bold);
|
private void embolden(SpriteText text) => text.Font = text.Font.With(weight: FontWeight.Bold);
|
||||||
|
@ -29,7 +29,7 @@ namespace osu.Game.Overlays.Profile.Header.Components
|
|||||||
}
|
}
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader]
|
||||||
private void load(OsuColour colours)
|
private void load(OverlayColourProvider colourProvider)
|
||||||
{
|
{
|
||||||
InternalChildren = new Drawable[]
|
InternalChildren = new Drawable[]
|
||||||
{
|
{
|
||||||
@ -42,7 +42,7 @@ namespace osu.Game.Overlays.Profile.Header.Components
|
|||||||
RelativeSizeAxes = Axes.Both,
|
RelativeSizeAxes = Axes.Both,
|
||||||
BackgroundColour = Color4.Black,
|
BackgroundColour = Color4.Black,
|
||||||
Direction = BarDirection.LeftToRight,
|
Direction = BarDirection.LeftToRight,
|
||||||
AccentColour = colours.Yellow
|
AccentColour = colourProvider.Highlight1
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
levelProgressText = new OsuSpriteText
|
levelProgressText = new OsuSpriteText
|
||||||
|
@ -2,12 +2,11 @@
|
|||||||
// See the LICENCE file in the repository root for full licence text.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using osu.Framework.Allocation;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Graphics.Containers;
|
using osu.Framework.Graphics.Containers;
|
||||||
using osu.Framework.Graphics.Shapes;
|
using osu.Framework.Graphics.Shapes;
|
||||||
using osu.Game.Graphics;
|
|
||||||
using osu.Game.Graphics.Containers;
|
using osu.Game.Graphics.Containers;
|
||||||
using osuTK.Graphics;
|
|
||||||
|
|
||||||
namespace osu.Game.Overlays.Profile.Header.Components
|
namespace osu.Game.Overlays.Profile.Header.Components
|
||||||
{
|
{
|
||||||
@ -24,9 +23,6 @@ namespace osu.Game.Overlays.Profile.Header.Components
|
|||||||
{
|
{
|
||||||
AutoSizeAxes = Axes.X;
|
AutoSizeAxes = Axes.X;
|
||||||
|
|
||||||
IdleColour = Color4.Black;
|
|
||||||
HoverColour = OsuColour.Gray(0.1f);
|
|
||||||
|
|
||||||
base.Content.Add(new CircularContainer
|
base.Content.Add(new CircularContainer
|
||||||
{
|
{
|
||||||
Masking = true,
|
Masking = true,
|
||||||
@ -47,5 +43,12 @@ namespace osu.Game.Overlays.Profile.Header.Components
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[BackgroundDependencyLoader]
|
||||||
|
private void load(OverlayColourProvider colourProvider)
|
||||||
|
{
|
||||||
|
IdleColour = colourProvider.Background6;
|
||||||
|
HoverColour = colourProvider.Background5;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -167,9 +167,9 @@ namespace osu.Game.Overlays.Profile.Header.Components
|
|||||||
}
|
}
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader]
|
||||||
private void load(OsuColour colours)
|
private void load(OverlayColourProvider colourProvider, OsuColour colours)
|
||||||
{
|
{
|
||||||
ballBg.Colour = colours.GreySeafoamDarker;
|
ballBg.Colour = colourProvider.Background5;
|
||||||
movingBall.BorderColour = line.Colour = colours.Yellow;
|
movingBall.BorderColour = line.Colour = colours.Yellow;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -270,7 +270,9 @@ namespace osu.Game.Overlays.Profile.Header.Components
|
|||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader]
|
||||||
private void load(OsuColour colours)
|
private void load(OsuColour colours)
|
||||||
{
|
{
|
||||||
background.Colour = colours.GreySeafoamDark;
|
// Temporary colour since it's currently impossible to change it without bugs (see https://github.com/ppy/osu-framework/issues/3231)
|
||||||
|
// If above is fixed, this should use OverlayColourProvider
|
||||||
|
background.Colour = colours.Gray1;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool SetContent(object content)
|
public bool SetContent(object content)
|
||||||
|
@ -10,7 +10,7 @@ using osu.Game.Graphics.Containers;
|
|||||||
namespace osu.Game.Overlays.Profile.Sections
|
namespace osu.Game.Overlays.Profile.Sections
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Display artist/title/mapper information, commonly used as the left portion of a profile or score display row (see <see cref="DrawableProfileRow"/>).
|
/// Display artist/title/mapper information, commonly used as the left portion of a profile or score display row.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public abstract class BeatmapMetadataContainer : OsuHoverContainer
|
public abstract class BeatmapMetadataContainer : OsuHoverContainer
|
||||||
{
|
{
|
||||||
|
@ -1,124 +0,0 @@
|
|||||||
// 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 osu.Framework.Allocation;
|
|
||||||
using osu.Framework.Extensions.Color4Extensions;
|
|
||||||
using osu.Framework.Graphics;
|
|
||||||
using osu.Framework.Graphics.Containers;
|
|
||||||
using osu.Framework.Graphics.Effects;
|
|
||||||
using osu.Framework.Graphics.Shapes;
|
|
||||||
using osu.Framework.Input.Events;
|
|
||||||
using osu.Game.Graphics;
|
|
||||||
using osuTK;
|
|
||||||
using osuTK.Graphics;
|
|
||||||
|
|
||||||
namespace osu.Game.Overlays.Profile.Sections
|
|
||||||
{
|
|
||||||
public abstract class DrawableProfileRow : Container
|
|
||||||
{
|
|
||||||
private const int fade_duration = 200;
|
|
||||||
|
|
||||||
private Box underscoreLine;
|
|
||||||
private Box coloredBackground;
|
|
||||||
private Container background;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// A visual element displayed to the left of <see cref="LeftFlowContainer"/> content.
|
|
||||||
/// </summary>
|
|
||||||
protected abstract Drawable CreateLeftVisual();
|
|
||||||
|
|
||||||
protected FillFlowContainer LeftFlowContainer { get; private set; }
|
|
||||||
protected FillFlowContainer RightFlowContainer { get; private set; }
|
|
||||||
|
|
||||||
protected override Container<Drawable> Content { get; }
|
|
||||||
|
|
||||||
protected DrawableProfileRow()
|
|
||||||
{
|
|
||||||
RelativeSizeAxes = Axes.X;
|
|
||||||
Height = 60;
|
|
||||||
|
|
||||||
Content = new Container
|
|
||||||
{
|
|
||||||
RelativeSizeAxes = Axes.Both,
|
|
||||||
Anchor = Anchor.TopCentre,
|
|
||||||
Origin = Anchor.TopCentre,
|
|
||||||
Width = 0.97f,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
[BackgroundDependencyLoader(true)]
|
|
||||||
private void load(OsuColour colour)
|
|
||||||
{
|
|
||||||
InternalChildren = new Drawable[]
|
|
||||||
{
|
|
||||||
background = new Container
|
|
||||||
{
|
|
||||||
RelativeSizeAxes = Axes.Both,
|
|
||||||
Masking = true,
|
|
||||||
CornerRadius = 3,
|
|
||||||
Alpha = 0,
|
|
||||||
EdgeEffect = new EdgeEffectParameters
|
|
||||||
{
|
|
||||||
Type = EdgeEffectType.Shadow,
|
|
||||||
Offset = new Vector2(0f, 1f),
|
|
||||||
Radius = 1f,
|
|
||||||
Colour = Color4.Black.Opacity(0.2f),
|
|
||||||
},
|
|
||||||
Child = coloredBackground = new Box { RelativeSizeAxes = Axes.Both }
|
|
||||||
},
|
|
||||||
Content,
|
|
||||||
underscoreLine = new Box
|
|
||||||
{
|
|
||||||
Anchor = Anchor.BottomCentre,
|
|
||||||
Origin = Anchor.BottomCentre,
|
|
||||||
RelativeSizeAxes = Axes.X,
|
|
||||||
Height = 1,
|
|
||||||
},
|
|
||||||
new FillFlowContainer
|
|
||||||
{
|
|
||||||
RelativeSizeAxes = Axes.Both,
|
|
||||||
Direction = FillDirection.Horizontal,
|
|
||||||
Children = new[]
|
|
||||||
{
|
|
||||||
CreateLeftVisual(),
|
|
||||||
LeftFlowContainer = new FillFlowContainer
|
|
||||||
{
|
|
||||||
RelativeSizeAxes = Axes.X,
|
|
||||||
AutoSizeAxes = Axes.Y,
|
|
||||||
Anchor = Anchor.CentreLeft,
|
|
||||||
Origin = Anchor.CentreLeft,
|
|
||||||
Margin = new MarginPadding { Left = 10 },
|
|
||||||
Direction = FillDirection.Vertical,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
},
|
|
||||||
RightFlowContainer = new FillFlowContainer
|
|
||||||
{
|
|
||||||
RelativeSizeAxes = Axes.X,
|
|
||||||
AutoSizeAxes = Axes.Y,
|
|
||||||
Anchor = Anchor.CentreRight,
|
|
||||||
Origin = Anchor.CentreRight,
|
|
||||||
Direction = FillDirection.Vertical,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
coloredBackground.Colour = underscoreLine.Colour = colour.Gray4;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override bool OnClick(ClickEvent e) => true;
|
|
||||||
|
|
||||||
protected override bool OnHover(HoverEvent e)
|
|
||||||
{
|
|
||||||
background.FadeIn(fade_duration, Easing.OutQuint);
|
|
||||||
underscoreLine.FadeOut(fade_duration, Easing.OutQuint);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void OnHoverLost(HoverLostEvent e)
|
|
||||||
{
|
|
||||||
background.FadeOut(fade_duration, Easing.OutQuint);
|
|
||||||
underscoreLine.FadeIn(fade_duration, Easing.OutQuint);
|
|
||||||
base.OnHoverLost(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -44,8 +44,8 @@ namespace osu.Game.Overlays.Profile.Sections
|
|||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader]
|
||||||
private void load(OverlayColourProvider colourProvider)
|
private void load(OverlayColourProvider colourProvider)
|
||||||
{
|
{
|
||||||
background.Colour = idleColour = colourProvider.Background4;
|
background.Colour = idleColour = colourProvider.Background3;
|
||||||
hoverColour = colourProvider.Background3;
|
hoverColour = colourProvider.Background2;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override bool OnHover(HoverEvent e)
|
protected override bool OnHover(HoverEvent e)
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
// 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.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
|
using System;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using JetBrains.Annotations;
|
using JetBrains.Annotations;
|
||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
using osu.Framework.Extensions.Color4Extensions;
|
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Graphics.Containers;
|
using osu.Framework.Graphics.Containers;
|
||||||
using osu.Framework.Graphics.Shapes;
|
using osu.Framework.Graphics.Shapes;
|
||||||
@ -16,14 +16,16 @@ using osu.Game.Online.Leaderboards;
|
|||||||
using osu.Game.Rulesets.UI;
|
using osu.Game.Rulesets.UI;
|
||||||
using osu.Game.Scoring;
|
using osu.Game.Scoring;
|
||||||
using osuTK;
|
using osuTK;
|
||||||
using osuTK.Graphics;
|
|
||||||
|
|
||||||
namespace osu.Game.Overlays.Profile.Sections.Ranks
|
namespace osu.Game.Overlays.Profile.Sections.Ranks
|
||||||
{
|
{
|
||||||
public class DrawableProfileScore : CompositeDrawable
|
public class DrawableProfileScore : CompositeDrawable
|
||||||
{
|
{
|
||||||
|
private const int height = 40;
|
||||||
private const int performance_width = 80;
|
private const int performance_width = 80;
|
||||||
private const int content_padding = 10;
|
|
||||||
|
private const float performance_background_shear = 0.45f;
|
||||||
|
private static readonly float performance_background_width = performance_width + (height / 4f * MathF.Tan(performance_background_shear));
|
||||||
|
|
||||||
protected readonly ScoreInfo Score;
|
protected readonly ScoreInfo Score;
|
||||||
|
|
||||||
@ -38,7 +40,7 @@ namespace osu.Game.Overlays.Profile.Sections.Ranks
|
|||||||
Score = score;
|
Score = score;
|
||||||
|
|
||||||
RelativeSizeAxes = Axes.X;
|
RelativeSizeAxes = Axes.X;
|
||||||
Height = 40;
|
Height = height;
|
||||||
}
|
}
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader]
|
||||||
@ -51,7 +53,7 @@ namespace osu.Game.Overlays.Profile.Sections.Ranks
|
|||||||
new Container
|
new Container
|
||||||
{
|
{
|
||||||
RelativeSizeAxes = Axes.Both,
|
RelativeSizeAxes = Axes.Both,
|
||||||
Padding = new MarginPadding { Left = content_padding, Right = performance_width + content_padding },
|
Padding = new MarginPadding { Left = 10, Right = performance_width + 30 },
|
||||||
Children = new Drawable[]
|
Children = new Drawable[]
|
||||||
{
|
{
|
||||||
new FillFlowContainer
|
new FillFlowContainer
|
||||||
@ -142,20 +144,26 @@ namespace osu.Game.Overlays.Profile.Sections.Ranks
|
|||||||
{
|
{
|
||||||
new Box
|
new Box
|
||||||
{
|
{
|
||||||
RelativeSizeAxes = Axes.Both,
|
Anchor = Anchor.TopRight,
|
||||||
Size = new Vector2(1, 0.5f),
|
Origin = Anchor.TopRight,
|
||||||
Colour = Color4.Black.Opacity(0.5f),
|
RelativeSizeAxes = Axes.Y,
|
||||||
Shear = new Vector2(-0.45f, 0),
|
Width = performance_background_width,
|
||||||
|
Height = 0.5f,
|
||||||
|
Colour = colourProvider.Background4,
|
||||||
|
Shear = new Vector2(-performance_background_shear, 0),
|
||||||
EdgeSmoothness = new Vector2(2, 0),
|
EdgeSmoothness = new Vector2(2, 0),
|
||||||
},
|
},
|
||||||
new Box
|
new Box
|
||||||
{
|
{
|
||||||
RelativeSizeAxes = Axes.Both,
|
Anchor = Anchor.TopRight,
|
||||||
|
Origin = Anchor.TopRight,
|
||||||
|
RelativeSizeAxes = Axes.Y,
|
||||||
RelativePositionAxes = Axes.Y,
|
RelativePositionAxes = Axes.Y,
|
||||||
Size = new Vector2(1, -0.5f),
|
Width = performance_background_width,
|
||||||
|
Height = -0.5f,
|
||||||
Position = new Vector2(0, 1),
|
Position = new Vector2(0, 1),
|
||||||
Colour = Color4.Black.Opacity(0.5f),
|
Colour = colourProvider.Background4,
|
||||||
Shear = new Vector2(0.45f, 0),
|
Shear = new Vector2(performance_background_shear, 0),
|
||||||
EdgeSmoothness = new Vector2(2, 0),
|
EdgeSmoothness = new Vector2(2, 0),
|
||||||
},
|
},
|
||||||
createDrawablePerformance().With(d =>
|
createDrawablePerformance().With(d =>
|
||||||
|
@ -1,9 +1,11 @@
|
|||||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
// 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.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
|
using System.Linq;
|
||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Graphics.Containers;
|
using osu.Framework.Graphics.Containers;
|
||||||
|
using osu.Framework.Graphics.Sprites;
|
||||||
using osu.Game.Graphics;
|
using osu.Game.Graphics;
|
||||||
using osu.Game.Graphics.Containers;
|
using osu.Game.Graphics.Containers;
|
||||||
using osu.Game.Online.API;
|
using osu.Game.Online.API;
|
||||||
@ -11,12 +13,19 @@ using osu.Game.Online.API.Requests;
|
|||||||
using osu.Game.Online.API.Requests.Responses;
|
using osu.Game.Online.API.Requests.Responses;
|
||||||
using osu.Game.Online.Chat;
|
using osu.Game.Online.Chat;
|
||||||
using osu.Game.Online.Leaderboards;
|
using osu.Game.Online.Leaderboards;
|
||||||
|
using osu.Game.Rulesets;
|
||||||
|
|
||||||
namespace osu.Game.Overlays.Profile.Sections.Recent
|
namespace osu.Game.Overlays.Profile.Sections.Recent
|
||||||
{
|
{
|
||||||
public class DrawableRecentActivity : DrawableProfileRow
|
public class DrawableRecentActivity : CompositeDrawable
|
||||||
{
|
{
|
||||||
private IAPIProvider api;
|
private const int font_size = 14;
|
||||||
|
|
||||||
|
[Resolved]
|
||||||
|
private IAPIProvider api { get; set; }
|
||||||
|
|
||||||
|
[Resolved]
|
||||||
|
private RulesetStore rulesets { get; set; }
|
||||||
|
|
||||||
private readonly APIRecentActivity activity;
|
private readonly APIRecentActivity activity;
|
||||||
|
|
||||||
@ -28,139 +37,191 @@ namespace osu.Game.Overlays.Profile.Sections.Recent
|
|||||||
}
|
}
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader]
|
||||||
private void load(IAPIProvider api)
|
private void load(OverlayColourProvider colourProvider)
|
||||||
{
|
{
|
||||||
this.api = api;
|
RelativeSizeAxes = Axes.X;
|
||||||
|
AutoSizeAxes = Axes.Y;
|
||||||
LeftFlowContainer.Padding = new MarginPadding { Left = 10, Right = 160 };
|
AddInternal(new GridContainer
|
||||||
|
|
||||||
LeftFlowContainer.Add(content = new LinkFlowContainer
|
|
||||||
{
|
{
|
||||||
|
RelativeSizeAxes = Axes.X,
|
||||||
|
AutoSizeAxes = Axes.Y,
|
||||||
|
ColumnDimensions = new[]
|
||||||
|
{
|
||||||
|
new Dimension(GridSizeMode.Absolute, size: 28),
|
||||||
|
new Dimension(),
|
||||||
|
new Dimension(GridSizeMode.AutoSize)
|
||||||
|
},
|
||||||
|
RowDimensions = new[]
|
||||||
|
{
|
||||||
|
new Dimension(GridSizeMode.AutoSize)
|
||||||
|
},
|
||||||
|
Content = new[]
|
||||||
|
{
|
||||||
|
new Drawable[]
|
||||||
|
{
|
||||||
|
new Container
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.X,
|
||||||
|
AutoSizeAxes = Axes.Y,
|
||||||
|
Child = createIcon().With(icon =>
|
||||||
|
{
|
||||||
|
icon.Anchor = Anchor.Centre;
|
||||||
|
icon.Origin = Anchor.Centre;
|
||||||
|
})
|
||||||
|
},
|
||||||
|
content = new LinkFlowContainer(t => t.Font = OsuFont.GetFont(size: font_size))
|
||||||
|
{
|
||||||
|
Anchor = Anchor.CentreLeft,
|
||||||
|
Origin = Anchor.CentreLeft,
|
||||||
AutoSizeAxes = Axes.Y,
|
AutoSizeAxes = Axes.Y,
|
||||||
RelativeSizeAxes = Axes.X,
|
RelativeSizeAxes = Axes.X,
|
||||||
});
|
},
|
||||||
|
new DrawableDate(activity.CreatedAt)
|
||||||
RightFlowContainer.Add(new DrawableDate(activity.CreatedAt)
|
|
||||||
{
|
{
|
||||||
Font = OsuFont.GetFont(size: 13),
|
Anchor = Anchor.CentreRight,
|
||||||
Colour = OsuColour.Gray(0xAA),
|
Origin = Anchor.CentreRight,
|
||||||
Anchor = Anchor.TopRight,
|
Colour = colourProvider.Foreground1,
|
||||||
Origin = Anchor.TopRight,
|
Font = OsuFont.GetFont(size: font_size),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
var formatted = createMessage();
|
createMessage();
|
||||||
|
|
||||||
content.AddLinks(formatted.Text, formatted.Links);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override Drawable CreateLeftVisual()
|
private Drawable createIcon()
|
||||||
{
|
{
|
||||||
switch (activity.Type)
|
switch (activity.Type)
|
||||||
{
|
{
|
||||||
case RecentActivityType.Rank:
|
case RecentActivityType.Rank:
|
||||||
return new UpdateableRank(activity.ScoreRank)
|
return new UpdateableRank(activity.ScoreRank)
|
||||||
{
|
{
|
||||||
RelativeSizeAxes = Axes.Y,
|
RelativeSizeAxes = Axes.X,
|
||||||
Width = 60,
|
Height = 11,
|
||||||
FillMode = FillMode.Fit,
|
FillMode = FillMode.Fit,
|
||||||
|
Margin = new MarginPadding { Top = 2 }
|
||||||
};
|
};
|
||||||
|
|
||||||
case RecentActivityType.Achievement:
|
case RecentActivityType.Achievement:
|
||||||
return new DelayedLoadWrapper(new MedalIcon(activity.Achievement.Slug)
|
return new DelayedLoadWrapper(new MedalIcon(activity.Achievement.Slug)
|
||||||
{
|
{
|
||||||
|
Anchor = Anchor.Centre,
|
||||||
|
Origin = Anchor.Centre,
|
||||||
RelativeSizeAxes = Axes.Both,
|
RelativeSizeAxes = Axes.Both,
|
||||||
FillMode = FillMode.Fit,
|
FillMode = FillMode.Fit,
|
||||||
})
|
})
|
||||||
{
|
{
|
||||||
RelativeSizeAxes = Axes.Y,
|
RelativeSizeAxes = Axes.X,
|
||||||
Width = 60,
|
Width = 0.5f,
|
||||||
|
Height = 18
|
||||||
};
|
};
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return new Container
|
return Empty();
|
||||||
{
|
|
||||||
RelativeSizeAxes = Axes.Y,
|
|
||||||
Width = 60,
|
|
||||||
FillMode = FillMode.Fit,
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private string toAbsoluteUrl(string url) => $"{api.Endpoint}{url}";
|
private void createMessage()
|
||||||
|
|
||||||
private MessageFormatter.MessageFormatterResult createMessage()
|
|
||||||
{
|
{
|
||||||
string userLinkTemplate() => $"[{toAbsoluteUrl(activity.User?.Url)} {activity.User?.Username}]";
|
|
||||||
string beatmapLinkTemplate() => $"[{toAbsoluteUrl(activity.Beatmap?.Url)} {activity.Beatmap?.Title}]";
|
|
||||||
string beatmapsetLinkTemplate() => $"[{toAbsoluteUrl(activity.Beatmapset?.Url)} {activity.Beatmapset?.Title}]";
|
|
||||||
|
|
||||||
string message;
|
|
||||||
|
|
||||||
switch (activity.Type)
|
switch (activity.Type)
|
||||||
{
|
{
|
||||||
case RecentActivityType.Achievement:
|
case RecentActivityType.Achievement:
|
||||||
message = $"{userLinkTemplate()} unlocked the {activity.Achievement.Name} medal!";
|
addUserLink();
|
||||||
|
addText($" unlocked the \"{activity.Achievement.Name}\" medal!");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case RecentActivityType.BeatmapPlaycount:
|
case RecentActivityType.BeatmapPlaycount:
|
||||||
message = $"{beatmapLinkTemplate()} has been played {activity.Count} times!";
|
addBeatmapLink();
|
||||||
|
addText($" has been played {activity.Count} times!");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case RecentActivityType.BeatmapsetApprove:
|
case RecentActivityType.BeatmapsetApprove:
|
||||||
message = $"{beatmapsetLinkTemplate()} has been {activity.Approval.ToString().ToLowerInvariant()}!";
|
addBeatmapsetLink();
|
||||||
|
addText($" has been {activity.Approval.ToString().ToLowerInvariant()}!");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case RecentActivityType.BeatmapsetDelete:
|
case RecentActivityType.BeatmapsetDelete:
|
||||||
message = $"{beatmapsetLinkTemplate()} has been deleted.";
|
addBeatmapsetLink();
|
||||||
|
addText(" has been deleted.");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case RecentActivityType.BeatmapsetRevive:
|
case RecentActivityType.BeatmapsetRevive:
|
||||||
message = $"{beatmapsetLinkTemplate()} has been revived from eternal slumber by {userLinkTemplate()}.";
|
addBeatmapsetLink();
|
||||||
|
addText(" has been revived from eternal slumber by ");
|
||||||
|
addUserLink();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case RecentActivityType.BeatmapsetUpdate:
|
case RecentActivityType.BeatmapsetUpdate:
|
||||||
message = $"{userLinkTemplate()} has updated the beatmap {beatmapsetLinkTemplate()}!";
|
addUserLink();
|
||||||
|
addText(" has updated the beatmap ");
|
||||||
|
addBeatmapsetLink();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case RecentActivityType.BeatmapsetUpload:
|
case RecentActivityType.BeatmapsetUpload:
|
||||||
message = $"{userLinkTemplate()} has submitted a new beatmap {beatmapsetLinkTemplate()}!";
|
addUserLink();
|
||||||
|
addText(" has submitted a new beatmap ");
|
||||||
|
addBeatmapsetLink();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case RecentActivityType.Medal:
|
case RecentActivityType.Medal:
|
||||||
// apparently this shouldn't exist look at achievement instead (https://github.com/ppy/osu-web/blob/master/resources/assets/coffee/react/profile-page/recent-activity.coffee#L111)
|
// apparently this shouldn't exist look at achievement instead (https://github.com/ppy/osu-web/blob/master/resources/assets/coffee/react/profile-page/recent-activity.coffee#L111)
|
||||||
message = string.Empty;
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case RecentActivityType.Rank:
|
case RecentActivityType.Rank:
|
||||||
message = $"{userLinkTemplate()} achieved rank #{activity.Rank} on {beatmapLinkTemplate()} ({activity.Mode}!)";
|
addUserLink();
|
||||||
|
addText($" achieved rank #{activity.Rank} on ");
|
||||||
|
addBeatmapLink();
|
||||||
|
addText($" ({getRulesetName()})");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case RecentActivityType.RankLost:
|
case RecentActivityType.RankLost:
|
||||||
message = $"{userLinkTemplate()} has lost first place on {beatmapLinkTemplate()} ({activity.Mode}!)";
|
addUserLink();
|
||||||
|
addText(" has lost first place on ");
|
||||||
|
addBeatmapLink();
|
||||||
|
addText($" ({getRulesetName()})");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case RecentActivityType.UserSupportAgain:
|
case RecentActivityType.UserSupportAgain:
|
||||||
message = $"{userLinkTemplate()} has once again chosen to support osu! - thanks for your generosity!";
|
addUserLink();
|
||||||
|
addText(" has once again chosen to support osu! - thanks for your generosity!");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case RecentActivityType.UserSupportFirst:
|
case RecentActivityType.UserSupportFirst:
|
||||||
message = $"{userLinkTemplate()} has become an osu!supporter - thanks for your generosity!";
|
addUserLink();
|
||||||
|
addText(" has become an osu!supporter - thanks for your generosity!");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case RecentActivityType.UserSupportGift:
|
case RecentActivityType.UserSupportGift:
|
||||||
message = $"{userLinkTemplate()} has received the gift of osu!supporter!";
|
addUserLink();
|
||||||
|
addText(" has received the gift of osu!supporter!");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case RecentActivityType.UsernameChange:
|
case RecentActivityType.UsernameChange:
|
||||||
message = $"{activity.User?.PreviousUsername} has changed their username to {userLinkTemplate()}!";
|
addText($"{activity.User?.PreviousUsername} has changed their username to ");
|
||||||
break;
|
addUserLink();
|
||||||
|
|
||||||
default:
|
|
||||||
message = string.Empty;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return MessageFormatter.FormatText(message);
|
private string getRulesetName() =>
|
||||||
}
|
rulesets.AvailableRulesets.FirstOrDefault(r => r.ShortName == activity.Mode)?.Name ?? activity.Mode;
|
||||||
|
|
||||||
|
private void addUserLink()
|
||||||
|
=> content.AddLink(activity.User?.Username, LinkAction.OpenUserProfile, getLinkArgument(activity.User?.Url), creationParameters: t => t.Font = getLinkFont(FontWeight.Bold));
|
||||||
|
|
||||||
|
private void addBeatmapLink()
|
||||||
|
=> content.AddLink(activity.Beatmap?.Title, LinkAction.OpenBeatmap, getLinkArgument(activity.Beatmap?.Url), creationParameters: t => t.Font = getLinkFont());
|
||||||
|
|
||||||
|
private void addBeatmapsetLink()
|
||||||
|
=> content.AddLink(activity.Beatmapset?.Title, LinkAction.OpenBeatmapSet, getLinkArgument(activity.Beatmapset?.Url), creationParameters: t => t.Font = getLinkFont());
|
||||||
|
|
||||||
|
private string getLinkArgument(string url) => MessageFormatter.GetLinkDetails($"{api.Endpoint}{url}").Argument;
|
||||||
|
|
||||||
|
private FontUsage getLinkFont(FontWeight fontWeight = FontWeight.Regular)
|
||||||
|
=> OsuFont.GetFont(size: font_size, weight: fontWeight, italics: true);
|
||||||
|
|
||||||
|
private void addText(string text)
|
||||||
|
=> content.AddText(text, t => t.Font = OsuFont.GetFont(size: font_size, weight: FontWeight.SemiBold));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -23,8 +23,7 @@ namespace osu.Game.Overlays.Profile.Sections.Recent
|
|||||||
|
|
||||||
Child = sprite = new Sprite
|
Child = sprite = new Sprite
|
||||||
{
|
{
|
||||||
Height = 40,
|
RelativeSizeAxes = Axes.Both,
|
||||||
Width = 40,
|
|
||||||
Anchor = Anchor.Centre,
|
Anchor = Anchor.Centre,
|
||||||
Origin = Anchor.Centre,
|
Origin = Anchor.Centre,
|
||||||
};
|
};
|
||||||
|
@ -8,6 +8,7 @@ using osu.Framework.Bindables;
|
|||||||
using osu.Game.Online.API.Requests.Responses;
|
using osu.Game.Online.API.Requests.Responses;
|
||||||
using osu.Game.Online.API;
|
using osu.Game.Online.API;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using osuTK;
|
||||||
|
|
||||||
namespace osu.Game.Overlays.Profile.Sections.Recent
|
namespace osu.Game.Overlays.Profile.Sections.Recent
|
||||||
{
|
{
|
||||||
@ -16,7 +17,8 @@ namespace osu.Game.Overlays.Profile.Sections.Recent
|
|||||||
public PaginatedRecentActivityContainer(Bindable<User> user, string header, string missing)
|
public PaginatedRecentActivityContainer(Bindable<User> user, string header, string missing)
|
||||||
: base(user, header, missing)
|
: base(user, header, missing)
|
||||||
{
|
{
|
||||||
ItemsPerPage = 5;
|
ItemsPerPage = 10;
|
||||||
|
ItemsContainer.Spacing = new Vector2(0, 8);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override APIRequest<List<APIRecentActivity>> CreateRequest() =>
|
protected override APIRequest<List<APIRecentActivity>> CreateRequest() =>
|
||||||
|
@ -99,7 +99,7 @@ namespace osu.Game.Overlays.Toolbar
|
|||||||
{
|
{
|
||||||
int requested = e.Key - Key.Number1;
|
int requested = e.Key - Key.Number1;
|
||||||
|
|
||||||
RulesetInfo found = Rulesets.AvailableRulesets.Skip(requested).FirstOrDefault();
|
RulesetInfo found = Rulesets.AvailableRulesets.ElementAtOrDefault(requested);
|
||||||
if (found != null)
|
if (found != null)
|
||||||
Current.Value = found;
|
Current.Value = found;
|
||||||
return true;
|
return true;
|
||||||
|
@ -67,7 +67,7 @@ namespace osu.Game.Overlays
|
|||||||
RelativeSizeAxes = Axes.X,
|
RelativeSizeAxes = Axes.X,
|
||||||
Anchor = Anchor.TopCentre,
|
Anchor = Anchor.TopCentre,
|
||||||
Origin = Anchor.TopCentre,
|
Origin = Anchor.TopCentre,
|
||||||
Height = 30
|
Height = 34
|
||||||
};
|
};
|
||||||
|
|
||||||
Add(new Box
|
Add(new Box
|
||||||
|
@ -154,7 +154,7 @@ namespace osu.Game.Rulesets.Edit
|
|||||||
{
|
{
|
||||||
if (e.Key >= Key.Number1 && e.Key <= Key.Number9)
|
if (e.Key >= Key.Number1 && e.Key <= Key.Number9)
|
||||||
{
|
{
|
||||||
var item = toolboxCollection.Items.Skip(e.Key - Key.Number1).FirstOrDefault();
|
var item = toolboxCollection.Items.ElementAtOrDefault(e.Key - Key.Number1);
|
||||||
|
|
||||||
if (item != null)
|
if (item != null)
|
||||||
{
|
{
|
||||||
|
@ -34,7 +34,7 @@ namespace osu.Game.Rulesets.Objects
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public event Action DefaultsApplied;
|
public event Action DefaultsApplied;
|
||||||
|
|
||||||
public readonly Bindable<double> StartTimeBindable = new Bindable<double>();
|
public readonly Bindable<double> StartTimeBindable = new BindableDouble();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The time at which the HitObject starts.
|
/// The time at which the HitObject starts.
|
||||||
|
@ -220,9 +220,11 @@ namespace osu.Game.Scoring.Legacy
|
|||||||
float lastTime = 0;
|
float lastTime = 0;
|
||||||
ReplayFrame currentFrame = null;
|
ReplayFrame currentFrame = null;
|
||||||
|
|
||||||
foreach (var l in reader.ReadToEnd().Split(','))
|
var frames = reader.ReadToEnd().Split(',');
|
||||||
|
|
||||||
|
for (var i = 0; i < frames.Length; i++)
|
||||||
{
|
{
|
||||||
var split = l.Split('|');
|
var split = frames[i].Split('|');
|
||||||
|
|
||||||
if (split.Length < 4)
|
if (split.Length < 4)
|
||||||
continue;
|
continue;
|
||||||
@ -234,8 +236,14 @@ namespace osu.Game.Scoring.Legacy
|
|||||||
}
|
}
|
||||||
|
|
||||||
var diff = Parsing.ParseFloat(split[0]);
|
var diff = Parsing.ParseFloat(split[0]);
|
||||||
|
|
||||||
lastTime += diff;
|
lastTime += diff;
|
||||||
|
|
||||||
|
if (i == 0 && diff == 0)
|
||||||
|
// osu-stable adds a zero-time frame before potentially valid negative user frames.
|
||||||
|
// we need to ignore this.
|
||||||
|
continue;
|
||||||
|
|
||||||
// Todo: At some point we probably want to rewind and play back the negative-time frames
|
// Todo: At some point we probably want to rewind and play back the negative-time frames
|
||||||
// but for now we'll achieve equal playback to stable by skipping negative frames
|
// but for now we'll achieve equal playback to stable by skipping negative frames
|
||||||
if (diff < 0)
|
if (diff < 0)
|
||||||
|
@ -36,7 +36,7 @@ namespace osu.Game.Screens.Backgrounds
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// The amount of blur to be applied in addition to user-specified blur.
|
/// The amount of blur to be applied in addition to user-specified blur.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public readonly Bindable<float> BlurAmount = new Bindable<float>();
|
public readonly Bindable<float> BlurAmount = new BindableFloat();
|
||||||
|
|
||||||
internal readonly IBindable<bool> IsBreakTime = new Bindable<bool>();
|
internal readonly IBindable<bool> IsBreakTime = new Bindable<bool>();
|
||||||
|
|
||||||
@ -119,7 +119,7 @@ namespace osu.Game.Screens.Backgrounds
|
|||||||
/// <remarks>
|
/// <remarks>
|
||||||
/// Used in contexts where there can potentially be both user and screen-specified blurring occuring at the same time, such as in <see cref="PlayerLoader"/>
|
/// Used in contexts where there can potentially be both user and screen-specified blurring occuring at the same time, such as in <see cref="PlayerLoader"/>
|
||||||
/// </remarks>
|
/// </remarks>
|
||||||
public readonly Bindable<float> BlurAmount = new Bindable<float>();
|
public readonly Bindable<float> BlurAmount = new BindableFloat();
|
||||||
|
|
||||||
public Background Background
|
public Background Background
|
||||||
{
|
{
|
||||||
|
@ -16,6 +16,7 @@ using System.Collections.Generic;
|
|||||||
using osu.Game.Rulesets.Mods;
|
using osu.Game.Rulesets.Mods;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using osu.Framework.Threading;
|
using osu.Framework.Threading;
|
||||||
|
using osu.Framework.Utils;
|
||||||
using osu.Game.Configuration;
|
using osu.Game.Configuration;
|
||||||
using osu.Game.Overlays.Settings;
|
using osu.Game.Overlays.Settings;
|
||||||
|
|
||||||
@ -26,7 +27,8 @@ namespace osu.Game.Screens.Select.Details
|
|||||||
[Resolved]
|
[Resolved]
|
||||||
private IBindable<IReadOnlyList<Mod>> mods { get; set; }
|
private IBindable<IReadOnlyList<Mod>> mods { get; set; }
|
||||||
|
|
||||||
private readonly StatisticRow firstValue, hpDrain, accuracy, approachRate, starDifficulty;
|
protected readonly StatisticRow FirstValue, HpDrain, Accuracy, ApproachRate;
|
||||||
|
private readonly StatisticRow starDifficulty;
|
||||||
|
|
||||||
private BeatmapInfo beatmap;
|
private BeatmapInfo beatmap;
|
||||||
|
|
||||||
@ -52,10 +54,10 @@ namespace osu.Game.Screens.Select.Details
|
|||||||
Spacing = new Vector2(4f),
|
Spacing = new Vector2(4f),
|
||||||
Children = new[]
|
Children = new[]
|
||||||
{
|
{
|
||||||
firstValue = new StatisticRow(), //circle size/key amount
|
FirstValue = new StatisticRow(), //circle size/key amount
|
||||||
hpDrain = new StatisticRow { Title = "HP Drain" },
|
HpDrain = new StatisticRow { Title = "HP Drain" },
|
||||||
accuracy = new StatisticRow { Title = "Accuracy" },
|
Accuracy = new StatisticRow { Title = "Accuracy" },
|
||||||
approachRate = new StatisticRow { Title = "Approach Rate" },
|
ApproachRate = new StatisticRow { Title = "Approach Rate" },
|
||||||
starDifficulty = new StatisticRow(10, true) { Title = "Star Difficulty" },
|
starDifficulty = new StatisticRow(10, true) { Title = "Star Difficulty" },
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
@ -122,24 +124,24 @@ namespace osu.Game.Screens.Select.Details
|
|||||||
case 3:
|
case 3:
|
||||||
// Account for mania differences locally for now
|
// Account for mania differences locally for now
|
||||||
// Eventually this should be handled in a more modular way, allowing rulesets to return arbitrary difficulty attributes
|
// Eventually this should be handled in a more modular way, allowing rulesets to return arbitrary difficulty attributes
|
||||||
firstValue.Title = "Key Count";
|
FirstValue.Title = "Key Count";
|
||||||
firstValue.Value = (baseDifficulty?.CircleSize ?? 0, null);
|
FirstValue.Value = (baseDifficulty?.CircleSize ?? 0, null);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
firstValue.Title = "Circle Size";
|
FirstValue.Title = "Circle Size";
|
||||||
firstValue.Value = (baseDifficulty?.CircleSize ?? 0, adjustedDifficulty?.CircleSize);
|
FirstValue.Value = (baseDifficulty?.CircleSize ?? 0, adjustedDifficulty?.CircleSize);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
starDifficulty.Value = ((float)(Beatmap?.StarDifficulty ?? 0), null);
|
starDifficulty.Value = ((float)(Beatmap?.StarDifficulty ?? 0), null);
|
||||||
|
|
||||||
hpDrain.Value = (baseDifficulty?.DrainRate ?? 0, adjustedDifficulty?.DrainRate);
|
HpDrain.Value = (baseDifficulty?.DrainRate ?? 0, adjustedDifficulty?.DrainRate);
|
||||||
accuracy.Value = (baseDifficulty?.OverallDifficulty ?? 0, adjustedDifficulty?.OverallDifficulty);
|
Accuracy.Value = (baseDifficulty?.OverallDifficulty ?? 0, adjustedDifficulty?.OverallDifficulty);
|
||||||
approachRate.Value = (baseDifficulty?.ApproachRate ?? 0, adjustedDifficulty?.ApproachRate);
|
ApproachRate.Value = (baseDifficulty?.ApproachRate ?? 0, adjustedDifficulty?.ApproachRate);
|
||||||
}
|
}
|
||||||
|
|
||||||
private class StatisticRow : Container, IHasAccentColour
|
public class StatisticRow : Container, IHasAccentColour
|
||||||
{
|
{
|
||||||
private const float value_width = 25;
|
private const float value_width = 25;
|
||||||
private const float name_width = 70;
|
private const float name_width = 70;
|
||||||
@ -147,7 +149,8 @@ namespace osu.Game.Screens.Select.Details
|
|||||||
private readonly float maxValue;
|
private readonly float maxValue;
|
||||||
private readonly bool forceDecimalPlaces;
|
private readonly bool forceDecimalPlaces;
|
||||||
private readonly OsuSpriteText name, valueText;
|
private readonly OsuSpriteText name, valueText;
|
||||||
private readonly Bar bar, modBar;
|
private readonly Bar bar;
|
||||||
|
public readonly Bar ModBar;
|
||||||
|
|
||||||
[Resolved]
|
[Resolved]
|
||||||
private OsuColour colours { get; set; }
|
private OsuColour colours { get; set; }
|
||||||
@ -173,14 +176,14 @@ namespace osu.Game.Screens.Select.Details
|
|||||||
bar.Length = value.baseValue / maxValue;
|
bar.Length = value.baseValue / maxValue;
|
||||||
|
|
||||||
valueText.Text = (value.adjustedValue ?? value.baseValue).ToString(forceDecimalPlaces ? "0.00" : "0.##");
|
valueText.Text = (value.adjustedValue ?? value.baseValue).ToString(forceDecimalPlaces ? "0.00" : "0.##");
|
||||||
modBar.Length = (value.adjustedValue ?? 0) / maxValue;
|
ModBar.Length = (value.adjustedValue ?? 0) / maxValue;
|
||||||
|
|
||||||
if (value.adjustedValue > value.baseValue)
|
if (Precision.AlmostEquals(value.baseValue, value.adjustedValue ?? value.baseValue, 0.05f))
|
||||||
modBar.AccentColour = valueText.Colour = colours.Red;
|
ModBar.AccentColour = valueText.Colour = Color4.White;
|
||||||
|
else if (value.adjustedValue > value.baseValue)
|
||||||
|
ModBar.AccentColour = valueText.Colour = colours.Red;
|
||||||
else if (value.adjustedValue < value.baseValue)
|
else if (value.adjustedValue < value.baseValue)
|
||||||
modBar.AccentColour = valueText.Colour = colours.BlueDark;
|
ModBar.AccentColour = valueText.Colour = colours.BlueDark;
|
||||||
else
|
|
||||||
modBar.AccentColour = valueText.Colour = Color4.White;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -217,7 +220,7 @@ namespace osu.Game.Screens.Select.Details
|
|||||||
BackgroundColour = Color4.White.Opacity(0.5f),
|
BackgroundColour = Color4.White.Opacity(0.5f),
|
||||||
Padding = new MarginPadding { Left = name_width + 10, Right = value_width + 10 },
|
Padding = new MarginPadding { Left = name_width + 10, Right = value_width + 10 },
|
||||||
},
|
},
|
||||||
modBar = new Bar
|
ModBar = new Bar
|
||||||
{
|
{
|
||||||
Origin = Anchor.CentreLeft,
|
Origin = Anchor.CentreLeft,
|
||||||
Anchor = Anchor.CentreLeft,
|
Anchor = Anchor.CentreLeft,
|
||||||
|
@ -149,8 +149,8 @@ namespace osu.Game.Screens.Select
|
|||||||
private readonly IBindable<RulesetInfo> ruleset = new Bindable<RulesetInfo>();
|
private readonly IBindable<RulesetInfo> ruleset = new Bindable<RulesetInfo>();
|
||||||
|
|
||||||
private readonly Bindable<bool> showConverted = new Bindable<bool>();
|
private readonly Bindable<bool> showConverted = new Bindable<bool>();
|
||||||
private readonly Bindable<double> minimumStars = new Bindable<double>();
|
private readonly Bindable<double> minimumStars = new BindableDouble();
|
||||||
private readonly Bindable<double> maximumStars = new Bindable<double>();
|
private readonly Bindable<double> maximumStars = new BindableDouble();
|
||||||
|
|
||||||
public readonly Box Background;
|
public readonly Box Background;
|
||||||
|
|
||||||
|
@ -345,8 +345,8 @@ namespace osu.Game.Screens.Select
|
|||||||
selectionChangedDebounce = null;
|
selectionChangedDebounce = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (performStartAction)
|
if (performStartAction && OnStart())
|
||||||
OnStart();
|
Carousel.AllowSelection = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -500,6 +500,8 @@ namespace osu.Game.Screens.Select
|
|||||||
|
|
||||||
public override void OnResuming(IScreen last)
|
public override void OnResuming(IScreen last)
|
||||||
{
|
{
|
||||||
|
Carousel.AllowSelection = true;
|
||||||
|
|
||||||
BeatmapDetails.Leaderboard.RefreshScores();
|
BeatmapDetails.Leaderboard.RefreshScores();
|
||||||
|
|
||||||
Beatmap.Value.Track.Looping = true;
|
Beatmap.Value.Track.Looping = true;
|
||||||
@ -647,7 +649,6 @@ namespace osu.Game.Screens.Select
|
|||||||
decoupledRuleset.ValueChanged += r => Ruleset.Value = r.NewValue;
|
decoupledRuleset.ValueChanged += r => Ruleset.Value = r.NewValue;
|
||||||
decoupledRuleset.DisabledChanged += r => Ruleset.Disabled = r;
|
decoupledRuleset.DisabledChanged += r => Ruleset.Disabled = r;
|
||||||
|
|
||||||
Beatmap.BindDisabledChanged(disabled => Carousel.AllowSelection = !disabled, true);
|
|
||||||
Beatmap.BindValueChanged(workingBeatmapChanged);
|
Beatmap.BindValueChanged(workingBeatmapChanged);
|
||||||
|
|
||||||
boundLocalBindables = true;
|
boundLocalBindables = true;
|
||||||
|
@ -33,8 +33,10 @@ namespace osu.Game.Tests.Visual
|
|||||||
}
|
}
|
||||||
|
|
||||||
[SetUpSteps]
|
[SetUpSteps]
|
||||||
public virtual void SetUpSteps()
|
public override void SetUpSteps()
|
||||||
{
|
{
|
||||||
|
base.SetUpSteps();
|
||||||
|
|
||||||
AddStep(ruleset.RulesetInfo.Name, loadPlayer);
|
AddStep(ruleset.RulesetInfo.Name, loadPlayer);
|
||||||
AddUntilStep("player loaded", () => Player.IsLoaded && Player.Alpha == 1);
|
AddUntilStep("player loaded", () => Player.IsLoaded && Player.Alpha == 1);
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Graphics.Containers;
|
using osu.Framework.Graphics.Containers;
|
||||||
|
using osu.Framework.Testing;
|
||||||
using osu.Game.Screens;
|
using osu.Game.Screens;
|
||||||
|
|
||||||
namespace osu.Game.Tests.Visual
|
namespace osu.Game.Tests.Visual
|
||||||
@ -27,11 +28,23 @@ namespace osu.Game.Tests.Visual
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void LoadScreen(OsuScreen screen)
|
protected void LoadScreen(OsuScreen screen) => Stack.Push(screen);
|
||||||
|
|
||||||
|
[SetUpSteps]
|
||||||
|
public virtual void SetUpSteps() => addExitAllScreensStep();
|
||||||
|
|
||||||
|
[TearDownSteps]
|
||||||
|
public void TearDownSteps() => addExitAllScreensStep();
|
||||||
|
|
||||||
|
private void addExitAllScreensStep()
|
||||||
{
|
{
|
||||||
if (Stack.CurrentScreen != null)
|
AddUntilStep("exit all screens", () =>
|
||||||
|
{
|
||||||
|
if (Stack.CurrentScreen == null) return true;
|
||||||
|
|
||||||
Stack.Exit();
|
Stack.Exit();
|
||||||
Stack.Push(screen);
|
return false;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -47,7 +47,7 @@ namespace osu.Game.Tests.Visual
|
|||||||
public readonly Bindable<ScrollingDirection> Direction = new Bindable<ScrollingDirection>();
|
public readonly Bindable<ScrollingDirection> Direction = new Bindable<ScrollingDirection>();
|
||||||
IBindable<ScrollingDirection> IScrollingInfo.Direction => Direction;
|
IBindable<ScrollingDirection> IScrollingInfo.Direction => Direction;
|
||||||
|
|
||||||
public readonly Bindable<double> TimeRange = new Bindable<double>(1000) { Value = 1000 };
|
public readonly Bindable<double> TimeRange = new BindableDouble(1000) { Value = 1000 };
|
||||||
IBindable<double> IScrollingInfo.TimeRange => TimeRange;
|
IBindable<double> IScrollingInfo.TimeRange => TimeRange;
|
||||||
|
|
||||||
public readonly TestScrollAlgorithm Algorithm = new TestScrollAlgorithm();
|
public readonly TestScrollAlgorithm Algorithm = new TestScrollAlgorithm();
|
||||||
|
@ -23,7 +23,7 @@
|
|||||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite.Core" Version="2.2.6" />
|
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite.Core" Version="2.2.6" />
|
||||||
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
|
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
|
||||||
<PackageReference Include="ppy.osu.Game.Resources" Version="2019.1230.0" />
|
<PackageReference Include="ppy.osu.Game.Resources" Version="2019.1230.0" />
|
||||||
<PackageReference Include="ppy.osu.Framework" Version="2020.125.0" />
|
<PackageReference Include="ppy.osu.Framework" Version="2020.131.0" />
|
||||||
<PackageReference Include="Sentry" Version="1.2.0" />
|
<PackageReference Include="Sentry" Version="1.2.0" />
|
||||||
<PackageReference Include="SharpCompress" Version="0.24.0" />
|
<PackageReference Include="SharpCompress" Version="0.24.0" />
|
||||||
<PackageReference Include="NUnit" Version="3.12.0" />
|
<PackageReference Include="NUnit" Version="3.12.0" />
|
||||||
|
@ -74,7 +74,7 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup Label="Package References">
|
<ItemGroup Label="Package References">
|
||||||
<PackageReference Include="ppy.osu.Game.Resources" Version="2019.1230.0" />
|
<PackageReference Include="ppy.osu.Game.Resources" Version="2019.1230.0" />
|
||||||
<PackageReference Include="ppy.osu.Framework.iOS" Version="2020.125.0" />
|
<PackageReference Include="ppy.osu.Framework.iOS" Version="2020.131.0" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<!-- Xamarin.iOS does not automatically handle transitive dependencies from NuGet packages. -->
|
<!-- Xamarin.iOS does not automatically handle transitive dependencies from NuGet packages. -->
|
||||||
<ItemGroup Label="Transitive Dependencies">
|
<ItemGroup Label="Transitive Dependencies">
|
||||||
@ -82,7 +82,7 @@
|
|||||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="2.2.6" />
|
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="2.2.6" />
|
||||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite.Core" Version="2.2.6" />
|
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite.Core" Version="2.2.6" />
|
||||||
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
|
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
|
||||||
<PackageReference Include="ppy.osu.Framework" Version="2020.125.0" />
|
<PackageReference Include="ppy.osu.Framework" Version="2020.131.0" />
|
||||||
<PackageReference Include="SharpCompress" Version="0.24.0" />
|
<PackageReference Include="SharpCompress" Version="0.24.0" />
|
||||||
<PackageReference Include="NUnit" Version="3.12.0" />
|
<PackageReference Include="NUnit" Version="3.12.0" />
|
||||||
<PackageReference Include="SharpRaven" Version="2.4.0" />
|
<PackageReference Include="SharpRaven" Version="2.4.0" />
|
||||||
|
Loading…
Reference in New Issue
Block a user