From 22b0105d629a70344609d33314a76978053e633d Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 6 Oct 2020 13:00:02 +0900 Subject: [PATCH 1/5] Show a notification if checking for updates via button and there are none available --- osu.Desktop/Updater/SquirrelUpdateManager.cs | 8 ++++--- .../Sections/General/UpdateSettings.cs | 21 +++++++++++++++++-- osu.Game/Updater/SimpleUpdateManager.cs | 7 ++++++- osu.Game/Updater/UpdateManager.cs | 19 ++++++++++------- 4 files changed, 41 insertions(+), 14 deletions(-) diff --git a/osu.Desktop/Updater/SquirrelUpdateManager.cs b/osu.Desktop/Updater/SquirrelUpdateManager.cs index 05c8e835ac..b9b148b383 100644 --- a/osu.Desktop/Updater/SquirrelUpdateManager.cs +++ b/osu.Desktop/Updater/SquirrelUpdateManager.cs @@ -37,9 +37,9 @@ namespace osu.Desktop.Updater Splat.Locator.CurrentMutable.Register(() => new SquirrelLogger(), typeof(Splat.ILogger)); } - protected override async Task PerformUpdateCheck() => await checkForUpdateAsync(); + protected override async Task PerformUpdateCheck() => await checkForUpdateAsync(); - private async Task checkForUpdateAsync(bool useDeltaPatching = true, UpdateProgressNotification notification = null) + private async Task checkForUpdateAsync(bool useDeltaPatching = true, UpdateProgressNotification notification = null) { // should we schedule a retry on completion of this check? bool scheduleRecheck = true; @@ -51,7 +51,7 @@ namespace osu.Desktop.Updater var info = await updateManager.CheckForUpdate(!useDeltaPatching); if (info.ReleasesToApply.Count == 0) // no updates available. bail and retry later. - return; + return false; if (notification == null) { @@ -103,6 +103,8 @@ namespace osu.Desktop.Updater Scheduler.AddDelayed(async () => await checkForUpdateAsync(), 60000 * 30); } } + + return true; } protected override void Dispose(bool isDisposing) diff --git a/osu.Game/Overlays/Settings/Sections/General/UpdateSettings.cs b/osu.Game/Overlays/Settings/Sections/General/UpdateSettings.cs index 9c7d0b0be4..9b7b7392d8 100644 --- a/osu.Game/Overlays/Settings/Sections/General/UpdateSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/General/UpdateSettings.cs @@ -4,9 +4,11 @@ using System.Threading.Tasks; using osu.Framework; using osu.Framework.Allocation; +using osu.Framework.Graphics.Sprites; using osu.Framework.Platform; using osu.Framework.Screens; using osu.Game.Configuration; +using osu.Game.Overlays.Notifications; using osu.Game.Overlays.Settings.Sections.Maintenance; using osu.Game.Updater; @@ -21,6 +23,9 @@ namespace osu.Game.Overlays.Settings.Sections.General private SettingsButton checkForUpdatesButton; + [Resolved] + private NotificationOverlay notifications { get; set; } + [BackgroundDependencyLoader(true)] private void load(Storage storage, OsuConfigManager config, OsuGame game) { @@ -30,7 +35,7 @@ namespace osu.Game.Overlays.Settings.Sections.General Bindable = config.GetBindable(OsuSetting.ReleaseStream), }); - if (updateManager?.CanCheckForUpdate == true) + //if (updateManager?.CanCheckForUpdate == true) { Add(checkForUpdatesButton = new SettingsButton { @@ -38,7 +43,19 @@ namespace osu.Game.Overlays.Settings.Sections.General Action = () => { checkForUpdatesButton.Enabled.Value = false; - Task.Run(updateManager.CheckForUpdateAsync).ContinueWith(t => Schedule(() => checkForUpdatesButton.Enabled.Value = true)); + Task.Run(updateManager.CheckForUpdateAsync).ContinueWith(t => Schedule(() => + { + if (!t.Result) + { + notifications.Post(new SimpleNotification + { + Text = $"You are running the latest release ({game.Version})", + Icon = FontAwesome.Solid.CheckCircle, + }); + } + + checkForUpdatesButton.Enabled.Value = true; + })); } }); } diff --git a/osu.Game/Updater/SimpleUpdateManager.cs b/osu.Game/Updater/SimpleUpdateManager.cs index ebb9995c66..79b2d46b93 100644 --- a/osu.Game/Updater/SimpleUpdateManager.cs +++ b/osu.Game/Updater/SimpleUpdateManager.cs @@ -30,7 +30,7 @@ namespace osu.Game.Updater version = game.Version; } - protected override async Task PerformUpdateCheck() + protected override async Task PerformUpdateCheck() { try { @@ -53,12 +53,17 @@ namespace osu.Game.Updater return true; } }); + + return true; } } catch { // we shouldn't crash on a web failure. or any failure for the matter. + return true; } + + return false; } private string getBestUrl(GitHubRelease release) diff --git a/osu.Game/Updater/UpdateManager.cs b/osu.Game/Updater/UpdateManager.cs index 61775a26b7..30e28f0e95 100644 --- a/osu.Game/Updater/UpdateManager.cs +++ b/osu.Game/Updater/UpdateManager.cs @@ -57,25 +57,28 @@ namespace osu.Game.Updater private readonly object updateTaskLock = new object(); - private Task updateCheckTask; + private Task updateCheckTask; - public async Task CheckForUpdateAsync() + public async Task CheckForUpdateAsync() { - if (!CanCheckForUpdate) - return; - - Task waitTask; + Task waitTask; lock (updateTaskLock) waitTask = (updateCheckTask ??= PerformUpdateCheck()); - await waitTask; + bool hasUpdates = await waitTask; lock (updateTaskLock) updateCheckTask = null; + + return hasUpdates; } - protected virtual Task PerformUpdateCheck() => Task.CompletedTask; + /// + /// Performs an asynchronous check for application updates. + /// + /// Whether any update is waiting. May return true if an error occured (there is potentially an update available). + protected virtual Task PerformUpdateCheck() => Task.FromResult(false); private class UpdateCompleteNotification : SimpleNotification { From de47392e3d11ddf7e7831c029ac4c5bf353007d2 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 6 Oct 2020 13:18:42 +0900 Subject: [PATCH 2/5] Display the "restart to update" notification on checking for update after dismissal --- osu.Desktop/Updater/SquirrelUpdateManager.cs | 50 ++++++++++++++------ 1 file changed, 36 insertions(+), 14 deletions(-) diff --git a/osu.Desktop/Updater/SquirrelUpdateManager.cs b/osu.Desktop/Updater/SquirrelUpdateManager.cs index b9b148b383..71f9fafe57 100644 --- a/osu.Desktop/Updater/SquirrelUpdateManager.cs +++ b/osu.Desktop/Updater/SquirrelUpdateManager.cs @@ -29,6 +29,11 @@ namespace osu.Desktop.Updater private static readonly Logger logger = Logger.GetLogger("updater"); + /// + /// Whether an update has been downloaded but not yet applied. + /// + private bool updatePending; + [BackgroundDependencyLoader] private void load(NotificationOverlay notification) { @@ -49,9 +54,19 @@ namespace osu.Desktop.Updater updateManager ??= await UpdateManager.GitHubUpdateManager(@"https://github.com/ppy/osu", @"osulazer", null, null, true); var info = await updateManager.CheckForUpdate(!useDeltaPatching); + if (info.ReleasesToApply.Count == 0) + { + if (updatePending) + { + // the user may have dismissed the completion notice, so show it again. + notificationOverlay.Post(new UpdateCompleteNotification(this)); + return true; + } + // no updates available. bail and retry later. return false; + } if (notification == null) { @@ -72,6 +87,7 @@ namespace osu.Desktop.Updater await updateManager.ApplyReleases(info, p => notification.Progress = p / 100f); notification.State = ProgressNotificationState.Completed; + updatePending = true; } catch (Exception e) { @@ -113,10 +129,27 @@ namespace osu.Desktop.Updater updateManager?.Dispose(); } + private class UpdateCompleteNotification : ProgressCompletionNotification + { + [Resolved] + private OsuGame game { get; set; } + + public UpdateCompleteNotification(SquirrelUpdateManager updateManager) + { + Text = @"Update ready to install. Click to restart!"; + + Activated = () => + { + updateManager.PrepareUpdateAsync() + .ContinueWith(_ => updateManager.Schedule(() => game.GracefullyExit())); + return true; + }; + } + } + private class UpdateProgressNotification : ProgressNotification { private readonly SquirrelUpdateManager updateManager; - private OsuGame game; public UpdateProgressNotification(SquirrelUpdateManager updateManager) { @@ -125,23 +158,12 @@ namespace osu.Desktop.Updater protected override Notification CreateCompletionNotification() { - return new ProgressCompletionNotification - { - Text = @"Update ready to install. Click to restart!", - Activated = () => - { - updateManager.PrepareUpdateAsync() - .ContinueWith(_ => updateManager.Schedule(() => game.GracefullyExit())); - return true; - } - }; + return new UpdateCompleteNotification(updateManager); } [BackgroundDependencyLoader] - private void load(OsuColour colours, OsuGame game) + private void load(OsuColour colours) { - this.game = game; - IconContent.AddRange(new Drawable[] { new Box From e8b34ba4acd0d5fb61e06bb3f1ce4c14bffdded4 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 6 Oct 2020 20:57:39 +0900 Subject: [PATCH 3/5] Fix incorrectly committed testing change --- osu.Game/Overlays/Settings/Sections/General/UpdateSettings.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Overlays/Settings/Sections/General/UpdateSettings.cs b/osu.Game/Overlays/Settings/Sections/General/UpdateSettings.cs index 9b7b7392d8..c216d1efe9 100644 --- a/osu.Game/Overlays/Settings/Sections/General/UpdateSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/General/UpdateSettings.cs @@ -35,7 +35,7 @@ namespace osu.Game.Overlays.Settings.Sections.General Bindable = config.GetBindable(OsuSetting.ReleaseStream), }); - //if (updateManager?.CanCheckForUpdate == true) + if (updateManager?.CanCheckForUpdate == true) { Add(checkForUpdatesButton = new SettingsButton { From b2dad67adead750b3b3f377d61449bf53e00d5a2 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 6 Oct 2020 21:28:59 +0900 Subject: [PATCH 4/5] Fix unresolvable dependency in settings test scene --- osu.Game/Overlays/Settings/Sections/General/UpdateSettings.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Overlays/Settings/Sections/General/UpdateSettings.cs b/osu.Game/Overlays/Settings/Sections/General/UpdateSettings.cs index c216d1efe9..c0a525e012 100644 --- a/osu.Game/Overlays/Settings/Sections/General/UpdateSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/General/UpdateSettings.cs @@ -23,7 +23,7 @@ namespace osu.Game.Overlays.Settings.Sections.General private SettingsButton checkForUpdatesButton; - [Resolved] + [Resolved(CanBeNull = true)] private NotificationOverlay notifications { get; set; } [BackgroundDependencyLoader(true)] @@ -47,7 +47,7 @@ namespace osu.Game.Overlays.Settings.Sections.General { if (!t.Result) { - notifications.Post(new SimpleNotification + notifications?.Post(new SimpleNotification { Text = $"You are running the latest release ({game.Version})", Icon = FontAwesome.Solid.CheckCircle, From 94a6e2856570bcb281d2073cd7eb6f716362b0bb Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 7 Oct 2020 18:40:09 +0900 Subject: [PATCH 5/5] Add back second removed condition --- osu.Game/Updater/UpdateManager.cs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/osu.Game/Updater/UpdateManager.cs b/osu.Game/Updater/UpdateManager.cs index 30e28f0e95..f772c6d282 100644 --- a/osu.Game/Updater/UpdateManager.cs +++ b/osu.Game/Updater/UpdateManager.cs @@ -61,6 +61,9 @@ namespace osu.Game.Updater public async Task CheckForUpdateAsync() { + if (!CanCheckForUpdate) + return false; + Task waitTask; lock (updateTaskLock)