diff --git a/src/Artemis.UI.Shared/Services/MainWindow/IMainWindowService.cs b/src/Artemis.UI.Shared/Services/MainWindow/IMainWindowService.cs
index bf7716f0b..e42d644dc 100644
--- a/src/Artemis.UI.Shared/Services/MainWindow/IMainWindowService.cs
+++ b/src/Artemis.UI.Shared/Services/MainWindow/IMainWindowService.cs
@@ -1,4 +1,5 @@
using System;
+using ReactiveUI;
namespace Artemis.UI.Shared.Services.MainWindow;
@@ -12,6 +13,11 @@ public interface IMainWindowService : IArtemisSharedUIService
///
bool IsMainWindowOpen { get; }
+ ///
+ /// Gets or sets the host screen contained in the main window
+ ///
+ IScreen? HostScreen { get; set; }
+
///
/// Sets up the main window provider that controls the state of the main window
///
diff --git a/src/Artemis.UI.Shared/Services/MainWindow/MainWindowService.cs b/src/Artemis.UI.Shared/Services/MainWindow/MainWindowService.cs
index fbdda52e1..98a6cba19 100644
--- a/src/Artemis.UI.Shared/Services/MainWindow/MainWindowService.cs
+++ b/src/Artemis.UI.Shared/Services/MainWindow/MainWindowService.cs
@@ -1,4 +1,5 @@
using System;
+using ReactiveUI;
namespace Artemis.UI.Shared.Services.MainWindow;
@@ -6,6 +7,12 @@ internal class MainWindowService : IMainWindowService
{
private IMainWindowProvider? _mainWindowManager;
+ ///
+ public bool IsMainWindowOpen { get; private set; }
+
+ ///
+ public IScreen? HostScreen { get; set; }
+
protected virtual void OnMainWindowOpened()
{
MainWindowOpened?.Invoke(this, EventArgs.Empty);
@@ -64,8 +71,6 @@ internal class MainWindowService : IMainWindowService
OnMainWindowUnfocused();
}
- public bool IsMainWindowOpen { get; private set; }
-
public void ConfigureMainWindowProvider(IMainWindowProvider mainWindowProvider)
{
if (mainWindowProvider == null) throw new ArgumentNullException(nameof(mainWindowProvider));
diff --git a/src/Artemis.UI.Windows/DryIoc/ContainerExtensions.cs b/src/Artemis.UI.Windows/DryIoc/ContainerExtensions.cs
index 4b3bf7fda..337e21744 100644
--- a/src/Artemis.UI.Windows/DryIoc/ContainerExtensions.cs
+++ b/src/Artemis.UI.Windows/DryIoc/ContainerExtensions.cs
@@ -1,5 +1,6 @@
using Artemis.Core.Providers;
using Artemis.Core.Services;
+using Artemis.UI.Services.Updating;
using Artemis.UI.Shared.Providers;
using Artemis.UI.Windows.Providers;
using Artemis.UI.Windows.Providers.Input;
@@ -22,5 +23,6 @@ public static class UIContainerExtensions
container.Register(Reuse.Singleton);
container.Register();
container.Register(serviceKey: WindowsInputProvider.Id);
+ container.Register();
}
}
\ No newline at end of file
diff --git a/src/Artemis.UI.Windows/Providers/WindowsUpdateNotificationProvider.cs b/src/Artemis.UI.Windows/Providers/WindowsUpdateNotificationProvider.cs
new file mode 100644
index 000000000..3cc68f83f
--- /dev/null
+++ b/src/Artemis.UI.Windows/Providers/WindowsUpdateNotificationProvider.cs
@@ -0,0 +1,146 @@
+using System;
+using System.ComponentModel;
+using System.Globalization;
+using System.Linq;
+using System.Threading;
+using System.Threading.Tasks;
+using Windows.UI.Notifications;
+using Artemis.UI.Screens.Settings;
+using Artemis.UI.Services.Updating;
+using Artemis.UI.Shared.Services.MainWindow;
+using Avalonia.Threading;
+using Microsoft.Toolkit.Uwp.Notifications;
+using ReactiveUI;
+
+namespace Artemis.UI.Windows.Providers;
+
+public class WindowsUpdateNotificationProvider : IUpdateNotificationProvider
+{
+ private readonly Func _getReleaseInstaller;
+ private readonly Func _getSettingsViewModel;
+ private readonly IMainWindowService _mainWindowService;
+ private readonly IUpdateService _updateService;
+
+ public WindowsUpdateNotificationProvider(IMainWindowService mainWindowService,
+ IUpdateService updateService,
+ Func getSettingsViewModel,
+ Func getReleaseInstaller)
+ {
+ _mainWindowService = mainWindowService;
+ _updateService = updateService;
+ _getSettingsViewModel = getSettingsViewModel;
+ _getReleaseInstaller = getReleaseInstaller;
+ ToastNotificationManagerCompat.OnActivated += ToastNotificationManagerCompatOnOnActivated;
+ }
+
+ private async void ToastNotificationManagerCompatOnOnActivated(ToastNotificationActivatedEventArgsCompat e)
+ {
+ ToastArguments args = ToastArguments.Parse(e.Argument);
+ string releaseId = args.Get("releaseId");
+ string releaseVersion = args.Get("releaseVersion");
+ string action = "view-changes";
+ if (args.Contains("action"))
+ action = args.Get("action");
+
+ if (action == "install")
+ await InstallRelease(releaseId, releaseVersion);
+ else if (action == "view-changes")
+ ViewRelease(releaseId);
+ else if (action == "restart-for-update")
+ _updateService.RestartForUpdate(false);
+ }
+
+ public async Task ShowNotification(string releaseId, string releaseVersion)
+ {
+ new ToastContentBuilder()
+ .AddArgument("releaseId", releaseId)
+ .AddArgument("releaseVersion", releaseVersion)
+ .AddText("Update available")
+ .AddText($"Artemis version {releaseVersion} has been released")
+ .AddButton(new ToastButton()
+ .SetContent("Install")
+ .AddArgument("action", "install").SetAfterActivationBehavior(ToastAfterActivationBehavior.PendingUpdate))
+ .AddButton(new ToastButton().SetContent("View changes").AddArgument("action", "view-changes"))
+ .Show(t => t.Tag = releaseId);
+ }
+
+ private void ViewRelease(string releaseId)
+ {
+ Dispatcher.UIThread.Post(() =>
+ {
+ _mainWindowService.OpenMainWindow();
+
+ // TODO: When proper routing has been implemented, use that here
+ // Create a settings VM to navigate to
+ SettingsViewModel settingsViewModel = _getSettingsViewModel(_mainWindowService.HostScreen);
+ // Get the release tab
+ ReleasesTabViewModel releaseTabViewModel = (ReleasesTabViewModel) settingsViewModel.SettingTabs.First(t => t is ReleasesTabViewModel);
+
+ // Navigate to the settings VM
+ _mainWindowService.HostScreen.Router.Navigate.Execute(settingsViewModel);
+ // Navigate to the release tab
+ releaseTabViewModel.PreselectId = releaseId;
+ settingsViewModel.SelectedTab = releaseTabViewModel;
+ });
+ }
+
+ private async Task InstallRelease(string releaseId, string releaseVersion)
+ {
+ ReleaseInstaller installer = _getReleaseInstaller(releaseId);
+ void InstallerOnPropertyChanged(object? sender, PropertyChangedEventArgs e) => UpdateInstallProgress(releaseId, installer);
+
+ new ToastContentBuilder()
+ .AddArgument("releaseId", releaseId)
+ .AddArgument("releaseVersion", releaseVersion)
+ .AddAudio(new ToastAudio {Silent = true})
+ .AddText("Installing Artemis update")
+ .AddVisualChild(new AdaptiveProgressBar()
+ {
+ Title = releaseVersion,
+ Value = new BindableProgressBarValue("progressValue"),
+ Status = new BindableString("progressStatus")
+ })
+ .AddButton(new ToastButton().SetContent("Cancel").AddArgument("action", "cancel"))
+ .Show(t =>
+ {
+ t.Tag = releaseId;
+ t.Data = GetInstallerNotificationData(installer);
+ });
+
+ await Task.Delay(2000);
+ installer.PropertyChanged += InstallerOnPropertyChanged;
+ await installer.InstallAsync(CancellationToken.None);
+ installer.PropertyChanged -= InstallerOnPropertyChanged;
+
+ _updateService.QueueUpdate();
+
+ new ToastContentBuilder()
+ .AddArgument("releaseId", releaseId)
+ .AddArgument("releaseVersion", releaseVersion)
+ .AddAudio(new ToastAudio {Silent = true})
+ .AddText("Update ready")
+ .AddText($"Artemis version {releaseVersion} is ready to be applied")
+ .AddButton(new ToastButton().SetContent("Restart Artemis").AddArgument("action", "restart-for-update"))
+ .AddButton(new ToastButton().SetContent("Later").AddArgument("action", "postpone-update"))
+ .Show(t => t.Tag = releaseId);
+ }
+
+ private void UpdateInstallProgress(string releaseId, ReleaseInstaller installer)
+ {
+ ToastNotificationManagerCompat.CreateToastNotifier().Update(GetInstallerNotificationData(installer), releaseId);
+ }
+
+ private NotificationData GetInstallerNotificationData(ReleaseInstaller installer)
+ {
+ NotificationData data = new()
+ {
+ Values =
+ {
+ ["progressValue"] = (installer.Progress / 100f).ToString(CultureInfo.InvariantCulture),
+ ["progressStatus"] = installer.Status
+ }
+ };
+
+ return data;
+ }
+}
\ No newline at end of file
diff --git a/src/Artemis.UI/DryIoc/ContainerExtensions.cs b/src/Artemis.UI/DryIoc/ContainerExtensions.cs
index da1dcd815..0f2ae6862 100644
--- a/src/Artemis.UI/DryIoc/ContainerExtensions.cs
+++ b/src/Artemis.UI/DryIoc/ContainerExtensions.cs
@@ -36,7 +36,7 @@ public static class UIContainerExtensions
container.Register(Reuse.Singleton);
container.Register(Reuse.Singleton);
- container.Register();
+ container.Register();
container.RegisterMany(thisAssembly, type => type.IsAssignableTo(), Reuse.Singleton);
}
diff --git a/src/Artemis.UI/Screens/Root/RootViewModel.cs b/src/Artemis.UI/Screens/Root/RootViewModel.cs
index fbd81e943..2037d0b1a 100644
--- a/src/Artemis.UI/Screens/Root/RootViewModel.cs
+++ b/src/Artemis.UI/Screens/Root/RootViewModel.cs
@@ -58,7 +58,8 @@ public class RootViewModel : ActivatableViewModelBase, IScreen, IMainWindowProvi
_lifeTime = (IClassicDesktopStyleApplicationLifetime) Application.Current!.ApplicationLifetime!;
mainWindowService.ConfigureMainWindowProvider(this);
-
+ mainWindowService.HostScreen = this;
+
DisplayAccordingToSettings();
Router.CurrentViewModel.Subscribe(UpdateTitleBarViewModel);
Task.Run(() =>
@@ -230,11 +231,6 @@ public class RootViewModel : ActivatableViewModelBase, IScreen, IMainWindowProvi
}
#endregion
-
- public void SaveWindowBounds(int x, int y, int width, int height)
- {
- throw new NotImplementedException();
- }
}
internal class EmptyViewModel : MainScreenViewModel
diff --git a/src/Artemis.UI/Screens/Settings/SettingsView.axaml b/src/Artemis.UI/Screens/Settings/SettingsView.axaml
index 96433edb6..78ac70be4 100644
--- a/src/Artemis.UI/Screens/Settings/SettingsView.axaml
+++ b/src/Artemis.UI/Screens/Settings/SettingsView.axaml
@@ -2,10 +2,12 @@
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
+ xmlns:settings="clr-namespace:Artemis.UI.Screens.Settings"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
- x:Class="Artemis.UI.Screens.Settings.SettingsView">
+ x:Class="Artemis.UI.Screens.Settings.SettingsView"
+ x:DataType="settings:SettingsViewModel">
-
+
diff --git a/src/Artemis.UI/Screens/Settings/SettingsViewModel.cs b/src/Artemis.UI/Screens/Settings/SettingsViewModel.cs
index 773656c1f..c91b33f8f 100644
--- a/src/Artemis.UI/Screens/Settings/SettingsViewModel.cs
+++ b/src/Artemis.UI/Screens/Settings/SettingsViewModel.cs
@@ -6,6 +6,8 @@ namespace Artemis.UI.Screens.Settings;
public class SettingsViewModel : MainScreenViewModel
{
+ private ActivatableViewModelBase _selectedTab;
+
public SettingsViewModel(IScreen hostScreen,
GeneralTabViewModel generalTabViewModel,
PluginsTabViewModel pluginsTabViewModel,
@@ -24,4 +26,10 @@ public class SettingsViewModel : MainScreenViewModel
}
public ObservableCollection SettingTabs { get; }
+
+ public ActivatableViewModelBase SelectedTab
+ {
+ get => _selectedTab;
+ set => RaiseAndSetIfChanged(ref _selectedTab, value);
+ }
}
\ No newline at end of file
diff --git a/src/Artemis.UI/Screens/Settings/Tabs/ReleasesTabViewModel.cs b/src/Artemis.UI/Screens/Settings/Tabs/ReleasesTabViewModel.cs
index 61da057c8..d7e3a6517 100644
--- a/src/Artemis.UI/Screens/Settings/Tabs/ReleasesTabViewModel.cs
+++ b/src/Artemis.UI/Screens/Settings/Tabs/ReleasesTabViewModel.cs
@@ -51,11 +51,12 @@ public class ReleasesTabViewModel : ActivatableViewModelBase
{
await updateService.CacheLatestRelease();
await GetMoreReleases(d.AsCancellationToken());
- SelectedReleaseViewModel = ReleaseViewModels.FirstOrDefault();
+ SelectedReleaseViewModel = ReleaseViewModels.FirstOrDefault(r => r.ReleaseId == PreselectId) ?? ReleaseViewModels.FirstOrDefault();
});
}
public ReadOnlyObservableCollection ReleaseViewModels { get; }
+ public string? PreselectId { get; set; }
public ReleaseViewModel? SelectedReleaseViewModel
{
diff --git a/src/Artemis.UI/Screens/Settings/Updating/ReleaseViewModel.cs b/src/Artemis.UI/Screens/Settings/Updating/ReleaseViewModel.cs
index 8201ecccf..bf965746a 100644
--- a/src/Artemis.UI/Screens/Settings/Updating/ReleaseViewModel.cs
+++ b/src/Artemis.UI/Screens/Settings/Updating/ReleaseViewModel.cs
@@ -22,7 +22,7 @@ public class ReleaseViewModel : ActivatableViewModelBase
{
private readonly ILogger _logger;
private readonly INotificationService _notificationService;
- private readonly string _releaseId;
+ private readonly IUpdateService _updateService;
private readonly Platform _updatePlatform;
private readonly IUpdatingClient _updatingClient;
private readonly IWindowService _windowService;
@@ -46,10 +46,10 @@ public class ReleaseViewModel : ActivatableViewModelBase
IUpdateService updateService,
IWindowService windowService)
{
- _releaseId = releaseId;
_logger = logger;
_updatingClient = updatingClient;
_notificationService = notificationService;
+ _updateService = updateService;
_windowService = windowService;
if (OperatingSystem.IsWindows())
@@ -61,12 +61,13 @@ public class ReleaseViewModel : ActivatableViewModelBase
else
throw new PlatformNotSupportedException("Cannot auto update on the current platform");
+ ReleaseId = releaseId;
Version = version;
CreatedAt = createdAt;
- ReleaseInstaller = updateService.GetReleaseInstaller(_releaseId);
+ ReleaseInstaller = updateService.GetReleaseInstaller(ReleaseId);
Install = ReactiveCommand.CreateFromTask(ExecuteInstall);
- Restart = ReactiveCommand.Create(() => Utilities.ApplyUpdate(false));
+ Restart = ReactiveCommand.Create(ExecuteRestart);
CancelInstall = ReactiveCommand.Create(() => _installerCts?.Cancel());
this.WhenActivated(d =>
@@ -74,12 +75,19 @@ public class ReleaseViewModel : ActivatableViewModelBase
// There's no point in running anything but the latest version of the current channel.
// Perhaps later that won't be true anymore, then we could consider allowing to install
// older versions with compatible database versions.
- InstallationAvailable = updateService.CachedLatestRelease?.Id == _releaseId;
+ InstallationAvailable = _updateService.CachedLatestRelease?.Id == ReleaseId;
RetrieveDetails(d.AsCancellationToken()).ToObservable();
Disposable.Create(_installerCts, cts => cts?.Cancel()).DisposeWith(d);
});
}
+ public string ReleaseId { get; }
+
+ private void ExecuteRestart()
+ {
+ _updateService.RestartForUpdate(false);
+ }
+
public ReactiveCommand Restart { get; set; }
public ReactiveCommand Install { get; }
public ReactiveCommand CancelInstall { get; }
@@ -148,6 +156,7 @@ public class ReleaseViewModel : ActivatableViewModelBase
{
InstallationInProgress = true;
await ReleaseInstaller.InstallAsync(_installerCts.Token);
+ _updateService.QueueUpdate();
InstallationFinished = true;
}
catch (TaskCanceledException)
@@ -173,7 +182,7 @@ public class ReleaseViewModel : ActivatableViewModelBase
{
Loading = true;
- IOperationResult result = await _updatingClient.GetReleaseById.ExecuteAsync(_releaseId, cancellationToken);
+ IOperationResult result = await _updatingClient.GetReleaseById.ExecuteAsync(ReleaseId, cancellationToken);
IGetReleaseById_PublishedRelease? release = result.Data?.PublishedRelease;
if (release == null)
return;
diff --git a/src/Artemis.UI/Screens/Sidebar/SidebarViewModel.cs b/src/Artemis.UI/Screens/Sidebar/SidebarViewModel.cs
index 4c3b971ad..7e1756384 100644
--- a/src/Artemis.UI/Screens/Sidebar/SidebarViewModel.cs
+++ b/src/Artemis.UI/Screens/Sidebar/SidebarViewModel.cs
@@ -137,6 +137,10 @@ public class SidebarViewModel : ActivatableViewModelBase
private void NavigateToScreen(SidebarScreenViewModel sidebarScreenViewModel)
{
+ // If the current screen changed through external means and already matches, don't navigate again
+ if (_hostScreen.Router.GetCurrentViewModel()?.GetType() == sidebarScreenViewModel.ScreenType)
+ return;
+
_hostScreen.Router.Navigate.Execute(sidebarScreenViewModel.CreateInstance(_container, _hostScreen));
_profileEditorService.ChangeCurrentProfileConfiguration(null);
}
diff --git a/src/Artemis.UI/Services/Updating/IUpdateNotificationProvider.cs b/src/Artemis.UI/Services/Updating/IUpdateNotificationProvider.cs
index fcf306bb4..0b7722609 100644
--- a/src/Artemis.UI/Services/Updating/IUpdateNotificationProvider.cs
+++ b/src/Artemis.UI/Services/Updating/IUpdateNotificationProvider.cs
@@ -4,5 +4,5 @@ namespace Artemis.UI.Services.Updating;
public interface IUpdateNotificationProvider
{
- Task ShowNotification(string releaseId);
+ Task ShowNotification(string releaseId, string releaseVersion);
}
\ No newline at end of file
diff --git a/src/Artemis.UI/Services/Updating/IUpdateService.cs b/src/Artemis.UI/Services/Updating/IUpdateService.cs
index 7b619900c..db716859e 100644
--- a/src/Artemis.UI/Services/Updating/IUpdateService.cs
+++ b/src/Artemis.UI/Services/Updating/IUpdateService.cs
@@ -11,8 +11,8 @@ public interface IUpdateService : IArtemisUIService
Task CacheLatestRelease();
Task CheckForUpdate();
- Task InstallRelease(string releaseId);
void QueueUpdate();
ReleaseInstaller GetReleaseInstaller(string releaseId);
+ void RestartForUpdate(bool silent);
}
\ No newline at end of file
diff --git a/src/Artemis.UI/Services/Updating/InAppUpdateNotificationProvider.cs b/src/Artemis.UI/Services/Updating/InAppUpdateNotificationProvider.cs
new file mode 100644
index 000000000..be08d2644
--- /dev/null
+++ b/src/Artemis.UI/Services/Updating/InAppUpdateNotificationProvider.cs
@@ -0,0 +1,66 @@
+using System;
+using System.Linq;
+using System.Threading.Tasks;
+using Artemis.UI.Screens.Settings;
+using Artemis.UI.Shared.Services;
+using Artemis.UI.Shared.Services.Builders;
+using Artemis.UI.Shared.Services.MainWindow;
+using ReactiveUI;
+
+namespace Artemis.UI.Services.Updating;
+
+public class InAppUpdateNotificationProvider : IUpdateNotificationProvider
+{
+ private readonly Func _getSettingsViewModel;
+ private readonly IMainWindowService _mainWindowService;
+ private readonly INotificationService _notificationService;
+ private Action? _notification;
+
+ public InAppUpdateNotificationProvider(INotificationService notificationService, IMainWindowService mainWindowService, Func getSettingsViewModel)
+ {
+ _notificationService = notificationService;
+ _mainWindowService = mainWindowService;
+ _getSettingsViewModel = getSettingsViewModel;
+ }
+
+ private void ShowInAppNotification(string releaseId, string releaseVersion)
+ {
+ _notification?.Invoke();
+ _notification = _notificationService.CreateNotification()
+ .WithTitle("Update available")
+ .WithMessage($"Artemis version {releaseVersion} has been released")
+ .WithSeverity(NotificationSeverity.Success)
+ .WithTimeout(TimeSpan.FromSeconds(15))
+ .HavingButton(b => b.WithText("View release").WithAction(() => ViewRelease(releaseId)))
+ .Show();
+ }
+
+ private void ViewRelease(string releaseId)
+ {
+ _notification?.Invoke();
+
+ if (_mainWindowService.HostScreen == null)
+ return;
+
+ // TODO: When proper routing has been implemented, use that here
+ // Create a settings VM to navigate to
+ SettingsViewModel settingsViewModel = _getSettingsViewModel(_mainWindowService.HostScreen);
+ // Get the release tab
+ ReleasesTabViewModel releaseTabViewModel = (ReleasesTabViewModel) settingsViewModel.SettingTabs.First(t => t is ReleasesTabViewModel);
+
+ // Navigate to the settings VM
+ _mainWindowService.HostScreen.Router.Navigate.Execute(settingsViewModel);
+ // Navigate to the release tab
+ releaseTabViewModel.PreselectId = releaseId;
+ settingsViewModel.SelectedTab = releaseTabViewModel;
+ }
+
+ ///
+ public async Task ShowNotification(string releaseId, string releaseVersion)
+ {
+ if (_mainWindowService.IsMainWindowOpen)
+ ShowInAppNotification(releaseId, releaseVersion);
+ else
+ _mainWindowService.MainWindowOpened += (_, _) => ShowInAppNotification(releaseId, releaseVersion);
+ }
+}
\ No newline at end of file
diff --git a/src/Artemis.UI/Services/Updating/SimpleUpdateNotificationProvider.cs b/src/Artemis.UI/Services/Updating/SimpleUpdateNotificationProvider.cs
deleted file mode 100644
index 86f8f7a91..000000000
--- a/src/Artemis.UI/Services/Updating/SimpleUpdateNotificationProvider.cs
+++ /dev/null
@@ -1,12 +0,0 @@
-using System.Threading.Tasks;
-
-namespace Artemis.UI.Services.Updating;
-
-public class SimpleUpdateNotificationProvider : IUpdateNotificationProvider
-{
- ///
- public async Task ShowNotification(string releaseId)
- {
- throw new System.NotImplementedException();
- }
-}
\ No newline at end of file
diff --git a/src/Artemis.UI/Services/Updating/UpdateService.cs b/src/Artemis.UI/Services/Updating/UpdateService.cs
index fb387a48f..2b97df2de 100644
--- a/src/Artemis.UI/Services/Updating/UpdateService.cs
+++ b/src/Artemis.UI/Services/Updating/UpdateService.cs
@@ -6,8 +6,6 @@ using Artemis.Core;
using Artemis.Core.Services;
using Artemis.Storage.Entities.General;
using Artemis.Storage.Repositories.Interfaces;
-using Artemis.UI.Screens.Settings.Updating;
-using Artemis.UI.Shared.Services;
using Artemis.UI.Shared.Services.MainWindow;
using Artemis.WebClient.Updating;
using Avalonia.Threading;
@@ -69,7 +67,7 @@ public class UpdateService : IUpdateService
_channel.Value = "feature/gh-actions";
_channel.Save();
-
+
InstallQueuedUpdate();
}
@@ -79,30 +77,21 @@ public class UpdateService : IUpdateService
if (!_queuedActionRepository.IsTypeQueued("InstallUpdate"))
return;
+ // Remove the queued action, in case something goes wrong then at least we don't end up in a loop
_queuedActionRepository.ClearByType("InstallUpdate");
+
_logger.Information("Installing queued update");
Utilities.ApplyUpdate(false);
}
- private async Task ShowUpdateDialog(string nextReleaseId)
+ private async Task ShowUpdateNotification(IGetNextRelease_NextPublishedRelease release)
{
-
-
- await Dispatcher.UIThread.InvokeAsync(async () =>
- {
- // Main window is probably already open but this will bring it into focus
- _mainWindowService.OpenMainWindow();
- });
+ await _updateNotificationProvider.Value.ShowNotification(release.Id, release.Version);
}
- private async Task ShowUpdateNotification(string nextReleaseId)
+ private async Task AutoInstallUpdate(IGetNextRelease_NextPublishedRelease release)
{
- await _updateNotificationProvider.Value.ShowNotification(nextReleaseId);
- }
-
- private async Task AutoInstallUpdate(string nextReleaseId)
- {
- ReleaseInstaller installer = _getReleaseInstaller(nextReleaseId);
+ ReleaseInstaller installer = _getReleaseInstaller(release.Id);
await installer.InstallAsync(CancellationToken.None);
Utilities.ApplyUpdate(true);
}
@@ -121,7 +110,7 @@ public class UpdateService : IUpdateService
_logger.Warning(ex, "Auto update failed");
}
}
-
+
public IGetNextRelease_NextPublishedRelease? CachedLatestRelease { get; private set; }
public string? CurrentVersion
@@ -139,12 +128,12 @@ public class UpdateService : IUpdateService
IOperationResult result = await _updatingClient.GetNextRelease.ExecuteAsync(CurrentVersion, _channel.Value, _updatePlatform);
CachedLatestRelease = result.Data?.NextPublishedRelease;
}
-
+
public async Task CheckForUpdate()
{
IOperationResult result = await _updatingClient.GetNextRelease.ExecuteAsync(CurrentVersion, _channel.Value, _updatePlatform);
result.EnsureNoErrors();
-
+
// Update cache
CachedLatestRelease = result.Data?.NextPublishedRelease;
@@ -156,27 +145,14 @@ public class UpdateService : IUpdateService
_suspendAutoCheck = true;
// If the window is open show the changelog, don't auto-update while the user is busy
- if (_mainWindowService.IsMainWindowOpen)
- await ShowUpdateDialog(CachedLatestRelease.Id);
- else if (!_autoInstall.Value)
- await ShowUpdateNotification(CachedLatestRelease.Id);
+ if (!_autoInstall.Value)
+ await ShowUpdateNotification(CachedLatestRelease);
else
- await AutoInstallUpdate(CachedLatestRelease.Id);
+ await AutoInstallUpdate(CachedLatestRelease);
return true;
}
- ///
- public async Task InstallRelease(string releaseId)
- {
- ReleaseInstaller installer = _getReleaseInstaller(releaseId);
- await Dispatcher.UIThread.InvokeAsync(() =>
- {
- // Main window is probably already open but this will bring it into focus
- _mainWindowService.OpenMainWindow();
- });
- }
-
///
public void QueueUpdate()
{
@@ -184,9 +160,22 @@ public class UpdateService : IUpdateService
_queuedActionRepository.Add(new QueuedActionEntity {Type = "InstallUpdate"});
}
+ ///
+ public void DequeueUpdate()
+ {
+ _queuedActionRepository.ClearByType("InstallUpdate");
+ }
+
///
public ReleaseInstaller GetReleaseInstaller(string releaseId)
{
return _getReleaseInstaller(releaseId);
}
+
+ ///
+ public void RestartForUpdate(bool silent)
+ {
+ DequeueUpdate();
+ Utilities.ApplyUpdate(silent);
+ }
}
\ No newline at end of file