1
0
mirror of https://github.com/ppy/osu.git synced 2025-01-18 11:52:54 +08:00

Merge pull request #31442 from peppy/supporter-button-always-warns

Always show dialog when clicking supporter icon before opening browser
This commit is contained in:
Bartłomiej Dach 2025-01-07 15:14:53 +01:00 committed by GitHub
commit d0a39a7733
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 90 additions and 35 deletions

View File

@ -12,7 +12,6 @@ using osu.Framework.Platform;
using osu.Framework.Testing; using osu.Framework.Testing;
using osu.Game.Beatmaps; using osu.Game.Beatmaps;
using osu.Game.Database; using osu.Game.Database;
using osu.Game.Extensions;
using osu.Game.Graphics.Sprites; using osu.Game.Graphics.Sprites;
using osu.Game.Online.API; using osu.Game.Online.API;
using osu.Game.Online.API.Requests; using osu.Game.Online.API.Requests;
@ -85,6 +84,7 @@ namespace osu.Game.Tests.Visual.SongSelect
} }
[Test] [Test]
[FlakyTest]
public void TestPresentedBeatmapIsRecommended() public void TestPresentedBeatmapIsRecommended()
{ {
List<BeatmapSetInfo> beatmapSets = null; List<BeatmapSetInfo> beatmapSets = null;
@ -106,6 +106,7 @@ namespace osu.Game.Tests.Visual.SongSelect
} }
[Test] [Test]
[FlakyTest]
public void TestCurrentRulesetIsRecommended() public void TestCurrentRulesetIsRecommended()
{ {
BeatmapSetInfo catchSet = null, mixedSet = null; BeatmapSetInfo catchSet = null, mixedSet = null;
@ -142,6 +143,7 @@ namespace osu.Game.Tests.Visual.SongSelect
} }
[Test] [Test]
[FlakyTest]
public void TestSecondBestRulesetIsRecommended() public void TestSecondBestRulesetIsRecommended()
{ {
BeatmapSetInfo osuSet = null, mixedSet = null; BeatmapSetInfo osuSet = null, mixedSet = null;
@ -159,6 +161,7 @@ namespace osu.Game.Tests.Visual.SongSelect
} }
[Test] [Test]
[FlakyTest]
public void TestCorrectStarRatingIsUsed() public void TestCorrectStarRatingIsUsed()
{ {
BeatmapSetInfo osuSet = null, maniaSet = null; BeatmapSetInfo osuSet = null, maniaSet = null;
@ -176,6 +179,7 @@ namespace osu.Game.Tests.Visual.SongSelect
} }
[Test] [Test]
[FlakyTest]
public void TestBeatmapListingFilter() public void TestBeatmapListingFilter()
{ {
AddStep("set playmode to taiko", () => ((DummyAPIAccess)API).LocalUser.Value.PlayMode = "taiko"); AddStep("set playmode to taiko", () => ((DummyAPIAccess)API).LocalUser.Value.PlayMode = "taiko");
@ -245,7 +249,7 @@ namespace osu.Game.Tests.Visual.SongSelect
AddStep("present beatmap", () => Game.PresentBeatmap(getImport())); AddStep("present beatmap", () => Game.PresentBeatmap(getImport()));
AddUntilStep("wait for song select", () => Game.ScreenStack.CurrentScreen is Screens.Select.SongSelect select && select.BeatmapSetsLoaded); AddUntilStep("wait for song select", () => Game.ScreenStack.CurrentScreen is Screens.Select.SongSelect select && select.BeatmapSetsLoaded);
AddUntilStep("recommended beatmap displayed", () => Game.Beatmap.Value.BeatmapInfo.MatchesOnlineID(getImport().Beatmaps[expectedDiff - 1])); AddUntilStep("recommended beatmap displayed", () => Game.Beatmap.Value.BeatmapInfo.OnlineID, () => Is.EqualTo(getImport().Beatmaps[expectedDiff - 1].OnlineID));
} }
protected override TestOsuGame CreateTestGame() => new NoBeatmapUpdateGame(LocalStorage, API); protected override TestOsuGame CreateTestGame() => new NoBeatmapUpdateGame(LocalStorage, API);

View File

@ -4,13 +4,16 @@
using System; using System;
using osu.Framework.Allocation; using osu.Framework.Allocation;
using osu.Framework.Bindables; using osu.Framework.Bindables;
using osu.Framework.Extensions;
using osu.Framework.Graphics; using osu.Framework.Graphics;
using osu.Framework.Graphics.Sprites; using osu.Framework.Graphics.Sprites;
using osu.Framework.Platform; using osu.Framework.Platform;
using osu.Game.Configuration; using osu.Game.Configuration;
using osu.Game.Localisation; using osu.Game.Localisation;
using osu.Game.Online.API;
using osu.Game.Overlays; using osu.Game.Overlays;
using osu.Game.Overlays.Dialog; using osu.Game.Overlays.Dialog;
using osu.Game.Overlays.Notifications;
using WebCommonStrings = osu.Game.Resources.Localisation.Web.CommonStrings; using WebCommonStrings = osu.Game.Resources.Localisation.Web.CommonStrings;
namespace osu.Game.Online.Chat namespace osu.Game.Online.Chat
@ -23,9 +26,15 @@ namespace osu.Game.Online.Chat
[Resolved] [Resolved]
private Clipboard clipboard { get; set; } = null!; private Clipboard clipboard { get; set; } = null!;
[Resolved(CanBeNull = true)] [Resolved]
private IDialogOverlay? dialogOverlay { get; set; } private IDialogOverlay? dialogOverlay { get; set; }
[Resolved]
private INotificationOverlay? notificationOverlay { get; set; }
[Resolved]
private IAPIProvider api { get; set; } = null!;
private Bindable<bool> externalLinkWarning = null!; private Bindable<bool> externalLinkWarning = null!;
[BackgroundDependencyLoader(true)] [BackgroundDependencyLoader(true)]
@ -34,9 +43,51 @@ namespace osu.Game.Online.Chat
externalLinkWarning = config.GetBindable<bool>(OsuSetting.ExternalLinkWarning); externalLinkWarning = config.GetBindable<bool>(OsuSetting.ExternalLinkWarning);
} }
public void OpenUrlExternally(string url, bool bypassWarning = false) public void OpenUrlExternally(string url, LinkWarnMode warnMode = LinkWarnMode.Default)
{ {
if (!bypassWarning && externalLinkWarning.Value && dialogOverlay != null) bool isTrustedDomain;
if (url.StartsWith('/'))
{
url = $"{api.WebsiteRootUrl}{url}";
isTrustedDomain = true;
}
else
{
isTrustedDomain = url.StartsWith(api.WebsiteRootUrl, StringComparison.Ordinal);
}
if (!url.CheckIsValidUrl())
{
notificationOverlay?.Post(new SimpleErrorNotification
{
Text = NotificationsStrings.UnsupportedOrDangerousUrlProtocol(url),
});
return;
}
bool shouldWarn;
switch (warnMode)
{
case LinkWarnMode.Default:
shouldWarn = externalLinkWarning.Value && !isTrustedDomain;
break;
case LinkWarnMode.AlwaysWarn:
shouldWarn = true;
break;
case LinkWarnMode.NeverWarn:
shouldWarn = false;
break;
default:
throw new ArgumentOutOfRangeException(nameof(warnMode), warnMode, null);
}
if (dialogOverlay != null && shouldWarn)
dialogOverlay.Push(new ExternalLinkDialog(url, () => host.OpenUrlExternally(url), () => clipboard.SetText(url))); dialogOverlay.Push(new ExternalLinkDialog(url, () => host.OpenUrlExternally(url), () => clipboard.SetText(url)));
else else
host.OpenUrlExternally(url); host.OpenUrlExternally(url);

View File

@ -0,0 +1,23 @@
// 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.
namespace osu.Game.Online.Chat
{
public enum LinkWarnMode
{
/// <summary>
/// Will show a dialog when opening a URL that is not on a trusted domain.
/// </summary>
Default,
/// <summary>
/// Will always show a dialog when opening a URL.
/// </summary>
AlwaysWarn,
/// <summary>
/// Will never show a dialog when opening a URL.
/// </summary>
NeverWarn,
}
}

View File

@ -18,7 +18,6 @@ using osu.Framework.Allocation;
using osu.Framework.Audio; using osu.Framework.Audio;
using osu.Framework.Bindables; using osu.Framework.Bindables;
using osu.Framework.Configuration; using osu.Framework.Configuration;
using osu.Framework.Extensions;
using osu.Framework.Extensions.IEnumerableExtensions; using osu.Framework.Extensions.IEnumerableExtensions;
using osu.Framework.Extensions.TypeExtensions; using osu.Framework.Extensions.TypeExtensions;
using osu.Framework.Graphics; using osu.Framework.Graphics;
@ -516,32 +515,7 @@ namespace osu.Game
onScreenDisplay.Display(new CopyUrlToast()); onScreenDisplay.Display(new CopyUrlToast());
}); });
public void OpenUrlExternally(string url, bool forceBypassExternalUrlWarning = false) => waitForReady(() => externalLinkOpener, _ => public void OpenUrlExternally(string url, LinkWarnMode warnMode = LinkWarnMode.Default) => waitForReady(() => externalLinkOpener, _ => externalLinkOpener.OpenUrlExternally(url, warnMode));
{
bool isTrustedDomain;
if (url.StartsWith('/'))
{
url = $"{API.WebsiteRootUrl}{url}";
isTrustedDomain = true;
}
else
{
isTrustedDomain = url.StartsWith(API.WebsiteRootUrl, StringComparison.Ordinal);
}
if (!url.CheckIsValidUrl())
{
Notifications.Post(new SimpleErrorNotification
{
Text = NotificationsStrings.UnsupportedOrDangerousUrlProtocol(url),
});
return;
}
externalLinkOpener.OpenUrlExternally(url, forceBypassExternalUrlWarning || isTrustedDomain);
});
/// <summary> /// <summary>
/// Open a specific channel in chat. /// Open a specific channel in chat.
@ -1340,7 +1314,7 @@ namespace osu.Game
IconColour = Colours.YellowDark, IconColour = Colours.YellowDark,
Activated = () => Activated = () =>
{ {
OpenUrlExternally("https://opentabletdriver.net/Tablets", true); OpenUrlExternally("https://opentabletdriver.net/Tablets", LinkWarnMode.NeverWarn);
return true; return true;
} }
})); }));

View File

@ -18,6 +18,7 @@ using osu.Game.Graphics.Sprites;
using osu.Game.Graphics.UserInterface; using osu.Game.Graphics.UserInterface;
using osu.Game.Localisation; using osu.Game.Localisation;
using osu.Game.Online.API; using osu.Game.Online.API;
using osu.Game.Online.Chat;
using osu.Game.Overlays.Settings; using osu.Game.Overlays.Settings;
using osu.Game.Resources.Localisation.Web; using osu.Game.Resources.Localisation.Web;
using osuTK; using osuTK;
@ -213,7 +214,7 @@ namespace osu.Game.Overlays.AccountCreation
if (!string.IsNullOrEmpty(errors.Message)) if (!string.IsNullOrEmpty(errors.Message))
passwordDescription.AddErrors(new[] { errors.Message }); passwordDescription.AddErrors(new[] { errors.Message });
game?.OpenUrlExternally($"{errors.Redirect}?username={usernameTextBox.Text}&email={emailTextBox.Text}", true); game?.OpenUrlExternally($"{errors.Redirect}?username={usernameTextBox.Text}&email={emailTextBox.Text}", LinkWarnMode.NeverWarn);
} }
} }
else else

View File

@ -11,6 +11,7 @@ using osu.Framework.Input.Events;
using osu.Framework.Localisation; using osu.Framework.Localisation;
using osu.Game.Graphics; using osu.Game.Graphics;
using osu.Game.Graphics.Containers; using osu.Game.Graphics.Containers;
using osu.Game.Online.Chat;
using osu.Game.Resources.Localisation.Web; using osu.Game.Resources.Localisation.Web;
namespace osu.Game.Overlays.Profile.Header.Components namespace osu.Game.Overlays.Profile.Header.Components
@ -87,7 +88,8 @@ namespace osu.Game.Overlays.Profile.Header.Components
{ {
background.Colour = colours.Pink; background.Colour = colours.Pink;
Action = () => game?.OpenUrlExternally(@"/home/support"); // Easy to accidentally click so let's always show the open URL popup.
Action = () => game?.OpenUrlExternally(@"/home/support", LinkWarnMode.AlwaysWarn);
} }
protected override bool OnHover(HoverEvent e) protected override bool OnHover(HoverEvent e)