1
0
mirror of https://github.com/ppy/osu.git synced 2025-02-15 16:13:20 +08:00

Merge pull request #8771 from EVAST9919/dashboard-overlay-new

Replace SocialOverlay with DashboardOverlay
This commit is contained in:
Dan Balasescu 2020-04-20 20:22:37 +09:00 committed by GitHub
commit 6ba1bef683
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 336 additions and 39 deletions

View File

@ -0,0 +1,43 @@
// 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 NUnit.Framework;
using osu.Game.Overlays;
using osu.Game.Overlays.Dashboard;
using osu.Game.Overlays.Dashboard.Friends;
namespace osu.Game.Tests.Visual.Online
{
public class TestSceneDashboardOverlay : OsuTestScene
{
public override IReadOnlyList<Type> RequiredTypes => new[]
{
typeof(DashboardOverlay),
typeof(DashboardOverlayHeader),
typeof(FriendDisplay)
};
protected override bool UseOnlineAPI => true;
private readonly DashboardOverlay overlay;
public TestSceneDashboardOverlay()
{
Add(overlay = new DashboardOverlay());
}
[Test]
public void TestShow()
{
AddStep("Show", overlay.Show);
}
[Test]
public void TestHide()
{
AddStep("Hide", overlay.Hide);
}
}
}

View File

@ -10,6 +10,7 @@ using osu.Game.Users;
using osu.Game.Overlays; using osu.Game.Overlays;
using osu.Framework.Allocation; using osu.Framework.Allocation;
using NUnit.Framework; using NUnit.Framework;
using osu.Game.Online.API;
namespace osu.Game.Tests.Visual.Online namespace osu.Game.Tests.Visual.Online
{ {
@ -27,7 +28,7 @@ namespace osu.Game.Tests.Visual.Online
[Cached] [Cached]
private readonly OverlayColourProvider colourProvider = new OverlayColourProvider(OverlayColourScheme.Purple); private readonly OverlayColourProvider colourProvider = new OverlayColourProvider(OverlayColourScheme.Purple);
private FriendDisplay display; private TestFriendDisplay display;
[SetUp] [SetUp]
public void Setup() => Schedule(() => public void Setup() => Schedule(() =>
@ -35,7 +36,7 @@ namespace osu.Game.Tests.Visual.Online
Child = new BasicScrollContainer Child = new BasicScrollContainer
{ {
RelativeSizeAxes = Axes.Both, RelativeSizeAxes = Axes.Both,
Child = display = new FriendDisplay() Child = display = new TestFriendDisplay()
}; };
}); });
@ -83,5 +84,17 @@ namespace osu.Game.Tests.Visual.Online
LastVisit = DateTimeOffset.Now LastVisit = DateTimeOffset.Now
} }
}; };
private class TestFriendDisplay : FriendDisplay
{
public void Fetch()
{
base.APIStateChanged(API, APIState.Online);
}
public override void APIStateChanged(IAPIProvider api, APIState state)
{
}
}
} }
} }

View File

@ -48,7 +48,7 @@ namespace osu.Game.Tests.Visual
typeof(OnScreenDisplay), typeof(OnScreenDisplay),
typeof(NotificationOverlay), typeof(NotificationOverlay),
typeof(DirectOverlay), typeof(DirectOverlay),
typeof(SocialOverlay), typeof(DashboardOverlay),
typeof(ChannelManager), typeof(ChannelManager),
typeof(ChatOverlay), typeof(ChatOverlay),
typeof(SettingsOverlay), typeof(SettingsOverlay),

View File

@ -67,7 +67,7 @@ namespace osu.Game
private DirectOverlay direct; private DirectOverlay direct;
private SocialOverlay social; private DashboardOverlay dashboard;
private UserProfileOverlay userProfile; private UserProfileOverlay userProfile;
@ -611,7 +611,7 @@ namespace osu.Game
//overlay elements //overlay elements
loadComponentSingleFile(direct = new DirectOverlay(), overlayContent.Add, true); loadComponentSingleFile(direct = new DirectOverlay(), overlayContent.Add, true);
loadComponentSingleFile(social = new SocialOverlay(), overlayContent.Add, true); loadComponentSingleFile(dashboard = new DashboardOverlay(), overlayContent.Add, true);
var rankingsOverlay = loadComponentSingleFile(new RankingsOverlay(), overlayContent.Add, true); var rankingsOverlay = loadComponentSingleFile(new RankingsOverlay(), overlayContent.Add, true);
loadComponentSingleFile(channelManager = new ChannelManager(), AddInternal, true); loadComponentSingleFile(channelManager = new ChannelManager(), AddInternal, true);
loadComponentSingleFile(chatOverlay = new ChatOverlay(), overlayContent.Add, true); loadComponentSingleFile(chatOverlay = new ChatOverlay(), overlayContent.Add, true);
@ -670,7 +670,7 @@ namespace osu.Game
} }
// ensure only one of these overlays are open at once. // ensure only one of these overlays are open at once.
var singleDisplayOverlays = new OverlayContainer[] { chatOverlay, social, direct, changelogOverlay, rankingsOverlay }; var singleDisplayOverlays = new OverlayContainer[] { chatOverlay, dashboard, direct, changelogOverlay, rankingsOverlay };
foreach (var overlay in singleDisplayOverlays) foreach (var overlay in singleDisplayOverlays)
{ {
@ -842,7 +842,7 @@ namespace osu.Game
return true; return true;
case GlobalAction.ToggleSocial: case GlobalAction.ToggleSocial:
social.ToggleVisibility(); dashboard.ToggleVisibility();
return true; return true;
case GlobalAction.ResetInputSettings: case GlobalAction.ResetInputSettings:

View File

@ -0,0 +1,24 @@
// 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.
namespace osu.Game.Overlays.Dashboard
{
public class DashboardOverlayHeader : TabControlOverlayHeader<DashboardOverlayTabs>
{
protected override OverlayTitle CreateTitle() => new DashboardTitle();
private class DashboardTitle : OverlayTitle
{
public DashboardTitle()
{
Title = "dashboard";
IconTexture = "Icons/changelog";
}
}
}
public enum DashboardOverlayTabs
{
Friends
}
}

View File

@ -16,7 +16,7 @@ using osuTK;
namespace osu.Game.Overlays.Dashboard.Friends namespace osu.Game.Overlays.Dashboard.Friends
{ {
public class FriendDisplay : CompositeDrawable public class FriendDisplay : OverlayView<List<User>>
{ {
private List<User> users = new List<User>(); private List<User> users = new List<User>();
@ -26,34 +26,29 @@ namespace osu.Game.Overlays.Dashboard.Friends
set set
{ {
users = value; users = value;
onlineStreamControl.Populate(value); onlineStreamControl.Populate(value);
} }
} }
[Resolved]
private IAPIProvider api { get; set; }
private GetFriendsRequest request;
private CancellationTokenSource cancellationToken; private CancellationTokenSource cancellationToken;
private Drawable currentContent; private Drawable currentContent;
private readonly FriendOnlineStreamControl onlineStreamControl; private FriendOnlineStreamControl onlineStreamControl;
private readonly Box background; private Box background;
private readonly Box controlBackground; private Box controlBackground;
private readonly UserListToolbar userListToolbar; private UserListToolbar userListToolbar;
private readonly Container itemsPlaceholder; private Container itemsPlaceholder;
private readonly LoadingLayer loading; private LoadingLayer loading;
public FriendDisplay() [BackgroundDependencyLoader]
private void load(OverlayColourProvider colourProvider)
{ {
RelativeSizeAxes = Axes.X;
AutoSizeAxes = Axes.Y;
InternalChild = new FillFlowContainer InternalChild = new FillFlowContainer
{ {
RelativeSizeAxes = Axes.X, RelativeSizeAxes = Axes.X,
AutoSizeAxes = Axes.Y, AutoSizeAxes = Axes.Y,
Direction = FillDirection.Vertical,
Children = new Drawable[] Children = new Drawable[]
{ {
new Container new Container
@ -134,11 +129,7 @@ namespace osu.Game.Overlays.Dashboard.Friends
} }
} }
}; };
}
[BackgroundDependencyLoader]
private void load(OverlayColourProvider colourProvider)
{
background.Colour = colourProvider.Background4; background.Colour = colourProvider.Background4;
controlBackground.Colour = colourProvider.Background5; controlBackground.Colour = colourProvider.Background5;
} }
@ -152,14 +143,11 @@ namespace osu.Game.Overlays.Dashboard.Friends
userListToolbar.SortCriteria.BindValueChanged(_ => recreatePanels()); userListToolbar.SortCriteria.BindValueChanged(_ => recreatePanels());
} }
public void Fetch() protected override APIRequest<List<User>> CreateRequest() => new GetFriendsRequest();
{
if (!api.IsLoggedIn)
return;
request = new GetFriendsRequest(); protected override void OnSuccess(List<User> response)
request.Success += response => Schedule(() => Users = response); {
api.Queue(request); Users = response;
} }
private void recreatePanels() private void recreatePanels()
@ -258,9 +246,7 @@ namespace osu.Game.Overlays.Dashboard.Friends
protected override void Dispose(bool isDisposing) protected override void Dispose(bool isDisposing)
{ {
request?.Cancel();
cancellationToken?.Cancel(); cancellationToken?.Cancel();
base.Dispose(isDisposing); base.Dispose(isDisposing);
} }
} }

View File

@ -0,0 +1,150 @@
// 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.Threading;
using osu.Framework.Allocation;
using osu.Framework.Bindables;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Shapes;
using osu.Game.Graphics.UserInterface;
using osu.Game.Online.API;
using osu.Game.Overlays.Dashboard;
using osu.Game.Overlays.Dashboard.Friends;
namespace osu.Game.Overlays
{
public class DashboardOverlay : FullscreenOverlay
{
private CancellationTokenSource cancellationToken;
private Box background;
private Container content;
private DashboardOverlayHeader header;
private LoadingLayer loading;
private OverlayScrollContainer scrollFlow;
public DashboardOverlay()
: base(OverlayColourScheme.Purple)
{
}
[BackgroundDependencyLoader]
private void load()
{
Children = new Drawable[]
{
background = new Box
{
RelativeSizeAxes = Axes.Both
},
scrollFlow = new OverlayScrollContainer
{
RelativeSizeAxes = Axes.Both,
ScrollbarVisible = false,
Child = new FillFlowContainer
{
AutoSizeAxes = Axes.Y,
RelativeSizeAxes = Axes.X,
Direction = FillDirection.Vertical,
Children = new Drawable[]
{
header = new DashboardOverlayHeader
{
Anchor = Anchor.TopCentre,
Origin = Anchor.TopCentre,
Depth = -float.MaxValue
},
content = new Container
{
RelativeSizeAxes = Axes.X,
AutoSizeAxes = Axes.Y
}
}
}
},
loading = new LoadingLayer(content),
};
background.Colour = ColourProvider.Background5;
}
protected override void LoadComplete()
{
base.LoadComplete();
header.Current.BindValueChanged(onTabChanged);
}
private bool displayUpdateRequired = true;
protected override void PopIn()
{
base.PopIn();
// We don't want to create a new display on every call, only when exiting from fully closed state.
if (displayUpdateRequired)
{
header.Current.TriggerChange();
displayUpdateRequired = false;
}
}
protected override void PopOutComplete()
{
base.PopOutComplete();
loadDisplay(Empty());
displayUpdateRequired = true;
}
private void loadDisplay(Drawable display)
{
scrollFlow.ScrollToStart();
LoadComponentAsync(display, loaded =>
{
if (API.IsLoggedIn)
loading.Hide();
content.Child = loaded;
}, (cancellationToken = new CancellationTokenSource()).Token);
}
private void onTabChanged(ValueChangedEvent<DashboardOverlayTabs> tab)
{
cancellationToken?.Cancel();
loading.Show();
if (!API.IsLoggedIn)
{
loadDisplay(Empty());
return;
}
switch (tab.NewValue)
{
case DashboardOverlayTabs.Friends:
loadDisplay(new FriendDisplay());
break;
default:
throw new NotImplementedException($"Display for {tab.NewValue} tab is not implemented");
}
}
public override void APIStateChanged(IAPIProvider api, APIState state)
{
if (State.Value == Visibility.Hidden)
return;
header.Current.TriggerChange();
}
protected override void Dispose(bool isDisposing)
{
cancellationToken?.Cancel();
base.Dispose(isDisposing);
}
}
}

View File

@ -12,6 +12,8 @@ namespace osu.Game.Overlays
{ {
public abstract class OverlayHeader : Container public abstract class OverlayHeader : Container
{ {
public const int CONTENT_X_MARGIN = 50;
private readonly Box titleBackground; private readonly Box titleBackground;
protected readonly FillFlowContainer HeaderInfo; protected readonly FillFlowContainer HeaderInfo;
@ -54,7 +56,7 @@ namespace osu.Game.Overlays
AutoSizeAxes = Axes.Y, AutoSizeAxes = Axes.Y,
Padding = new MarginPadding Padding = new MarginPadding
{ {
Horizontal = UserProfileOverlay.CONTENT_X_MARGIN, Horizontal = CONTENT_X_MARGIN,
}, },
Children = new[] Children = new[]
{ {

View File

@ -0,0 +1,79 @@
// 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;
using osu.Framework.Graphics.Containers;
using osu.Game.Online.API;
namespace osu.Game.Overlays
{
/// <summary>
/// A subview containing online content, to be displayed inside a <see cref="FullscreenOverlay"/>.
/// </summary>
/// <remarks>
/// Automatically performs a data fetch on load.
/// </remarks>
/// <typeparam name="T">The type of the API response.</typeparam>
public abstract class OverlayView<T> : CompositeDrawable, IOnlineComponent
where T : class
{
[Resolved]
protected IAPIProvider API { get; private set; }
private APIRequest<T> request;
protected OverlayView()
{
RelativeSizeAxes = Axes.X;
AutoSizeAxes = Axes.Y;
}
protected override void LoadComplete()
{
base.LoadComplete();
API.Register(this);
}
/// <summary>
/// Create the API request for fetching data.
/// </summary>
protected abstract APIRequest<T> CreateRequest();
/// <summary>
/// Fired when results arrive from the main API request.
/// </summary>
/// <param name="response"></param>
protected abstract void OnSuccess(T response);
/// <summary>
/// Force a re-request for data from the API.
/// </summary>
protected void PerformFetch()
{
request?.Cancel();
request = CreateRequest();
request.Success += response => Schedule(() => OnSuccess(response));
API.Queue(request);
}
public virtual void APIStateChanged(IAPIProvider api, APIState state)
{
switch (state)
{
case APIState.Online:
PerformFetch();
break;
}
}
protected override void Dispose(bool isDisposing)
{
request?.Cancel();
API?.Unregister(this);
base.Dispose(isDisposing);
}
}
}

View File

@ -44,7 +44,7 @@ namespace osu.Game.Overlays
}, },
TabControl = CreateTabControl().With(control => TabControl = CreateTabControl().With(control =>
{ {
control.Margin = new MarginPadding { Left = UserProfileOverlay.CONTENT_X_MARGIN }; control.Margin = new MarginPadding { Left = CONTENT_X_MARGIN };
control.Current = Current; control.Current = Current;
}) })
} }

View File

@ -14,9 +14,9 @@ namespace osu.Game.Overlays.Toolbar
} }
[BackgroundDependencyLoader(true)] [BackgroundDependencyLoader(true)]
private void load(SocialOverlay chat) private void load(DashboardOverlay dashboard)
{ {
StateContainer = chat; StateContainer = dashboard;
} }
} }
} }