mirror of
https://github.com/ppy/osu.git
synced 2025-01-28 06:42:54 +08:00
Merge pull request #1740 from ppy/osu/expand-social-tab
Add "Friends" tab to social browser
This commit is contained in:
commit
260cf59afb
@ -1,13 +1,26 @@
|
|||||||
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
using osu.Game.Overlays;
|
using osu.Game.Overlays;
|
||||||
|
using osu.Game.Overlays.Social;
|
||||||
using osu.Game.Users;
|
using osu.Game.Users;
|
||||||
|
|
||||||
namespace osu.Game.Tests.Visual
|
namespace osu.Game.Tests.Visual
|
||||||
{
|
{
|
||||||
public class TestCaseSocial : OsuTestCase
|
public class TestCaseSocial : OsuTestCase
|
||||||
{
|
{
|
||||||
|
public override IReadOnlyList<Type> RequiredTypes => new[]
|
||||||
|
{
|
||||||
|
typeof(UserPanel),
|
||||||
|
typeof(SocialPanel),
|
||||||
|
typeof(FilterControl),
|
||||||
|
typeof(SocialOverlay),
|
||||||
|
typeof(SocialGridPanel),
|
||||||
|
typeof(SocialListPanel)
|
||||||
|
};
|
||||||
|
|
||||||
public TestCaseSocial()
|
public TestCaseSocial()
|
||||||
{
|
{
|
||||||
SocialOverlay s = new SocialOverlay
|
SocialOverlay s = new SocialOverlay
|
||||||
|
13
osu.Game/Online/API/Requests/GetFriendsRequest.cs
Normal file
13
osu.Game/Online/API/Requests/GetFriendsRequest.cs
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||||
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using osu.Game.Users;
|
||||||
|
|
||||||
|
namespace osu.Game.Online.API.Requests
|
||||||
|
{
|
||||||
|
public class GetFriendsRequest : APIRequest<List<User>>
|
||||||
|
{
|
||||||
|
protected override string Target => @"friends";
|
||||||
|
}
|
||||||
|
}
|
@ -22,7 +22,8 @@ namespace osu.Game.Overlays.Social
|
|||||||
public enum SocialSortCriteria
|
public enum SocialSortCriteria
|
||||||
{
|
{
|
||||||
Rank,
|
Rank,
|
||||||
//Location,
|
Name,
|
||||||
|
Location,
|
||||||
//[Description("Time Zone")]
|
//[Description("Time Zone")]
|
||||||
//TimeZone,
|
//TimeZone,
|
||||||
//[Description("World Map")]
|
//[Description("World Map")]
|
||||||
|
@ -18,7 +18,8 @@ namespace osu.Game.Overlays.Social
|
|||||||
|
|
||||||
protected override Color4 BackgroundColour => OsuColour.FromHex(@"38202e");
|
protected override Color4 BackgroundColour => OsuColour.FromHex(@"38202e");
|
||||||
protected override float TabStripWidth => 438;
|
protected override float TabStripWidth => 438;
|
||||||
protected override SocialTab DefaultTab => SocialTab.OnlinePlayers;
|
|
||||||
|
protected override SocialTab DefaultTab => SocialTab.AllPlayers;
|
||||||
protected override FontAwesome Icon => FontAwesome.fa_users;
|
protected override FontAwesome Icon => FontAwesome.fa_users;
|
||||||
|
|
||||||
protected override Drawable CreateHeaderText()
|
protected override Drawable CreateHeaderText()
|
||||||
@ -53,12 +54,12 @@ namespace osu.Game.Overlays.Social
|
|||||||
|
|
||||||
public enum SocialTab
|
public enum SocialTab
|
||||||
{
|
{
|
||||||
[Description("Online Players")]
|
[Description("All Players")]
|
||||||
OnlinePlayers,
|
AllPlayers,
|
||||||
//[Description("Online Friends")]
|
[Description("Friends")]
|
||||||
//OnlineFriends,
|
Friends,
|
||||||
//[Description("Online Team Members")]
|
//[Description("Team Members")]
|
||||||
//OnlineTeamMembers,
|
//TeamMembers,
|
||||||
//[Description("Chat Channels")]
|
//[Description("Chat Channels")]
|
||||||
//ChatChannels,
|
//ChatChannels,
|
||||||
}
|
}
|
||||||
|
15
osu.Game/Overlays/Social/SocialGridPanel.cs
Normal file
15
osu.Game/Overlays/Social/SocialGridPanel.cs
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||||
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
|
using osu.Game.Users;
|
||||||
|
|
||||||
|
namespace osu.Game.Overlays.Social
|
||||||
|
{
|
||||||
|
public class SocialGridPanel : SocialPanel
|
||||||
|
{
|
||||||
|
public SocialGridPanel(User user) : base(user)
|
||||||
|
{
|
||||||
|
Width = 300;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
16
osu.Game/Overlays/Social/SocialListPanel.cs
Normal file
16
osu.Game/Overlays/Social/SocialListPanel.cs
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||||
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
|
using osu.Framework.Graphics;
|
||||||
|
using osu.Game.Users;
|
||||||
|
|
||||||
|
namespace osu.Game.Overlays.Social
|
||||||
|
{
|
||||||
|
public class SocialListPanel : SocialPanel
|
||||||
|
{
|
||||||
|
public SocialListPanel(User user) : base(user)
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.X;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
60
osu.Game/Overlays/Social/SocialPanel.cs
Normal file
60
osu.Game/Overlays/Social/SocialPanel.cs
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||||
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
|
using OpenTK;
|
||||||
|
using OpenTK.Graphics;
|
||||||
|
using osu.Framework.Extensions.Color4Extensions;
|
||||||
|
using osu.Framework.Graphics;
|
||||||
|
using osu.Framework.Graphics.Containers;
|
||||||
|
using osu.Framework.Input;
|
||||||
|
using osu.Game.Users;
|
||||||
|
|
||||||
|
namespace osu.Game.Overlays.Social
|
||||||
|
{
|
||||||
|
public class SocialPanel : UserPanel
|
||||||
|
{
|
||||||
|
private const double hover_transition_time = 400;
|
||||||
|
|
||||||
|
public SocialPanel(User user) : base(user)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
private readonly EdgeEffectParameters edgeEffectNormal = new EdgeEffectParameters
|
||||||
|
{
|
||||||
|
Type = EdgeEffectType.Shadow,
|
||||||
|
Offset = new Vector2(0f, 1f),
|
||||||
|
Radius = 2f,
|
||||||
|
Colour = Color4.Black.Opacity(0.25f),
|
||||||
|
};
|
||||||
|
|
||||||
|
private readonly EdgeEffectParameters edgeEffectHovered = new EdgeEffectParameters
|
||||||
|
{
|
||||||
|
Type = EdgeEffectType.Shadow,
|
||||||
|
Offset = new Vector2(0f, 5f),
|
||||||
|
Radius = 10f,
|
||||||
|
Colour = Color4.Black.Opacity(0.3f),
|
||||||
|
};
|
||||||
|
|
||||||
|
protected override bool OnHover(InputState state)
|
||||||
|
{
|
||||||
|
Content.TweenEdgeEffectTo(edgeEffectHovered, hover_transition_time, Easing.OutQuint);
|
||||||
|
Content.MoveToY(-4, hover_transition_time, Easing.OutQuint);
|
||||||
|
|
||||||
|
return base.OnHover(state);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnHoverLost(InputState state)
|
||||||
|
{
|
||||||
|
Content.TweenEdgeEffectTo(edgeEffectNormal, hover_transition_time, Easing.OutQuint);
|
||||||
|
Content.MoveToY(0, hover_transition_time, Easing.OutQuint);
|
||||||
|
|
||||||
|
base.OnHoverLost(state);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void LoadComplete()
|
||||||
|
{
|
||||||
|
base.LoadComplete();
|
||||||
|
this.FadeInFromZero(200, Easing.Out);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -9,19 +9,22 @@ using OpenTK.Graphics;
|
|||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Graphics.Containers;
|
using osu.Framework.Graphics.Containers;
|
||||||
using osu.Game.Graphics;
|
using osu.Game.Graphics;
|
||||||
using osu.Game.Graphics.Cursor;
|
|
||||||
using osu.Game.Graphics.UserInterface;
|
using osu.Game.Graphics.UserInterface;
|
||||||
using osu.Game.Online.API;
|
using osu.Game.Online.API;
|
||||||
using osu.Game.Online.API.Requests;
|
using osu.Game.Online.API.Requests;
|
||||||
using osu.Game.Overlays.SearchableList;
|
using osu.Game.Overlays.SearchableList;
|
||||||
using osu.Game.Overlays.Social;
|
using osu.Game.Overlays.Social;
|
||||||
using osu.Game.Users;
|
using osu.Game.Users;
|
||||||
|
using osu.Framework.Configuration;
|
||||||
|
using osu.Framework.Threading;
|
||||||
|
|
||||||
namespace osu.Game.Overlays
|
namespace osu.Game.Overlays
|
||||||
{
|
{
|
||||||
public class SocialOverlay : SearchableListOverlay<SocialTab, SocialSortCriteria, SortDirection>, IOnlineComponent
|
public class SocialOverlay : SearchableListOverlay<SocialTab, SocialSortCriteria, SortDirection>, IOnlineComponent
|
||||||
{
|
{
|
||||||
private readonly FillFlowContainer<UserPanel> panelFlow;
|
private APIAccess api;
|
||||||
|
private readonly LoadingAnimation loading;
|
||||||
|
private FillFlowContainer<SocialPanel> panels;
|
||||||
|
|
||||||
protected override Color4 BackgroundColour => OsuColour.FromHex(@"60284b");
|
protected override Color4 BackgroundColour => OsuColour.FromHex(@"60284b");
|
||||||
protected override Color4 TrianglesColourLight => OsuColour.FromHex(@"672b51");
|
protected override Color4 TrianglesColourLight => OsuColour.FromHex(@"672b51");
|
||||||
@ -31,27 +34,15 @@ namespace osu.Game.Overlays
|
|||||||
protected override SearchableListFilterControl<SocialSortCriteria, SortDirection> CreateFilterControl() => new FilterControl();
|
protected override SearchableListFilterControl<SocialSortCriteria, SortDirection> CreateFilterControl() => new FilterControl();
|
||||||
|
|
||||||
private IEnumerable<User> users;
|
private IEnumerable<User> users;
|
||||||
private readonly LoadingAnimation loading;
|
|
||||||
|
|
||||||
public IEnumerable<User> Users
|
public IEnumerable<User> Users
|
||||||
{
|
{
|
||||||
get { return users; }
|
get { return users; }
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
if (users?.Equals(value) ?? false) return;
|
if (users?.Equals(value) ?? false)
|
||||||
users = value;
|
return;
|
||||||
|
|
||||||
if (users == null)
|
users = value?.ToList();
|
||||||
panelFlow.Clear();
|
|
||||||
else
|
|
||||||
{
|
|
||||||
panelFlow.ChildrenEnumerable = users.Select(u =>
|
|
||||||
{
|
|
||||||
var p = new UserPanel(u) { Width = 300 };
|
|
||||||
p.Status.BindTo(u.Status);
|
|
||||||
return p;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -62,57 +53,153 @@ namespace osu.Game.Overlays
|
|||||||
ThirdWaveColour = OsuColour.FromHex(@"9b2b6e");
|
ThirdWaveColour = OsuColour.FromHex(@"9b2b6e");
|
||||||
FourthWaveColour = OsuColour.FromHex(@"6d214d");
|
FourthWaveColour = OsuColour.FromHex(@"6d214d");
|
||||||
|
|
||||||
ScrollFlow.Children = new[]
|
Add(loading = new LoadingAnimation());
|
||||||
|
|
||||||
|
Filter.Search.Current.ValueChanged += text =>
|
||||||
{
|
{
|
||||||
new OsuContextMenuContainer
|
if (!string.IsNullOrEmpty(text))
|
||||||
{
|
{
|
||||||
RelativeSizeAxes = Axes.X,
|
// force searching in players until searching for friends is supported
|
||||||
AutoSizeAxes = Axes.Y,
|
Header.Tabs.Current.Value = SocialTab.AllPlayers;
|
||||||
Child = panelFlow = new FillFlowContainer<UserPanel>
|
|
||||||
{
|
if (Filter.Tabs.Current.Value != SocialSortCriteria.Rank)
|
||||||
RelativeSizeAxes = Axes.X,
|
Filter.Tabs.Current.Value = SocialSortCriteria.Rank;
|
||||||
AutoSizeAxes = Axes.Y,
|
}
|
||||||
Margin = new MarginPadding { Top = 20 },
|
|
||||||
Spacing = new Vector2(10f),
|
|
||||||
}
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
Add(loading = new LoadingAnimation());
|
Header.Tabs.Current.ValueChanged += tab => Scheduler.AddOnce(updateSearch);
|
||||||
|
|
||||||
|
Filter.Tabs.Current.ValueChanged += sortCriteria => Scheduler.AddOnce(updateSearch);
|
||||||
|
|
||||||
|
Filter.DisplayStyleControl.DisplayStyle.ValueChanged += recreatePanels;
|
||||||
|
Filter.DisplayStyleControl.Dropdown.Current.ValueChanged += sortOrder => Scheduler.AddOnce(updateSearch);
|
||||||
|
|
||||||
|
currentQuery.ValueChanged += query =>
|
||||||
|
{
|
||||||
|
queryChangedDebounce?.Cancel();
|
||||||
|
|
||||||
|
if (string.IsNullOrEmpty(query))
|
||||||
|
Scheduler.AddOnce(updateSearch);
|
||||||
|
else
|
||||||
|
queryChangedDebounce = Scheduler.AddDelayed(updateSearch, 500);
|
||||||
|
};
|
||||||
|
|
||||||
|
currentQuery.BindTo(Filter.Search.Current);
|
||||||
}
|
}
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader]
|
||||||
private void load(APIAccess api)
|
private void load(APIAccess api)
|
||||||
{
|
{
|
||||||
if (Users == null)
|
this.api = api;
|
||||||
reloadUsers(api);
|
api.Register(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void reloadUsers(APIAccess api)
|
private void recreatePanels(PanelDisplayStyle displayStyle)
|
||||||
{
|
{
|
||||||
Users = null;
|
clearPanels();
|
||||||
|
|
||||||
// no this is not the correct data source, but it's something.
|
if (Users == null)
|
||||||
var request = new GetUsersRequest();
|
return;
|
||||||
request.Success += res =>
|
|
||||||
|
var newPanels = new FillFlowContainer<SocialPanel>
|
||||||
{
|
{
|
||||||
Users = res.Select(e => e.User);
|
RelativeSizeAxes = Axes.X,
|
||||||
loading.Hide();
|
AutoSizeAxes = Axes.Y,
|
||||||
|
Spacing = new Vector2(10f),
|
||||||
|
Margin = new MarginPadding { Top = 10 },
|
||||||
|
ChildrenEnumerable = Users.Select(u =>
|
||||||
|
{
|
||||||
|
SocialPanel panel;
|
||||||
|
switch (displayStyle)
|
||||||
|
{
|
||||||
|
case PanelDisplayStyle.Grid:
|
||||||
|
panel = new SocialGridPanel(u)
|
||||||
|
{
|
||||||
|
Anchor = Anchor.TopCentre,
|
||||||
|
Origin = Anchor.TopCentre
|
||||||
|
};
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
panel = new SocialListPanel(u);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
panel.Status.BindTo(u.Status);
|
||||||
|
return panel;
|
||||||
|
})
|
||||||
};
|
};
|
||||||
|
|
||||||
api.Queue(request);
|
LoadComponentAsync(newPanels, f =>
|
||||||
|
{
|
||||||
|
if(panels != null)
|
||||||
|
ScrollFlow.Remove(panels);
|
||||||
|
|
||||||
|
ScrollFlow.Add(panels = newPanels);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private APIRequest getUsersRequest;
|
||||||
|
|
||||||
|
private readonly Bindable<string> currentQuery = new Bindable<string>();
|
||||||
|
|
||||||
|
private ScheduledDelegate queryChangedDebounce;
|
||||||
|
|
||||||
|
private void updateSearch()
|
||||||
|
{
|
||||||
|
queryChangedDebounce?.Cancel();
|
||||||
|
|
||||||
|
if (!IsLoaded)
|
||||||
|
return;
|
||||||
|
|
||||||
|
Users = null;
|
||||||
|
clearPanels();
|
||||||
|
loading.Hide();
|
||||||
|
getUsersRequest?.Cancel();
|
||||||
|
|
||||||
|
if (api?.IsLoggedIn == false)
|
||||||
|
return;
|
||||||
|
|
||||||
|
switch (Header.Tabs.Current.Value)
|
||||||
|
{
|
||||||
|
case SocialTab.Friends:
|
||||||
|
var friendRequest = new GetFriendsRequest(); // TODO filter arguments?
|
||||||
|
friendRequest.Success += updateUsers;
|
||||||
|
api.Queue(getUsersRequest = friendRequest);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
var userRequest = new GetUsersRequest(); // TODO filter arguments!
|
||||||
|
userRequest.Success += response => updateUsers(response.Select(r => r.User));
|
||||||
|
api.Queue(getUsersRequest = userRequest);
|
||||||
|
break;
|
||||||
|
}
|
||||||
loading.Show();
|
loading.Show();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void updateUsers(IEnumerable<User> newUsers)
|
||||||
|
{
|
||||||
|
Users = newUsers;
|
||||||
|
loading.Hide();
|
||||||
|
recreatePanels(Filter.DisplayStyleControl.DisplayStyle.Value);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void clearPanels()
|
||||||
|
{
|
||||||
|
if (panels != null)
|
||||||
|
{
|
||||||
|
panels.Expire();
|
||||||
|
panels = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void APIStateChanged(APIAccess api, APIState state)
|
public void APIStateChanged(APIAccess api, APIState state)
|
||||||
{
|
{
|
||||||
switch (state)
|
switch (state)
|
||||||
{
|
{
|
||||||
case APIState.Online:
|
case APIState.Online:
|
||||||
reloadUsers(api);
|
Scheduler.AddOnce(updateSearch);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
Users = null;
|
Users = null;
|
||||||
|
clearPanels();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -120,7 +207,7 @@ namespace osu.Game.Overlays
|
|||||||
|
|
||||||
public enum SortDirection
|
public enum SortDirection
|
||||||
{
|
{
|
||||||
Descending,
|
|
||||||
Ascending,
|
Ascending,
|
||||||
|
Descending
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -44,7 +44,7 @@ namespace osu.Game.Users
|
|||||||
new Avatar(user)
|
new Avatar(user)
|
||||||
{
|
{
|
||||||
RelativeSizeAxes = Axes.Both,
|
RelativeSizeAxes = Axes.Both,
|
||||||
OnLoadComplete = d => d.FadeInFromZero(200),
|
OnLoadComplete = d => d.FadeInFromZero(300, Easing.OutQuint),
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -39,10 +39,14 @@ namespace osu.Game.Users
|
|||||||
public string AvatarUrl;
|
public string AvatarUrl;
|
||||||
|
|
||||||
[JsonProperty(@"cover_url")]
|
[JsonProperty(@"cover_url")]
|
||||||
public string CoverUrl;
|
public string CoverUrl
|
||||||
|
{
|
||||||
|
get { return Cover?.Url; }
|
||||||
|
set { Cover = new UserCover { Url = value }; }
|
||||||
|
}
|
||||||
|
|
||||||
//[JsonProperty(@"cover")]
|
[JsonProperty(@"cover")]
|
||||||
//public UserCover Cover;
|
public UserCover Cover;
|
||||||
|
|
||||||
public class UserCover
|
public class UserCover
|
||||||
{
|
{
|
||||||
|
@ -28,9 +28,12 @@ namespace osu.Game.Users
|
|||||||
private const float content_padding = 10;
|
private const float content_padding = 10;
|
||||||
private const float status_height = 30;
|
private const float status_height = 30;
|
||||||
|
|
||||||
private readonly Container statusBar;
|
private Container statusBar;
|
||||||
private readonly Box statusBg;
|
private Box statusBg;
|
||||||
private readonly OsuSpriteText statusMessage;
|
private OsuSpriteText statusMessage;
|
||||||
|
|
||||||
|
private Container content;
|
||||||
|
protected override Container<Drawable> Content => content;
|
||||||
|
|
||||||
public readonly Bindable<UserStatus> Status = new Bindable<UserStatus>();
|
public readonly Bindable<UserStatus> Status = new Bindable<UserStatus>();
|
||||||
|
|
||||||
@ -45,133 +48,7 @@ namespace osu.Game.Users
|
|||||||
|
|
||||||
this.user = user;
|
this.user = user;
|
||||||
|
|
||||||
FillFlowContainer infoContainer;
|
|
||||||
|
|
||||||
Height = height - status_height;
|
Height = height - status_height;
|
||||||
Masking = true;
|
|
||||||
CornerRadius = 5;
|
|
||||||
EdgeEffect = new EdgeEffectParameters
|
|
||||||
{
|
|
||||||
Type = EdgeEffectType.Shadow,
|
|
||||||
Colour = Color4.Black.Opacity(0.25f),
|
|
||||||
Radius = 4,
|
|
||||||
};
|
|
||||||
|
|
||||||
Children = new Drawable[]
|
|
||||||
{
|
|
||||||
new DelayedLoadWrapper(new UserCoverBackground(user)
|
|
||||||
{
|
|
||||||
RelativeSizeAxes = Axes.Both,
|
|
||||||
Anchor = Anchor.Centre,
|
|
||||||
Origin = Anchor.Centre,
|
|
||||||
FillMode = FillMode.Fill,
|
|
||||||
OnLoadComplete = d => d.FadeInFromZero(200),
|
|
||||||
}, 0) { RelativeSizeAxes = Axes.Both },
|
|
||||||
new Box
|
|
||||||
{
|
|
||||||
RelativeSizeAxes = Axes.Both,
|
|
||||||
Colour = Color4.Black.Opacity(0.7f),
|
|
||||||
},
|
|
||||||
new Container
|
|
||||||
{
|
|
||||||
RelativeSizeAxes = Axes.X,
|
|
||||||
AutoSizeAxes = Axes.Y,
|
|
||||||
Padding = new MarginPadding { Top = content_padding, Left = content_padding, Right = content_padding },
|
|
||||||
Children = new Drawable[]
|
|
||||||
{
|
|
||||||
new UpdateableAvatar
|
|
||||||
{
|
|
||||||
Size = new Vector2(height - status_height - content_padding * 2),
|
|
||||||
User = user,
|
|
||||||
Masking = true,
|
|
||||||
CornerRadius = 5,
|
|
||||||
EdgeEffect = new EdgeEffectParameters
|
|
||||||
{
|
|
||||||
Type = EdgeEffectType.Shadow,
|
|
||||||
Colour = Color4.Black.Opacity(0.25f),
|
|
||||||
Radius = 4,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
new Container
|
|
||||||
{
|
|
||||||
RelativeSizeAxes = Axes.Both,
|
|
||||||
Padding = new MarginPadding { Left = height - status_height - content_padding },
|
|
||||||
Children = new Drawable[]
|
|
||||||
{
|
|
||||||
new OsuSpriteText
|
|
||||||
{
|
|
||||||
Text = user.Username,
|
|
||||||
TextSize = 18,
|
|
||||||
Font = @"Exo2.0-SemiBoldItalic",
|
|
||||||
},
|
|
||||||
infoContainer = new FillFlowContainer
|
|
||||||
{
|
|
||||||
Anchor = Anchor.BottomLeft,
|
|
||||||
Origin = Anchor.BottomLeft,
|
|
||||||
AutoSizeAxes = Axes.X,
|
|
||||||
Height = 20f,
|
|
||||||
Direction = FillDirection.Horizontal,
|
|
||||||
Spacing = new Vector2(5f, 0f),
|
|
||||||
Children = new Drawable[]
|
|
||||||
{
|
|
||||||
new DrawableFlag(user.Country)
|
|
||||||
{
|
|
||||||
Width = 30f,
|
|
||||||
RelativeSizeAxes = Axes.Y,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
statusBar = new Container
|
|
||||||
{
|
|
||||||
Anchor = Anchor.BottomLeft,
|
|
||||||
Origin = Anchor.BottomLeft,
|
|
||||||
RelativeSizeAxes = Axes.X,
|
|
||||||
Alpha = 0f,
|
|
||||||
Children = new Drawable[]
|
|
||||||
{
|
|
||||||
statusBg = new Box
|
|
||||||
{
|
|
||||||
RelativeSizeAxes = Axes.Both,
|
|
||||||
Alpha = 0.5f,
|
|
||||||
},
|
|
||||||
new FillFlowContainer
|
|
||||||
{
|
|
||||||
Anchor = Anchor.Centre,
|
|
||||||
Origin = Anchor.Centre,
|
|
||||||
AutoSizeAxes = Axes.Both,
|
|
||||||
Spacing = new Vector2(5f, 0f),
|
|
||||||
Children = new Drawable[]
|
|
||||||
{
|
|
||||||
new SpriteIcon
|
|
||||||
{
|
|
||||||
Anchor = Anchor.CentreLeft,
|
|
||||||
Origin = Anchor.CentreLeft,
|
|
||||||
Icon = FontAwesome.fa_circle_o,
|
|
||||||
Shadow = true,
|
|
||||||
Size = new Vector2(14),
|
|
||||||
},
|
|
||||||
statusMessage = new OsuSpriteText
|
|
||||||
{
|
|
||||||
Anchor = Anchor.CentreLeft,
|
|
||||||
Origin = Anchor.CentreLeft,
|
|
||||||
Font = @"Exo2.0-Semibold",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
if (user.IsSupporter)
|
|
||||||
infoContainer.Add(new SupporterIcon
|
|
||||||
{
|
|
||||||
RelativeSizeAxes = Axes.Y,
|
|
||||||
Width = 20f,
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[BackgroundDependencyLoader(permitNulls: true)]
|
[BackgroundDependencyLoader(permitNulls: true)]
|
||||||
@ -180,6 +57,139 @@ namespace osu.Game.Users
|
|||||||
if (colours == null)
|
if (colours == null)
|
||||||
throw new ArgumentNullException(nameof(colours));
|
throw new ArgumentNullException(nameof(colours));
|
||||||
|
|
||||||
|
FillFlowContainer infoContainer;
|
||||||
|
|
||||||
|
AddInternal(content = new Container
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.Both,
|
||||||
|
Masking = true,
|
||||||
|
CornerRadius = 5,
|
||||||
|
EdgeEffect = new EdgeEffectParameters
|
||||||
|
{
|
||||||
|
Type = EdgeEffectType.Shadow,
|
||||||
|
Colour = Color4.Black.Opacity(0.25f),
|
||||||
|
Radius = 4,
|
||||||
|
},
|
||||||
|
|
||||||
|
Children = new Drawable[]
|
||||||
|
{
|
||||||
|
new DelayedLoadWrapper(new UserCoverBackground(user)
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.Both,
|
||||||
|
Anchor = Anchor.Centre,
|
||||||
|
Origin = Anchor.Centre,
|
||||||
|
FillMode = FillMode.Fill,
|
||||||
|
OnLoadComplete = d => d.FadeInFromZero(400, Easing.Out)
|
||||||
|
}, 300) { RelativeSizeAxes = Axes.Both },
|
||||||
|
new Box
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.Both,
|
||||||
|
Colour = Color4.Black.Opacity(0.7f),
|
||||||
|
},
|
||||||
|
new Container
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.X,
|
||||||
|
AutoSizeAxes = Axes.Y,
|
||||||
|
Padding = new MarginPadding { Top = content_padding, Horizontal = content_padding },
|
||||||
|
Children = new Drawable[]
|
||||||
|
{
|
||||||
|
new UpdateableAvatar
|
||||||
|
{
|
||||||
|
Size = new Vector2(height - status_height - content_padding * 2),
|
||||||
|
User = user,
|
||||||
|
Masking = true,
|
||||||
|
CornerRadius = 5,
|
||||||
|
EdgeEffect = new EdgeEffectParameters
|
||||||
|
{
|
||||||
|
Type = EdgeEffectType.Shadow,
|
||||||
|
Colour = Color4.Black.Opacity(0.25f),
|
||||||
|
Radius = 4,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
new Container
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.Both,
|
||||||
|
Padding = new MarginPadding { Left = height - status_height - content_padding },
|
||||||
|
Children = new Drawable[]
|
||||||
|
{
|
||||||
|
new OsuSpriteText
|
||||||
|
{
|
||||||
|
Text = user.Username,
|
||||||
|
TextSize = 18,
|
||||||
|
Font = @"Exo2.0-SemiBoldItalic",
|
||||||
|
},
|
||||||
|
infoContainer = new FillFlowContainer
|
||||||
|
{
|
||||||
|
Anchor = Anchor.BottomLeft,
|
||||||
|
Origin = Anchor.BottomLeft,
|
||||||
|
AutoSizeAxes = Axes.X,
|
||||||
|
Height = 20f,
|
||||||
|
Direction = FillDirection.Horizontal,
|
||||||
|
Spacing = new Vector2(5f, 0f),
|
||||||
|
Children = new Drawable[]
|
||||||
|
{
|
||||||
|
new DrawableFlag(user.Country)
|
||||||
|
{
|
||||||
|
Width = 30f,
|
||||||
|
RelativeSizeAxes = Axes.Y,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
statusBar = new Container
|
||||||
|
{
|
||||||
|
Anchor = Anchor.BottomLeft,
|
||||||
|
Origin = Anchor.BottomLeft,
|
||||||
|
RelativeSizeAxes = Axes.X,
|
||||||
|
Alpha = 0f,
|
||||||
|
Children = new Drawable[]
|
||||||
|
{
|
||||||
|
statusBg = new Box
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.Both,
|
||||||
|
Alpha = 0.5f,
|
||||||
|
},
|
||||||
|
new FillFlowContainer
|
||||||
|
{
|
||||||
|
Anchor = Anchor.Centre,
|
||||||
|
Origin = Anchor.Centre,
|
||||||
|
AutoSizeAxes = Axes.Both,
|
||||||
|
Spacing = new Vector2(5f, 0f),
|
||||||
|
Children = new Drawable[]
|
||||||
|
{
|
||||||
|
new SpriteIcon
|
||||||
|
{
|
||||||
|
Anchor = Anchor.CentreLeft,
|
||||||
|
Origin = Anchor.CentreLeft,
|
||||||
|
Icon = FontAwesome.fa_circle_o,
|
||||||
|
Shadow = true,
|
||||||
|
Size = new Vector2(14),
|
||||||
|
},
|
||||||
|
statusMessage = new OsuSpriteText
|
||||||
|
{
|
||||||
|
Anchor = Anchor.CentreLeft,
|
||||||
|
Origin = Anchor.CentreLeft,
|
||||||
|
Font = @"Exo2.0-Semibold",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (user.IsSupporter)
|
||||||
|
{
|
||||||
|
infoContainer.Add(new SupporterIcon
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.Y,
|
||||||
|
Width = 20f,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
Status.ValueChanged += displayStatus;
|
Status.ValueChanged += displayStatus;
|
||||||
Status.ValueChanged += status => statusBg.FadeColour(status?.GetAppropriateColour(colours) ?? colours.Gray5, 500, Easing.OutQuint);
|
Status.ValueChanged += status => statusBg.FadeColour(status?.GetAppropriateColour(colours) ?? colours.Gray5, 500, Easing.OutQuint);
|
||||||
|
|
||||||
|
@ -269,6 +269,7 @@
|
|||||||
<Compile Include="Database\IHasPrimaryKey.cs" />
|
<Compile Include="Database\IHasPrimaryKey.cs" />
|
||||||
<Compile Include="Graphics\Textures\LargeTextureStore.cs" />
|
<Compile Include="Graphics\Textures\LargeTextureStore.cs" />
|
||||||
<Compile Include="Overlays\Profile\SupporterIcon.cs" />
|
<Compile Include="Overlays\Profile\SupporterIcon.cs" />
|
||||||
|
<Compile Include="Online\API\Requests\GetFriendsRequest.cs" />
|
||||||
<Compile Include="Overlays\Settings\DangerousSettingsButton.cs" />
|
<Compile Include="Overlays\Settings\DangerousSettingsButton.cs" />
|
||||||
<Compile Include="Graphics\UserInterface\HoverClickSounds.cs" />
|
<Compile Include="Graphics\UserInterface\HoverClickSounds.cs" />
|
||||||
<Compile Include="Graphics\UserInterface\HoverSounds.cs" />
|
<Compile Include="Graphics\UserInterface\HoverSounds.cs" />
|
||||||
@ -314,6 +315,9 @@
|
|||||||
<Compile Include="Rulesets\Mods\IApplicableFailOverride.cs" />
|
<Compile Include="Rulesets\Mods\IApplicableFailOverride.cs" />
|
||||||
<Compile Include="Rulesets\Mods\IApplicableMod.cs" />
|
<Compile Include="Rulesets\Mods\IApplicableMod.cs" />
|
||||||
<Compile Include="Rulesets\Mods\IApplicableToBeatmapConverter.cs" />
|
<Compile Include="Rulesets\Mods\IApplicableToBeatmapConverter.cs" />
|
||||||
|
<Compile Include="Overlays\Social\SocialGridPanel.cs" />
|
||||||
|
<Compile Include="Overlays\Social\SocialListPanel.cs" />
|
||||||
|
<Compile Include="Overlays\Social\SocialPanel.cs" />
|
||||||
<Compile Include="Rulesets\Mods\IApplicableToDrawableHitObject.cs" />
|
<Compile Include="Rulesets\Mods\IApplicableToDrawableHitObject.cs" />
|
||||||
<Compile Include="Screens\Select\ImportFromStablePopup.cs" />
|
<Compile Include="Screens\Select\ImportFromStablePopup.cs" />
|
||||||
<Compile Include="Overlays\Settings\SettingsButton.cs" />
|
<Compile Include="Overlays\Settings\SettingsButton.cs" />
|
||||||
|
Loading…
Reference in New Issue
Block a user