add update page

This commit is contained in:
IsWaffle 2024-06-29 11:05:35 -04:00
parent 1dc4202353
commit bb8b05a2d4
14 changed files with 77 additions and 120 deletions

View File

@ -1,23 +0,0 @@
<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"
xmlns:dialogHost="clr-namespace:DialogHostAvalonia;assembly=DialogHost.Avalonia"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
x:Class="SPTInstaller.CustomControls.Dialogs.ChangeLogDialog"
MinWidth="400" MaxWidth="600">
<StackPanel>
<Label Content="{Binding Version, RelativeSource={RelativeSource AncestorType=UserControl}, StringFormat='{}Installer Change Log for {0}'}" FontSize="18" FontWeight="SemiBold"
/>
<Separator Margin="0 10" Padding="0" Background="{StaticResource SPT_Yellow}"/>
<ScrollViewer MaxHeight="250">
<TextBlock Text="{Binding Message, RelativeSource={RelativeSource AncestorType=UserControl}}"
TextWrapping="Wrap" MinHeight="100"
/>
</ScrollViewer>
<Button Content="Close" Classes="yellow"
HorizontalAlignment="Right"
Command="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=dialogHost:DialogHost}, Path=CloseDialogCommand}"
/>
</StackPanel>
</UserControl>

View File

@ -1,27 +0,0 @@
using Avalonia;
using Avalonia.Controls;
using Avalonia.Markup.Xaml;
using Tmds.DBus.Protocol;
namespace SPTInstaller.CustomControls.Dialogs;
public partial class ChangeLogDialog : UserControl
{
public string Message { get; set; }
public string Version { get; set; }
public ChangeLogDialog(string newVersion, string message)
{
InitializeComponent();
Message = message;
Version = newVersion;
}
// public static readonly StyledProperty<string> MessageProperty =
// AvaloniaProperty.Register<ChangeLogDialog, string>("Message");
//
// public string Message
// {
// get => GetValue(MessageProperty);
// set => SetValue(MessageProperty, value);
// }
}

View File

@ -26,8 +26,6 @@
<Button Content="Not now" CornerRadius="0 20 20 0" <Button Content="Not now" CornerRadius="0 20 20 0"
Command="{Binding DismissCommand, RelativeSource={RelativeSource AncestorType=UserControl}}" /> Command="{Binding DismissCommand, RelativeSource={RelativeSource AncestorType=UserControl}}" />
</StackPanel> </StackPanel>
<Button HorizontalAlignment="Center" Content="What's new?" Classes="link"
Command="{Binding WhatsNewCommand, RelativeSource={RelativeSource AncestorType=UserControl}}"/>
</StackPanel> </StackPanel>
<Panel Margin="0 10"> <Panel Margin="0 10">

View File

@ -50,15 +50,6 @@ public partial class UpdateButton : UserControl
set => SetValue(UpdateCommandProperty, value); set => SetValue(UpdateCommandProperty, value);
} }
public static readonly StyledProperty<ICommand> WhatsNewCommandProperty =
AvaloniaProperty.Register<UpdateButton, ICommand>("WhatsNewCommand");
public ICommand WhatsNewCommand
{
get => GetValue(WhatsNewCommandProperty);
set => SetValue(WhatsNewCommandProperty, value);
}
public static readonly StyledProperty<bool> UpdatingProperty = AvaloniaProperty.Register<UpdateButton, bool>( public static readonly StyledProperty<bool> UpdatingProperty = AvaloniaProperty.Register<UpdateButton, bool>(
"Updating"); "Updating");

View File

@ -142,6 +142,8 @@ public static class FileHelper
/// <returns>Returns true if the path is bad, otherwise false</returns> /// <returns>Returns true if the path is bad, otherwise false</returns>
public static bool CheckPathForProblemLocations(string path, out PathCheck failedCheck) public static bool CheckPathForProblemLocations(string path, out PathCheck failedCheck)
{ {
path = Path.TrimEndingDirectorySeparator(path);
failedCheck = new(); failedCheck = new();
var problemPaths = new List<PathCheck>() var problemPaths = new List<PathCheck>()

View File

@ -11,7 +11,7 @@ public class InstallerUpdateInfo : ReactiveObject
{ {
public Version? NewVersion { get; private set; } public Version? NewVersion { get; private set; }
public string ChangeLog = ""; public string ChangeLog { get; private set; }= "";
private string _updateInfoText = ""; private string _updateInfoText = "";
@ -21,14 +21,6 @@ public class InstallerUpdateInfo : ReactiveObject
set => this.RaiseAndSetIfChanged(ref _updateInfoText, value); set => this.RaiseAndSetIfChanged(ref _updateInfoText, value);
} }
private bool _show = false;
public bool Show
{
get => _show;
set => this.RaiseAndSetIfChanged(ref _show, value);
}
private bool _updating = false; private bool _updating = false;
public bool Updating public bool Updating
@ -123,7 +115,6 @@ public class InstallerUpdateInfo : ReactiveObject
} }
UpdateInfoText = infoText; UpdateInfoText = infoText;
Show = updateAvailable;
CheckingForUpdates = false; CheckingForUpdates = false;
UpdateAvailable = updateAvailable; UpdateAvailable = updateAvailable;
} }
@ -134,7 +125,6 @@ public class InstallerUpdateInfo : ReactiveObject
return; return;
UpdateInfoText = "Checking for installer updates"; UpdateInfoText = "Checking for installer updates";
Show = true;
CheckingForUpdates = true; CheckingForUpdates = true;
try try

View File

@ -10,8 +10,8 @@
<PackageIcon>icon.ico</PackageIcon> <PackageIcon>icon.ico</PackageIcon>
<ApplicationIcon>Assets\spt_installer.ico</ApplicationIcon> <ApplicationIcon>Assets\spt_installer.ico</ApplicationIcon>
<Configurations>Debug;Release;TEST</Configurations> <Configurations>Debug;Release;TEST</Configurations>
<AssemblyVersion>2.71</AssemblyVersion> <AssemblyVersion>2.80</AssemblyVersion>
<FileVersion>2.71</FileVersion> <FileVersion>2.80</FileVersion>
<Company>SPT</Company> <Company>SPT</Company>
</PropertyGroup> </PropertyGroup>

View File

@ -1,4 +1,5 @@
using System.Linq; using System.Linq;
using System.Text.RegularExpressions;
using System.Threading.Tasks; using System.Threading.Tasks;
using Avalonia; using Avalonia;
using Avalonia.Controls.ApplicationLifetimes; using Avalonia.Controls.ApplicationLifetimes;
@ -81,11 +82,19 @@ public class InstallPathSelectionViewModel : ViewModelBase
return; return;
} }
var match = Regex.Match(SelectedPath[2..], @"[\/:*?""<>|]");
if (match.Success)
{
ErrorMessage = "Path cannot contain these characters: / : * ? \" < > |";
ValidPath = false;
return;
}
if (FileHelper.CheckPathForProblemLocations(SelectedPath, out var failedCheck)) if (FileHelper.CheckPathForProblemLocations(SelectedPath, out var failedCheck))
{ {
if (failedCheck.CheckType == PathCheckType.EndsWith) if (failedCheck.CheckType == PathCheckType.EndsWith)
{ {
ErrorMessage = "This folder can be install in, but only in a subdirectory"; ErrorMessage = $"You can install in {failedCheck.Target}, but only in a subdirectory. Example: ..\\{failedCheck.Target}\\SPT";
ValidPath = false; ValidPath = false;
return; return;
} }
@ -124,7 +133,7 @@ public class InstallPathSelectionViewModel : ViewModelBase
public async Task NextCommand() public async Task NextCommand()
{ {
if (FileHelper.CheckPathForProblemLocations(SelectedPath, out _)) if (FileHelper.CheckPathForProblemLocations(SelectedPath, out var failedCheck) && failedCheck.CheckAction == PathCheckAction.Deny)
{ {
return; return;
} }

View File

@ -1,12 +1,40 @@
using ReactiveUI; using System.Reflection;
using System.Threading.Tasks;
using ReactiveUI;
using SPTInstaller.Helpers;
using SPTInstaller.Models;
namespace SPTInstaller.ViewModels; namespace SPTInstaller.ViewModels;
public class InstallerUpdateViewModel : ViewModelBase public class InstallerUpdateViewModel : ViewModelBase
{ {
public InstallerUpdateInfo UpdateInfo { get; set; } = new();
private InternalData _data;
private bool _debugging; private bool _debugging;
public InstallerUpdateViewModel(IScreen Host, bool debugging) : base(Host) public InstallerUpdateViewModel(IScreen Host, bool debugging) : base(Host)
{ {
_debugging = debugging; _debugging = debugging;
_data = ServiceHelper.Get<InternalData>() ?? throw new Exception("Failed to get internal data");
Task.Run(async () =>
{
await UpdateInfo.CheckForUpdates(Assembly.GetExecutingAssembly().GetName().Version);
if (!UpdateInfo.UpdateAvailable)
{
NavigateTo(new InstallPathSelectionViewModel(HostScreen, _debugging));
}
});
}
public void NotNowCommand()
{
NavigateTo(new InstallPathSelectionViewModel(HostScreen, _debugging));
}
public async Task UpdateInstallCommand()
{
await UpdateInfo.UpdateInstaller();
} }
} }

View File

@ -1,6 +1,5 @@
using System.Collections.ObjectModel; using System.Collections.ObjectModel;
using System.Diagnostics; using System.Diagnostics;
using System.Reflection;
using System.Threading.Tasks; using System.Threading.Tasks;
using System.Windows.Input; using System.Windows.Input;
using Avalonia.Threading; using Avalonia.Threading;
@ -32,16 +31,8 @@ public class PreChecksViewModel : ViewModelBase
public ICommand SelectPreCheckCommand { get; set; } public ICommand SelectPreCheckCommand { get; set; }
public ICommand StartInstallCommand { get; set; } public ICommand StartInstallCommand { get; set; }
public ICommand UpdateInstallerCommand { get; set; }
public ICommand DismissUpdateCommand { get; set; }
public ICommand WhatsNewCommand { get; set; }
public ICommand LaunchWithDebug { get; set; } public ICommand LaunchWithDebug { get; set; }
public InstallerUpdateInfo UpdateInfo { get; set; } = new();
private bool _debugging; private bool _debugging;
public bool Debugging public bool Debugging
@ -195,8 +186,8 @@ public class PreChecksViewModel : ViewModelBase
if (confirmation == null || !bool.TryParse(confirmation.ToString(), out var confirm) || if (confirmation == null || !bool.TryParse(confirmation.ToString(), out var confirm) ||
!confirm) !confirm)
{ {
Log.Information("User declined install path, exiting"); Log.Information("User declined install path");
Environment.Exit(0); NavigateBack();
} }
}); });
@ -258,31 +249,14 @@ public class PreChecksViewModel : ViewModelBase
StartInstallCommand = ReactiveCommand.Create(async () => StartInstallCommand = ReactiveCommand.Create(async () =>
{ {
UpdateInfo.Show = false;
NavigateTo(new InstallViewModel(HostScreen)); NavigateTo(new InstallViewModel(HostScreen));
}); });
UpdateInstallerCommand = ReactiveCommand.Create(async () =>
{
AllowDetailsButton = false;
AllowInstall = false;
await UpdateInfo.UpdateInstaller();
});
DismissUpdateCommand = ReactiveCommand.Create(() => { UpdateInfo.Show = false; });
WhatsNewCommand =
ReactiveCommand.Create(async () => await DialogHost.Show(new ChangeLogDialog(UpdateInfo.NewVersion.ToString(), UpdateInfo.ChangeLog)));
Task.Run(async () => Task.Run(async () =>
{ {
// run prechecks // run prechecks
var result = await installer.RunPreChecks(); var result = await installer.RunPreChecks();
// check for updates
await UpdateInfo.CheckForUpdates(Assembly.GetExecutingAssembly().GetName()?.Version);
// get latest spt version // get latest spt version
InstallButtonText = "Getting latest release ..."; InstallButtonText = "Getting latest release ...";
InstallButtonCheckState = StatusSpinner.SpinnerState.Running; InstallButtonCheckState = StatusSpinner.SpinnerState.Running;

View File

@ -48,6 +48,11 @@ public class ViewModelBase : ReactiveObject, IActivatableViewModel, IRoutableVie
Dispatcher.UIThread.InvokeAsync(() => { HostScreen.Router.Navigate.Execute(ViewModel); }); Dispatcher.UIThread.InvokeAsync(() => { HostScreen.Router.Navigate.Execute(ViewModel); });
} }
public void NavigateBack()
{
Dispatcher.UIThread.InvokeAsync(() => { HostScreen.Router.NavigateBack.Execute(); });
}
public ViewModelBase(IScreen Host) public ViewModelBase(IScreen Host)
{ {
HostScreen = Host; HostScreen = Host;

View File

@ -27,6 +27,7 @@
</TextBox.Styles> </TextBox.Styles>
</TextBox> </TextBox>
<Button Grid.Row="1" Grid.Column="1" <Button Grid.Row="1" Grid.Column="1"
CornerRadius="20"
Margin="10 0 0 0" Margin="10 0 0 0"
Command="{Binding SelectFolderCommand}" Command="{Binding SelectFolderCommand}"
> >
@ -50,6 +51,7 @@
MinWidth="100" MinWidth="100"
MinHeight="30" MinHeight="30"
FontSize="16" FontSize="16"
CornerRadius="20"
FontWeight="SemiBold" FontWeight="SemiBold"
VerticalAlignment="Bottom" VerticalAlignment="Bottom"
HorizontalContentAlignment="Center" HorizontalContentAlignment="Center"

View File

@ -2,7 +2,29 @@
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"
xmlns:cc="using:SPTInstaller.CustomControls"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450" mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
x:Class="SPTInstaller.Views.InstallerUpdateView"> x:Class="SPTInstaller.Views.InstallerUpdateView">
Welcome to Avalonia! <Grid RowDefinitions="10,Auto,*,10" ColumnDefinitions="10,*,10">
<StackPanel Grid.Row="1" Grid.Column="1" IsVisible="{Binding UpdateInfo.UpdateAvailable}">
<Label Content="{Binding UpdateInfo.NewVersion, StringFormat='{}Installer Change Log for {0}'}" FontSize="18" FontWeight="SemiBold"
/>
<Separator Margin="0 10" Padding="0" Background="{StaticResource SPT_Yellow}"/>
<ScrollViewer MaxHeight="250" Background="#323232">
<TextBlock Text="{Binding UpdateInfo.ChangeLog}"
TextWrapping="Wrap" MinHeight="100"
/>
</ScrollViewer>
</StackPanel>
<cc:UpdateButton Grid.Row="2" Grid.Column="1" VerticalAlignment="Center" HorizontalAlignment="Center"
IsIndeterminate="{Binding UpdateInfo.CheckingForUpdates}"
InfoText="{Binding UpdateInfo.UpdateInfoText}"
Updating="{Binding UpdateInfo.Updating}"
DismissCommand="{Binding NotNowCommand}"
UpdateCommand="{Binding UpdateInstallCommand}"
DownloadProgress="{Binding UpdateInfo.DownloadProgress}"
UpdateAvailable="{Binding UpdateInfo.UpdateAvailable}"
CheckingForUpdate="{Binding UpdateInfo.CheckingForUpdates}"
/>
</Grid>
</UserControl> </UserControl>

View File

@ -93,19 +93,5 @@
IsVisible="{Binding !AllowInstall}" /> IsVisible="{Binding !AllowInstall}" />
</StackPanel> </StackPanel>
</Button> </Button>
<!-- Update installer button -->
<cc:UpdateButton Grid.Column="2" Grid.Row="3"
IsVisible="{Binding UpdateInfo.Show}"
IsEnabled="{Binding UpdateInfo.Show}"
IsIndeterminate="{Binding UpdateInfo.CheckingForUpdates}"
InfoText="{Binding UpdateInfo.UpdateInfoText}"
Updating="{Binding UpdateInfo.Updating}"
DismissCommand="{Binding DismissUpdateCommand}"
UpdateCommand="{Binding UpdateInstallerCommand}"
WhatsNewCommand="{Binding WhatsNewCommand}"
DownloadProgress="{Binding UpdateInfo.DownloadProgress}"
UpdateAvailable="{Binding UpdateInfo.UpdateAvailable}"
CheckingForUpdate="{Binding UpdateInfo.CheckingForUpdates}" />
</Grid> </Grid>
</UserControl> </UserControl>