mirror of
https://github.com/osukey/osukey.git
synced 2025-08-05 23:53:51 +09:00
Implement TabbableOnlineOverlay component
This commit is contained in:
@ -2,115 +2,35 @@
|
|||||||
// 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.Threading;
|
|
||||||
using osu.Framework.Allocation;
|
|
||||||
using osu.Framework.Bindables;
|
|
||||||
using osu.Framework.Graphics;
|
|
||||||
using osu.Framework.Graphics.Containers;
|
|
||||||
using osu.Game.Online.API;
|
|
||||||
using osu.Game.Overlays.Dashboard;
|
using osu.Game.Overlays.Dashboard;
|
||||||
using osu.Game.Overlays.Dashboard.Friends;
|
using osu.Game.Overlays.Dashboard.Friends;
|
||||||
|
|
||||||
namespace osu.Game.Overlays
|
namespace osu.Game.Overlays
|
||||||
{
|
{
|
||||||
public class DashboardOverlay : OnlineOverlay<DashboardOverlayHeader>
|
public class DashboardOverlay : TabbableOnlineOverlay<DashboardOverlayHeader, DashboardOverlayTabs>
|
||||||
{
|
{
|
||||||
private CancellationTokenSource cancellationToken;
|
|
||||||
|
|
||||||
public DashboardOverlay()
|
public DashboardOverlay()
|
||||||
: base(OverlayColourScheme.Purple)
|
: base(OverlayColourScheme.Purple)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
private readonly IBindable<APIState> apiState = new Bindable<APIState>();
|
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
|
||||||
private void load(IAPIProvider api)
|
|
||||||
{
|
|
||||||
apiState.BindTo(api.State);
|
|
||||||
apiState.BindValueChanged(onlineStateChanged, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void LoadComplete()
|
|
||||||
{
|
|
||||||
base.LoadComplete();
|
|
||||||
Header.Current.BindValueChanged(onTabChanged);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override DashboardOverlayHeader CreateHeader() => new DashboardOverlayHeader();
|
protected override DashboardOverlayHeader CreateHeader() => new DashboardOverlayHeader();
|
||||||
|
|
||||||
private bool displayUpdateRequired = true;
|
protected override void CreateDisplayToLoad(DashboardOverlayTabs tab)
|
||||||
|
|
||||||
protected override void PopIn()
|
|
||||||
{
|
{
|
||||||
base.PopIn();
|
switch (tab)
|
||||||
|
|
||||||
// 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();
|
|
||||||
|
|
||||||
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:
|
case DashboardOverlayTabs.Friends:
|
||||||
loadDisplay(new FriendDisplay());
|
LoadDisplay(new FriendDisplay());
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DashboardOverlayTabs.CurrentlyPlaying:
|
case DashboardOverlayTabs.CurrentlyPlaying:
|
||||||
loadDisplay(new CurrentlyPlayingDisplay());
|
LoadDisplay(new CurrentlyPlayingDisplay());
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
throw new NotImplementedException($"Display for {tab.NewValue} tab is not implemented");
|
throw new NotImplementedException($"Display for {tab} tab is not implemented");
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
private void onlineStateChanged(ValueChangedEvent<APIState> state) => Schedule(() =>
|
|
||||||
{
|
|
||||||
if (State.Value == Visibility.Hidden)
|
|
||||||
return;
|
|
||||||
|
|
||||||
Header.Current.TriggerChange();
|
|
||||||
});
|
|
||||||
|
|
||||||
protected override void Dispose(bool isDisposing)
|
|
||||||
{
|
|
||||||
cancellationToken?.Cancel();
|
|
||||||
base.Dispose(isDisposing);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -8,20 +8,18 @@ using osu.Game.Overlays.Rankings;
|
|||||||
using osu.Game.Users;
|
using osu.Game.Users;
|
||||||
using osu.Game.Rulesets;
|
using osu.Game.Rulesets;
|
||||||
using osu.Game.Online.API;
|
using osu.Game.Online.API;
|
||||||
using System.Threading;
|
|
||||||
using osu.Game.Online.API.Requests;
|
using osu.Game.Online.API.Requests;
|
||||||
using osu.Game.Overlays.Rankings.Tables;
|
using osu.Game.Overlays.Rankings.Tables;
|
||||||
|
|
||||||
namespace osu.Game.Overlays
|
namespace osu.Game.Overlays
|
||||||
{
|
{
|
||||||
public class RankingsOverlay : OnlineOverlay<RankingsOverlayHeader>
|
public class RankingsOverlay : TabbableOnlineOverlay<RankingsOverlayHeader, RankingsScope>
|
||||||
{
|
{
|
||||||
protected Bindable<Country> Country => Header.Country;
|
protected Bindable<Country> Country => Header.Country;
|
||||||
|
|
||||||
protected Bindable<RankingsScope> Scope => Header.Current;
|
protected Bindable<RankingsScope> Scope => Header.Current;
|
||||||
|
|
||||||
private APIRequest lastRequest;
|
private APIRequest lastRequest;
|
||||||
private CancellationTokenSource cancellationToken;
|
|
||||||
|
|
||||||
[Resolved]
|
[Resolved]
|
||||||
private IAPIProvider api { get; set; }
|
private IAPIProvider api { get; set; }
|
||||||
@ -34,11 +32,6 @@ namespace osu.Game.Overlays
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
|
||||||
private void load()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void LoadComplete()
|
protected override void LoadComplete()
|
||||||
{
|
{
|
||||||
base.LoadComplete();
|
base.LoadComplete();
|
||||||
@ -54,6 +47,8 @@ namespace osu.Game.Overlays
|
|||||||
Scheduler.AddOnce(loadNewContent);
|
Scheduler.AddOnce(loadNewContent);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Unbind events from scope so base class event will not be called
|
||||||
|
Scope.UnbindEvents();
|
||||||
Scope.BindValueChanged(_ =>
|
Scope.BindValueChanged(_ =>
|
||||||
{
|
{
|
||||||
// country filtering is only valid for performance scope.
|
// country filtering is only valid for performance scope.
|
||||||
@ -70,8 +65,6 @@ namespace osu.Game.Overlays
|
|||||||
|
|
||||||
Scheduler.AddOnce(loadNewContent);
|
Scheduler.AddOnce(loadNewContent);
|
||||||
});
|
});
|
||||||
|
|
||||||
Scheduler.AddOnce(loadNewContent);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override RankingsOverlayHeader CreateHeader() => new RankingsOverlayHeader();
|
protected override RankingsOverlayHeader CreateHeader() => new RankingsOverlayHeader();
|
||||||
@ -92,16 +85,13 @@ namespace osu.Game.Overlays
|
|||||||
Show();
|
Show();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void loadNewContent()
|
protected override void CreateDisplayToLoad(RankingsScope tab)
|
||||||
{
|
{
|
||||||
Loading.Show();
|
|
||||||
|
|
||||||
cancellationToken?.Cancel();
|
|
||||||
lastRequest?.Cancel();
|
lastRequest?.Cancel();
|
||||||
|
|
||||||
if (Scope.Value == RankingsScope.Spotlights)
|
if (Scope.Value == RankingsScope.Spotlights)
|
||||||
{
|
{
|
||||||
loadContent(new SpotlightsLayout
|
LoadDisplay(new SpotlightsLayout
|
||||||
{
|
{
|
||||||
Ruleset = { BindTarget = ruleset }
|
Ruleset = { BindTarget = ruleset }
|
||||||
});
|
});
|
||||||
@ -113,12 +103,12 @@ namespace osu.Game.Overlays
|
|||||||
|
|
||||||
if (request == null)
|
if (request == null)
|
||||||
{
|
{
|
||||||
loadContent(null);
|
LoadDisplay(Empty());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
request.Success += () => Schedule(() => loadContent(createTableFromResponse(request)));
|
request.Success += () => Schedule(() => LoadDisplay(createTableFromResponse(request)));
|
||||||
request.Failure += _ => Schedule(() => loadContent(null));
|
request.Failure += _ => Schedule(() => LoadDisplay(Empty()));
|
||||||
|
|
||||||
api.Queue(request);
|
api.Queue(request);
|
||||||
}
|
}
|
||||||
@ -163,29 +153,11 @@ namespace osu.Game.Overlays
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void loadContent(Drawable content)
|
private void loadNewContent() => OnTabChanged(Scope.Value);
|
||||||
{
|
|
||||||
ScrollFlow.ScrollToStart();
|
|
||||||
|
|
||||||
if (content == null)
|
|
||||||
{
|
|
||||||
Clear();
|
|
||||||
Loading.Hide();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
LoadComponentAsync(content, loaded =>
|
|
||||||
{
|
|
||||||
Loading.Hide();
|
|
||||||
Child = loaded;
|
|
||||||
}, (cancellationToken = new CancellationTokenSource()).Token);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void Dispose(bool isDisposing)
|
protected override void Dispose(bool isDisposing)
|
||||||
{
|
{
|
||||||
lastRequest?.Cancel();
|
lastRequest?.Cancel();
|
||||||
cancellationToken?.Cancel();
|
|
||||||
|
|
||||||
base.Dispose(isDisposing);
|
base.Dispose(isDisposing);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
101
osu.Game/Overlays/TabbableOnlineOverlay.cs
Normal file
101
osu.Game/Overlays/TabbableOnlineOverlay.cs
Normal file
@ -0,0 +1,101 @@
|
|||||||
|
// 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.Threading;
|
||||||
|
using osu.Framework.Allocation;
|
||||||
|
using osu.Framework.Bindables;
|
||||||
|
using osu.Framework.Graphics;
|
||||||
|
using osu.Framework.Graphics.Containers;
|
||||||
|
using osu.Game.Online.API;
|
||||||
|
|
||||||
|
namespace osu.Game.Overlays
|
||||||
|
{
|
||||||
|
public abstract class TabbableOnlineOverlay<THeader, TEnum> : OnlineOverlay<THeader>
|
||||||
|
where THeader : TabControlOverlayHeader<TEnum>
|
||||||
|
{
|
||||||
|
private readonly IBindable<APIState> apiState = new Bindable<APIState>();
|
||||||
|
|
||||||
|
private CancellationTokenSource cancellationToken;
|
||||||
|
private bool displayUpdateRequired = true;
|
||||||
|
|
||||||
|
protected TabbableOnlineOverlay(OverlayColourScheme colourScheme)
|
||||||
|
: base(colourScheme)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
[BackgroundDependencyLoader]
|
||||||
|
private void load(IAPIProvider api)
|
||||||
|
{
|
||||||
|
apiState.BindTo(api.State);
|
||||||
|
apiState.BindValueChanged(onlineStateChanged, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void LoadComplete()
|
||||||
|
{
|
||||||
|
base.LoadComplete();
|
||||||
|
Header.Current.BindValueChanged(tab => OnTabChanged(tab.NewValue));
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void LoadDisplay(Drawable display)
|
||||||
|
{
|
||||||
|
ScrollFlow.ScrollToStart();
|
||||||
|
|
||||||
|
LoadComponentAsync(display, loaded =>
|
||||||
|
{
|
||||||
|
if (API.IsLoggedIn)
|
||||||
|
Loading.Hide();
|
||||||
|
|
||||||
|
Child = loaded;
|
||||||
|
}, (cancellationToken = new CancellationTokenSource()).Token);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void OnTabChanged(TEnum tab)
|
||||||
|
{
|
||||||
|
cancellationToken?.Cancel();
|
||||||
|
Loading.Show();
|
||||||
|
|
||||||
|
if (!API.IsLoggedIn)
|
||||||
|
{
|
||||||
|
LoadDisplay(Empty());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
CreateDisplayToLoad(tab);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected abstract void CreateDisplayToLoad(TEnum tab);
|
||||||
|
|
||||||
|
private void onlineStateChanged(ValueChangedEvent<APIState> state) => Schedule(() =>
|
||||||
|
{
|
||||||
|
if (State.Value == Visibility.Hidden)
|
||||||
|
return;
|
||||||
|
|
||||||
|
Header.Current.TriggerChange();
|
||||||
|
});
|
||||||
|
|
||||||
|
protected override void Dispose(bool isDisposing)
|
||||||
|
{
|
||||||
|
cancellationToken?.Cancel();
|
||||||
|
base.Dispose(isDisposing);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Reference in New Issue
Block a user