mirror of
https://github.com/ppy/osu
synced 2025-02-23 14:17:03 +00:00
Merge branch 'master' into fix-holdnote-lenient-press
This commit is contained in:
commit
581155c719
@ -5,6 +5,6 @@
|
|||||||
"version": "3.1.100"
|
"version": "3.1.100"
|
||||||
},
|
},
|
||||||
"msbuild-sdks": {
|
"msbuild-sdks": {
|
||||||
"Microsoft.Build.Traversal": "2.0.50"
|
"Microsoft.Build.Traversal": "2.0.52"
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -36,7 +36,7 @@ namespace osu.Game.Rulesets.Osu.Tests
|
|||||||
|
|
||||||
private void testSingle(float circleSize, bool auto = false)
|
private void testSingle(float circleSize, bool auto = false)
|
||||||
{
|
{
|
||||||
var spinner = new Spinner { StartTime = Time.Current + 1000, EndTime = Time.Current + 4000 };
|
var spinner = new Spinner { StartTime = Time.Current + 2000, EndTime = Time.Current + 5000 };
|
||||||
|
|
||||||
spinner.ApplyDefaults(new ControlPointInfo(), new BeatmapDifficulty { CircleSize = circleSize });
|
spinner.ApplyDefaults(new ControlPointInfo(), new BeatmapDifficulty { CircleSize = circleSize });
|
||||||
|
|
||||||
|
@ -93,7 +93,10 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
|
|||||||
{
|
{
|
||||||
Background = new SpinnerBackground
|
Background = new SpinnerBackground
|
||||||
{
|
{
|
||||||
Alpha = 0.6f,
|
Disc =
|
||||||
|
{
|
||||||
|
Alpha = 0f,
|
||||||
|
},
|
||||||
Anchor = Anchor.Centre,
|
Anchor = Anchor.Centre,
|
||||||
Origin = Anchor.Centre,
|
Origin = Anchor.Centre,
|
||||||
},
|
},
|
||||||
@ -125,10 +128,10 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
|
|||||||
private void load(OsuColour colours)
|
private void load(OsuColour colours)
|
||||||
{
|
{
|
||||||
normalColour = baseColour;
|
normalColour = baseColour;
|
||||||
|
completeColour = colours.YellowLight;
|
||||||
|
|
||||||
Background.AccentColour = normalColour;
|
Background.AccentColour = normalColour;
|
||||||
|
Ticks.AccentColour = normalColour;
|
||||||
completeColour = colours.YellowLight.Opacity(0.75f);
|
|
||||||
|
|
||||||
Disc.AccentColour = fillColour;
|
Disc.AccentColour = fillColour;
|
||||||
circle.Colour = colours.BlueDark;
|
circle.Colour = colours.BlueDark;
|
||||||
@ -147,16 +150,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
|
|||||||
if (Progress >= 1 && !Disc.Complete)
|
if (Progress >= 1 && !Disc.Complete)
|
||||||
{
|
{
|
||||||
Disc.Complete = true;
|
Disc.Complete = true;
|
||||||
|
transformFillColour(completeColour, 200);
|
||||||
const float duration = 200;
|
|
||||||
|
|
||||||
Disc.FadeAccent(completeColour, duration);
|
|
||||||
|
|
||||||
Background.FadeAccent(completeColour, duration);
|
|
||||||
Background.FadeOut(duration);
|
|
||||||
|
|
||||||
circle.FadeColour(completeColour, duration);
|
|
||||||
glow.FadeColour(completeColour, duration);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (userTriggered || Time.Current < Spinner.EndTime)
|
if (userTriggered || Time.Current < Spinner.EndTime)
|
||||||
@ -204,32 +198,59 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
|
|||||||
{
|
{
|
||||||
base.UpdateInitialTransforms();
|
base.UpdateInitialTransforms();
|
||||||
|
|
||||||
circleContainer.ScaleTo(Spinner.Scale * 0.3f);
|
circleContainer.ScaleTo(0);
|
||||||
circleContainer.ScaleTo(Spinner.Scale, HitObject.TimePreempt / 1.4f, Easing.OutQuint);
|
mainContainer.ScaleTo(0);
|
||||||
|
|
||||||
|
using (BeginDelayedSequence(HitObject.TimePreempt / 2, true))
|
||||||
|
{
|
||||||
|
float phaseOneScale = Spinner.Scale * 0.7f;
|
||||||
|
|
||||||
|
circleContainer.ScaleTo(phaseOneScale, HitObject.TimePreempt / 4, Easing.OutQuint);
|
||||||
|
|
||||||
mainContainer
|
mainContainer
|
||||||
.ScaleTo(0)
|
.ScaleTo(phaseOneScale * circle.DrawHeight / DrawHeight * 1.6f, HitObject.TimePreempt / 4, Easing.OutQuint)
|
||||||
.ScaleTo(Spinner.Scale * circle.DrawHeight / DrawHeight * 1.4f, HitObject.TimePreempt - 150, Easing.OutQuint)
|
.RotateTo((float)(25 * Spinner.Duration / 2000), HitObject.TimePreempt + Spinner.Duration);
|
||||||
.Then()
|
|
||||||
.ScaleTo(1, 500, Easing.OutQuint);
|
using (BeginDelayedSequence(HitObject.TimePreempt / 2, true))
|
||||||
|
{
|
||||||
|
circleContainer.ScaleTo(Spinner.Scale, 400, Easing.OutQuint);
|
||||||
|
mainContainer.ScaleTo(1, 400, Easing.OutQuint);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void UpdateStateTransforms(ArmedState state)
|
protected override void UpdateStateTransforms(ArmedState state)
|
||||||
{
|
{
|
||||||
base.UpdateStateTransforms(state);
|
base.UpdateStateTransforms(state);
|
||||||
|
|
||||||
var sequence = this.Delay(Spinner.Duration).FadeOut(160);
|
using (BeginDelayedSequence(Spinner.Duration, true))
|
||||||
|
{
|
||||||
|
this.FadeOut(160);
|
||||||
|
|
||||||
switch (state)
|
switch (state)
|
||||||
{
|
{
|
||||||
case ArmedState.Hit:
|
case ArmedState.Hit:
|
||||||
sequence.ScaleTo(Scale * 1.2f, 320, Easing.Out);
|
transformFillColour(completeColour, 0);
|
||||||
|
this.ScaleTo(Scale * 1.2f, 320, Easing.Out);
|
||||||
|
mainContainer.RotateTo(mainContainer.Rotation + 180, 320);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ArmedState.Miss:
|
case ArmedState.Miss:
|
||||||
sequence.ScaleTo(Scale * 0.8f, 320, Easing.In);
|
this.ScaleTo(Scale * 0.8f, 320, Easing.In);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void transformFillColour(Colour4 colour, double duration)
|
||||||
|
{
|
||||||
|
Disc.FadeAccent(colour, duration);
|
||||||
|
|
||||||
|
Background.FadeAccent(colour.Darken(1), duration);
|
||||||
|
Ticks.FadeAccent(colour, duration);
|
||||||
|
|
||||||
|
circle.FadeColour(colour, duration);
|
||||||
|
glow.FadeColour(colour, duration);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,18 +1,18 @@
|
|||||||
// 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 osuTK.Graphics;
|
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Graphics.Containers;
|
using osu.Framework.Graphics.Containers;
|
||||||
using osu.Framework.Graphics.Effects;
|
using osu.Framework.Graphics.Effects;
|
||||||
using osu.Framework.Graphics.Shapes;
|
using osu.Framework.Graphics.Shapes;
|
||||||
using osu.Game.Graphics;
|
using osu.Game.Graphics;
|
||||||
|
using osuTK.Graphics;
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces
|
namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces
|
||||||
{
|
{
|
||||||
public class SpinnerBackground : CircularContainer, IHasAccentColour
|
public class SpinnerBackground : CircularContainer, IHasAccentColour
|
||||||
{
|
{
|
||||||
protected Box Disc;
|
public readonly Box Disc;
|
||||||
|
|
||||||
public Color4 AccentColour
|
public Color4 AccentColour
|
||||||
{
|
{
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
// 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;
|
||||||
|
using System.Linq;
|
||||||
using osu.Framework.Extensions.Color4Extensions;
|
using osu.Framework.Extensions.Color4Extensions;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Graphics.Containers;
|
using osu.Framework.Graphics.Containers;
|
||||||
@ -9,10 +10,11 @@ using osu.Framework.Graphics.Effects;
|
|||||||
using osuTK;
|
using osuTK;
|
||||||
using osuTK.Graphics;
|
using osuTK.Graphics;
|
||||||
using osu.Framework.Graphics.Shapes;
|
using osu.Framework.Graphics.Shapes;
|
||||||
|
using osu.Game.Graphics;
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces
|
namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces
|
||||||
{
|
{
|
||||||
public class SpinnerTicks : Container
|
public class SpinnerTicks : Container, IHasAccentColour
|
||||||
{
|
{
|
||||||
public SpinnerTicks()
|
public SpinnerTicks()
|
||||||
{
|
{
|
||||||
@ -20,28 +22,22 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces
|
|||||||
Anchor = Anchor.Centre;
|
Anchor = Anchor.Centre;
|
||||||
RelativeSizeAxes = Axes.Both;
|
RelativeSizeAxes = Axes.Both;
|
||||||
|
|
||||||
const float count = 18;
|
const float count = 8;
|
||||||
|
|
||||||
for (float i = 0; i < count; i++)
|
for (float i = 0; i < count; i++)
|
||||||
{
|
{
|
||||||
Add(new Container
|
Add(new Container
|
||||||
{
|
{
|
||||||
Colour = Color4.Black,
|
|
||||||
Alpha = 0.4f,
|
Alpha = 0.4f,
|
||||||
EdgeEffect = new EdgeEffectParameters
|
Blending = BlendingParameters.Additive,
|
||||||
{
|
|
||||||
Type = EdgeEffectType.Glow,
|
|
||||||
Radius = 10,
|
|
||||||
Colour = Color4.Gray.Opacity(0.2f),
|
|
||||||
},
|
|
||||||
RelativePositionAxes = Axes.Both,
|
RelativePositionAxes = Axes.Both,
|
||||||
Masking = true,
|
Masking = true,
|
||||||
CornerRadius = 5,
|
CornerRadius = 5,
|
||||||
Size = new Vector2(60, 10),
|
Size = new Vector2(60, 10),
|
||||||
Origin = Anchor.Centre,
|
Origin = Anchor.Centre,
|
||||||
Position = new Vector2(
|
Position = new Vector2(
|
||||||
0.5f + MathF.Sin(i / count * 2 * MathF.PI) / 2 * 0.86f,
|
0.5f + MathF.Sin(i / count * 2 * MathF.PI) / 2 * 0.83f,
|
||||||
0.5f + MathF.Cos(i / count * 2 * MathF.PI) / 2 * 0.86f
|
0.5f + MathF.Cos(i / count * 2 * MathF.PI) / 2 * 0.83f
|
||||||
),
|
),
|
||||||
Rotation = -i / count * 360 + 90,
|
Rotation = -i / count * 360 + 90,
|
||||||
Children = new[]
|
Children = new[]
|
||||||
@ -54,5 +50,25 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Color4 AccentColour
|
||||||
|
{
|
||||||
|
get => Colour;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
Colour = value;
|
||||||
|
|
||||||
|
foreach (var c in Children.OfType<Container>())
|
||||||
|
{
|
||||||
|
c.EdgeEffect =
|
||||||
|
new EdgeEffectParameters
|
||||||
|
{
|
||||||
|
Type = EdgeEffectType.Glow,
|
||||||
|
Radius = 20,
|
||||||
|
Colour = value.Opacity(0.8f),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,84 +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 NUnit.Framework;
|
|
||||||
using osu.Game.Overlays;
|
|
||||||
using osu.Game.Users;
|
|
||||||
|
|
||||||
namespace osu.Game.Tests.Visual.Online
|
|
||||||
{
|
|
||||||
[TestFixture]
|
|
||||||
public class TestSceneSocialOverlay : OsuTestScene
|
|
||||||
{
|
|
||||||
protected override bool UseOnlineAPI => true;
|
|
||||||
|
|
||||||
public TestSceneSocialOverlay()
|
|
||||||
{
|
|
||||||
SocialOverlay s = new SocialOverlay
|
|
||||||
{
|
|
||||||
Users = new[]
|
|
||||||
{
|
|
||||||
new User
|
|
||||||
{
|
|
||||||
Username = @"flyte",
|
|
||||||
Id = 3103765,
|
|
||||||
Country = new Country { FlagName = @"JP" },
|
|
||||||
CoverUrl = @"https://osu.ppy.sh/images/headers/profile-covers/c1.jpg",
|
|
||||||
},
|
|
||||||
new User
|
|
||||||
{
|
|
||||||
Username = @"Cookiezi",
|
|
||||||
Id = 124493,
|
|
||||||
Country = new Country { FlagName = @"KR" },
|
|
||||||
CoverUrl = @"https://osu.ppy.sh/images/headers/profile-covers/c2.jpg",
|
|
||||||
},
|
|
||||||
new User
|
|
||||||
{
|
|
||||||
Username = @"Angelsim",
|
|
||||||
Id = 1777162,
|
|
||||||
Country = new Country { FlagName = @"KR" },
|
|
||||||
CoverUrl = @"https://osu.ppy.sh/images/headers/profile-covers/c3.jpg",
|
|
||||||
},
|
|
||||||
new User
|
|
||||||
{
|
|
||||||
Username = @"Rafis",
|
|
||||||
Id = 2558286,
|
|
||||||
Country = new Country { FlagName = @"PL" },
|
|
||||||
CoverUrl = @"https://osu.ppy.sh/images/headers/profile-covers/c4.jpg",
|
|
||||||
},
|
|
||||||
new User
|
|
||||||
{
|
|
||||||
Username = @"hvick225",
|
|
||||||
Id = 50265,
|
|
||||||
Country = new Country { FlagName = @"TW" },
|
|
||||||
CoverUrl = @"https://osu.ppy.sh/images/headers/profile-covers/c5.jpg",
|
|
||||||
},
|
|
||||||
new User
|
|
||||||
{
|
|
||||||
Username = @"peppy",
|
|
||||||
Id = 2,
|
|
||||||
Country = new Country { FlagName = @"AU" },
|
|
||||||
CoverUrl = @"https://osu.ppy.sh/images/headers/profile-covers/c6.jpg"
|
|
||||||
},
|
|
||||||
new User
|
|
||||||
{
|
|
||||||
Username = @"filsdelama",
|
|
||||||
Id = 2831793,
|
|
||||||
Country = new Country { FlagName = @"FR" },
|
|
||||||
CoverUrl = @"https://osu.ppy.sh/images/headers/profile-covers/c7.jpg"
|
|
||||||
},
|
|
||||||
new User
|
|
||||||
{
|
|
||||||
Username = @"_index",
|
|
||||||
Id = 652457,
|
|
||||||
Country = new Country { FlagName = @"RU" },
|
|
||||||
CoverUrl = @"https://osu.ppy.sh/images/headers/profile-covers/c8.jpg"
|
|
||||||
},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
Add(s);
|
|
||||||
|
|
||||||
AddStep(@"toggle", s.ToggleVisibility);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,33 +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.Extensions.Color4Extensions;
|
|
||||||
using osuTK.Graphics;
|
|
||||||
using osu.Framework.Graphics;
|
|
||||||
using osu.Game.Overlays.SearchableList;
|
|
||||||
|
|
||||||
namespace osu.Game.Overlays.Social
|
|
||||||
{
|
|
||||||
public class FilterControl : SearchableListFilterControl<SocialSortCriteria, SortDirection>
|
|
||||||
{
|
|
||||||
protected override Color4 BackgroundColour => Color4Extensions.FromHex(@"47253a");
|
|
||||||
protected override SocialSortCriteria DefaultTab => SocialSortCriteria.Rank;
|
|
||||||
protected override SortDirection DefaultCategory => SortDirection.Ascending;
|
|
||||||
|
|
||||||
public FilterControl()
|
|
||||||
{
|
|
||||||
Tabs.Margin = new MarginPadding { Top = 10 };
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public enum SocialSortCriteria
|
|
||||||
{
|
|
||||||
Rank,
|
|
||||||
Name,
|
|
||||||
Location,
|
|
||||||
//[Description("Time Zone")]
|
|
||||||
//TimeZone,
|
|
||||||
//[Description("World Map")]
|
|
||||||
//WorldMap,
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,67 +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.Game.Overlays.SearchableList;
|
|
||||||
using osuTK.Graphics;
|
|
||||||
using osu.Framework.Graphics;
|
|
||||||
using osu.Game.Graphics.Sprites;
|
|
||||||
using osu.Framework.Graphics.Containers;
|
|
||||||
using osu.Game.Graphics;
|
|
||||||
using osu.Framework.Allocation;
|
|
||||||
using System.ComponentModel;
|
|
||||||
using osu.Framework.Extensions.Color4Extensions;
|
|
||||||
using osu.Framework.Graphics.Sprites;
|
|
||||||
|
|
||||||
namespace osu.Game.Overlays.Social
|
|
||||||
{
|
|
||||||
public class Header : SearchableListHeader<SocialTab>
|
|
||||||
{
|
|
||||||
private OsuSpriteText browser;
|
|
||||||
|
|
||||||
protected override Color4 BackgroundColour => Color4Extensions.FromHex(@"38202e");
|
|
||||||
|
|
||||||
protected override SocialTab DefaultTab => SocialTab.AllPlayers;
|
|
||||||
protected override IconUsage Icon => FontAwesome.Solid.Users;
|
|
||||||
|
|
||||||
protected override Drawable CreateHeaderText()
|
|
||||||
{
|
|
||||||
return new FillFlowContainer
|
|
||||||
{
|
|
||||||
AutoSizeAxes = Axes.Both,
|
|
||||||
Direction = FillDirection.Horizontal,
|
|
||||||
Children = new[]
|
|
||||||
{
|
|
||||||
new OsuSpriteText
|
|
||||||
{
|
|
||||||
Text = "social ",
|
|
||||||
Font = OsuFont.GetFont(size: 25),
|
|
||||||
},
|
|
||||||
browser = new OsuSpriteText
|
|
||||||
{
|
|
||||||
Text = "browser",
|
|
||||||
Font = OsuFont.GetFont(size: 25, weight: FontWeight.Light),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
|
||||||
private void load(OsuColour colours)
|
|
||||||
{
|
|
||||||
browser.Colour = colours.Pink;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public enum SocialTab
|
|
||||||
{
|
|
||||||
[Description("All Players")]
|
|
||||||
AllPlayers,
|
|
||||||
|
|
||||||
[Description("Friends")]
|
|
||||||
Friends,
|
|
||||||
//[Description("Team Members")]
|
|
||||||
//TeamMembers,
|
|
||||||
//[Description("Chat Channels")]
|
|
||||||
//ChatChannels,
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,242 +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 System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using osu.Framework.Bindables;
|
|
||||||
using osuTK;
|
|
||||||
using osuTK.Graphics;
|
|
||||||
using osu.Framework.Graphics;
|
|
||||||
using osu.Framework.Graphics.Containers;
|
|
||||||
using osu.Game.Graphics.UserInterface;
|
|
||||||
using osu.Game.Online.API;
|
|
||||||
using osu.Game.Online.API.Requests;
|
|
||||||
using osu.Game.Overlays.SearchableList;
|
|
||||||
using osu.Game.Overlays.Social;
|
|
||||||
using osu.Game.Users;
|
|
||||||
using System.Threading;
|
|
||||||
using osu.Framework.Allocation;
|
|
||||||
using osu.Framework.Extensions.Color4Extensions;
|
|
||||||
using osu.Framework.Threading;
|
|
||||||
|
|
||||||
namespace osu.Game.Overlays
|
|
||||||
{
|
|
||||||
public class SocialOverlay : SearchableListOverlay<SocialTab, SocialSortCriteria, SortDirection>
|
|
||||||
{
|
|
||||||
private readonly LoadingSpinner loading;
|
|
||||||
private FillFlowContainer<UserPanel> panels;
|
|
||||||
|
|
||||||
protected override Color4 BackgroundColour => Color4Extensions.FromHex(@"60284b");
|
|
||||||
protected override Color4 TrianglesColourLight => Color4Extensions.FromHex(@"672b51");
|
|
||||||
protected override Color4 TrianglesColourDark => Color4Extensions.FromHex(@"5c2648");
|
|
||||||
|
|
||||||
protected override SearchableListHeader<SocialTab> CreateHeader() => new Header();
|
|
||||||
protected override SearchableListFilterControl<SocialSortCriteria, SortDirection> CreateFilterControl() => new FilterControl();
|
|
||||||
|
|
||||||
private User[] users = Array.Empty<User>();
|
|
||||||
|
|
||||||
public User[] Users
|
|
||||||
{
|
|
||||||
get => users;
|
|
||||||
set
|
|
||||||
{
|
|
||||||
if (users == value)
|
|
||||||
return;
|
|
||||||
|
|
||||||
users = value ?? Array.Empty<User>();
|
|
||||||
|
|
||||||
if (LoadState >= LoadState.Ready)
|
|
||||||
recreatePanels();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public SocialOverlay()
|
|
||||||
: base(OverlayColourScheme.Pink)
|
|
||||||
{
|
|
||||||
Add(loading = new LoadingSpinner());
|
|
||||||
|
|
||||||
Filter.Search.Current.ValueChanged += text =>
|
|
||||||
{
|
|
||||||
if (!string.IsNullOrEmpty(text.NewValue))
|
|
||||||
{
|
|
||||||
// force searching in players until searching for friends is supported
|
|
||||||
Header.Tabs.Current.Value = SocialTab.AllPlayers;
|
|
||||||
|
|
||||||
if (Filter.Tabs.Current.Value != SocialSortCriteria.Rank)
|
|
||||||
Filter.Tabs.Current.Value = SocialSortCriteria.Rank;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
Header.Tabs.Current.ValueChanged += _ => queueUpdate();
|
|
||||||
Filter.Tabs.Current.ValueChanged += _ => onFilterUpdate();
|
|
||||||
|
|
||||||
Filter.DisplayStyleControl.DisplayStyle.ValueChanged += _ => recreatePanels();
|
|
||||||
Filter.Dropdown.Current.ValueChanged += _ => recreatePanels();
|
|
||||||
|
|
||||||
currentQuery.BindTo(Filter.Search.Current);
|
|
||||||
currentQuery.ValueChanged += query =>
|
|
||||||
{
|
|
||||||
queryChangedDebounce?.Cancel();
|
|
||||||
|
|
||||||
if (string.IsNullOrEmpty(query.NewValue))
|
|
||||||
queueUpdate();
|
|
||||||
else
|
|
||||||
queryChangedDebounce = Scheduler.AddDelayed(updateSearch, 500);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
|
||||||
private void load()
|
|
||||||
{
|
|
||||||
recreatePanels();
|
|
||||||
}
|
|
||||||
|
|
||||||
private APIRequest getUsersRequest;
|
|
||||||
|
|
||||||
private readonly Bindable<string> currentQuery = new Bindable<string>();
|
|
||||||
|
|
||||||
private ScheduledDelegate queryChangedDebounce;
|
|
||||||
|
|
||||||
private void queueUpdate() => Scheduler.AddOnce(updateSearch);
|
|
||||||
|
|
||||||
private CancellationTokenSource loadCancellation;
|
|
||||||
|
|
||||||
private void updateSearch()
|
|
||||||
{
|
|
||||||
queryChangedDebounce?.Cancel();
|
|
||||||
|
|
||||||
if (!IsLoaded)
|
|
||||||
return;
|
|
||||||
|
|
||||||
Users = null;
|
|
||||||
clearPanels();
|
|
||||||
getUsersRequest?.Cancel();
|
|
||||||
|
|
||||||
if (API?.IsLoggedIn != true)
|
|
||||||
return;
|
|
||||||
|
|
||||||
switch (Header.Tabs.Current.Value)
|
|
||||||
{
|
|
||||||
case SocialTab.Friends:
|
|
||||||
var friendRequest = new GetFriendsRequest(); // TODO filter arguments?
|
|
||||||
friendRequest.Success += users => Users = users.ToArray();
|
|
||||||
API.Queue(getUsersRequest = friendRequest);
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
var userRequest = new GetUsersRequest(); // TODO filter arguments!
|
|
||||||
userRequest.Success += res => Users = res.Users.Select(r => r.User).ToArray();
|
|
||||||
API.Queue(getUsersRequest = userRequest);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void recreatePanels()
|
|
||||||
{
|
|
||||||
clearPanels();
|
|
||||||
|
|
||||||
if (Users == null)
|
|
||||||
{
|
|
||||||
loading.Hide();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
IEnumerable<User> sortedUsers = Users;
|
|
||||||
|
|
||||||
switch (Filter.Tabs.Current.Value)
|
|
||||||
{
|
|
||||||
case SocialSortCriteria.Location:
|
|
||||||
sortedUsers = sortedUsers.OrderBy(u => u.Country.FullName);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case SocialSortCriteria.Name:
|
|
||||||
sortedUsers = sortedUsers.OrderBy(u => u.Username);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Filter.Dropdown.Current.Value == SortDirection.Descending)
|
|
||||||
sortedUsers = sortedUsers.Reverse();
|
|
||||||
|
|
||||||
var newPanels = new FillFlowContainer<UserPanel>
|
|
||||||
{
|
|
||||||
RelativeSizeAxes = Axes.X,
|
|
||||||
AutoSizeAxes = Axes.Y,
|
|
||||||
Spacing = new Vector2(10f),
|
|
||||||
Margin = new MarginPadding { Top = 10 },
|
|
||||||
ChildrenEnumerable = sortedUsers.Select(u =>
|
|
||||||
{
|
|
||||||
UserPanel panel;
|
|
||||||
|
|
||||||
switch (Filter.DisplayStyleControl.DisplayStyle.Value)
|
|
||||||
{
|
|
||||||
case PanelDisplayStyle.Grid:
|
|
||||||
panel = new UserGridPanel(u)
|
|
||||||
{
|
|
||||||
Anchor = Anchor.TopCentre,
|
|
||||||
Origin = Anchor.TopCentre,
|
|
||||||
Width = 290,
|
|
||||||
};
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
panel = new UserListPanel(u);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
panel.Status.BindTo(u.Status);
|
|
||||||
panel.Activity.BindTo(u.Activity);
|
|
||||||
return panel;
|
|
||||||
})
|
|
||||||
};
|
|
||||||
|
|
||||||
LoadComponentAsync(newPanels, f =>
|
|
||||||
{
|
|
||||||
if (panels != null)
|
|
||||||
ScrollFlow.Remove(panels);
|
|
||||||
|
|
||||||
loading.Hide();
|
|
||||||
ScrollFlow.Add(panels = newPanels);
|
|
||||||
}, (loadCancellation = new CancellationTokenSource()).Token);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void onFilterUpdate()
|
|
||||||
{
|
|
||||||
if (Filter.Tabs.Current.Value == SocialSortCriteria.Rank)
|
|
||||||
{
|
|
||||||
queueUpdate();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
recreatePanels();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void clearPanels()
|
|
||||||
{
|
|
||||||
loading.Show();
|
|
||||||
|
|
||||||
loadCancellation?.Cancel();
|
|
||||||
|
|
||||||
if (panels != null)
|
|
||||||
{
|
|
||||||
panels.Expire();
|
|
||||||
panels = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void APIStateChanged(IAPIProvider api, APIState state)
|
|
||||||
{
|
|
||||||
switch (state)
|
|
||||||
{
|
|
||||||
case APIState.Online:
|
|
||||||
queueUpdate();
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
Users = null;
|
|
||||||
clearPanels();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
Reference in New Issue
Block a user