mirror of
https://github.com/ppy/osu.git
synced 2024-11-06 10:47:28 +08:00
Merge pull request #12869 from EVAST9919/sidebar
Add sidebar to news overlay
This commit is contained in:
commit
1c560a9490
@ -8,10 +8,12 @@ namespace osu.Game.Online.API.Requests
|
||||
{
|
||||
public class GetNewsRequest : APIRequest<GetNewsResponse>
|
||||
{
|
||||
private readonly int? year;
|
||||
private readonly Cursor cursor;
|
||||
|
||||
public GetNewsRequest(Cursor cursor = null)
|
||||
public GetNewsRequest(int? year = null, Cursor cursor = null)
|
||||
{
|
||||
this.year = year;
|
||||
this.cursor = cursor;
|
||||
}
|
||||
|
||||
@ -19,6 +21,10 @@ namespace osu.Game.Online.API.Requests
|
||||
{
|
||||
var req = base.CreateWebRequest();
|
||||
req.AddCursor(cursor);
|
||||
|
||||
if (year.HasValue)
|
||||
req.AddParameter("year", year.Value.ToString());
|
||||
|
||||
return req;
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
// 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.Linq;
|
||||
using System.Threading;
|
||||
using osu.Framework.Allocation;
|
||||
@ -9,12 +10,18 @@ using osu.Framework.Graphics.Containers;
|
||||
using osu.Game.Graphics.UserInterface;
|
||||
using osu.Game.Online.API;
|
||||
using osu.Game.Online.API.Requests;
|
||||
using osu.Game.Online.API.Requests.Responses;
|
||||
using osuTK;
|
||||
|
||||
namespace osu.Game.Overlays.News.Displays
|
||||
{
|
||||
public class FrontPageDisplay : CompositeDrawable
|
||||
/// <summary>
|
||||
/// Lists articles in a vertical flow for a specified year.
|
||||
/// </summary>
|
||||
public class ArticleListing : CompositeDrawable
|
||||
{
|
||||
public Action<APINewsSidebar> SidebarMetadataUpdated;
|
||||
|
||||
[Resolved]
|
||||
private IAPIProvider api { get; set; }
|
||||
|
||||
@ -24,6 +31,17 @@ namespace osu.Game.Overlays.News.Displays
|
||||
private GetNewsRequest request;
|
||||
private Cursor lastCursor;
|
||||
|
||||
private readonly int? year;
|
||||
|
||||
/// <summary>
|
||||
/// Instantiate a listing for the specified year.
|
||||
/// </summary>
|
||||
/// <param name="year">The year to load articles from. If null, will show the most recent articles.</param>
|
||||
public ArticleListing(int? year = null)
|
||||
{
|
||||
this.year = year;
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load()
|
||||
{
|
||||
@ -74,7 +92,7 @@ namespace osu.Game.Overlays.News.Displays
|
||||
{
|
||||
request?.Cancel();
|
||||
|
||||
request = new GetNewsRequest(lastCursor);
|
||||
request = new GetNewsRequest(year, lastCursor);
|
||||
request.Success += response => Schedule(() => onSuccess(response));
|
||||
api.PerformAsync(request);
|
||||
}
|
||||
@ -85,22 +103,19 @@ namespace osu.Game.Overlays.News.Displays
|
||||
{
|
||||
cancellationToken?.Cancel();
|
||||
|
||||
// only needs to be updated on the initial load, as the content won't change during pagination.
|
||||
if (lastCursor == null)
|
||||
SidebarMetadataUpdated?.Invoke(response.SidebarMetadata);
|
||||
|
||||
// store cursor for next pagination request.
|
||||
lastCursor = response.Cursor;
|
||||
|
||||
var flow = new FillFlowContainer<NewsCard>
|
||||
LoadComponentsAsync(response.NewsPosts.Select(p => new NewsCard(p)).ToList(), loaded =>
|
||||
{
|
||||
RelativeSizeAxes = Axes.X,
|
||||
AutoSizeAxes = Axes.Y,
|
||||
Direction = FillDirection.Vertical,
|
||||
Spacing = new Vector2(0, 10),
|
||||
Children = response.NewsPosts.Select(p => new NewsCard(p)).ToList()
|
||||
};
|
||||
content.AddRange(loaded);
|
||||
|
||||
LoadComponentAsync(flow, loaded =>
|
||||
{
|
||||
content.Add(loaded);
|
||||
showMore.IsLoading = false;
|
||||
showMore.Alpha = lastCursor == null ? 0 : 1;
|
||||
showMore.Alpha = response.Cursor != null ? 1 : 0;
|
||||
}, (cancellationToken = new CancellationTokenSource()).Token);
|
||||
}
|
||||
|
@ -19,13 +19,18 @@ namespace osu.Game.Overlays.News
|
||||
{
|
||||
TabControl.AddItem(front_page_string);
|
||||
|
||||
article.BindValueChanged(onArticleChanged, true);
|
||||
}
|
||||
|
||||
protected override void LoadComplete()
|
||||
{
|
||||
base.LoadComplete();
|
||||
|
||||
Current.BindValueChanged(e =>
|
||||
{
|
||||
if (e.NewValue == front_page_string)
|
||||
ShowFrontPage?.Invoke();
|
||||
});
|
||||
|
||||
article.BindValueChanged(onArticleChanged, true);
|
||||
}
|
||||
|
||||
public void SetFrontPage() => article.Value = null;
|
||||
|
@ -9,6 +9,7 @@ using osu.Game.Online.API.Requests.Responses;
|
||||
using osu.Framework.Graphics.Shapes;
|
||||
using osuTK;
|
||||
using System.Linq;
|
||||
using osu.Game.Graphics.Containers;
|
||||
|
||||
namespace osu.Game.Overlays.News.Sidebar
|
||||
{
|
||||
@ -31,9 +32,31 @@ namespace osu.Game.Overlays.News.Sidebar
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Colour = colourProvider.Background4
|
||||
},
|
||||
new Box
|
||||
{
|
||||
RelativeSizeAxes = Axes.Y,
|
||||
Width = OsuScrollContainer.SCROLL_BAR_HEIGHT,
|
||||
Anchor = Anchor.TopRight,
|
||||
Origin = Anchor.TopRight,
|
||||
Colour = colourProvider.Background3,
|
||||
Alpha = 0.5f
|
||||
},
|
||||
new Container
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Padding = new MarginPadding { Right = -3 }, // Compensate for scrollbar margin
|
||||
Child = new OsuScrollContainer
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Child = new Container
|
||||
{
|
||||
RelativeSizeAxes = Axes.X,
|
||||
AutoSizeAxes = Axes.Y,
|
||||
Padding = new MarginPadding { Right = 3 }, // Addeded 3px back
|
||||
Child = new Container
|
||||
{
|
||||
RelativeSizeAxes = Axes.X,
|
||||
AutoSizeAxes = Axes.Y,
|
||||
Padding = new MarginPadding
|
||||
{
|
||||
Vertical = 20,
|
||||
@ -59,6 +82,9 @@ namespace osu.Game.Overlays.News.Sidebar
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -81,6 +81,9 @@ namespace osu.Game.Overlays.News.Sidebar
|
||||
{
|
||||
public int Year { get; }
|
||||
|
||||
[Resolved(canBeNull: true)]
|
||||
private NewsOverlay overlay { get; set; }
|
||||
|
||||
private readonly bool isCurrent;
|
||||
|
||||
public YearButton(int year, bool isCurrent)
|
||||
@ -106,7 +109,11 @@ namespace osu.Game.Overlays.News.Sidebar
|
||||
{
|
||||
IdleColour = isCurrent ? Color4.White : colourProvider.Light2;
|
||||
HoverColour = isCurrent ? Color4.White : colourProvider.Light1;
|
||||
Action = () => { }; // Avoid button being disabled since there's no proper action assigned.
|
||||
Action = () =>
|
||||
{
|
||||
if (!isCurrent)
|
||||
overlay?.ShowYear(Year);
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,11 +1,14 @@
|
||||
// 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.Bindables;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Game.Overlays.News;
|
||||
using osu.Game.Overlays.News.Displays;
|
||||
using osu.Game.Overlays.News.Sidebar;
|
||||
|
||||
namespace osu.Game.Overlays
|
||||
{
|
||||
@ -13,9 +16,48 @@ namespace osu.Game.Overlays
|
||||
{
|
||||
private readonly Bindable<string> article = new Bindable<string>(null);
|
||||
|
||||
private readonly Container sidebarContainer;
|
||||
private readonly NewsSidebar sidebar;
|
||||
|
||||
private readonly Container content;
|
||||
|
||||
private CancellationTokenSource cancellationToken;
|
||||
|
||||
private bool displayUpdateRequired = true;
|
||||
|
||||
public NewsOverlay()
|
||||
: base(OverlayColourScheme.Purple, false)
|
||||
{
|
||||
Child = new GridContainer
|
||||
{
|
||||
RelativeSizeAxes = Axes.X,
|
||||
AutoSizeAxes = Axes.Y,
|
||||
RowDimensions = new[]
|
||||
{
|
||||
new Dimension(GridSizeMode.AutoSize)
|
||||
},
|
||||
ColumnDimensions = new[]
|
||||
{
|
||||
new Dimension(GridSizeMode.AutoSize),
|
||||
new Dimension()
|
||||
},
|
||||
Content = new[]
|
||||
{
|
||||
new Drawable[]
|
||||
{
|
||||
sidebarContainer = new Container
|
||||
{
|
||||
AutoSizeAxes = Axes.X,
|
||||
Child = sidebar = new NewsSidebar()
|
||||
},
|
||||
content = new Container
|
||||
{
|
||||
RelativeSizeAxes = Axes.X,
|
||||
AutoSizeAxes = Axes.Y
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
protected override void LoadComplete()
|
||||
@ -26,12 +68,7 @@ namespace osu.Game.Overlays
|
||||
article.BindValueChanged(onArticleChanged);
|
||||
}
|
||||
|
||||
protected override NewsHeader CreateHeader() => new NewsHeader
|
||||
{
|
||||
ShowFrontPage = ShowFrontPage
|
||||
};
|
||||
|
||||
private bool displayUpdateRequired = true;
|
||||
protected override NewsHeader CreateHeader() => new NewsHeader { ShowFrontPage = ShowFrontPage };
|
||||
|
||||
protected override void PopIn()
|
||||
{
|
||||
@ -56,38 +93,69 @@ namespace osu.Game.Overlays
|
||||
Show();
|
||||
}
|
||||
|
||||
public void ShowYear(int year)
|
||||
{
|
||||
loadFrontPage(year);
|
||||
Show();
|
||||
}
|
||||
|
||||
public void ShowArticle(string slug)
|
||||
{
|
||||
article.Value = slug;
|
||||
Show();
|
||||
}
|
||||
|
||||
private CancellationTokenSource cancellationToken;
|
||||
|
||||
private void onArticleChanged(ValueChangedEvent<string> e)
|
||||
{
|
||||
cancellationToken?.Cancel();
|
||||
Loading.Show();
|
||||
|
||||
if (e.NewValue == null)
|
||||
{
|
||||
Header.SetFrontPage();
|
||||
LoadDisplay(new FrontPageDisplay());
|
||||
return;
|
||||
}
|
||||
|
||||
Header.SetArticle(e.NewValue);
|
||||
LoadDisplay(Empty());
|
||||
}
|
||||
|
||||
protected void LoadDisplay(Drawable display)
|
||||
{
|
||||
ScrollFlow.ScrollToStart();
|
||||
LoadComponentAsync(display, loaded =>
|
||||
LoadComponentAsync(display, loaded => content.Child = loaded, (cancellationToken = new CancellationTokenSource()).Token);
|
||||
}
|
||||
|
||||
protected override void UpdateAfterChildren()
|
||||
{
|
||||
Child = loaded;
|
||||
base.UpdateAfterChildren();
|
||||
sidebarContainer.Height = DrawHeight;
|
||||
sidebarContainer.Y = Math.Clamp(ScrollFlow.Current - Header.DrawHeight, 0, Math.Max(ScrollFlow.ScrollContent.DrawHeight - DrawHeight - Header.DrawHeight, 0));
|
||||
}
|
||||
|
||||
private void onArticleChanged(ValueChangedEvent<string> article)
|
||||
{
|
||||
if (article.NewValue == null)
|
||||
loadFrontPage();
|
||||
else
|
||||
loadArticle(article.NewValue);
|
||||
}
|
||||
|
||||
private void loadFrontPage(int? year = null)
|
||||
{
|
||||
beginLoading();
|
||||
|
||||
Header.SetFrontPage();
|
||||
|
||||
var page = new ArticleListing(year);
|
||||
page.SidebarMetadataUpdated += metadata => Schedule(() =>
|
||||
{
|
||||
sidebar.Metadata.Value = metadata;
|
||||
Loading.Hide();
|
||||
}, (cancellationToken = new CancellationTokenSource()).Token);
|
||||
});
|
||||
LoadDisplay(page);
|
||||
}
|
||||
|
||||
private void loadArticle(string article)
|
||||
{
|
||||
beginLoading();
|
||||
|
||||
Header.SetArticle(article);
|
||||
|
||||
// Temporary, should be handled by ArticleDisplay later
|
||||
LoadDisplay(Empty());
|
||||
Loading.Hide();
|
||||
}
|
||||
|
||||
private void beginLoading()
|
||||
{
|
||||
cancellationToken?.Cancel();
|
||||
Loading.Show();
|
||||
}
|
||||
|
||||
protected override void Dispose(bool isDisposing)
|
||||
|
Loading…
Reference in New Issue
Block a user