mirror of
https://github.com/ppy/osu.git
synced 2026-05-13 20:33:35 +08:00
Add ability to search for users (#37225)
This was a private request for roundtable event usage. It’s also a common feature request, so I decided to spend a bit of time getting this working well-enough. https://github.com/user-attachments/assets/acceb57f-2979-43d0-9fc2-33e977bd2dd5 --- ### Delay loading spinner / loading layer initial load briefly to avoid flickering There's cases in this overlay where loading takes a few milliseconds. The loading spinner gets annoying. This also happens elsewhere, so this could be considered a global fix. Separate PR? probably... ### Ingest loading state of dashboard child content to show more correct loading layer Each display had their own loading layer implementation, but this is already too deep (inside the scroll content) and doesn't display great when for instance, results don't take up the full screen height. --------- Co-authored-by: Bartłomiej Dach <dach.bartlomiej@gmail.com>
This commit is contained in:
committed by
GitHub
Unverified
parent
a3a530c25d
commit
c570db6c40
@@ -12,7 +12,6 @@ using osu.Framework.Extensions.TypeExtensions;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Testing;
|
||||
using osu.Game.Graphics.UserInterface;
|
||||
using osu.Game.Online.API;
|
||||
using osu.Game.Online.API.Requests.Responses;
|
||||
using osu.Game.Online.Metadata;
|
||||
@@ -219,13 +218,13 @@ namespace osu.Game.Tests.Visual.Online
|
||||
}
|
||||
|
||||
private void waitForLoad()
|
||||
=> AddUntilStep("wait for panels to load", () => this.ChildrenOfType<LoadingSpinner>().First().State.Value, () => Is.EqualTo(Visibility.Hidden));
|
||||
=> AddUntilStep("wait for panels to load", () => this.ChildrenOfType<UserPanel>().Any());
|
||||
|
||||
private void assertVisiblePanelCount<T>(int expectedVisible)
|
||||
where T : UserPanel
|
||||
{
|
||||
AddAssert($"{typeof(T).ReadableName()}s in list", () => this.ChildrenOfType<FriendsList>().Last().ChildrenOfType<UserPanel>().All(p => p is T));
|
||||
AddAssert($"{expectedVisible} panels visible", () => this.ChildrenOfType<FriendsList>().Last().ChildrenOfType<FriendsList.FilterableUserPanel>().Count(p => p.IsPresent),
|
||||
AddUntilStep($"{typeof(T).ReadableName()}s in list", () => this.ChildrenOfType<FriendsList>().Last().ChildrenOfType<UserPanel>().All(p => p is T));
|
||||
AddUntilStep($"{expectedVisible} panels visible", () => this.ChildrenOfType<FriendsList>().Last().ChildrenOfType<FriendsList.FilterableUserPanel>().Count(p => p.IsPresent),
|
||||
() => Is.EqualTo(expectedVisible));
|
||||
}
|
||||
|
||||
|
||||
@@ -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.
|
||||
|
||||
using NUnit.Framework;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Game.Overlays;
|
||||
using osu.Game.Overlays.Dashboard.UserSearch;
|
||||
|
||||
namespace osu.Game.Tests.Visual.Online
|
||||
{
|
||||
public partial class TestSceneUserSearchDisplay : OsuTestScene
|
||||
{
|
||||
[Cached]
|
||||
private readonly OverlayColourProvider colourProvider = new OverlayColourProvider(OverlayColourScheme.Purple);
|
||||
|
||||
protected override bool UseOnlineAPI => true;
|
||||
|
||||
[SetUp]
|
||||
public void Setup() => Schedule(() =>
|
||||
{
|
||||
Child = new UserSearchDisplay();
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -22,7 +22,7 @@ namespace osu.Game.Tests.Visual.UserInterface
|
||||
OsuSpriteText sort;
|
||||
OsuSpriteText displayStyle;
|
||||
|
||||
Add(toolbar = new UserListToolbar(true)
|
||||
Add(toolbar = new UserListToolbar
|
||||
{
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
|
||||
@@ -171,7 +171,12 @@ namespace osu.Game.Graphics.UserInterface
|
||||
rotate();
|
||||
|
||||
MainContents.ScaleTo(1, TRANSITION_DURATION, Easing.OutQuint);
|
||||
this.FadeIn(TRANSITION_DURATION, Easing.OutQuint);
|
||||
|
||||
// Very slight delay to avoid spinner flickering briefly during minimal loads.
|
||||
// Note that we still use fade in here because it is important for input blocking cases (see `LoadingLayer`).
|
||||
this.FadeTo(0.01f, 50)
|
||||
.Then()
|
||||
.FadeIn(TRANSITION_DURATION, Easing.OutQuint);
|
||||
}
|
||||
|
||||
protected override void PopOut()
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
// 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.IO.Network;
|
||||
|
||||
namespace osu.Game.Online.API.Requests
|
||||
{
|
||||
/// <summary>
|
||||
/// Lookup up users with the given <see cref="Query"/>.
|
||||
/// </summary>
|
||||
public class SearchUsersRequest : APIRequest<SearchUsersResponse>
|
||||
{
|
||||
public readonly string Query;
|
||||
|
||||
public SearchUsersRequest(string query)
|
||||
{
|
||||
Query = query;
|
||||
}
|
||||
|
||||
protected override string Target => "search";
|
||||
|
||||
protected override WebRequest CreateWebRequest()
|
||||
{
|
||||
var req = base.CreateWebRequest();
|
||||
|
||||
req.AddParameter("mode", "user");
|
||||
req.AddParameter("query", Query);
|
||||
|
||||
return req;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
// 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 Newtonsoft.Json;
|
||||
using osu.Game.Online.API.Requests.Responses;
|
||||
|
||||
namespace osu.Game.Online.API.Requests
|
||||
{
|
||||
public class SearchUsersResponse
|
||||
{
|
||||
[JsonProperty("total")]
|
||||
public int Total;
|
||||
|
||||
public List<APIUser> Users => data.Users;
|
||||
|
||||
[JsonProperty("user")]
|
||||
private UserData data = null!;
|
||||
|
||||
[Serializable]
|
||||
private class UserData
|
||||
{
|
||||
[JsonProperty("data")]
|
||||
public List<APIUser> Users = new List<APIUser>();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -18,6 +18,9 @@ namespace osu.Game.Overlays.Dashboard.CurrentlyOnline
|
||||
{
|
||||
public partial class CurrentlyOnlineDisplay : CompositeDrawable
|
||||
{
|
||||
public IBindable<bool> Loading => loading;
|
||||
private readonly BindableBool loading = new BindableBool();
|
||||
|
||||
/// <summary>
|
||||
/// The current state of the <see cref="DashboardOverlay"/>.
|
||||
/// Presence is only updated when this value is <see cref="Visibility.Visible"/>.
|
||||
@@ -32,7 +35,6 @@ namespace osu.Game.Overlays.Dashboard.CurrentlyOnline
|
||||
private Box background = null!;
|
||||
private UserListToolbar userListToolbar = null!;
|
||||
private Container<RealtimeUserList> listContainer = null!;
|
||||
private LoadingLayer loading = null!;
|
||||
private BasicSearchTextBox searchTextBox = null!;
|
||||
|
||||
private CancellationTokenSource? listLoadCancellation;
|
||||
@@ -95,7 +97,7 @@ namespace osu.Game.Overlays.Dashboard.CurrentlyOnline
|
||||
PlaceholderText = HomeStrings.SearchPlaceholder,
|
||||
},
|
||||
Empty(),
|
||||
userListToolbar = new UserListToolbar(false)
|
||||
userListToolbar = new UserListToolbar(supportsBrickMode: false)
|
||||
{
|
||||
Anchor = Anchor.CentreRight,
|
||||
Origin = Anchor.CentreRight,
|
||||
@@ -115,7 +117,6 @@ namespace osu.Game.Overlays.Dashboard.CurrentlyOnline
|
||||
AutoSizeAxes = Axes.Y,
|
||||
Padding = new MarginPadding { Horizontal = WaveOverlayContainer.HORIZONTAL_PADDING }
|
||||
},
|
||||
loading = new LoadingLayer(true)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -149,12 +150,12 @@ namespace osu.Game.Overlays.Dashboard.CurrentlyOnline
|
||||
SearchText = { BindTarget = searchTextBox.Current }
|
||||
};
|
||||
|
||||
loading.Show();
|
||||
loading.Value = true;
|
||||
LoadComponentAsync(newList, finishLoad, cancellationSource.Token);
|
||||
|
||||
void finishLoad(RealtimeUserList list)
|
||||
{
|
||||
loading.Hide();
|
||||
loading.Value = false;
|
||||
|
||||
if (currentList != null)
|
||||
{
|
||||
|
||||
@@ -30,6 +30,9 @@ namespace osu.Game.Overlays.Dashboard
|
||||
Friends,
|
||||
|
||||
[Description("Currently online")]
|
||||
CurrentlyPlaying
|
||||
CurrentlyPlaying,
|
||||
|
||||
[Description("User search")]
|
||||
UserSearch
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,6 +17,9 @@ namespace osu.Game.Overlays.Dashboard.Friends
|
||||
{
|
||||
public partial class FriendDisplay : CompositeDrawable
|
||||
{
|
||||
public IBindable<bool> Loading => loading;
|
||||
private readonly BindableBool loading = new BindableBool();
|
||||
|
||||
private readonly IBindableList<APIRelation> apiFriends = new BindableList<APIRelation>();
|
||||
|
||||
[Resolved]
|
||||
@@ -27,7 +30,6 @@ namespace osu.Game.Overlays.Dashboard.Friends
|
||||
private Box controlBackground = null!;
|
||||
private UserListToolbar userListToolbar = null!;
|
||||
private Container<FriendsList> listContainer = null!;
|
||||
private LoadingLayer loading = null!;
|
||||
private BasicSearchTextBox searchTextBox = null!;
|
||||
|
||||
private CancellationTokenSource? listLoadCancellation;
|
||||
@@ -124,7 +126,7 @@ namespace osu.Game.Overlays.Dashboard.Friends
|
||||
PlaceholderText = HomeStrings.SearchPlaceholder,
|
||||
},
|
||||
Empty(),
|
||||
userListToolbar = new UserListToolbar(true)
|
||||
userListToolbar = new UserListToolbar
|
||||
{
|
||||
Anchor = Anchor.CentreRight,
|
||||
Origin = Anchor.CentreRight,
|
||||
@@ -144,7 +146,6 @@ namespace osu.Game.Overlays.Dashboard.Friends
|
||||
AutoSizeAxes = Axes.Y,
|
||||
Padding = new MarginPadding { Horizontal = WaveOverlayContainer.HORIZONTAL_PADDING }
|
||||
},
|
||||
loading = new LoadingLayer(true)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -183,12 +184,12 @@ namespace osu.Game.Overlays.Dashboard.Friends
|
||||
SearchText = { BindTarget = searchTextBox.Current }
|
||||
};
|
||||
|
||||
loading.Show();
|
||||
loading.Value = true;
|
||||
LoadComponentAsync(newList, finishLoad, cancellationSource.Token);
|
||||
|
||||
void finishLoad(FriendsList list)
|
||||
{
|
||||
loading.Hide();
|
||||
loading.Value = false;
|
||||
|
||||
if (currentList != null)
|
||||
{
|
||||
|
||||
@@ -2,11 +2,11 @@
|
||||
// See the LICENCE file in the repository root for full licence text.
|
||||
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Bindables;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osuTK;
|
||||
using osu.Framework.Bindables;
|
||||
using osu.Game.Configuration;
|
||||
using osuTK;
|
||||
|
||||
namespace osu.Game.Overlays.Dashboard.Friends
|
||||
{
|
||||
@@ -19,10 +19,11 @@ namespace osu.Game.Overlays.Dashboard.Friends
|
||||
private readonly Bindable<OverlayPanelDisplayStyle> configDisplayStyle = new Bindable<OverlayPanelDisplayStyle>();
|
||||
|
||||
private readonly bool supportsBrickMode;
|
||||
|
||||
private readonly UserSortTabControl sortControl;
|
||||
private readonly OverlayPanelDisplayStyleControl styleControl;
|
||||
|
||||
public UserListToolbar(bool supportsBrickMode)
|
||||
public UserListToolbar(bool supportsBrickMode = true, bool supportsSort = true)
|
||||
{
|
||||
this.supportsBrickMode = supportsBrickMode;
|
||||
|
||||
@@ -37,6 +38,7 @@ namespace osu.Game.Overlays.Dashboard.Friends
|
||||
{
|
||||
sortControl = new UserSortTabControl
|
||||
{
|
||||
Alpha = supportsSort ? 1 : 0,
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
},
|
||||
|
||||
@@ -0,0 +1,69 @@
|
||||
// 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.Linq;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Game.Online.API.Requests.Responses;
|
||||
using osu.Game.Users;
|
||||
using osuTK;
|
||||
|
||||
namespace osu.Game.Overlays.Dashboard.UserSearch
|
||||
{
|
||||
/// <summary>
|
||||
/// This is copy pasted to hell, but it's where we're at. Based off FriendList but without the friend overheads.
|
||||
/// </summary>
|
||||
public partial class UserPanelList : CompositeDrawable
|
||||
{
|
||||
private readonly OverlayPanelDisplayStyle style;
|
||||
private readonly APIUser[] users;
|
||||
|
||||
public UserPanelList(OverlayPanelDisplayStyle style, APIUser[] users)
|
||||
{
|
||||
this.style = style;
|
||||
this.users = users;
|
||||
|
||||
RelativeSizeAxes = Axes.X;
|
||||
AutoSizeAxes = Axes.Y;
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load()
|
||||
{
|
||||
InternalChild = new FillFlowContainer
|
||||
{
|
||||
RelativeSizeAxes = Axes.X,
|
||||
AutoSizeAxes = Axes.Y,
|
||||
Spacing = new Vector2(style == OverlayPanelDisplayStyle.Card ? 10 : 2),
|
||||
ChildrenEnumerable = users.Select(createUserPanel)
|
||||
};
|
||||
}
|
||||
|
||||
private UserPanel createUserPanel(APIUser user)
|
||||
{
|
||||
UserPanel panel;
|
||||
|
||||
switch (style)
|
||||
{
|
||||
default:
|
||||
case OverlayPanelDisplayStyle.Card:
|
||||
panel = new UserGridPanel(user);
|
||||
panel.Anchor = Anchor.TopCentre;
|
||||
panel.Origin = Anchor.TopCentre;
|
||||
panel.Width = 290;
|
||||
break;
|
||||
|
||||
case OverlayPanelDisplayStyle.List:
|
||||
panel = new UserListPanel(user);
|
||||
break;
|
||||
|
||||
case OverlayPanelDisplayStyle.Brick:
|
||||
panel = new UserBrickPanel(user);
|
||||
break;
|
||||
}
|
||||
|
||||
return panel;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,187 @@
|
||||
// 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.Bindables;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Graphics.Shapes;
|
||||
using osu.Framework.Threading;
|
||||
using osu.Game.Graphics.UserInterface;
|
||||
using osu.Game.Online.API;
|
||||
using osu.Game.Online.API.Requests;
|
||||
using osu.Game.Overlays.Dashboard.Friends;
|
||||
using osu.Game.Resources.Localisation.Web;
|
||||
|
||||
namespace osu.Game.Overlays.Dashboard.UserSearch
|
||||
{
|
||||
public partial class UserSearchDisplay : CompositeDrawable
|
||||
{
|
||||
[Resolved]
|
||||
private IAPIProvider api { get; set; } = null!;
|
||||
|
||||
public IBindable<bool> Loading => loading;
|
||||
private readonly BindableBool loading = new BindableBool();
|
||||
|
||||
private Box background = null!;
|
||||
private UserListToolbar userListToolbar = null!;
|
||||
private Container listContainer = null!;
|
||||
private BasicSearchTextBox searchTextBox = null!;
|
||||
|
||||
public UserSearchDisplay()
|
||||
{
|
||||
RelativeSizeAxes = Axes.X;
|
||||
AutoSizeAxes = Axes.Y;
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(OverlayColourProvider colourProvider)
|
||||
{
|
||||
InternalChild = new FillFlowContainer
|
||||
{
|
||||
RelativeSizeAxes = Axes.X,
|
||||
AutoSizeAxes = Axes.Y,
|
||||
Direction = FillDirection.Vertical,
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new Container
|
||||
{
|
||||
Name = "User List",
|
||||
RelativeSizeAxes = Axes.X,
|
||||
AutoSizeAxes = Axes.Y,
|
||||
Children = new Drawable[]
|
||||
{
|
||||
background = new Box
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both
|
||||
},
|
||||
new FillFlowContainer
|
||||
{
|
||||
RelativeSizeAxes = Axes.X,
|
||||
AutoSizeAxes = Axes.Y,
|
||||
Direction = FillDirection.Vertical,
|
||||
Margin = new MarginPadding { Bottom = 20 },
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new GridContainer
|
||||
{
|
||||
RelativeSizeAxes = Axes.X,
|
||||
AutoSizeAxes = Axes.Y,
|
||||
Padding = new MarginPadding
|
||||
{
|
||||
Horizontal = 40,
|
||||
Vertical = 20
|
||||
},
|
||||
ColumnDimensions = new[]
|
||||
{
|
||||
new Dimension(),
|
||||
new Dimension(GridSizeMode.Absolute, 50),
|
||||
new Dimension(GridSizeMode.AutoSize),
|
||||
},
|
||||
RowDimensions = new[]
|
||||
{
|
||||
new Dimension(GridSizeMode.AutoSize),
|
||||
},
|
||||
Content = new[]
|
||||
{
|
||||
new[]
|
||||
{
|
||||
searchTextBox = new BasicSearchTextBox
|
||||
{
|
||||
RelativeSizeAxes = Axes.X,
|
||||
Anchor = Anchor.CentreLeft,
|
||||
Origin = Anchor.CentreLeft,
|
||||
Height = 40,
|
||||
ReleaseFocusOnCommit = false,
|
||||
HoldFocus = true,
|
||||
PlaceholderText = HomeStrings.SearchPlaceholder,
|
||||
},
|
||||
Empty(),
|
||||
userListToolbar = new UserListToolbar(supportsBrickMode: true, supportsSort: false)
|
||||
{
|
||||
Anchor = Anchor.CentreRight,
|
||||
Origin = Anchor.CentreRight,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
new Container
|
||||
{
|
||||
RelativeSizeAxes = Axes.X,
|
||||
AutoSizeAxes = Axes.Y,
|
||||
Children = new Drawable[]
|
||||
{
|
||||
listContainer = new Container
|
||||
{
|
||||
RelativeSizeAxes = Axes.X,
|
||||
AutoSizeAxes = Axes.Y,
|
||||
Padding = new MarginPadding { Horizontal = WaveOverlayContainer.HORIZONTAL_PADDING }
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
background.Colour = colourProvider.Background4;
|
||||
}
|
||||
|
||||
protected override void LoadComplete()
|
||||
{
|
||||
base.LoadComplete();
|
||||
|
||||
searchTextBox.Current.BindValueChanged(_ => queueUpdateSearch());
|
||||
userListToolbar.DisplayStyle.BindValueChanged(_ => performSearch());
|
||||
}
|
||||
|
||||
private ScheduledDelegate? queryChangedDebounce;
|
||||
|
||||
private void queueUpdateSearch()
|
||||
{
|
||||
queryChangedDebounce?.Cancel();
|
||||
|
||||
if (!api.IsLoggedIn)
|
||||
{
|
||||
clearPreviousResults();
|
||||
return;
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(searchTextBox.Current.Value))
|
||||
{
|
||||
loading.Value = false;
|
||||
return;
|
||||
}
|
||||
|
||||
queryChangedDebounce = Scheduler.AddDelayed(performSearch, 500);
|
||||
}
|
||||
|
||||
private void performSearch()
|
||||
{
|
||||
loading.Value = true;
|
||||
var getUsersRequest = new SearchUsersRequest(searchTextBox.Current.Value);
|
||||
getUsersRequest.Success += showResults;
|
||||
api.Queue(getUsersRequest);
|
||||
}
|
||||
|
||||
private void showResults(SearchUsersResponse response)
|
||||
{
|
||||
clearPreviousResults();
|
||||
var friendsList = new UserPanelList(userListToolbar.DisplayStyle.Value, response.Users.ToArray());
|
||||
listContainer.Add(friendsList);
|
||||
|
||||
friendsList.FadeInFromZero(500, Easing.OutQuint);
|
||||
}
|
||||
|
||||
private void clearPreviousResults()
|
||||
{
|
||||
foreach (var child in listContainer.Children)
|
||||
child.FadeOut(200).Expire();
|
||||
listContainer.Clear();
|
||||
|
||||
loading.Value = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2,19 +2,36 @@
|
||||
// See the LICENCE file in the repository root for full licence text.
|
||||
|
||||
using System;
|
||||
using osu.Framework.Bindables;
|
||||
using osu.Game.Overlays.Dashboard;
|
||||
using osu.Game.Overlays.Dashboard.CurrentlyOnline;
|
||||
using osu.Game.Overlays.Dashboard.Friends;
|
||||
using osu.Game.Overlays.Dashboard.UserSearch;
|
||||
|
||||
namespace osu.Game.Overlays
|
||||
{
|
||||
public partial class DashboardOverlay : TabbableOnlineOverlay<DashboardOverlayHeader, DashboardOverlayTabs>
|
||||
{
|
||||
private readonly BindableBool loading = new BindableBool();
|
||||
|
||||
public DashboardOverlay()
|
||||
: base(OverlayColourScheme.Purple)
|
||||
{
|
||||
}
|
||||
|
||||
protected override void LoadComplete()
|
||||
{
|
||||
base.LoadComplete();
|
||||
|
||||
loading.BindValueChanged(loading =>
|
||||
{
|
||||
if (loading.NewValue)
|
||||
Loading.Show();
|
||||
else
|
||||
Loading.Hide();
|
||||
}, true);
|
||||
}
|
||||
|
||||
protected override DashboardOverlayHeader CreateHeader() => new DashboardOverlayHeader();
|
||||
|
||||
public override bool AcceptsFocus => false;
|
||||
@@ -24,16 +41,27 @@ namespace osu.Game.Overlays
|
||||
switch (tab)
|
||||
{
|
||||
case DashboardOverlayTabs.Friends:
|
||||
LoadDisplay(new FriendDisplay());
|
||||
LoadDisplay(new FriendDisplay
|
||||
{
|
||||
Loading = { BindTarget = loading },
|
||||
});
|
||||
break;
|
||||
|
||||
case DashboardOverlayTabs.CurrentlyPlaying:
|
||||
LoadDisplay(new CurrentlyOnlineDisplay
|
||||
{
|
||||
Loading = { BindTarget = loading },
|
||||
OverlayState = { BindTarget = State }
|
||||
});
|
||||
break;
|
||||
|
||||
case DashboardOverlayTabs.UserSearch:
|
||||
LoadDisplay(new UserSearchDisplay
|
||||
{
|
||||
Loading = { BindTarget = loading },
|
||||
});
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new NotImplementedException($"Display for {tab} tab is not implemented");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user