diff --git a/osu.Game.Tests/Visual/TestCaseChatLink.cs b/osu.Game.Tests/Visual/TestCaseChatLink.cs index 4dac46831c..eddcd16b93 100644 --- a/osu.Game.Tests/Visual/TestCaseChatLink.cs +++ b/osu.Game.Tests/Visual/TestCaseChatLink.cs @@ -23,6 +23,7 @@ namespace osu.Game.Tests.Visual public class TestCaseChatLink : OsuTestCase { private readonly TestChatLineContainer textContainer; + private readonly DialogOverlay dialogOverlay; private Color4 linkColour; public override IReadOnlyList RequiredTypes => new[] @@ -37,6 +38,7 @@ namespace osu.Game.Tests.Visual public TestCaseChatLink() { + Add(dialogOverlay = new DialogOverlay { Depth = float.MinValue }); Add(textContainer = new TestChatLineContainer { Padding = new MarginPadding { Left = 20, Right = 20 }, @@ -57,6 +59,7 @@ namespace osu.Game.Tests.Visual Dependencies.Cache(chatManager); Dependencies.Cache(new ChatOverlay()); + Dependencies.Cache(dialogOverlay); testLinksGeneral(); testEcho(); diff --git a/osu.Game/Configuration/OsuConfigManager.cs b/osu.Game/Configuration/OsuConfigManager.cs index 9ac2cabe9f..8975ab8a0e 100644 --- a/osu.Game/Configuration/OsuConfigManager.cs +++ b/osu.Game/Configuration/OsuConfigManager.cs @@ -42,6 +42,8 @@ namespace osu.Game.Configuration if (!val) Set(OsuSetting.SavePassword, false); }; + Set(OsuSetting.ExternalLinkWarning, true); + // Audio Set(OsuSetting.VolumeInactive, 0.25, 0, 1, 0.01); @@ -148,6 +150,7 @@ namespace osu.Game.Configuration BeatmapSkins, BeatmapHitsounds, IncreaseFirstObjectVisibility, - ScoreDisplayMode + ScoreDisplayMode, + ExternalLinkWarning } } diff --git a/osu.Game/Graphics/Containers/LinkFlowContainer.cs b/osu.Game/Graphics/Containers/LinkFlowContainer.cs index 5c8fddc342..54a2ea47f9 100644 --- a/osu.Game/Graphics/Containers/LinkFlowContainer.cs +++ b/osu.Game/Graphics/Containers/LinkFlowContainer.cs @@ -8,7 +8,6 @@ using osu.Framework.Allocation; using osu.Framework.Graphics.Sprites; using System.Collections.Generic; using osu.Framework.Logging; -using osu.Framework.Platform; using osu.Game.Overlays; using osu.Game.Overlays.Notifications; @@ -24,14 +23,12 @@ namespace osu.Game.Graphics.Containers private OsuGame game; private ChannelManager channelManager; private Action showNotImplementedError; - private GameHost host; [BackgroundDependencyLoader(true)] - private void load(OsuGame game, NotificationOverlay notifications, GameHost host, ChannelManager channelManager) + private void load(OsuGame game, NotificationOverlay notifications, ChannelManager channelManager) { // will be null in tests this.game = game; - this.host = host; this.channelManager = channelManager; showNotImplementedError = () => notifications?.Post(new SimpleNotification @@ -98,7 +95,7 @@ namespace osu.Game.Graphics.Containers showNotImplementedError?.Invoke(); break; case LinkAction.External: - host.OpenUrlExternally(url); + game?.OpenUrlExternally(url); break; case LinkAction.OpenUserProfile: if (long.TryParse(linkArgument, out long userId)) diff --git a/osu.Game/Online/Chat/ExternalLinkOpener.cs b/osu.Game/Online/Chat/ExternalLinkOpener.cs new file mode 100644 index 0000000000..d8b8adbbad --- /dev/null +++ b/osu.Game/Online/Chat/ExternalLinkOpener.cs @@ -0,0 +1,36 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using osu.Framework.Allocation; +using osu.Framework.Configuration; +using osu.Framework.Graphics; +using osu.Framework.Platform; +using osu.Game.Configuration; +using osu.Game.Overlays; +using osu.Game.Overlays.Chat; + +namespace osu.Game.Online.Chat +{ + public class ExternalLinkOpener : Component + { + private GameHost host; + private DialogOverlay dialogOverlay; + private Bindable externalLinkWarning; + + [BackgroundDependencyLoader(true)] + private void load(GameHost host, DialogOverlay dialogOverlay, OsuConfigManager config) + { + this.host = host; + this.dialogOverlay = dialogOverlay; + externalLinkWarning = config.GetBindable(OsuSetting.ExternalLinkWarning); + } + + public void OpenUrlExternally(string url) + { + if (externalLinkWarning) + dialogOverlay.Push(new ExternalLinkDialog(url, () => host.OpenUrlExternally(url))); + else + host.OpenUrlExternally(url); + } + } +} diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index 2894e096fb..1b0a0b2210 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -181,6 +181,9 @@ namespace osu.Game LocalConfig.BindWith(OsuSetting.VolumeInactive, inactiveVolumeAdjust); } + private ExternalLinkOpener externalLinkOpener; + public void OpenUrlExternally(string url) => externalLinkOpener.OpenUrlExternally(url); + private ScheduledDelegate scoreLoad; /// @@ -382,6 +385,8 @@ namespace osu.Game dependencies.Cache(notifications); dependencies.Cache(dialogOverlay); + Add(externalLinkOpener = new ExternalLinkOpener()); + var singleDisplaySideOverlays = new OverlayContainer[] { settings, notifications }; overlays.AddRange(singleDisplaySideOverlays); diff --git a/osu.Game/Overlays/Chat/ExternalLinkDialog.cs b/osu.Game/Overlays/Chat/ExternalLinkDialog.cs new file mode 100644 index 0000000000..b3f7b282a9 --- /dev/null +++ b/osu.Game/Overlays/Chat/ExternalLinkDialog.cs @@ -0,0 +1,33 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using System; +using osu.Game.Graphics; +using osu.Game.Overlays.Dialog; + +namespace osu.Game.Overlays.Chat +{ + public class ExternalLinkDialog : PopupDialog + { + public ExternalLinkDialog(string url, Action openExternalLinkAction) + { + HeaderText = "Just checking..."; + BodyText = $"You are about to leave osu! and open the following link in a web browser:\n\n{url}"; + + Icon = FontAwesome.fa_warning; + + Buttons = new PopupDialogButton[] + { + new PopupDialogOkButton + { + Text = @"Yes. Go for it.", + Action = openExternalLinkAction + }, + new PopupDialogCancelButton + { + Text = @"No! Abort mission!" + }, + }; + } + } +} diff --git a/osu.Game/Overlays/Dialog/PopupDialog.cs b/osu.Game/Overlays/Dialog/PopupDialog.cs index 3100266c6f..ca921b7882 100644 --- a/osu.Game/Overlays/Dialog/PopupDialog.cs +++ b/osu.Game/Overlays/Dialog/PopupDialog.cs @@ -7,12 +7,10 @@ using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; -using osu.Framework.Graphics.Sprites; using osu.Framework.Input.Events; using osu.Game.Graphics; using osu.Game.Graphics.Backgrounds; using osu.Game.Graphics.Containers; -using osu.Game.Graphics.Sprites; using osu.Game.Input.Bindings; using osuTK; using osuTK.Graphics; @@ -35,7 +33,7 @@ namespace osu.Game.Overlays.Dialog private readonly Container ring; private readonly FillFlowContainer buttonsContainer; private readonly SpriteIcon icon; - private readonly SpriteText header; + private readonly TextFlowContainer header; private readonly TextFlowContainer body; private bool actionInvoked; @@ -46,10 +44,19 @@ namespace osu.Game.Overlays.Dialog set => icon.Icon = value; } + private string text; + public string HeaderText { - get => header.Text; - set => header.Text = value; + get => text; + set + { + if (text == value) + return; + text = value; + + header.Text = value; + } } public string BodyText @@ -164,18 +171,20 @@ namespace osu.Game.Overlays.Dialog }, }, }, - header = new OsuSpriteText + header = new OsuTextFlowContainer(t => t.TextSize = 25) { Origin = Anchor.TopCentre, Anchor = Anchor.TopCentre, - TextSize = 25, - Shadow = true, + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Padding = new MarginPadding(15), + TextAnchor = Anchor.TopCentre, }, body = new OsuTextFlowContainer(t => t.TextSize = 18) { - Padding = new MarginPadding(15), RelativeSizeAxes = Axes.X, AutoSizeAxes = Axes.Y, + Padding = new MarginPadding(15), TextAnchor = Anchor.TopCentre, }, }, diff --git a/osu.Game/Overlays/Settings/Sections/Online/WebSettings.cs b/osu.Game/Overlays/Settings/Sections/Online/WebSettings.cs new file mode 100644 index 0000000000..62e307f323 --- /dev/null +++ b/osu.Game/Overlays/Settings/Sections/Online/WebSettings.cs @@ -0,0 +1,27 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using osu.Framework.Allocation; +using osu.Framework.Graphics; +using osu.Game.Configuration; + +namespace osu.Game.Overlays.Settings.Sections.Online +{ + public class WebSettings : SettingsSubsection + { + protected override string Header => "Web"; + + [BackgroundDependencyLoader] + private void load(OsuConfigManager config) + { + Children = new Drawable[] + { + new SettingsCheckbox + { + LabelText = "Warn about opening external links", + Bindable = config.GetBindable(OsuSetting.ExternalLinkWarning) + }, + }; + } + } +} diff --git a/osu.Game/Overlays/Settings/Sections/OnlineSection.cs b/osu.Game/Overlays/Settings/Sections/OnlineSection.cs index 28cb503288..3a2e52d2eb 100644 --- a/osu.Game/Overlays/Settings/Sections/OnlineSection.cs +++ b/osu.Game/Overlays/Settings/Sections/OnlineSection.cs @@ -3,6 +3,7 @@ using osu.Framework.Graphics; using osu.Game.Graphics; +using osu.Game.Overlays.Settings.Sections.Online; namespace osu.Game.Overlays.Settings.Sections { @@ -15,6 +16,7 @@ namespace osu.Game.Overlays.Settings.Sections { Children = new Drawable[] { + new WebSettings() }; } }