finish auto update feature
This commit is contained in:
parent
e70e30ff57
commit
f135a3e325
@ -169,6 +169,28 @@
|
|||||||
</Style>
|
</Style>
|
||||||
|
|
||||||
<!-- Button outlined Style -->
|
<!-- Button outlined Style -->
|
||||||
|
<Style Selector="Button.outlined">
|
||||||
|
<Setter Property="Foreground" Value="{StaticResource AKI_Brush_Lighter}"/>
|
||||||
|
<Setter Property="Background" Value="Transparent"/>
|
||||||
|
<Setter Property="BorderBrush" Value="{StaticResource AKI_Brush_DarkGrayBlue}"/>
|
||||||
|
<Setter Property="BorderThickness" Value="2"/>
|
||||||
|
</Style>
|
||||||
|
|
||||||
|
<Style Selector="Button.outlined:pointerover /template/ ContentPresenter">
|
||||||
|
<Setter Property="TextBlock.Foreground" Value="{StaticResource AKI_Brush_Yellow}"/>
|
||||||
|
<Setter Property="Background" Value="Transparent"/>
|
||||||
|
<Setter Property="BorderBrush" Value="{StaticResource AKI_Brush_Yellow}"/>
|
||||||
|
<Setter Property="BorderThickness" Value="2"/>
|
||||||
|
</Style>
|
||||||
|
|
||||||
|
<Style Selector="Button.outlined:pressed /template/ ContentPresenter">
|
||||||
|
<Setter Property="TextBlock.Foreground" Value="{StaticResource AKI_Brush_DarkGrayBlue}"/>
|
||||||
|
<Setter Property="Background" Value="Transparent"/>
|
||||||
|
<Setter Property="BorderBrush" Value="Transparent"/>
|
||||||
|
<Setter Property="BorderThickness" Value="0"/>
|
||||||
|
</Style>
|
||||||
|
|
||||||
|
<!-- Button outlinedTLCorner Style -->
|
||||||
<Style Selector="Button.outlinedTLCorner">
|
<Style Selector="Button.outlinedTLCorner">
|
||||||
<Setter Property="Foreground" Value="{StaticResource AKI_Brush_Lighter}"/>
|
<Setter Property="Foreground" Value="{StaticResource AKI_Brush_Lighter}"/>
|
||||||
<Setter Property="Background" Value="Transparent"/>
|
<Setter Property="Background" Value="Transparent"/>
|
||||||
@ -180,7 +202,7 @@
|
|||||||
<Setter Property="TextBlock.Foreground" Value="{StaticResource AKI_Brush_Yellow}"/>
|
<Setter Property="TextBlock.Foreground" Value="{StaticResource AKI_Brush_Yellow}"/>
|
||||||
<Setter Property="Background" Value="Transparent"/>
|
<Setter Property="Background" Value="Transparent"/>
|
||||||
<Setter Property="BorderBrush" Value="{StaticResource AKI_Brush_Yellow}"/>
|
<Setter Property="BorderBrush" Value="{StaticResource AKI_Brush_Yellow}"/>
|
||||||
<Setter Property="BorderThickness" Value="1 1 0 0"/>
|
<Setter Property="BorderThickness" Value="2 2 0 0"/>
|
||||||
</Style>
|
</Style>
|
||||||
|
|
||||||
<Style Selector="Button.outlinedTLCorner:pressed /template/ ContentPresenter">
|
<Style Selector="Button.outlinedTLCorner:pressed /template/ ContentPresenter">
|
||||||
|
53
SPTInstaller/CustomControls/UpdateInfoCard.axaml
Normal file
53
SPTInstaller/CustomControls/UpdateInfoCard.axaml
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
<UserControl xmlns="https://github.com/avaloniaui"
|
||||||
|
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"
|
||||||
|
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
|
||||||
|
x:Class="SPTInstaller.CustomControls.UpdateInfoCard"
|
||||||
|
MinHeight="100" MinWidth="300">
|
||||||
|
|
||||||
|
<UserControl.Styles>
|
||||||
|
<Style Selector="Grid">
|
||||||
|
<Setter Property="Opacity" Value="0"/>
|
||||||
|
<Setter Property="Transitions">
|
||||||
|
<Setter.Value>
|
||||||
|
<Transitions>
|
||||||
|
<DoubleTransition Property="Opacity" Duration="0:0:0.2"/>
|
||||||
|
</Transitions>
|
||||||
|
</Setter.Value>
|
||||||
|
</Setter>
|
||||||
|
</Style>
|
||||||
|
<Style Selector="Grid.show">
|
||||||
|
<Setter Property="Opacity" Value="1"/>
|
||||||
|
</Style>
|
||||||
|
</UserControl.Styles>
|
||||||
|
|
||||||
|
<Grid ColumnDefinitions="10,*,AUTO,AUTO,10" RowDefinitions="10,AUTO,AUTO,10"
|
||||||
|
Classes.show="{Binding ShowUpdateCard, RelativeSource={RelativeSource AncestorType=UserControl}}">
|
||||||
|
<Border Grid.ColumnSpan="5" Grid.RowSpan="4" Background="{StaticResource AKI_Background_Light}"
|
||||||
|
BoxShadow="2 2 10 .1 black" CornerRadius="8"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<TextBlock Grid.Row="1" Grid.Column="1" Grid.ColumnSpan="3" MaxWidth="400"
|
||||||
|
Text="{Binding InfoText, RelativeSource={RelativeSource AncestorType=UserControl}}"
|
||||||
|
TextWrapping="Wrap" Margin="0 10"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<Button Grid.Column="2" Grid.Row="2" Content="Not now"
|
||||||
|
Classes="outlined"
|
||||||
|
IsVisible="{Binding !Updating, RelativeSource={RelativeSource AncestorType=UserControl}}"
|
||||||
|
Command="{Binding NotNowCommand, RelativeSource={RelativeSource AncestorType=UserControl}}"
|
||||||
|
/>
|
||||||
|
<Button Grid.Column="3" Grid.Row="2" Content="Update"
|
||||||
|
Classes="yellow" Margin="10 0 0 0"
|
||||||
|
IsVisible="{Binding !Updating, RelativeSource={RelativeSource AncestorType=UserControl}}"
|
||||||
|
Command="{Binding UpdateInstallerCommand, RelativeSource={RelativeSource AncestorType=UserControl}}"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<ProgressBar Grid.Row="4" Grid.Column="1" Grid.ColumnSpan="3"
|
||||||
|
Value="{Binding DownloadProgress, RelativeSource={RelativeSource AncestorType=UserControl}}"
|
||||||
|
IsVisible="{Binding Updating, RelativeSource={RelativeSource AncestorType=UserControl}}"
|
||||||
|
/>
|
||||||
|
|
||||||
|
</Grid>
|
||||||
|
</UserControl>
|
60
SPTInstaller/CustomControls/UpdateInfoCard.axaml.cs
Normal file
60
SPTInstaller/CustomControls/UpdateInfoCard.axaml.cs
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
using Avalonia;
|
||||||
|
using Avalonia.Controls;
|
||||||
|
using System.Windows.Input;
|
||||||
|
|
||||||
|
namespace SPTInstaller.CustomControls;
|
||||||
|
public partial class UpdateInfoCard : UserControl
|
||||||
|
{
|
||||||
|
public UpdateInfoCard()
|
||||||
|
{
|
||||||
|
InitializeComponent();
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool ShowUpdateCard
|
||||||
|
{
|
||||||
|
get => GetValue(ShowUpdateCardProperty);
|
||||||
|
set => SetValue(ShowUpdateCardProperty, value);
|
||||||
|
}
|
||||||
|
public static readonly StyledProperty<bool> ShowUpdateCardProperty =
|
||||||
|
AvaloniaProperty.Register<UpdateInfoCard, bool>(nameof(ShowUpdateCard));
|
||||||
|
|
||||||
|
public bool Updating
|
||||||
|
{
|
||||||
|
get => GetValue(UpdatingProperty);
|
||||||
|
set => SetValue(UpdatingProperty, value);
|
||||||
|
}
|
||||||
|
public static readonly StyledProperty<bool> UpdatingProperty =
|
||||||
|
AvaloniaProperty.Register<UpdateInfoCard, bool>(nameof(Updating));
|
||||||
|
|
||||||
|
public string InfoText
|
||||||
|
{
|
||||||
|
get => GetValue(InfoTextProperty);
|
||||||
|
set => SetValue(InfoTextProperty, value);
|
||||||
|
}
|
||||||
|
public static readonly StyledProperty<string> InfoTextProperty =
|
||||||
|
AvaloniaProperty.Register<UpdateInfoCard, string>(nameof(InfoText));
|
||||||
|
|
||||||
|
public int DownloadProgress
|
||||||
|
{
|
||||||
|
get => GetValue(DownloadProgressProperty);
|
||||||
|
set => SetValue(DownloadProgressProperty, value);
|
||||||
|
}
|
||||||
|
public static readonly StyledProperty<int> DownloadProgressProperty =
|
||||||
|
AvaloniaProperty.Register<UpdateInfoCard, int>(nameof(DownloadProgress));
|
||||||
|
|
||||||
|
public ICommand NotNowCommand
|
||||||
|
{
|
||||||
|
get => GetValue(NotNowCommandProperty);
|
||||||
|
set => SetValue(NotNowCommandProperty, value);
|
||||||
|
}
|
||||||
|
public static readonly StyledProperty<ICommand> NotNowCommandProperty =
|
||||||
|
AvaloniaProperty.Register<UpdateInfoCard, ICommand>(nameof(NotNowCommand));
|
||||||
|
|
||||||
|
public ICommand UpdateInstallerCommand
|
||||||
|
{
|
||||||
|
get => GetValue(UpdateInstallerCommandProperty);
|
||||||
|
set => SetValue(UpdateInstallerCommandProperty, value);
|
||||||
|
}
|
||||||
|
public static readonly StyledProperty<ICommand> UpdateInstallerCommandProperty =
|
||||||
|
AvaloniaProperty.Register<UpdateInfoCard, ICommand>(nameof(UpdateInstallerCommand));
|
||||||
|
}
|
@ -9,14 +9,14 @@ public static class DownloadCacheHelper
|
|||||||
{
|
{
|
||||||
private static HttpClient _httpClient = new() { Timeout = TimeSpan.FromHours(1) };
|
private static HttpClient _httpClient = new() { Timeout = TimeSpan.FromHours(1) };
|
||||||
|
|
||||||
private static string _cachePath = Path.Join(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "spt-installer/cache");
|
public static string CachePath = Path.Join(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "spt-installer/cache");
|
||||||
|
|
||||||
private static bool CheckCache(FileInfo cacheFile, string expectedHash = null)
|
private static bool CheckCache(FileInfo cacheFile, string expectedHash = null)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
cacheFile.Refresh();
|
cacheFile.Refresh();
|
||||||
Directory.CreateDirectory(_cachePath);
|
Directory.CreateDirectory(CachePath);
|
||||||
|
|
||||||
if (cacheFile.Exists)
|
if (cacheFile.Exists)
|
||||||
{
|
{
|
||||||
@ -108,7 +108,7 @@ public static class DownloadCacheHelper
|
|||||||
|
|
||||||
public static async Task<FileInfo?> GetOrDownloadFileAsync(string fileName, string targetLink, IProgress<double> progress, string expectedHash = null)
|
public static async Task<FileInfo?> GetOrDownloadFileAsync(string fileName, string targetLink, IProgress<double> progress, string expectedHash = null)
|
||||||
{
|
{
|
||||||
var cacheFile = new FileInfo(Path.Join(_cachePath, fileName));
|
var cacheFile = new FileInfo(Path.Join(CachePath, fileName));
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@ -125,7 +125,7 @@ public static class DownloadCacheHelper
|
|||||||
|
|
||||||
public static async Task<FileInfo?> GetOrDownloadFileAsync(string fileName, Stream fileDownloadStream, string expectedHash = null)
|
public static async Task<FileInfo?> GetOrDownloadFileAsync(string fileName, Stream fileDownloadStream, string expectedHash = null)
|
||||||
{
|
{
|
||||||
var cacheFile = new FileInfo(Path.Join(_cachePath, fileName));
|
var cacheFile = new FileInfo(Path.Join(CachePath, fileName));
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
@ -1,4 +1,6 @@
|
|||||||
using System.Text.RegularExpressions;
|
using System.Linq;
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Text.RegularExpressions;
|
||||||
using Serilog;
|
using Serilog;
|
||||||
using SPTInstaller.Models;
|
using SPTInstaller.Models;
|
||||||
|
|
||||||
@ -83,4 +85,30 @@ public static class FileHelper
|
|||||||
return Result.FromError(ex.Message);
|
return Result.FromError(ex.Message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void StreamAssemblyResourceOut(string resourceName, string outputFilePath)
|
||||||
|
{
|
||||||
|
var assembly = Assembly.GetExecutingAssembly();
|
||||||
|
|
||||||
|
FileInfo outputFile = new FileInfo(outputFilePath);
|
||||||
|
|
||||||
|
if (outputFile.Exists)
|
||||||
|
{
|
||||||
|
outputFile.Delete();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!outputFile.Directory.Exists)
|
||||||
|
{
|
||||||
|
Directory.CreateDirectory(outputFile.Directory.FullName);
|
||||||
|
}
|
||||||
|
|
||||||
|
var resName = assembly.GetManifestResourceNames().First(x => x.EndsWith(resourceName));
|
||||||
|
|
||||||
|
using (FileStream fs = File.Create(outputFilePath))
|
||||||
|
using (Stream s = assembly.GetManifestResourceStream(resName))
|
||||||
|
{
|
||||||
|
s.CopyTo(fs);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -2,12 +2,24 @@
|
|||||||
using Gitea.Client;
|
using Gitea.Client;
|
||||||
using ReactiveUI;
|
using ReactiveUI;
|
||||||
using Serilog;
|
using Serilog;
|
||||||
|
using SPTInstaller.Helpers;
|
||||||
|
using System.Diagnostics;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using System.Windows.Input;
|
|
||||||
|
|
||||||
namespace SPTInstaller.Models;
|
namespace SPTInstaller.Models;
|
||||||
public class InstallerUpdateInfo : ReactiveObject
|
public class InstallerUpdateInfo : ReactiveObject
|
||||||
{
|
{
|
||||||
|
private Version? _newVersion;
|
||||||
|
|
||||||
|
public string NewInstallerUrl = "";
|
||||||
|
|
||||||
|
private string _updateInfoText = "";
|
||||||
|
public string UpdateInfoText
|
||||||
|
{
|
||||||
|
get => _updateInfoText;
|
||||||
|
set => this.RaiseAndSetIfChanged(ref _updateInfoText, value);
|
||||||
|
}
|
||||||
|
|
||||||
private bool _updateAvailable;
|
private bool _updateAvailable;
|
||||||
public bool UpdateAvailable
|
public bool UpdateAvailable
|
||||||
{
|
{
|
||||||
@ -15,31 +27,67 @@ public class InstallerUpdateInfo : ReactiveObject
|
|||||||
set => this.RaiseAndSetIfChanged(ref _updateAvailable, value);
|
set => this.RaiseAndSetIfChanged(ref _updateAvailable, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
private Version _currentVersion;
|
private bool _updating;
|
||||||
public Version CurrentVersion
|
public bool Updating
|
||||||
{
|
{
|
||||||
get => _currentVersion;
|
get => _updating;
|
||||||
set => this.RaiseAndSetIfChanged(ref _currentVersion, value);
|
set => this.RaiseAndSetIfChanged(ref _updating, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
private Version _newVersion;
|
private int _downloadProgress;
|
||||||
public Version NewVersion
|
public int DownloadProgress
|
||||||
{
|
{
|
||||||
get => _newVersion;
|
get => _downloadProgress;
|
||||||
set => this.RaiseAndSetIfChanged(ref _newVersion, value);
|
set => this.RaiseAndSetIfChanged(ref _downloadProgress, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async Task UpdateInstaller()
|
||||||
private bool _checkingForUpdates;
|
|
||||||
public bool CheckingForUpdates
|
|
||||||
{
|
{
|
||||||
get => _checkingForUpdates;
|
Updating = true;
|
||||||
set => this.RaiseAndSetIfChanged(ref _checkingForUpdates, value);
|
|
||||||
|
var updater = new FileInfo(Path.Join(DownloadCacheHelper.CachePath, "update.ps1"));
|
||||||
|
FileHelper.StreamAssemblyResourceOut("update.ps1", updater.FullName);
|
||||||
|
|
||||||
|
|
||||||
|
if (!updater.Exists)
|
||||||
|
{
|
||||||
|
UpdateInfoText = "Failed to get updater from resources :(";
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<bool> CheckForUpdates()
|
var newInstallerPath = await DownloadNewInstaller();
|
||||||
|
|
||||||
|
if(string.IsNullOrWhiteSpace(newInstallerPath))
|
||||||
|
return;
|
||||||
|
|
||||||
|
Process.Start(new ProcessStartInfo
|
||||||
{
|
{
|
||||||
CheckingForUpdates = true;
|
FileName = "powershell.exe",
|
||||||
|
ArgumentList = { "-ExecutionPolicy", "Bypass", "-File", $"{updater.FullName}", $"{newInstallerPath}", $"{Path.Join(Environment.CurrentDirectory, "SPTInstaller.exe")}" }
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task<string> DownloadNewInstaller()
|
||||||
|
{
|
||||||
|
UpdateInfoText = $"Downloading new installer v{_newVersion}";
|
||||||
|
|
||||||
|
var progress = new Progress<double>(x => DownloadProgress = (int)x);
|
||||||
|
|
||||||
|
var file = await DownloadCacheHelper.GetOrDownloadFileAsync("SPTInstller.exe", NewInstallerUrl, progress);
|
||||||
|
|
||||||
|
if (file == null || !file.Exists)
|
||||||
|
{
|
||||||
|
UpdateInfoText = "Failed to download new installer :(";
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
return file.FullName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task CheckForUpdates(Version? currentVersion)
|
||||||
|
{
|
||||||
|
if (currentVersion == null)
|
||||||
|
return;
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@ -48,45 +96,33 @@ public class InstallerUpdateInfo : ReactiveObject
|
|||||||
var releases = await repo.RepoListReleasesAsync("CWX", "SPT-AKI-Installer");
|
var releases = await repo.RepoListReleasesAsync("CWX", "SPT-AKI-Installer");
|
||||||
|
|
||||||
if (releases == null || releases.Count == 0)
|
if (releases == null || releases.Count == 0)
|
||||||
return false;
|
return;
|
||||||
|
|
||||||
var latest = releases.FindAll(x => !x.Prerelease)[0];
|
var latest = releases.FindAll(x => !x.Prerelease)[0];
|
||||||
|
|
||||||
if (latest == null)
|
if (latest == null)
|
||||||
return false;
|
return;
|
||||||
|
|
||||||
var latestVersion = new Version(latest.TagName);
|
var latestVersion = new Version(latest.TagName);
|
||||||
|
|
||||||
if (latestVersion == null || latestVersion <= CurrentVersion)
|
if (latestVersion == null || latestVersion <= currentVersion)
|
||||||
return false;
|
return;
|
||||||
|
|
||||||
NewVersion = latestVersion;
|
|
||||||
UpdateAvailable = true;
|
UpdateAvailable = true;
|
||||||
CheckingForUpdates = false;
|
|
||||||
|
|
||||||
return true;
|
_newVersion = latestVersion;
|
||||||
|
|
||||||
|
UpdateInfoText = $"A newer installer is available, version {latestVersion}";
|
||||||
|
|
||||||
|
NewInstallerUrl = latest.Assets[0].BrowserDownloadUrl;
|
||||||
|
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Log.Logger.Error(ex, "Failed to check for updates");
|
Log.Logger.Error(ex, "Failed to check for updates");
|
||||||
}
|
}
|
||||||
|
|
||||||
CheckingForUpdates = false;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ICommand UpdateInstaller { get; set; }
|
|
||||||
|
|
||||||
public InstallerUpdateInfo(Version? currentVersion)
|
|
||||||
{
|
|
||||||
if (currentVersion == null)
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
CurrentVersion = currentVersion;
|
|
||||||
|
|
||||||
UpdateInstaller = ReactiveCommand.Create(() =>
|
|
||||||
{
|
|
||||||
// TODO: update installer here
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
27
SPTInstaller/Resources/update.ps1
Normal file
27
SPTInstaller/Resources/update.ps1
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
param(
|
||||||
|
[string]$source,
|
||||||
|
[string]$destination
|
||||||
|
)
|
||||||
|
|
||||||
|
clear
|
||||||
|
|
||||||
|
Write-Host "Stopping installer ..."
|
||||||
|
|
||||||
|
$installer = Stop-Process -Name "SPTInstaller" -ErrorAction SilentlyContinue
|
||||||
|
|
||||||
|
if ($installer -ne $null) {
|
||||||
|
Write-Host "Something went wrong, couldn't stop installer process'"
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Write-Host "Copying new installer ..."
|
||||||
|
|
||||||
|
Import-Module BitsTransfer
|
||||||
|
|
||||||
|
Start-BitsTransfer -Source $source -Destination $destination -DisplayName "Updating" -Description "Copying new installer"
|
||||||
|
|
||||||
|
Remove-Module -Name BitsTransfer
|
||||||
|
|
||||||
|
Start-Process $destination
|
||||||
|
|
||||||
|
Write-Host "Done"
|
@ -17,6 +17,11 @@
|
|||||||
<AvaloniaResource Include="Assets\**" />
|
<AvaloniaResource Include="Assets\**" />
|
||||||
<None Remove=".gitignore" />
|
<None Remove=".gitignore" />
|
||||||
<None Remove="Assets\icon.ico" />
|
<None Remove="Assets\icon.ico" />
|
||||||
|
<None Remove="Resources\update.ps1" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<EmbeddedResource Include="Resources\update.ps1" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
namespace SPTInstaller.ViewModels;
|
namespace SPTInstaller.ViewModels;
|
||||||
public class DetailedPreChecksViewModel : PreChecksViewModel
|
public class DetailedPreChecksViewModel : PreChecksViewModel
|
||||||
{
|
{
|
||||||
public DetailedPreChecksViewModel(IScreen host) : base(host)
|
public DetailedPreChecksViewModel(IScreen host) : base(host, null)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -12,6 +12,7 @@ public class MainWindowViewModel : ReactiveObject, IActivatableViewModel, IScree
|
|||||||
{
|
{
|
||||||
public RoutingState Router { get; } = new();
|
public RoutingState Router { get; } = new();
|
||||||
public ViewModelActivator Activator { get; } = new();
|
public ViewModelActivator Activator { get; } = new();
|
||||||
|
public InstallerUpdateInfo UpdateInfo { get; } = new();
|
||||||
|
|
||||||
private string _title;
|
private string _title;
|
||||||
public string Title
|
public string Title
|
||||||
@ -31,14 +32,12 @@ public class MainWindowViewModel : ReactiveObject, IActivatableViewModel, IScree
|
|||||||
Log.Information($"========= {Title} Started =========");
|
Log.Information($"========= {Title} Started =========");
|
||||||
Log.Information(Environment.OSVersion.VersionString);
|
Log.Information(Environment.OSVersion.VersionString);
|
||||||
|
|
||||||
var updateInfo = new InstallerUpdateInfo(version);
|
|
||||||
|
|
||||||
Task.Run(async () =>
|
Task.Run(async () =>
|
||||||
{
|
{
|
||||||
await updateInfo.CheckForUpdates();
|
await UpdateInfo.CheckForUpdates(version);
|
||||||
});
|
});
|
||||||
|
|
||||||
Router.Navigate.Execute(new PreChecksViewModel(this));
|
Router.Navigate.Execute(new PreChecksViewModel(this, DismissUpdateCommand));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void CloseCommand()
|
public void CloseCommand()
|
||||||
@ -57,4 +56,14 @@ public class MainWindowViewModel : ReactiveObject, IActivatableViewModel, IScree
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void DismissUpdateCommand()
|
||||||
|
{
|
||||||
|
UpdateInfo.UpdateAvailable = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task UpdateInstallerCommand()
|
||||||
|
{
|
||||||
|
Router.Navigate.Execute(new MessageViewModel(this, Result.FromSuccess("Please wait while the update is installed"), false));
|
||||||
|
await UpdateInfo.UpdateInstaller();
|
||||||
|
}
|
||||||
}
|
}
|
@ -22,6 +22,13 @@ public class MessageViewModel : ViewModelBase
|
|||||||
set => this.RaiseAndSetIfChanged(ref _Message, value);
|
set => this.RaiseAndSetIfChanged(ref _Message, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private bool _showCloseButton;
|
||||||
|
public bool ShowCloseButton
|
||||||
|
{
|
||||||
|
get => _showCloseButton;
|
||||||
|
set => this.RaiseAndSetIfChanged(ref _showCloseButton, value);
|
||||||
|
}
|
||||||
|
|
||||||
public ICommand CloseCommand { get; set; } = ReactiveCommand.Create(() =>
|
public ICommand CloseCommand { get; set; } = ReactiveCommand.Create(() =>
|
||||||
{
|
{
|
||||||
if (Application.Current.ApplicationLifetime is Avalonia.Controls.ApplicationLifetimes.IClassicDesktopStyleApplicationLifetime desktopApp)
|
if (Application.Current.ApplicationLifetime is Avalonia.Controls.ApplicationLifetimes.IClassicDesktopStyleApplicationLifetime desktopApp)
|
||||||
@ -30,8 +37,9 @@ public class MessageViewModel : ViewModelBase
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
public MessageViewModel(IScreen Host, IResult result) : base(Host)
|
public MessageViewModel(IScreen Host, IResult result, bool showCloseButton = true) : base(Host)
|
||||||
{
|
{
|
||||||
|
ShowCloseButton = showCloseButton;
|
||||||
Message = result.Message;
|
Message = result.Message;
|
||||||
|
|
||||||
if(result.Succeeded)
|
if(result.Succeeded)
|
||||||
|
@ -30,7 +30,7 @@ public class PreChecksViewModel : ViewModelBase
|
|||||||
set => this.RaiseAndSetIfChanged(ref _allowInstall, value);
|
set => this.RaiseAndSetIfChanged(ref _allowInstall, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
public PreChecksViewModel(IScreen host) : base(host)
|
public PreChecksViewModel(IScreen host, Action? dismissUpdateCard) : base(host)
|
||||||
{
|
{
|
||||||
var data = ServiceHelper.Get<InternalData?>();
|
var data = ServiceHelper.Get<InternalData?>();
|
||||||
var installer = ServiceHelper.Get<InstallController?>();
|
var installer = ServiceHelper.Get<InstallController?>();
|
||||||
@ -51,9 +51,15 @@ public class PreChecksViewModel : ViewModelBase
|
|||||||
data.TargetInstallPath = Environment.CurrentDirectory;
|
data.TargetInstallPath = Environment.CurrentDirectory;
|
||||||
InstallPath = data.TargetInstallPath;
|
InstallPath = data.TargetInstallPath;
|
||||||
|
|
||||||
StartInstallCommand = ReactiveCommand.Create(() => NavigateTo(new InstallViewModel(HostScreen)));
|
StartInstallCommand = ReactiveCommand.Create(() =>
|
||||||
|
{
|
||||||
|
dismissUpdateCard?.Invoke();
|
||||||
|
NavigateTo(new InstallViewModel(HostScreen));
|
||||||
|
});
|
||||||
|
|
||||||
ShowDetailedViewCommand = ReactiveCommand.Create(() =>
|
ShowDetailedViewCommand = ReactiveCommand.Create(() =>
|
||||||
{
|
{
|
||||||
|
dismissUpdateCard?.Invoke();
|
||||||
Log.Logger.Information("Opening Detailed PreCheck View");
|
Log.Logger.Information("Opening Detailed PreCheck View");
|
||||||
NavigateTo(new DetailedPreChecksViewModel(HostScreen));
|
NavigateTo(new DetailedPreChecksViewModel(HostScreen));
|
||||||
});
|
});
|
||||||
|
@ -33,5 +33,15 @@
|
|||||||
/>
|
/>
|
||||||
|
|
||||||
<rxui:RoutedViewHost Router="{Binding Router}" Grid.Row="1"/>
|
<rxui:RoutedViewHost Router="{Binding Router}" Grid.Row="1"/>
|
||||||
|
|
||||||
|
<cc:UpdateInfoCard Grid.Row="1" Padding="10"
|
||||||
|
VerticalAlignment="Top" HorizontalAlignment="Left"
|
||||||
|
InfoText="{Binding UpdateInfo.UpdateInfoText}"
|
||||||
|
ShowUpdateCard="{Binding UpdateInfo.UpdateAvailable}"
|
||||||
|
NotNowCommand="{Binding DismissUpdateCommand}"
|
||||||
|
UpdateInstallerCommand="{Binding UpdateInstallerCommand}"
|
||||||
|
Updating="{Binding UpdateInfo.Updating}"
|
||||||
|
DownloadProgress="{Binding UpdateInfo.DownloadProgress}"
|
||||||
|
/>
|
||||||
</Grid>
|
</Grid>
|
||||||
</Window>
|
</Window>
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
<UserControl xmlns="https://github.com/avaloniaui"
|
<UserControl xmlns="https://github.com/avaloniaui"
|
||||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
@ -31,6 +31,7 @@
|
|||||||
Content="Close" Command="{Binding CloseCommand}"
|
Content="Close" Command="{Binding CloseCommand}"
|
||||||
FontSize="15" FontWeight="SemiBold"
|
FontSize="15" FontWeight="SemiBold"
|
||||||
Classes.yellow="{Binding !HasErrors}"
|
Classes.yellow="{Binding !HasErrors}"
|
||||||
|
IsVisible="{Binding ShowCloseButton}"
|
||||||
HorizontalAlignment="Center"
|
HorizontalAlignment="Center"
|
||||||
VerticalContentAlignment="Center" HorizontalContentAlignment="Center"
|
VerticalContentAlignment="Center" HorizontalContentAlignment="Center"
|
||||||
Padding="20 10"
|
Padding="20 10"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user