using System.ComponentModel; using System.Windows.Threading; using CommunityToolkit.Mvvm.ComponentModel; using Livia.Models.Data; using Livia.Properties; using Livia.Views.Utility; using Microsoft.Extensions.Logging; using Velopack; namespace Livia.Models; public interface IVersionUpdateManager : INotifyPropertyChanged, INotifyPropertyChanging { bool UpdateAvailable { get; } bool Updating { get; } string CurrentVersion { get; } public Task CheckForUpdate(bool showResult); public Task UpdateApp(); } internal class VersionUpdateManager : ObservableObject, IVersionUpdateManager { public bool UpdateAvailable { get => _updateAvailable; private set => SetProperty(ref _updateAvailable, value); } public bool Updating { get => _updating; private set => SetProperty(ref _updating, value); } public string CurrentVersion { get => _currentVersion; private set => SetProperty(ref _currentVersion, value); } private readonly ILogger _logger; private readonly IWarningSystem _warningSystem; private bool _updateAvailable; private bool _updating; private string _currentVersion = "Not Installed Version"; private readonly UpdateManager _updateManager; public VersionUpdateManager(ILogger logger, IWarningSystem warningSystem) { _logger = logger; _warningSystem = warningSystem; UpdateOptions updateOptions = new() { AllowVersionDowngrade = true, ExplicitChannel = $"win-{Settings.Default.UpdateChannel}" }; _updateManager = new UpdateManager(ServiceConfigurations.UpdateServerAddress, updateOptions); DispatcherTimer dispatcherTimer = new(); dispatcherTimer.Tick += Tick; dispatcherTimer.Interval = new TimeSpan(0, 30, 0); dispatcherTimer.Start(); //tick once on start Tick(null, null); } private void Tick(object? sender, EventArgs? e) { Task.Run(() => CheckForUpdate(false)); } public async Task CheckForUpdate(bool showResult) { if (!_updateManager.IsInstalled) { _logger.LogInformation("Not installed version"); return; } if (!Settings.Default.ShowUpdateButton) { return; } CurrentVersion = _updateManager.CurrentVersion?.ToFullString() ?? CurrentVersion; _logger.LogInformation("Checking for update"); //wait for 30s TimeSpan waitTime = TimeSpan.FromSeconds(30); try { UpdateInfo? updateInfo = await _updateManager.CheckForUpdatesAsync().WaitAsync(waitTime); if (updateInfo == null) { if (showResult) _warningSystem.ShowDialog(WarningWindowKind.Info, false, "NoNewVersionInfoMessage"); } else { _logger.LogInformation("New Version Found: {version}", updateInfo.TargetFullRelease); //NewVersion = updateInfo.FutureReleaseEntry.Version.ToString(); UpdateAvailable = true; } } catch (Exception e) { _logger.LogError(e, "Error Checking for update"); if (showResult) _warningSystem.ShowDialog(WarningWindowKind.Info, false, "CannotGetUpdateInfoMessage"); } } public async Task UpdateApp() { Updating = true; _logger.LogInformation("Updating app"); //wait for 10 min TimeSpan waitTime = TimeSpan.FromMinutes(10); try { UpdateInfo? updateInfo = await _updateManager.CheckForUpdatesAsync().WaitAsync(waitTime); if (updateInfo == null) { _logger.LogError("updateInfo is null"); return; } // install new version and restart app await _updateManager.DownloadUpdatesAsync(updateInfo); Settings.Default.ApplicationQuitNormally = true; Settings.Default.Save(); _updateManager.ApplyUpdatesAndRestart(updateInfo); } catch (Exception e) { _logger.LogError(e, "Error Updating app"); _warningSystem.ShowDialog(WarningWindowKind.Info, false, "CannotGetUpdateInfoMessage"); } finally { Updating = false; } } }