Merge pull request 'Improve Installer Update Controls' (#69) from waffle.lord/SPT-AKI-Installer:impr/installer-update-control into master

Reviewed-on: CWX/SPT-AKI-Installer#69
This commit is contained in:
IsWaffle 2024-03-27 13:27:05 +00:00
commit 8e8d7d534f
10 changed files with 169 additions and 47 deletions

View File

@ -8,10 +8,12 @@
<entry key="SPTInstaller/CustomControls/CacheInfo.axaml" value="SPTInstaller/SPTInstaller.csproj" /> <entry key="SPTInstaller/CustomControls/CacheInfo.axaml" value="SPTInstaller/SPTInstaller.csproj" />
<entry key="SPTInstaller/CustomControls/DetailedPreCheckItem.axaml" value="SPTInstaller/SPTInstaller.csproj" /> <entry key="SPTInstaller/CustomControls/DetailedPreCheckItem.axaml" value="SPTInstaller/SPTInstaller.csproj" />
<entry key="SPTInstaller/CustomControls/Dialogs/WhyCacheThoughDialog.axaml" value="SPTInstaller/SPTInstaller.csproj" /> <entry key="SPTInstaller/CustomControls/Dialogs/WhyCacheThoughDialog.axaml" value="SPTInstaller/SPTInstaller.csproj" />
<entry key="SPTInstaller/CustomControls/MainInstallerButton.axaml" value="SPTInstaller/SPTInstaller.csproj" />
<entry key="SPTInstaller/CustomControls/PreCheckDetails.axaml" value="SPTInstaller/SPTInstaller.csproj" /> <entry key="SPTInstaller/CustomControls/PreCheckDetails.axaml" value="SPTInstaller/SPTInstaller.csproj" />
<entry key="SPTInstaller/CustomControls/PreCheckItem.axaml" value="SPTInstaller/SPTInstaller.csproj" /> <entry key="SPTInstaller/CustomControls/PreCheckItem.axaml" value="SPTInstaller/SPTInstaller.csproj" />
<entry key="SPTInstaller/CustomControls/ProgressableTaskItem.axaml" value="SPTInstaller/SPTInstaller.csproj" /> <entry key="SPTInstaller/CustomControls/ProgressableTaskItem.axaml" value="SPTInstaller/SPTInstaller.csproj" />
<entry key="SPTInstaller/CustomControls/SPTInstallButton.axaml" value="SPTInstaller/SPTInstaller.csproj" /> <entry key="SPTInstaller/CustomControls/SPTInstallButton.axaml" value="SPTInstaller/SPTInstaller.csproj" />
<entry key="SPTInstaller/CustomControls/UpdateButton.axaml" value="SPTInstaller/SPTInstaller.csproj" />
<entry key="SPTInstaller/CustomControls/UpdateInfoCard.axaml" value="SPTInstaller/SPTInstaller.csproj" /> <entry key="SPTInstaller/CustomControls/UpdateInfoCard.axaml" value="SPTInstaller/SPTInstaller.csproj" />
<entry key="SPTInstaller/Views/DetailedPreChecksView.axaml" value="SPTInstaller/SPTInstaller.csproj" /> <entry key="SPTInstaller/Views/DetailedPreChecksView.axaml" value="SPTInstaller/SPTInstaller.csproj" />
<entry key="SPTInstaller/Views/MainWindow.axaml" value="SPTInstaller/SPTInstaller.csproj" /> <entry key="SPTInstaller/Views/MainWindow.axaml" value="SPTInstaller/SPTInstaller.csproj" />

View File

@ -21,6 +21,7 @@
<Color x:Key="AKI_White">#FFFFFF</Color> <Color x:Key="AKI_White">#FFFFFF</Color>
<Color x:Key="AKI_Gray">#282828</Color> <Color x:Key="AKI_Gray">#282828</Color>
<Color x:Key="AKI_DarkGrayBlue">#323947</Color> <Color x:Key="AKI_DarkGrayBlue">#323947</Color>
<Color x:Key="AKI_LightGrayBlue">#444259</Color>
<!-- Brushes --> <!-- Brushes -->
<SolidColorBrush x:Key="AKI_Foreground_Light" Color="{StaticResource AKI_White}"/> <SolidColorBrush x:Key="AKI_Foreground_Light" Color="{StaticResource AKI_White}"/>
@ -28,6 +29,7 @@
<SolidColorBrush x:Key="AKI_Background_Dark" Color="{StaticResource AKI_DarkGray}"/> <SolidColorBrush x:Key="AKI_Background_Dark" Color="{StaticResource AKI_DarkGray}"/>
<SolidColorBrush x:Key="AKI_Brush_Yellow" Color="{StaticResource AKI_Yellow}"/> <SolidColorBrush x:Key="AKI_Brush_Yellow" Color="{StaticResource AKI_Yellow}"/>
<SolidColorBrush x:Key="AKI_Brush_DarkGrayBlue" Color="{StaticResource AKI_DarkGrayBlue}"/> <SolidColorBrush x:Key="AKI_Brush_DarkGrayBlue" Color="{StaticResource AKI_DarkGrayBlue}"/>
<SolidColorBrush x:Key="AKI_Brush_LightGrayBlue" Color="{StaticResource AKI_LightGrayBlue}"/>
<SolidColorBrush x:Key="AKI_Brush_Lighter" Color="Gainsboro"/> <SolidColorBrush x:Key="AKI_Brush_Lighter" Color="Gainsboro"/>
<!-- Path Geometry --> <!-- Path Geometry -->

View File

@ -123,16 +123,13 @@
<!-- SourceRef: https://github.com/AvaloniaUI/Avalonia/blob/master/src/Avalonia.Themes.Fluent/Controls/Button.xaml --> <!-- SourceRef: https://github.com/AvaloniaUI/Avalonia/blob/master/src/Avalonia.Themes.Fluent/Controls/Button.xaml -->
<Style Selector="Button"> <Style Selector="Button">
<Setter Property="Background" Value="{StaticResource AKI_Brush_DarkGrayBlue}"/> <Setter Property="Background" Value="{StaticResource AKI_Brush_DarkGrayBlue}"/>
<Setter Property="Foreground" Value="{StaticResource AKI_Background_Dark}"/> <Setter Property="Foreground" Value="{StaticResource AKI_White}"/>
</Style>
<Style Selector="Button:pointerover">
<Setter Property="FontWeight" Value="SemiBold"/>
</Style> </Style>
<Style Selector="Button:pointerover /template/ ContentPresenter"> <Style Selector="Button:pointerover /template/ ContentPresenter">
<Setter Property="Background" Value="{StaticResource AKI_Background_Light}"/> <Setter Property="Background" Value="{StaticResource AKI_LightGrayBlue}"/>
<Setter Property="BorderBrush" Value="{StaticResource AKI_Brush_Yellow}"/> <Setter Property="BorderBrush" Value="{StaticResource AKI_LightGrayBlue}"/>
<Setter Property="Foreground" Value="{StaticResource AKI_White}"/>
<Setter Property="BorderThickness" Value="1"/> <Setter Property="BorderThickness" Value="1"/>
</Style> </Style>
@ -159,6 +156,7 @@
<Style Selector="Button.yellow:pointerover /template/ ContentPresenter"> <Style Selector="Button.yellow:pointerover /template/ ContentPresenter">
<Setter Property="Background" Value="Gold"/> <Setter Property="Background" Value="Gold"/>
<Setter Property="BorderBrush" Value="{StaticResource AKI_Brush_DarkGrayBlue}"/> <Setter Property="BorderBrush" Value="{StaticResource AKI_Brush_DarkGrayBlue}"/>
<Setter Property="Foreground" Value="{StaticResource AKI_Background_Dark}"/>
<Setter Property="BorderThickness" Value="1"/> <Setter Property="BorderThickness" Value="1"/>
</Style> </Style>

View File

@ -38,8 +38,7 @@
</Style> </Style>
<Style Selector="Button.selected"> <Style Selector="Button.selected">
<Setter Property="Background" Value="{StaticResource AKI_Brush_DarkGrayBlue}" /> <Setter Property="Background" Value="{StaticResource AKI_Brush_LightGrayBlue}" />
<Setter Property="BorderBrush" Value="{StaticResource AKI_Yellow}"/>
<Setter Property="BorderThickness" Value="1"/> <Setter Property="BorderThickness" Value="1"/>
</Style> </Style>
</UserControl.Styles> </UserControl.Styles>

View File

@ -0,0 +1,47 @@
<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.UpdateButton">
<UserControl.Styles>
<StyleInclude Source="../Assets/Styles.axaml"/>
</UserControl.Styles>
<Panel>
<StackPanel Orientation="Horizontal">
<StackPanel.IsVisible>
<MultiBinding Converter="{x:Static BoolConverters.And}">
<Binding Path="!Updating" RelativeSource="{RelativeSource AncestorType=UserControl}"/>
<Binding Path="UpdateAvailable" RelativeSource="{RelativeSource AncestorType=UserControl}"/>
</MultiBinding>
</StackPanel.IsVisible>
<Button Content="{Binding InfoText, RelativeSource={RelativeSource AncestorType=UserControl}}"
CornerRadius="20 0 0 20"
Classes="yellow"
Command="{Binding UpdateCommand, RelativeSource={RelativeSource AncestorType=UserControl}}"
/>
<Button Content="Not now" CornerRadius="0 20 20 0"
Command="{Binding DismissCommand, RelativeSource={RelativeSource AncestorType=UserControl}}"
/>
</StackPanel>
<Panel Margin="0 10">
<Panel.IsVisible>
<MultiBinding Converter="{x:Static BoolConverters.Or}">
<Binding Path="Updating" RelativeSource="{RelativeSource AncestorType=UserControl}"/>
<Binding Path="CheckingForUpdate" RelativeSource="{RelativeSource AncestorType=UserControl}"/>
</MultiBinding>
</Panel.IsVisible>
<ProgressBar CornerRadius="20" VerticalAlignment="Stretch"
Value="{Binding DownloadProgress, RelativeSource={RelativeSource AncestorType=UserControl}}"
IsIndeterminate="{Binding IsIndeterminate, RelativeSource={RelativeSource AncestorType=UserControl}}"
/>
<Label Content="{Binding InfoText, RelativeSource={RelativeSource AncestorType=UserControl}}"
VerticalAlignment="Center" HorizontalAlignment="Center"
Foreground="Black" FontWeight="SemiBold"/>
</Panel>
</Panel>
</UserControl>

View File

@ -0,0 +1,85 @@
using System.Windows.Input;
using Avalonia;
using Avalonia.Controls;
namespace SPTInstaller.CustomControls;
public partial class UpdateButton : UserControl
{
public UpdateButton()
{
InitializeComponent();
}
public static readonly StyledProperty<string> InfoTextProperty = AvaloniaProperty.Register<UpdateButton, string>(
"InfoText");
public string InfoText
{
get => GetValue(InfoTextProperty);
set => SetValue(InfoTextProperty, value);
}
public static readonly StyledProperty<bool> CheckingForUpdateProperty = AvaloniaProperty.Register<UpdateButton, bool>(
"CheckingForUpdate");
public bool CheckingForUpdate
{
get => GetValue(CheckingForUpdateProperty);
set => SetValue(CheckingForUpdateProperty, value);
}
public static readonly StyledProperty<ICommand> DismissCommandProperty = AvaloniaProperty.Register<UpdateButton, ICommand>(
"DismissCommand");
public ICommand DismissCommand
{
get => GetValue(DismissCommandProperty);
set => SetValue(DismissCommandProperty, value);
}
public static readonly StyledProperty<ICommand> UpdateCommandProperty = AvaloniaProperty.Register<UpdateButton, ICommand>(
"UpdateCommand");
public ICommand UpdateCommand
{
get => GetValue(UpdateCommandProperty);
set => SetValue(UpdateCommandProperty, value);
}
public static readonly StyledProperty<bool> UpdatingProperty = AvaloniaProperty.Register<UpdateButton, bool>(
"Updating");
public bool Updating
{
get => GetValue(UpdatingProperty);
set => SetValue(UpdatingProperty, value);
}
public static readonly StyledProperty<int> DownloadProgressProperty = AvaloniaProperty.Register<UpdateButton, int>(
"DownloadProgress");
public int DownloadProgress
{
get => GetValue(DownloadProgressProperty);
set => SetValue(DownloadProgressProperty, value);
}
public static readonly StyledProperty<bool> IsIndeterminateProperty = AvaloniaProperty.Register<UpdateButton, bool>(
"IsIndeterminate");
public bool IsIndeterminate
{
get => GetValue(IsIndeterminateProperty);
set => SetValue(IsIndeterminateProperty, value);
}
public static readonly StyledProperty<bool> UpdateAvailableProperty = AvaloniaProperty.Register<UpdateButton, bool>(
"UpdateAvailable");
public bool UpdateAvailable
{
get => GetValue(UpdateAvailableProperty);
set => SetValue(UpdateAvailableProperty, value);
}
}

View File

@ -20,11 +20,11 @@ public class InstallerUpdateInfo : ReactiveObject
set => this.RaiseAndSetIfChanged(ref _updateInfoText, value); set => this.RaiseAndSetIfChanged(ref _updateInfoText, value);
} }
private bool _showCard = false; private bool _show = false;
public bool ShowCard public bool Show
{ {
get => _showCard; get => _show;
set => this.RaiseAndSetIfChanged(ref _showCard, value); set => this.RaiseAndSetIfChanged(ref _show, value);
} }
private bool _updating = false; private bool _updating = false;
@ -89,7 +89,7 @@ public class InstallerUpdateInfo : ReactiveObject
private async Task<string> DownloadNewInstaller() private async Task<string> DownloadNewInstaller()
{ {
UpdateInfoText = $"Downloading new installer v{_newVersion}"; UpdateInfoText = $"Downloading installer v{_newVersion}";
var progress = new Progress<double>(x => DownloadProgress = (int)x); var progress = new Progress<double>(x => DownloadProgress = (int)x);
@ -112,21 +112,7 @@ public class InstallerUpdateInfo : ReactiveObject
} }
UpdateInfoText = infoText; UpdateInfoText = infoText;
Show = updateAvailable;
if (!updateAvailable)
{
Task.Run(async () =>
{
// delay card dismiss
await Task.Delay(TimeSpan.FromSeconds(2));
ShowCard = updateAvailable;
});
}
else
{
ShowCard = updateAvailable;
}
CheckingForUpdates = false; CheckingForUpdates = false;
UpdateAvailable = updateAvailable; UpdateAvailable = updateAvailable;
} }
@ -137,7 +123,7 @@ public class InstallerUpdateInfo : ReactiveObject
return; return;
UpdateInfoText = "Checking for installer updates"; UpdateInfoText = "Checking for installer updates";
ShowCard = true; Show = true;
CheckingForUpdates = true; CheckingForUpdates = true;
try try
@ -172,7 +158,7 @@ public class InstallerUpdateInfo : ReactiveObject
NewInstallerUrl = latest.Assets[0].BrowserDownloadUrl; NewInstallerUrl = latest.Assets[0].BrowserDownloadUrl;
EndCheck($"Update available, version {latestVersion}", true); EndCheck($"Update available: v{latestVersion}", true);
return; return;
} }

View File

@ -9,8 +9,8 @@
<PackageIcon>icon.ico</PackageIcon> <PackageIcon>icon.ico</PackageIcon>
<ApplicationIcon>Assets\icon.ico</ApplicationIcon> <ApplicationIcon>Assets\icon.ico</ApplicationIcon>
<Configurations>Debug;Release;TEST</Configurations> <Configurations>Debug;Release;TEST</Configurations>
<AssemblyVersion>2.53</AssemblyVersion> <AssemblyVersion>2.54</AssemblyVersion>
<FileVersion>2.53</FileVersion> <FileVersion>2.54</FileVersion>
<Company>SPT-AKI</Company> <Company>SPT-AKI</Company>
</PropertyGroup> </PropertyGroup>

View File

@ -220,7 +220,7 @@ public class PreChecksViewModel : ViewModelBase
StartInstallCommand = ReactiveCommand.Create(async () => StartInstallCommand = ReactiveCommand.Create(async () =>
{ {
UpdateInfo.ShowCard = false; UpdateInfo.Show = false;
NavigateTo(new InstallViewModel(HostScreen)); NavigateTo(new InstallViewModel(HostScreen));
}); });
@ -233,7 +233,7 @@ public class PreChecksViewModel : ViewModelBase
DismissUpdateCommand = ReactiveCommand.Create(() => DismissUpdateCommand = ReactiveCommand.Create(() =>
{ {
UpdateInfo.ShowCard = false; UpdateInfo.Show = false;
}); });

View File

@ -75,9 +75,10 @@
<!-- Start install button --> <!-- Start install button -->
<Button Grid.Column="2" Grid.Row="3" Padding="20 10" <Button Grid.Column="2" Grid.Row="3" Padding="20 10"
IsVisible="{Binding !UpdateInfo.Show}"
IsEnabled="{Binding AllowInstall}"
FontSize="15" FontWeight="SemiBold" FontSize="15" FontWeight="SemiBold"
Classes="yellow" Classes="yellow"
IsEnabled="{Binding AllowInstall}"
Command="{Binding StartInstallCommand}" Command="{Binding StartInstallCommand}"
CornerRadius="15" CornerRadius="15"
> >
@ -87,16 +88,18 @@
</StackPanel> </StackPanel>
</Button> </Button>
<cc:UpdateInfoCard Grid.Row="1" Grid.RowSpan="5" Grid.ColumnSpan="5" Padding="10" <!-- Update installer button -->
VerticalAlignment="Center" HorizontalAlignment="Center" <cc:UpdateButton Grid.Column="2" Grid.Row="3"
InfoText="{Binding UpdateInfo.UpdateInfoText}" IsVisible="{Binding UpdateInfo.Show}"
ShowUpdateCard="{Binding UpdateInfo.ShowCard}" IsEnabled="{Binding UpdateInfo.Show}"
NotNowCommand="{Binding DismissUpdateCommand}" IsIndeterminate="{Binding UpdateInfo.CheckingForUpdates}"
UpdateInstallerCommand="{Binding UpdateInstallerCommand}" InfoText="{Binding UpdateInfo.UpdateInfoText}"
Updating="{Binding UpdateInfo.Updating}" Updating="{Binding UpdateInfo.Updating}"
DownloadProgress="{Binding UpdateInfo.DownloadProgress}" DismissCommand="{Binding DismissUpdateCommand}"
IndeterminateProgress="{Binding UpdateInfo.CheckingForUpdates}" UpdateCommand="{Binding UpdateInstallerCommand}"
UpdateAvailable="{Binding UpdateInfo.UpdateAvailable}" DownloadProgress="{Binding UpdateInfo.DownloadProgress}"
/> UpdateAvailable="{Binding UpdateInfo.UpdateAvailable}"
CheckingForUpdate="{Binding UpdateInfo.CheckingForUpdates}"
/>
</Grid> </Grid>
</UserControl> </UserControl>