From 3183621d3d20e05d65d4f6b9ea383d7cc6df3512 Mon Sep 17 00:00:00 2001 From: sw1tchbl4d3 Date: Thu, 26 May 2022 22:57:24 +0200 Subject: [PATCH 01/13] Add search bar for the `CurrentlyPlayingDisplay` --- .../Dashboard/CurrentlyPlayingDisplay.cs | 119 ++++++++++++++---- 1 file changed, 98 insertions(+), 21 deletions(-) diff --git a/osu.Game/Overlays/Dashboard/CurrentlyPlayingDisplay.cs b/osu.Game/Overlays/Dashboard/CurrentlyPlayingDisplay.cs index a9312e9a3a..1c14eee9c7 100644 --- a/osu.Game/Overlays/Dashboard/CurrentlyPlayingDisplay.cs +++ b/osu.Game/Overlays/Dashboard/CurrentlyPlayingDisplay.cs @@ -1,6 +1,7 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. +using System.Collections.Generic; using System.Collections.Specialized; using System.Diagnostics; using System.Linq; @@ -11,6 +12,8 @@ using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Screens; using osu.Game.Database; +using osu.Game.Graphics; +using osu.Game.Graphics.UserInterface; using osu.Game.Online.API; using osu.Game.Online.API.Requests.Responses; using osu.Game.Online.Spectator; @@ -24,10 +27,17 @@ namespace osu.Game.Overlays.Dashboard { internal class CurrentlyPlayingDisplay : CompositeDrawable { + private const float search_bar_height = 40; + private const float search_bar_width = 250; + private readonly IBindableList playingUsers = new BindableList(); private FillFlowContainer userFlow; + private List currentUsers = new List(); + private FocusedTextBox searchBar; + private Container searchBarContainer; + [Resolved] private SpectatorClient spectatorClient { get; set; } @@ -37,13 +47,46 @@ namespace osu.Game.Overlays.Dashboard RelativeSizeAxes = Axes.X; AutoSizeAxes = Axes.Y; - InternalChild = userFlow = new FillFlowContainer + searchBarContainer = new Container + { + Anchor = Anchor.TopCentre, + Origin = Anchor.TopCentre, + Padding = new MarginPadding(10), + Child = searchBar = new FocusedTextBox + { + Anchor = Anchor.TopCentre, + Origin = Anchor.TopCentre, + Height = search_bar_height, + Width = search_bar_width, + + Colour = OsuColour.Gray(0.8f), + + PlaceholderText = "Search for User...", + HoldFocus = true, + ReleaseFocusOnCommit = true, + }, + }; + + userFlow = new FillFlowContainer { RelativeSizeAxes = Axes.X, AutoSizeAxes = Axes.Y, - Padding = new MarginPadding(10), + Padding = new MarginPadding { + Top = 10 + 10 + search_bar_height, + Bottom = 10, + Right = 10, + Left = 10, + }, Spacing = new Vector2(10), }; + + InternalChildren = new Drawable[] + { + searchBarContainer, + userFlow, + }; + + searchBar.Current.ValueChanged += onSearchBarValueChanged; } [Resolved] @@ -57,6 +100,57 @@ namespace osu.Game.Overlays.Dashboard playingUsers.BindCollectionChanged(onPlayingUsersChanged, true); } + private void addCard(int userId) + { + if (currentUsers.Contains(userId)) + return; + + users.GetUserAsync(userId).ContinueWith(task => + { + var user = task.GetResultSafely(); + + if (user == null) + return; + + if (!user.Username.ToLower().Contains(searchBar.Text.ToLower())) + return; + + Schedule(() => + { + // user may no longer be playing. + if (!playingUsers.Contains(user.Id)) + return; + + currentUsers.Add(user.Id); + + userFlow.Add(createUserPanel(user)); + }); + }); + } + + private void removeCard(PlayingUserPanel card) + { + if (card == null) + return; + + currentUsers.Remove(card.User.Id); + card.Expire(); + } + + private void onSearchBarValueChanged(ValueChangedEvent change) + { + foreach (PlayingUserPanel card in userFlow) + { + if (!card.User.Username.ToLower().Contains(change.NewValue.ToLower())) + removeCard(card); + } + + foreach (int userId in playingUsers) + { + addCard(userId); + } + } + private void onPlayingUsersChanged(object sender, NotifyCollectionChangedEventArgs e) => Schedule(() => { switch (e.Action) @@ -65,24 +159,7 @@ namespace osu.Game.Overlays.Dashboard Debug.Assert(e.NewItems != null); foreach (int userId in e.NewItems) - { - users.GetUserAsync(userId).ContinueWith(task => - { - var user = task.GetResultSafely(); - - if (user == null) - return; - - Schedule(() => - { - // user may no longer be playing. - if (!playingUsers.Contains(user.Id)) - return; - - userFlow.Add(createUserPanel(user)); - }); - }); - } + addCard(userId); break; @@ -90,7 +167,7 @@ namespace osu.Game.Overlays.Dashboard Debug.Assert(e.OldItems != null); foreach (int userId in e.OldItems) - userFlow.FirstOrDefault(card => card.User.Id == userId)?.Expire(); + removeCard(userFlow.FirstOrDefault(card => card.User.Id == userId)); break; } }); From de5b60ab66a6d33655e7b003c1ff21caa87867ad Mon Sep 17 00:00:00 2001 From: sw1tchbl4d3 Date: Fri, 27 May 2022 00:40:23 +0200 Subject: [PATCH 02/13] Move filtering from manual loops to `SearchContainer` --- .../Dashboard/CurrentlyPlayingDisplay.cs | 57 ++++++++----------- 1 file changed, 25 insertions(+), 32 deletions(-) diff --git a/osu.Game/Overlays/Dashboard/CurrentlyPlayingDisplay.cs b/osu.Game/Overlays/Dashboard/CurrentlyPlayingDisplay.cs index 1c14eee9c7..7dd5c73b79 100644 --- a/osu.Game/Overlays/Dashboard/CurrentlyPlayingDisplay.cs +++ b/osu.Game/Overlays/Dashboard/CurrentlyPlayingDisplay.cs @@ -10,6 +10,7 @@ using osu.Framework.Bindables; using osu.Framework.Extensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; +using osu.Framework.Localisation; using osu.Framework.Screens; using osu.Game.Database; using osu.Game.Graphics; @@ -32,9 +33,8 @@ namespace osu.Game.Overlays.Dashboard private readonly IBindableList playingUsers = new BindableList(); - private FillFlowContainer userFlow; + private SearchContainer userFlow; - private List currentUsers = new List(); private FocusedTextBox searchBar; private Container searchBarContainer; @@ -67,7 +67,7 @@ namespace osu.Game.Overlays.Dashboard }, }; - userFlow = new FillFlowContainer + userFlow = new SearchContainer { RelativeSizeAxes = Axes.X, AutoSizeAxes = Axes.Y, @@ -102,9 +102,6 @@ namespace osu.Game.Overlays.Dashboard private void addCard(int userId) { - if (currentUsers.Contains(userId)) - return; - users.GetUserAsync(userId).ContinueWith(task => { var user = task.GetResultSafely(); @@ -121,35 +118,12 @@ namespace osu.Game.Overlays.Dashboard if (!playingUsers.Contains(user.Id)) return; - currentUsers.Add(user.Id); - userFlow.Add(createUserPanel(user)); }); }); } - private void removeCard(PlayingUserPanel card) - { - if (card == null) - return; - - currentUsers.Remove(card.User.Id); - card.Expire(); - } - - private void onSearchBarValueChanged(ValueChangedEvent change) - { - foreach (PlayingUserPanel card in userFlow) - { - if (!card.User.Username.ToLower().Contains(change.NewValue.ToLower())) - removeCard(card); - } - - foreach (int userId in playingUsers) - { - addCard(userId); - } - } + private void onSearchBarValueChanged(ValueChangedEvent change) => userFlow.SearchTerm = searchBar.Text; private void onPlayingUsersChanged(object sender, NotifyCollectionChangedEventArgs e) => Schedule(() => { @@ -167,7 +141,7 @@ namespace osu.Game.Overlays.Dashboard Debug.Assert(e.OldItems != null); foreach (int userId in e.OldItems) - removeCard(userFlow.FirstOrDefault(card => card.User.Id == userId)); + userFlow.FirstOrDefault(card => card.User.Id == userId)?.Expire(); break; } }); @@ -179,16 +153,35 @@ namespace osu.Game.Overlays.Dashboard panel.Origin = Anchor.TopCentre; }); - private class PlayingUserPanel : CompositeDrawable + private class PlayingUserPanel : CompositeDrawable, IFilterable { public readonly APIUser User; + public IEnumerable FilterTerms => filterTerm; [Resolved(canBeNull: true)] private IPerformFromScreenRunner performer { get; set; } + private IEnumerable filterTerm; + + public bool MatchingFilter + { + set + { + if (value) + Show(); + else + Hide(); + } + } + + public bool FilteringActive + { + set { } + } public PlayingUserPanel(APIUser user) { User = user; + filterTerm = new LocalisableString[] { User.Username }; AutoSizeAxes = Axes.Both; } From a8e453e6601f495613b11ebbe42c635113cf4d8d Mon Sep 17 00:00:00 2001 From: sw1tchbl4d3 Date: Fri, 27 May 2022 00:43:29 +0200 Subject: [PATCH 03/13] Remove now unnecessary username filter check --- osu.Game/Overlays/Dashboard/CurrentlyPlayingDisplay.cs | 3 --- 1 file changed, 3 deletions(-) diff --git a/osu.Game/Overlays/Dashboard/CurrentlyPlayingDisplay.cs b/osu.Game/Overlays/Dashboard/CurrentlyPlayingDisplay.cs index 7dd5c73b79..f57c808144 100644 --- a/osu.Game/Overlays/Dashboard/CurrentlyPlayingDisplay.cs +++ b/osu.Game/Overlays/Dashboard/CurrentlyPlayingDisplay.cs @@ -109,9 +109,6 @@ namespace osu.Game.Overlays.Dashboard if (user == null) return; - if (!user.Username.ToLower().Contains(searchBar.Text.ToLower())) - return; - Schedule(() => { // user may no longer be playing. From 4967d036063f954cdd37ac33134288ebfb26a881 Mon Sep 17 00:00:00 2001 From: sw1tchbl4d3 Date: Fri, 27 May 2022 09:58:40 +0200 Subject: [PATCH 04/13] Update currently playing search bar to resemble existing UI --- .../Dashboard/CurrentlyPlayingDisplay.cs | 37 +++++++++++-------- 1 file changed, 22 insertions(+), 15 deletions(-) diff --git a/osu.Game/Overlays/Dashboard/CurrentlyPlayingDisplay.cs b/osu.Game/Overlays/Dashboard/CurrentlyPlayingDisplay.cs index f57c808144..b6deae27e5 100644 --- a/osu.Game/Overlays/Dashboard/CurrentlyPlayingDisplay.cs +++ b/osu.Game/Overlays/Dashboard/CurrentlyPlayingDisplay.cs @@ -10,6 +10,8 @@ using osu.Framework.Bindables; using osu.Framework.Extensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Effects; +using osu.Framework.Graphics.Shapes; using osu.Framework.Localisation; using osu.Framework.Screens; using osu.Game.Database; @@ -35,35 +37,42 @@ namespace osu.Game.Overlays.Dashboard private SearchContainer userFlow; - private FocusedTextBox searchBar; - private Container searchBarContainer; + private Box searchBarBackground; + private BasicSearchTextBox searchBar; + private Container searchBarContainer; [Resolved] private SpectatorClient spectatorClient { get; set; } [BackgroundDependencyLoader] - private void load() + private void load(OverlayColourProvider colourProvider) { RelativeSizeAxes = Axes.X; AutoSizeAxes = Axes.Y; - searchBarContainer = new Container + searchBarBackground = new Box + { + RelativeSizeAxes = Axes.X, + Height = 10*2 + search_bar_height, + Colour = colourProvider.Background4, + }; + + searchBarContainer = new Container { Anchor = Anchor.TopCentre, Origin = Anchor.TopCentre, + RelativeSizeAxes = Axes.X, Padding = new MarginPadding(10), - Child = searchBar = new FocusedTextBox + + Child = searchBar = new BasicSearchTextBox { Anchor = Anchor.TopCentre, Origin = Anchor.TopCentre, Height = search_bar_height, - Width = search_bar_width, - Colour = OsuColour.Gray(0.8f), + RelativeSizeAxes = Axes.X, - PlaceholderText = "Search for User...", - HoldFocus = true, - ReleaseFocusOnCommit = true, + PlaceholderText = "type to search", }, }; @@ -72,7 +81,7 @@ namespace osu.Game.Overlays.Dashboard RelativeSizeAxes = Axes.X, AutoSizeAxes = Axes.Y, Padding = new MarginPadding { - Top = 10 + 10 + search_bar_height, + Top = 10*3 + search_bar_height, Bottom = 10, Right = 10, Left = 10, @@ -82,6 +91,7 @@ namespace osu.Game.Overlays.Dashboard InternalChildren = new Drawable[] { + searchBarBackground, searchBarContainer, userFlow, }; @@ -170,10 +180,7 @@ namespace osu.Game.Overlays.Dashboard } } - public bool FilteringActive - { - set { } - } + public bool FilteringActive { set; get; } public PlayingUserPanel(APIUser user) { From 7c459faaf0bd9978f44ec6b2436b08818561866b Mon Sep 17 00:00:00 2001 From: sw1tchbl4d3 Date: Fri, 27 May 2022 10:05:59 +0200 Subject: [PATCH 05/13] Remove unneeded search_bar_width and more --- osu.Game/Overlays/Dashboard/CurrentlyPlayingDisplay.cs | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/osu.Game/Overlays/Dashboard/CurrentlyPlayingDisplay.cs b/osu.Game/Overlays/Dashboard/CurrentlyPlayingDisplay.cs index b6deae27e5..c7b08a1ffc 100644 --- a/osu.Game/Overlays/Dashboard/CurrentlyPlayingDisplay.cs +++ b/osu.Game/Overlays/Dashboard/CurrentlyPlayingDisplay.cs @@ -10,7 +10,6 @@ using osu.Framework.Bindables; using osu.Framework.Extensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; -using osu.Framework.Graphics.Effects; using osu.Framework.Graphics.Shapes; using osu.Framework.Localisation; using osu.Framework.Screens; @@ -30,8 +29,7 @@ namespace osu.Game.Overlays.Dashboard { internal class CurrentlyPlayingDisplay : CompositeDrawable { - private const float search_bar_height = 40; - private const float search_bar_width = 250; + private const float SEARCHBAR_HEIGHT = 40; private readonly IBindableList playingUsers = new BindableList(); @@ -53,7 +51,7 @@ namespace osu.Game.Overlays.Dashboard searchBarBackground = new Box { RelativeSizeAxes = Axes.X, - Height = 10*2 + search_bar_height, + Height = 10*2 + SEARCHBAR_HEIGHT, Colour = colourProvider.Background4, }; @@ -68,7 +66,7 @@ namespace osu.Game.Overlays.Dashboard { Anchor = Anchor.TopCentre, Origin = Anchor.TopCentre, - Height = search_bar_height, + Height = SEARCHBAR_HEIGHT, RelativeSizeAxes = Axes.X, @@ -81,7 +79,7 @@ namespace osu.Game.Overlays.Dashboard RelativeSizeAxes = Axes.X, AutoSizeAxes = Axes.Y, Padding = new MarginPadding { - Top = 10*3 + search_bar_height, + Top = 10*3 + SEARCHBAR_HEIGHT, Bottom = 10, Right = 10, Left = 10, From 6a0cf26722cfa9ab08de4f8f00156657c798afbd Mon Sep 17 00:00:00 2001 From: sw1tchbl4d3 Date: Fri, 27 May 2022 12:36:43 +0200 Subject: [PATCH 06/13] Make text localisable and add padding constant --- osu.Game/Overlays/Dashboard/CurrentlyPlayingDisplay.cs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/osu.Game/Overlays/Dashboard/CurrentlyPlayingDisplay.cs b/osu.Game/Overlays/Dashboard/CurrentlyPlayingDisplay.cs index c7b08a1ffc..d9418a303e 100644 --- a/osu.Game/Overlays/Dashboard/CurrentlyPlayingDisplay.cs +++ b/osu.Game/Overlays/Dashboard/CurrentlyPlayingDisplay.cs @@ -30,6 +30,7 @@ namespace osu.Game.Overlays.Dashboard internal class CurrentlyPlayingDisplay : CompositeDrawable { private const float SEARCHBAR_HEIGHT = 40; + private const float CONTAINER_PADDING = 10; private readonly IBindableList playingUsers = new BindableList(); @@ -51,7 +52,7 @@ namespace osu.Game.Overlays.Dashboard searchBarBackground = new Box { RelativeSizeAxes = Axes.X, - Height = 10*2 + SEARCHBAR_HEIGHT, + Height = CONTAINER_PADDING * 2 + SEARCHBAR_HEIGHT, Colour = colourProvider.Background4, }; @@ -70,7 +71,7 @@ namespace osu.Game.Overlays.Dashboard RelativeSizeAxes = Axes.X, - PlaceholderText = "type to search", + PlaceholderText = Resources.Localisation.Web.HomeStrings.SearchPlaceholder, }, }; @@ -79,7 +80,7 @@ namespace osu.Game.Overlays.Dashboard RelativeSizeAxes = Axes.X, AutoSizeAxes = Axes.Y, Padding = new MarginPadding { - Top = 10*3 + SEARCHBAR_HEIGHT, + Top = CONTAINER_PADDING * 3 + SEARCHBAR_HEIGHT, Bottom = 10, Right = 10, Left = 10, From e1fd37fd4481a7bbee4e2bd20e4a65da943382f3 Mon Sep 17 00:00:00 2001 From: sw1tchbl4d3 Date: Fri, 27 May 2022 12:40:31 +0200 Subject: [PATCH 07/13] Use new padding constant where appropriate --- osu.Game/Overlays/Dashboard/CurrentlyPlayingDisplay.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/osu.Game/Overlays/Dashboard/CurrentlyPlayingDisplay.cs b/osu.Game/Overlays/Dashboard/CurrentlyPlayingDisplay.cs index d9418a303e..a9e9932b5b 100644 --- a/osu.Game/Overlays/Dashboard/CurrentlyPlayingDisplay.cs +++ b/osu.Game/Overlays/Dashboard/CurrentlyPlayingDisplay.cs @@ -61,7 +61,7 @@ namespace osu.Game.Overlays.Dashboard Anchor = Anchor.TopCentre, Origin = Anchor.TopCentre, RelativeSizeAxes = Axes.X, - Padding = new MarginPadding(10), + Padding = new MarginPadding(CONTAINER_PADDING), Child = searchBar = new BasicSearchTextBox { @@ -81,9 +81,9 @@ namespace osu.Game.Overlays.Dashboard AutoSizeAxes = Axes.Y, Padding = new MarginPadding { Top = CONTAINER_PADDING * 3 + SEARCHBAR_HEIGHT, - Bottom = 10, - Right = 10, - Left = 10, + Bottom = CONTAINER_PADDING, + Right = CONTAINER_PADDING, + Left = CONTAINER_PADDING, }, Spacing = new Vector2(10), }; From e2951d70d1eac5ee0f2291c2192ac9d8f8598269 Mon Sep 17 00:00:00 2001 From: sw1tchbl4d3 Date: Fri, 27 May 2022 16:38:54 +0200 Subject: [PATCH 08/13] Address code style issues --- .../TestSceneCurrentlyPlayingDisplay.cs | 4 +- .../Dashboard/CurrentlyPlayingDisplay.cs | 143 ++++++++---------- 2 files changed, 68 insertions(+), 79 deletions(-) diff --git a/osu.Game.Tests/Visual/Online/TestSceneCurrentlyPlayingDisplay.cs b/osu.Game.Tests/Visual/Online/TestSceneCurrentlyPlayingDisplay.cs index 35a4f8cf2d..edee26c081 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneCurrentlyPlayingDisplay.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneCurrentlyPlayingDisplay.cs @@ -11,6 +11,7 @@ using osu.Framework.Testing; using osu.Game.Database; using osu.Game.Online.API.Requests.Responses; using osu.Game.Online.Spectator; +using osu.Game.Overlays; using osu.Game.Overlays.Dashboard; using osu.Game.Tests.Visual.Spectator; using osu.Game.Users; @@ -42,7 +43,8 @@ namespace osu.Game.Tests.Visual.Online CachedDependencies = new (Type, object)[] { (typeof(SpectatorClient), spectatorClient), - (typeof(UserLookupCache), lookupCache) + (typeof(UserLookupCache), lookupCache), + (typeof(OverlayColourProvider), new OverlayColourProvider(OverlayColourScheme.Purple)), }, Child = currentlyPlaying = new CurrentlyPlayingDisplay { diff --git a/osu.Game/Overlays/Dashboard/CurrentlyPlayingDisplay.cs b/osu.Game/Overlays/Dashboard/CurrentlyPlayingDisplay.cs index a9e9932b5b..3020b37351 100644 --- a/osu.Game/Overlays/Dashboard/CurrentlyPlayingDisplay.cs +++ b/osu.Game/Overlays/Dashboard/CurrentlyPlayingDisplay.cs @@ -14,7 +14,6 @@ using osu.Framework.Graphics.Shapes; using osu.Framework.Localisation; using osu.Framework.Screens; using osu.Game.Database; -using osu.Game.Graphics; using osu.Game.Graphics.UserInterface; using osu.Game.Online.API; using osu.Game.Online.API.Requests.Responses; @@ -29,16 +28,13 @@ namespace osu.Game.Overlays.Dashboard { internal class CurrentlyPlayingDisplay : CompositeDrawable { - private const float SEARCHBAR_HEIGHT = 40; - private const float CONTAINER_PADDING = 10; + private const float searchbox_height = 40f; + private const float container_padding = 10f; private readonly IBindableList playingUsers = new BindableList(); private SearchContainer userFlow; - - private Box searchBarBackground; - private BasicSearchTextBox searchBar; - private Container searchBarContainer; + private BasicSearchTextBox userFlowSearchTextBox; [Resolved] private SpectatorClient spectatorClient { get; set; } @@ -49,53 +45,48 @@ namespace osu.Game.Overlays.Dashboard RelativeSizeAxes = Axes.X; AutoSizeAxes = Axes.Y; - searchBarBackground = new Box - { - RelativeSizeAxes = Axes.X, - Height = CONTAINER_PADDING * 2 + SEARCHBAR_HEIGHT, - Colour = colourProvider.Background4, - }; - - searchBarContainer = new Container - { - Anchor = Anchor.TopCentre, - Origin = Anchor.TopCentre, - RelativeSizeAxes = Axes.X, - Padding = new MarginPadding(CONTAINER_PADDING), - - Child = searchBar = new BasicSearchTextBox - { - Anchor = Anchor.TopCentre, - Origin = Anchor.TopCentre, - Height = SEARCHBAR_HEIGHT, - - RelativeSizeAxes = Axes.X, - - PlaceholderText = Resources.Localisation.Web.HomeStrings.SearchPlaceholder, - }, - }; - - userFlow = new SearchContainer - { - RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.Y, - Padding = new MarginPadding { - Top = CONTAINER_PADDING * 3 + SEARCHBAR_HEIGHT, - Bottom = CONTAINER_PADDING, - Right = CONTAINER_PADDING, - Left = CONTAINER_PADDING, - }, - Spacing = new Vector2(10), - }; - InternalChildren = new Drawable[] { - searchBarBackground, - searchBarContainer, - userFlow, + new Box + { + RelativeSizeAxes = Axes.X, + Height = container_padding * 2 + searchbox_height, + Colour = colourProvider.Background4, + }, + + new Container + { + RelativeSizeAxes = Axes.X, + Anchor = Anchor.TopCentre, + Origin = Anchor.TopCentre, + Padding = new MarginPadding(container_padding), + + Child = userFlowSearchTextBox = new BasicSearchTextBox + { + RelativeSizeAxes = Axes.X, + Anchor = Anchor.TopCentre, + Origin = Anchor.TopCentre, + Height = searchbox_height, + PlaceholderText = Resources.Localisation.Web.HomeStrings.SearchPlaceholder, + }, + }, + + userFlow = new SearchContainer + { + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Padding = new MarginPadding + { + Top = container_padding * 3 + searchbox_height, + Bottom = container_padding, + Right = container_padding, + Left = container_padding, + }, + Spacing = new Vector2(10), + }, }; - searchBar.Current.ValueChanged += onSearchBarValueChanged; + userFlowSearchTextBox.Current.ValueChanged += onSearchBarValueChanged; } [Resolved] @@ -109,27 +100,7 @@ namespace osu.Game.Overlays.Dashboard playingUsers.BindCollectionChanged(onPlayingUsersChanged, true); } - private void addCard(int userId) - { - users.GetUserAsync(userId).ContinueWith(task => - { - var user = task.GetResultSafely(); - - if (user == null) - return; - - Schedule(() => - { - // user may no longer be playing. - if (!playingUsers.Contains(user.Id)) - return; - - userFlow.Add(createUserPanel(user)); - }); - }); - } - - private void onSearchBarValueChanged(ValueChangedEvent change) => userFlow.SearchTerm = searchBar.Text; + private void onSearchBarValueChanged(ValueChangedEvent change) => userFlow.SearchTerm = userFlowSearchTextBox.Text; private void onPlayingUsersChanged(object sender, NotifyCollectionChangedEventArgs e) => Schedule(() => { @@ -139,7 +110,24 @@ namespace osu.Game.Overlays.Dashboard Debug.Assert(e.NewItems != null); foreach (int userId in e.NewItems) - addCard(userId); + { + users.GetUserAsync(userId).ContinueWith(task => + { + var user = task.GetResultSafely(); + + if (user == null) + return; + + Schedule(() => + { + // user may no longer be playing. + if (!playingUsers.Contains(user.Id)) + return; + + userFlow.Add(createUserPanel(user)); + }); + }); + } break; @@ -159,14 +147,15 @@ namespace osu.Game.Overlays.Dashboard panel.Origin = Anchor.TopCentre; }); - private class PlayingUserPanel : CompositeDrawable, IFilterable + public class PlayingUserPanel : CompositeDrawable, IFilterable { public readonly APIUser User; - public IEnumerable FilterTerms => filterTerm; + public IEnumerable FilterTerms { get; set; } [Resolved(canBeNull: true)] private IPerformFromScreenRunner performer { get; set; } - private IEnumerable filterTerm; + + public bool FilteringActive { set; get; } public bool MatchingFilter { @@ -179,12 +168,10 @@ namespace osu.Game.Overlays.Dashboard } } - public bool FilteringActive { set; get; } - public PlayingUserPanel(APIUser user) { User = user; - filterTerm = new LocalisableString[] { User.Username }; + FilterTerms = new LocalisableString[] { User.Username }; AutoSizeAxes = Axes.Both; } From 254039b8fe9fa21ae584663b792aa7b81d650a29 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Sat, 28 May 2022 04:01:51 +0900 Subject: [PATCH 09/13] Address remaining code quality concerns --- .../Dashboard/CurrentlyPlayingDisplay.cs | 40 +++++++++---------- 1 file changed, 18 insertions(+), 22 deletions(-) diff --git a/osu.Game/Overlays/Dashboard/CurrentlyPlayingDisplay.cs b/osu.Game/Overlays/Dashboard/CurrentlyPlayingDisplay.cs index 3020b37351..0a1cf5524f 100644 --- a/osu.Game/Overlays/Dashboard/CurrentlyPlayingDisplay.cs +++ b/osu.Game/Overlays/Dashboard/CurrentlyPlayingDisplay.cs @@ -18,6 +18,7 @@ using osu.Game.Graphics.UserInterface; using osu.Game.Online.API; using osu.Game.Online.API.Requests.Responses; using osu.Game.Online.Spectator; +using osu.Game.Resources.Localisation.Web; using osu.Game.Screens; using osu.Game.Screens.OnlinePlay.Match.Components; using osu.Game.Screens.Play; @@ -28,13 +29,13 @@ namespace osu.Game.Overlays.Dashboard { internal class CurrentlyPlayingDisplay : CompositeDrawable { - private const float searchbox_height = 40f; - private const float container_padding = 10f; + private const float search_textbox_height = 40; + private const float padding = 10; private readonly IBindableList playingUsers = new BindableList(); private SearchContainer userFlow; - private BasicSearchTextBox userFlowSearchTextBox; + private BasicSearchTextBox searchTextBox; [Resolved] private SpectatorClient spectatorClient { get; set; } @@ -50,43 +51,38 @@ namespace osu.Game.Overlays.Dashboard new Box { RelativeSizeAxes = Axes.X, - Height = container_padding * 2 + searchbox_height, + Height = padding * 2 + search_textbox_height, Colour = colourProvider.Background4, }, - new Container { RelativeSizeAxes = Axes.X, - Anchor = Anchor.TopCentre, - Origin = Anchor.TopCentre, - Padding = new MarginPadding(container_padding), - - Child = userFlowSearchTextBox = new BasicSearchTextBox + Padding = new MarginPadding(padding), + Child = searchTextBox = new BasicSearchTextBox { RelativeSizeAxes = Axes.X, Anchor = Anchor.TopCentre, Origin = Anchor.TopCentre, - Height = searchbox_height, - PlaceholderText = Resources.Localisation.Web.HomeStrings.SearchPlaceholder, + Height = search_textbox_height, + PlaceholderText = HomeStrings.SearchPlaceholder, }, }, - userFlow = new SearchContainer { RelativeSizeAxes = Axes.X, AutoSizeAxes = Axes.Y, + Spacing = new Vector2(10), Padding = new MarginPadding { - Top = container_padding * 3 + searchbox_height, - Bottom = container_padding, - Right = container_padding, - Left = container_padding, + Top = padding * 3 + search_textbox_height, + Bottom = padding, + Right = padding, + Left = padding, }, - Spacing = new Vector2(10), }, }; - userFlowSearchTextBox.Current.ValueChanged += onSearchBarValueChanged; + searchTextBox.Current.ValueChanged += text => userFlow.SearchTerm = text.NewValue; } [Resolved] @@ -100,8 +96,6 @@ namespace osu.Game.Overlays.Dashboard playingUsers.BindCollectionChanged(onPlayingUsersChanged, true); } - private void onSearchBarValueChanged(ValueChangedEvent change) => userFlow.SearchTerm = userFlowSearchTextBox.Text; - private void onPlayingUsersChanged(object sender, NotifyCollectionChangedEventArgs e) => Schedule(() => { switch (e.Action) @@ -150,7 +144,8 @@ namespace osu.Game.Overlays.Dashboard public class PlayingUserPanel : CompositeDrawable, IFilterable { public readonly APIUser User; - public IEnumerable FilterTerms { get; set; } + + public IEnumerable FilterTerms { get; } [Resolved(canBeNull: true)] private IPerformFromScreenRunner performer { get; set; } @@ -171,6 +166,7 @@ namespace osu.Game.Overlays.Dashboard public PlayingUserPanel(APIUser user) { User = user; + FilterTerms = new LocalisableString[] { User.Username }; AutoSizeAxes = Axes.Both; From cd84200ad9486ad9b4f1e62941244750a1dc593b Mon Sep 17 00:00:00 2001 From: sw1tchbl4d3 Date: Fri, 27 May 2022 21:23:37 +0200 Subject: [PATCH 10/13] Add HoldFocus and ReleaseFocusOnCommit attributes to searchbar --- osu.Game/Overlays/Dashboard/CurrentlyPlayingDisplay.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/osu.Game/Overlays/Dashboard/CurrentlyPlayingDisplay.cs b/osu.Game/Overlays/Dashboard/CurrentlyPlayingDisplay.cs index 0a1cf5524f..c8c53ec507 100644 --- a/osu.Game/Overlays/Dashboard/CurrentlyPlayingDisplay.cs +++ b/osu.Game/Overlays/Dashboard/CurrentlyPlayingDisplay.cs @@ -64,6 +64,8 @@ namespace osu.Game.Overlays.Dashboard Anchor = Anchor.TopCentre, Origin = Anchor.TopCentre, Height = search_textbox_height, + ReleaseFocusOnCommit = false, + HoldFocus = true, PlaceholderText = HomeStrings.SearchPlaceholder, }, }, From ede3ab9dc00692559786b6e5691e07d8af3c12ee Mon Sep 17 00:00:00 2001 From: sw1tchbl4d3 Date: Sat, 28 May 2022 12:04:25 +0200 Subject: [PATCH 11/13] Add OnFocus handler to CurrentlyPlayingDisplay --- osu.Game/Overlays/Dashboard/CurrentlyPlayingDisplay.cs | 8 ++++++++ osu.Game/Overlays/DashboardOverlay.cs | 2 ++ 2 files changed, 10 insertions(+) diff --git a/osu.Game/Overlays/Dashboard/CurrentlyPlayingDisplay.cs b/osu.Game/Overlays/Dashboard/CurrentlyPlayingDisplay.cs index c8c53ec507..23f67a06cb 100644 --- a/osu.Game/Overlays/Dashboard/CurrentlyPlayingDisplay.cs +++ b/osu.Game/Overlays/Dashboard/CurrentlyPlayingDisplay.cs @@ -11,6 +11,7 @@ using osu.Framework.Extensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; +using osu.Framework.Input.Events; using osu.Framework.Localisation; using osu.Framework.Screens; using osu.Game.Database; @@ -98,6 +99,13 @@ namespace osu.Game.Overlays.Dashboard playingUsers.BindCollectionChanged(onPlayingUsersChanged, true); } + protected override void OnFocus(FocusEvent e) + { + base.OnFocus(e); + + searchTextBox.TakeFocus(); + } + private void onPlayingUsersChanged(object sender, NotifyCollectionChangedEventArgs e) => Schedule(() => { switch (e.Action) diff --git a/osu.Game/Overlays/DashboardOverlay.cs b/osu.Game/Overlays/DashboardOverlay.cs index 83ad8faf1c..79d972bdcc 100644 --- a/osu.Game/Overlays/DashboardOverlay.cs +++ b/osu.Game/Overlays/DashboardOverlay.cs @@ -16,6 +16,8 @@ namespace osu.Game.Overlays protected override DashboardOverlayHeader CreateHeader() => new DashboardOverlayHeader(); + public override bool AcceptsFocus => false; + protected override void CreateDisplayToLoad(DashboardOverlayTabs tab) { switch (tab) From 82a1ba1d46650bf11164e26537ddfa64ae995c84 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 30 May 2022 17:42:27 +0900 Subject: [PATCH 12/13] Use pooled memory for memory copies performed by `ZipArchiveReader` --- osu.Game/IO/Archives/ZipArchiveReader.cs | 56 +++++++++++++++++++++--- osu.Game/osu.Game.csproj | 1 + 2 files changed, 51 insertions(+), 6 deletions(-) diff --git a/osu.Game/IO/Archives/ZipArchiveReader.cs b/osu.Game/IO/Archives/ZipArchiveReader.cs index 80dfa104f3..ae2b85da51 100644 --- a/osu.Game/IO/Archives/ZipArchiveReader.cs +++ b/osu.Game/IO/Archives/ZipArchiveReader.cs @@ -1,11 +1,15 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. +using System.Buffers; using System.Collections.Generic; using System.IO; using System.Linq; +using Microsoft.Toolkit.HighPerformance; +using osu.Framework.Extensions; using osu.Framework.IO.Stores; using SharpCompress.Archives.Zip; +using SixLabors.ImageSharp.Memory; namespace osu.Game.IO.Archives { @@ -27,15 +31,12 @@ namespace osu.Game.IO.Archives if (entry == null) throw new FileNotFoundException(); - // allow seeking - MemoryStream copy = new MemoryStream(); + var owner = MemoryAllocator.Default.Allocate((int)entry.Size); using (Stream s = entry.OpenEntryStream()) - s.CopyTo(copy); + s.ReadToFill(owner.Memory.Span); - copy.Position = 0; - - return copy; + return new MemoryOwnerMemoryStream(owner); } public override void Dispose() @@ -45,5 +46,48 @@ namespace osu.Game.IO.Archives } public override IEnumerable Filenames => archive.Entries.Select(e => e.Key).ExcludeSystemFileNames(); + + private class MemoryOwnerMemoryStream : Stream + { + private readonly IMemoryOwner owner; + private readonly Stream stream; + + public MemoryOwnerMemoryStream(IMemoryOwner owner) + { + this.owner = owner; + + stream = owner.Memory.AsStream(); + } + + protected override void Dispose(bool disposing) + { + owner?.Dispose(); + base.Dispose(disposing); + } + + public override void Flush() => stream.Flush(); + + public override int Read(byte[] buffer, int offset, int count) => stream.Read(buffer, offset, count); + + public override long Seek(long offset, SeekOrigin origin) => stream.Seek(offset, origin); + + public override void SetLength(long value) => stream.SetLength(value); + + public override void Write(byte[] buffer, int offset, int count) => stream.Write(buffer, offset, count); + + public override bool CanRead => stream.CanRead; + + public override bool CanSeek => stream.CanSeek; + + public override bool CanWrite => stream.CanWrite; + + public override long Length => stream.Length; + + public override long Position + { + get => stream.Position; + set => stream.Position = value; + } + } } } diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index 79cfd7c917..6ce21ccad6 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -29,6 +29,7 @@ + all From d6b18d87b8f7c14bb078dca1863a4283ee16cb7f Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 30 May 2022 19:58:47 +0900 Subject: [PATCH 13/13] Update framework --- osu.Android.props | 2 +- osu.Game/osu.Game.csproj | 2 +- osu.iOS.props | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/osu.Android.props b/osu.Android.props index c28085557e..116c7dbfcd 100644 --- a/osu.Android.props +++ b/osu.Android.props @@ -52,7 +52,7 @@ - + diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index 6ce21ccad6..eb47d0468f 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -36,7 +36,7 @@ runtime; build; native; contentfiles; analyzers; buildtransitive - + diff --git a/osu.iOS.props b/osu.iOS.props index b1ba64beba..ccecad6f82 100644 --- a/osu.iOS.props +++ b/osu.iOS.props @@ -61,7 +61,7 @@ - + @@ -84,7 +84,7 @@ - +