1
0
mirror of https://github.com/ppy/osu.git synced 2025-01-12 16:02:55 +08:00

Merge pull request #12950 from gagahpangeran/osu-wiki-overlay

Initial implementation of Wiki Overlay
This commit is contained in:
Dean Herbert 2021-06-01 15:20:56 +09:00 committed by GitHub
commit dce24e3d4d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
18 changed files with 514 additions and 25 deletions

View File

@ -51,7 +51,7 @@
<Reference Include="Java.Interop" /> <Reference Include="Java.Interop" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="ppy.osu.Game.Resources" Version="2021.422.0" /> <PackageReference Include="ppy.osu.Game.Resources" Version="2021.525.0" />
<PackageReference Include="ppy.osu.Framework.Android" Version="2021.528.0" /> <PackageReference Include="ppy.osu.Framework.Android" Version="2021.528.0" />
</ItemGroup> </ItemGroup>
</Project> </Project>

View File

@ -24,10 +24,10 @@ namespace osu.Game.Tests.Chat
[TestCase(LinkAction.OpenBeatmap, "456", "https://dev.ppy.sh/beatmapsets/123#osu/456")] [TestCase(LinkAction.OpenBeatmap, "456", "https://dev.ppy.sh/beatmapsets/123#osu/456")]
[TestCase(LinkAction.OpenBeatmap, "456", "https://dev.ppy.sh/beatmapsets/123#osu/456?whatever")] [TestCase(LinkAction.OpenBeatmap, "456", "https://dev.ppy.sh/beatmapsets/123#osu/456?whatever")]
[TestCase(LinkAction.OpenBeatmap, "456", "https://dev.ppy.sh/beatmapsets/123/456")] [TestCase(LinkAction.OpenBeatmap, "456", "https://dev.ppy.sh/beatmapsets/123/456")]
[TestCase(LinkAction.External, null, "https://dev.ppy.sh/beatmapsets/abc/def")] [TestCase(LinkAction.External, "https://dev.ppy.sh/beatmapsets/abc/def", "https://dev.ppy.sh/beatmapsets/abc/def")]
[TestCase(LinkAction.OpenBeatmapSet, "123", "https://dev.ppy.sh/beatmapsets/123")] [TestCase(LinkAction.OpenBeatmapSet, "123", "https://dev.ppy.sh/beatmapsets/123")]
[TestCase(LinkAction.OpenBeatmapSet, "123", "https://dev.ppy.sh/beatmapsets/123/whatever")] [TestCase(LinkAction.OpenBeatmapSet, "123", "https://dev.ppy.sh/beatmapsets/123/whatever")]
[TestCase(LinkAction.External, null, "https://dev.ppy.sh/beatmapsets/abc")] [TestCase(LinkAction.External, "https://dev.ppy.sh/beatmapsets/abc", "https://dev.ppy.sh/beatmapsets/abc")]
public void TestBeatmapLinks(LinkAction expectedAction, string expectedArg, string link) public void TestBeatmapLinks(LinkAction expectedAction, string expectedArg, string link)
{ {
MessageFormatter.WebsiteRootUrl = "dev.ppy.sh"; MessageFormatter.WebsiteRootUrl = "dev.ppy.sh";

View File

@ -0,0 +1,102 @@
// 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.Collections.Generic;
using System.Linq;
using NUnit.Framework;
using osu.Framework.Allocation;
using osu.Framework.Bindables;
using osu.Framework.Graphics;
using osu.Game.Online.API.Requests.Responses;
using osu.Game.Overlays;
using osu.Game.Overlays.Wiki;
namespace osu.Game.Tests.Visual.Online
{
public class TestSceneWikiHeader : OsuTestScene
{
[Cached]
private readonly OverlayColourProvider colourProvider = new OverlayColourProvider(OverlayColourScheme.Orange);
[Cached]
private readonly Bindable<APIWikiPage> wikiPageData = new Bindable<APIWikiPage>(new APIWikiPage
{
Title = "Main Page",
Path = "Main_Page",
});
private TestHeader header;
[SetUp]
public void SetUp() => Schedule(() =>
{
Child = header = new TestHeader
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
ShowIndexPage = dummyShowIndexPage,
ShowParentPage = dummyShowParentPage,
};
wikiPageData.BindTo(header.WikiPageData);
});
[Test]
public void TestWikiHeader()
{
AddAssert("Current is index", () => checkCurrent("index"));
AddStep("Change wiki page data", () => wikiPageData.Value = new APIWikiPage
{
Title = "Welcome",
Path = "Welcome"
});
AddAssert("Current is welcome", () => checkCurrent("Welcome"));
AddAssert("Check breadcrumb", checkBreadcrumb);
AddStep("Change current to index", () => header.Current.Value = "index");
AddAssert("Current is index", () => checkCurrent("index"));
AddStep("Change wiki page data", () => wikiPageData.Value = new APIWikiPage
{
Title = "Developers",
Path = "People/The_Team/Developers",
Subtitle = "The Team",
});
AddAssert("Current is 'Developers'", () => checkCurrent("Developers"));
AddAssert("Check breadcrumb", checkBreadcrumb);
AddStep("Change current to 'The Team'", () => header.Current.Value = "The Team");
AddAssert("Current is 'The Team'", () => checkCurrent("The Team"));
AddAssert("Check breadcrumb", checkBreadcrumb);
}
private bool checkCurrent(string expectedCurrent) => header.Current.Value == expectedCurrent;
private bool checkBreadcrumb()
{
var result = header.TabControlItems.Contains(wikiPageData.Value.Title);
if (wikiPageData.Value.Subtitle != null)
result = header.TabControlItems.Contains(wikiPageData.Value.Subtitle) && result;
return result;
}
private void dummyShowIndexPage() => wikiPageData.SetDefault();
private void dummyShowParentPage()
{
wikiPageData.Value = new APIWikiPage
{
Path = "People/The_Team",
Title = "The Team",
Subtitle = "People"
};
}
private class TestHeader : WikiHeader
{
public IReadOnlyList<string> TabControlItems => TabControl.Items;
}
}
}

View File

@ -48,7 +48,7 @@ namespace osu.Game.Tests.Visual.Online
[Test] [Test]
public void TestLink() public void TestLink()
{ {
AddStep("set current path", () => markdownContainer.CurrentPath = "Article_styling_criteria/"); AddStep("set current path", () => markdownContainer.CurrentPath = $"{API.WebsiteRootUrl}/wiki/Article_styling_criteria/");
AddStep("set '/wiki/Main_Page''", () => markdownContainer.Text = "[wiki main page](/wiki/Main_Page)"); AddStep("set '/wiki/Main_Page''", () => markdownContainer.Text = "[wiki main page](/wiki/Main_Page)");
AddAssert("check url", () => markdownContainer.Link.Url == $"{API.WebsiteRootUrl}/wiki/Main_Page"); AddAssert("check url", () => markdownContainer.Link.Url == $"{API.WebsiteRootUrl}/wiki/Main_Page");
@ -113,7 +113,7 @@ needs_cleanup: true
AddStep("Add relative image", () => AddStep("Add relative image", () =>
{ {
markdownContainer.DocumentUrl = "https://dev.ppy.sh"; markdownContainer.DocumentUrl = "https://dev.ppy.sh";
markdownContainer.CurrentPath = "Interface/"; markdownContainer.CurrentPath = $"{API.WebsiteRootUrl}/wiki/Interface/";
markdownContainer.Text = "![intro](img/intro-screen.jpg)"; markdownContainer.Text = "![intro](img/intro-screen.jpg)";
}); });
} }
@ -124,7 +124,7 @@ needs_cleanup: true
AddStep("Add paragraph with block image", () => AddStep("Add paragraph with block image", () =>
{ {
markdownContainer.DocumentUrl = "https://dev.ppy.sh"; markdownContainer.DocumentUrl = "https://dev.ppy.sh";
markdownContainer.CurrentPath = "Interface/"; markdownContainer.CurrentPath = $"{API.WebsiteRootUrl}/wiki/Interface/";
markdownContainer.Text = @"Line before image markdownContainer.Text = @"Line before image
![play menu](img/play-menu.jpg ""Main Menu in osu!"") ![play menu](img/play-menu.jpg ""Main Menu in osu!"")

File diff suppressed because one or more lines are too long

View File

@ -6,13 +6,11 @@ using Markdig.Extensions.AutoIdentifiers;
using Markdig.Extensions.Tables; using Markdig.Extensions.Tables;
using Markdig.Extensions.Yaml; using Markdig.Extensions.Yaml;
using Markdig.Syntax; using Markdig.Syntax;
using osu.Framework.Allocation;
using osu.Framework.Graphics; using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Containers.Markdown; using osu.Framework.Graphics.Containers.Markdown;
using osu.Framework.Graphics.Sprites; using osu.Framework.Graphics.Sprites;
using osu.Game.Graphics.Sprites; using osu.Game.Graphics.Sprites;
using osu.Game.Online.API;
namespace osu.Game.Graphics.Containers.Markdown namespace osu.Game.Graphics.Containers.Markdown
{ {
@ -23,16 +21,6 @@ namespace osu.Game.Graphics.Containers.Markdown
LineSpacing = 21; LineSpacing = 21;
} }
protected override IReadOnlyDependencyContainer CreateChildDependencies(IReadOnlyDependencyContainer parent)
{
var api = parent.Get<IAPIProvider>();
// needs to be set before the base BDL call executes to avoid invalidating any already populated markdown content.
DocumentUrl = api.WebsiteRootUrl;
return base.CreateChildDependencies(parent);
}
protected override void AddMarkdownComponent(IMarkdownObject markdownObject, FillFlowContainer container, int level) protected override void AddMarkdownComponent(IMarkdownObject markdownObject, FillFlowContainer container, int level)
{ {
switch (markdownObject) switch (markdownObject)

View File

@ -0,0 +1,21 @@
// 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.Game.Online.API.Requests.Responses;
namespace osu.Game.Online.API.Requests
{
public class GetWikiRequest : APIRequest<APIWikiPage>
{
private readonly string path;
private readonly string locale;
public GetWikiRequest(string path, string locale = "en")
{
this.path = path;
this.locale = locale;
}
protected override string Target => $"wiki/{locale}/{path}";
}
}

View File

@ -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 System.Collections.Generic;
using Newtonsoft.Json;
namespace osu.Game.Online.API.Requests.Responses
{
public class APIWikiPage
{
[JsonProperty("layout")]
public string Layout { get; set; }
[JsonProperty("locale")]
public string Locale { get; set; }
[JsonProperty("markdown")]
public string Markdown { get; set; }
[JsonProperty("path")]
public string Path { get; set; }
[JsonProperty("subtitle")]
public string Subtitle { get; set; }
[JsonProperty("tags")]
public List<string> Tags { get; set; }
[JsonProperty("title")]
public string Title { get; set; }
}
}

View File

@ -167,10 +167,13 @@ namespace osu.Game.Online.Chat
case "u": case "u":
case "users": case "users":
return new LinkDetails(LinkAction.OpenUserProfile, mainArg); return new LinkDetails(LinkAction.OpenUserProfile, mainArg);
case "wiki":
return new LinkDetails(LinkAction.OpenWiki, string.Join('/', args.Skip(3)));
} }
} }
return new LinkDetails(LinkAction.External, null); return new LinkDetails(LinkAction.External, url);
case "osu": case "osu":
// every internal link also needs some kind of argument // every internal link also needs some kind of argument
@ -311,7 +314,8 @@ namespace osu.Game.Online.Chat
JoinMultiplayerMatch, JoinMultiplayerMatch,
Spectate, Spectate,
OpenUserProfile, OpenUserProfile,
Custom OpenWiki,
Custom,
} }
public class Link : IComparable<Link> public class Link : IComparable<Link>

View File

@ -81,6 +81,8 @@ namespace osu.Game
private BeatmapSetOverlay beatmapSetOverlay; private BeatmapSetOverlay beatmapSetOverlay;
private WikiOverlay wikiOverlay;
private SkinEditorOverlay skinEditor; private SkinEditorOverlay skinEditor;
private Container overlayContent; private Container overlayContent;
@ -307,6 +309,10 @@ namespace osu.Game
ShowUser(userId); ShowUser(userId);
break; break;
case LinkAction.OpenWiki:
ShowWiki(link.Argument);
break;
default: default:
throw new NotImplementedException($"This {nameof(LinkAction)} ({link.Action.ToString()}) is missing an associated action."); throw new NotImplementedException($"This {nameof(LinkAction)} ({link.Action.ToString()}) is missing an associated action.");
} }
@ -354,6 +360,12 @@ namespace osu.Game
/// <param name="beatmapId">The beatmap to show.</param> /// <param name="beatmapId">The beatmap to show.</param>
public void ShowBeatmap(int beatmapId) => waitForReady(() => beatmapSetOverlay, _ => beatmapSetOverlay.FetchAndShowBeatmap(beatmapId)); public void ShowBeatmap(int beatmapId) => waitForReady(() => beatmapSetOverlay, _ => beatmapSetOverlay.FetchAndShowBeatmap(beatmapId));
/// <summary>
/// Show a wiki's page as an overlay
/// </summary>
/// <param name="path">The wiki page to show</param>
public void ShowWiki(string path) => waitForReady(() => wikiOverlay, _ => wikiOverlay.ShowPage(path));
/// <summary> /// <summary>
/// Present a beatmap at song select immediately. /// Present a beatmap at song select immediately.
/// The user should have already requested this interactively. /// The user should have already requested this interactively.
@ -719,6 +731,7 @@ namespace osu.Game
var changelogOverlay = loadComponentSingleFile(new ChangelogOverlay(), overlayContent.Add, true); var changelogOverlay = loadComponentSingleFile(new ChangelogOverlay(), overlayContent.Add, true);
loadComponentSingleFile(userProfile = new UserProfileOverlay(), overlayContent.Add, true); loadComponentSingleFile(userProfile = new UserProfileOverlay(), overlayContent.Add, true);
loadComponentSingleFile(beatmapSetOverlay = new BeatmapSetOverlay(), overlayContent.Add, true); loadComponentSingleFile(beatmapSetOverlay = new BeatmapSetOverlay(), overlayContent.Add, true);
loadComponentSingleFile(wikiOverlay = new WikiOverlay(), overlayContent.Add, true);
loadComponentSingleFile(skinEditor = new SkinEditorOverlay(screenContainer), overlayContent.Add); loadComponentSingleFile(skinEditor = new SkinEditorOverlay(screenContainer), overlayContent.Add);
loadComponentSingleFile(new LoginOverlay loadComponentSingleFile(new LoginOverlay
@ -769,7 +782,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, news, dashboard, beatmapListing, changelogOverlay, rankingsOverlay }; var singleDisplayOverlays = new OverlayContainer[] { chatOverlay, news, dashboard, beatmapListing, changelogOverlay, rankingsOverlay, wikiOverlay };
foreach (var overlay in singleDisplayOverlays) foreach (var overlay in singleDisplayOverlays)
{ {

View File

@ -92,6 +92,7 @@ namespace osu.Game.Overlays.Toolbar
new ToolbarBeatmapListingButton(), new ToolbarBeatmapListingButton(),
new ToolbarChatButton(), new ToolbarChatButton(),
new ToolbarSocialButton(), new ToolbarSocialButton(),
new ToolbarWikiButton(),
new ToolbarMusicButton(), new ToolbarMusicButton(),
//new ToolbarButton //new ToolbarButton
//{ //{

View File

@ -0,0 +1,19 @@
// 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;
namespace osu.Game.Overlays.Toolbar
{
public class ToolbarWikiButton : ToolbarOverlayToggleButton
{
protected override Anchor TooltipAnchor => Anchor.TopRight;
[BackgroundDependencyLoader(true)]
private void load(WikiOverlay wiki)
{
StateContainer = wiki;
}
}
}

View File

@ -5,17 +5,22 @@ using System.Linq;
using Markdig.Extensions.Yaml; using Markdig.Extensions.Yaml;
using Markdig.Syntax; using Markdig.Syntax;
using Markdig.Syntax.Inlines; using Markdig.Syntax.Inlines;
using osu.Framework.Allocation;
using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Containers.Markdown; using osu.Framework.Graphics.Containers.Markdown;
using osu.Game.Graphics.Containers.Markdown; using osu.Game.Graphics.Containers.Markdown;
using osu.Game.Online.API;
namespace osu.Game.Overlays.Wiki.Markdown namespace osu.Game.Overlays.Wiki.Markdown
{ {
public class WikiMarkdownContainer : OsuMarkdownContainer public class WikiMarkdownContainer : OsuMarkdownContainer
{ {
[Resolved]
private IAPIProvider api { get; set; }
public string CurrentPath public string CurrentPath
{ {
set => DocumentUrl = $"{DocumentUrl}wiki/{value}"; set => DocumentUrl = value;
} }
protected override void AddMarkdownComponent(IMarkdownObject markdownObject, FillFlowContainer container, int level) protected override void AddMarkdownComponent(IMarkdownObject markdownObject, FillFlowContainer container, int level)

View File

@ -0,0 +1,82 @@
// 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 osu.Framework.Bindables;
using osu.Framework.Graphics;
using osu.Game.Online.API.Requests.Responses;
namespace osu.Game.Overlays.Wiki
{
public class WikiHeader : BreadcrumbControlOverlayHeader
{
private const string index_page_string = "index";
private const string index_path = "Main_Page";
public readonly Bindable<APIWikiPage> WikiPageData = new Bindable<APIWikiPage>();
public Action ShowIndexPage;
public Action ShowParentPage;
public WikiHeader()
{
TabControl.AddItem(index_page_string);
Current.Value = index_page_string;
WikiPageData.BindValueChanged(onWikiPageChange);
Current.BindValueChanged(onCurrentChange);
}
private void onWikiPageChange(ValueChangedEvent<APIWikiPage> e)
{
if (e.NewValue == null)
return;
TabControl.Clear();
Current.Value = null;
TabControl.AddItem(index_page_string);
if (e.NewValue.Path == index_path)
{
Current.Value = index_page_string;
return;
}
if (e.NewValue.Subtitle != null)
TabControl.AddItem(e.NewValue.Subtitle);
TabControl.AddItem(e.NewValue.Title);
Current.Value = e.NewValue.Title;
}
private void onCurrentChange(ValueChangedEvent<string> e)
{
if (e.NewValue == TabControl.Items.LastOrDefault())
return;
if (e.NewValue == index_page_string)
{
ShowIndexPage?.Invoke();
return;
}
ShowParentPage?.Invoke();
}
protected override Drawable CreateBackground() => new OverlayHeaderBackground(@"Headers/wiki");
protected override OverlayTitle CreateTitle() => new WikiHeaderTitle();
private class WikiHeaderTitle : OverlayTitle
{
public WikiHeaderTitle()
{
Title = "wiki";
Description = "knowledge base";
IconTexture = "Icons/Hexacons/wiki";
}
}
}
}

View File

@ -13,6 +13,7 @@ using osu.Framework.Graphics.Shapes;
using osu.Framework.Graphics.Sprites; using osu.Framework.Graphics.Sprites;
using osu.Game.Graphics; using osu.Game.Graphics;
using osu.Game.Graphics.Containers.Markdown; using osu.Game.Graphics.Containers.Markdown;
using osu.Game.Online.API;
using osu.Game.Overlays.Wiki.Markdown; using osu.Game.Overlays.Wiki.Markdown;
using osuTK; using osuTK;
using osuTK.Graphics; using osuTK.Graphics;
@ -37,7 +38,7 @@ namespace osu.Game.Overlays.Wiki
} }
[BackgroundDependencyLoader] [BackgroundDependencyLoader]
private void load(OverlayColourProvider colourProvider) private void load(OverlayColourProvider colourProvider, IAPIProvider api)
{ {
Children = new Drawable[] Children = new Drawable[]
{ {
@ -61,6 +62,7 @@ namespace osu.Game.Overlays.Wiki
}, },
panelContainer = new WikiPanelMarkdownContainer(isFullWidth) panelContainer = new WikiPanelMarkdownContainer(isFullWidth)
{ {
CurrentPath = $@"{api.WebsiteRootUrl}/wiki/",
Text = text, Text = text,
RelativeSizeAxes = Axes.X, RelativeSizeAxes = Axes.X,
AutoSizeAxes = Axes.Y, AutoSizeAxes = Axes.Y,

View File

@ -0,0 +1,148 @@
// 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 System.Threading;
using osu.Framework.Allocation;
using osu.Framework.Bindables;
using osu.Framework.Graphics;
using osu.Game.Online.API;
using osu.Game.Online.API.Requests;
using osu.Game.Online.API.Requests.Responses;
using osu.Game.Overlays.Wiki;
using osu.Game.Overlays.Wiki.Markdown;
namespace osu.Game.Overlays
{
public class WikiOverlay : OnlineOverlay<WikiHeader>
{
private const string index_path = @"main_page";
private readonly Bindable<string> path = new Bindable<string>(index_path);
private readonly Bindable<APIWikiPage> wikiData = new Bindable<APIWikiPage>();
[Resolved]
private IAPIProvider api { get; set; }
private GetWikiRequest request;
private CancellationTokenSource cancellationToken;
private bool displayUpdateRequired = true;
public WikiOverlay()
: base(OverlayColourScheme.Orange, false)
{
}
public void ShowPage(string pagePath = index_path)
{
path.Value = pagePath.Trim('/');
Show();
}
protected override WikiHeader CreateHeader() => new WikiHeader
{
ShowIndexPage = () => ShowPage(),
ShowParentPage = showParentPage,
};
protected override void LoadComplete()
{
base.LoadComplete();
path.BindValueChanged(onPathChanged);
wikiData.BindTo(Header.WikiPageData);
}
protected override void PopIn()
{
base.PopIn();
if (displayUpdateRequired)
{
path.TriggerChange();
displayUpdateRequired = false;
}
}
protected override void PopOutComplete()
{
base.PopOutComplete();
displayUpdateRequired = true;
}
protected void LoadDisplay(Drawable display)
{
ScrollFlow.ScrollToStart();
LoadComponentAsync(display, loaded =>
{
Child = loaded;
Loading.Hide();
}, (cancellationToken = new CancellationTokenSource()).Token);
}
private void onPathChanged(ValueChangedEvent<string> e)
{
cancellationToken?.Cancel();
request?.Cancel();
request = new GetWikiRequest(e.NewValue);
Loading.Show();
request.Success += response => Schedule(() => onSuccess(response));
request.Failure += _ => Schedule(() => LoadDisplay(Empty()));
api.PerformAsync(request);
}
private void onSuccess(APIWikiPage response)
{
wikiData.Value = response;
if (response.Layout == index_path)
{
LoadDisplay(new WikiMainPage
{
Markdown = response.Markdown,
Padding = new MarginPadding
{
Vertical = 20,
Horizontal = 50,
},
});
}
else
{
LoadDisplay(new WikiMarkdownContainer
{
RelativeSizeAxes = Axes.X,
AutoSizeAxes = Axes.Y,
CurrentPath = $@"{api.WebsiteRootUrl}/wiki/{path.Value}/",
Text = response.Markdown,
DocumentMargin = new MarginPadding(0),
DocumentPadding = new MarginPadding
{
Vertical = 20,
Left = 30,
Right = 50,
},
});
}
}
private void showParentPage()
{
var parentPath = string.Join("/", path.Value.Split('/').SkipLast(1));
ShowPage(parentPath);
}
protected override void Dispose(bool isDisposing)
{
cancellationToken?.Cancel();
request?.Cancel();
base.Dispose(isDisposing);
}
}
}

View File

@ -35,7 +35,7 @@
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference> </PackageReference>
<PackageReference Include="ppy.osu.Framework" Version="2021.528.0" /> <PackageReference Include="ppy.osu.Framework" Version="2021.528.0" />
<PackageReference Include="ppy.osu.Game.Resources" Version="2021.422.0" /> <PackageReference Include="ppy.osu.Game.Resources" Version="2021.525.0" />
<PackageReference Include="Sentry" Version="3.3.4" /> <PackageReference Include="Sentry" Version="3.3.4" />
<PackageReference Include="SharpCompress" Version="0.28.2" /> <PackageReference Include="SharpCompress" Version="0.28.2" />
<PackageReference Include="NUnit" Version="3.13.2" /> <PackageReference Include="NUnit" Version="3.13.2" />

View File

@ -71,7 +71,7 @@
</ItemGroup> </ItemGroup>
<ItemGroup Label="Package References"> <ItemGroup Label="Package References">
<PackageReference Include="ppy.osu.Framework.iOS" Version="2021.528.0" /> <PackageReference Include="ppy.osu.Framework.iOS" Version="2021.528.0" />
<PackageReference Include="ppy.osu.Game.Resources" Version="2021.422.0" /> <PackageReference Include="ppy.osu.Game.Resources" Version="2021.525.0" />
</ItemGroup> </ItemGroup>
<!-- See https://github.com/dotnet/runtime/issues/35988 (can be removed after Xamarin uses net5.0 / net6.0) --> <!-- See https://github.com/dotnet/runtime/issues/35988 (can be removed after Xamarin uses net5.0 / net6.0) -->
<PropertyGroup> <PropertyGroup>