udpate prechecks to use status spinner
This commit is contained in:
parent
d8d442c195
commit
ada70d7957
@ -1,5 +1,6 @@
|
||||
using Serilog;
|
||||
using SharpCompress;
|
||||
using SPTInstaller.CustomControls;
|
||||
using SPTInstaller.Interfaces;
|
||||
using SPTInstaller.Models;
|
||||
using System.Collections.Generic;
|
||||
@ -26,7 +27,7 @@ public class InstallController
|
||||
Log.Information("-<>--<>- Running PreChecks -<>--<>-");
|
||||
var requiredResults = new List<IResult>();
|
||||
|
||||
_preChecks.ForEach(x => x.IsPending = true);
|
||||
_preChecks.ForEach(x => x.State = StatusSpinner.SpinnerState.Pending);
|
||||
|
||||
foreach (var check in _preChecks)
|
||||
{
|
||||
|
@ -2,29 +2,10 @@
|
||||
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:cc="using:SPTInstaller.CustomControls"
|
||||
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
|
||||
x:Class="SPTInstaller.CustomControls.DetailedPreCheckItem"
|
||||
Background="Transparent" MinHeight="100">
|
||||
<UserControl.Styles>
|
||||
<Style Selector="Arc.running">
|
||||
<Setter Property="Stroke" Value="DodgerBlue"/>
|
||||
</Style>
|
||||
|
||||
<Style Selector="Arc">
|
||||
<Setter Property="Stroke" Value="Gray"/>
|
||||
<Setter Property="IsVisible" Value="{Binding IsPending, RelativeSource={RelativeSource AncestorType=UserControl}}"/>
|
||||
<Style.Animations>
|
||||
<Animation Duration="0:0:1" IterationCount="Infinite">
|
||||
<KeyFrame Cue="0%">
|
||||
<Setter Property="RotateTransform.Angle" Value="0"/>
|
||||
</KeyFrame>
|
||||
<KeyFrame Cue="100%">
|
||||
<Setter Property="RotateTransform.Angle" Value="360"/>
|
||||
</KeyFrame>
|
||||
</Animation>
|
||||
</Style.Animations>
|
||||
</Style>
|
||||
</UserControl.Styles>
|
||||
|
||||
<Grid RowDefinitions="3,AUTO,3,*,30,3" ColumnDefinitions="3,*,AUTO,3" Margin="10">
|
||||
<Border Grid.RowSpan="5" Grid.ColumnSpan="3"
|
||||
@ -35,36 +16,13 @@
|
||||
Background="{StaticResource AKI_Brush_DarkGrayBlue}" CornerRadius="8 8 0 0"
|
||||
/>
|
||||
|
||||
<Grid Grid.Row="1" Grid.Column="1" ColumnDefinitions="22, AUTO" Margin="3">
|
||||
<Canvas Margin="0 3 0 0"
|
||||
IsVisible="{Binding !IsPending, RelativeSource={RelativeSource AncestorType=UserControl}}">
|
||||
<Ellipse Fill="White" Height="15" Width="15" Canvas.Top="3" Canvas.Left="3"
|
||||
/>
|
||||
<Path Name="iconPath" StrokeThickness="2"
|
||||
Classes.passed="{Binding Passed, RelativeSource={RelativeSource AncestorType=UserControl}}"
|
||||
>
|
||||
<Classes.failed>
|
||||
<MultiBinding Converter="{x:Static BoolConverters.And}">
|
||||
<Binding Path="IsRequired"/>
|
||||
<Binding Path="!Passed"/>
|
||||
</MultiBinding>
|
||||
</Classes.failed>
|
||||
<Classes.warning>
|
||||
<MultiBinding Converter="{x:Static BoolConverters.And}">
|
||||
<Binding Path="!IsRequired"/>
|
||||
<Binding Path="!Passed"/>
|
||||
</MultiBinding>
|
||||
</Classes.warning>
|
||||
</Path>
|
||||
</Canvas>
|
||||
|
||||
<Arc StartAngle="280" SweepAngle="80" Margin="0 3 0 0" StrokeThickness="3"
|
||||
Width="20" Height="20" VerticalAlignment="Top"
|
||||
Classes.running="{Binding IsRunning, RelativeSource={RelativeSource AncestorType=UserControl}}"
|
||||
/>
|
||||
<Grid Grid.Row="1" Grid.Column="1" ColumnDefinitions="AUTO, AUTO" Margin="3">
|
||||
<cc:StatusSpinner State="{Binding State, RelativeSource={RelativeSource AncestorType=UserControl}}"/>
|
||||
<Label Grid.Column="1"
|
||||
Content="{Binding PreCheckName, RelativeSource={RelativeSource AncestorType=UserControl}}"
|
||||
Classes.bold="{Binding IsRunning, RelativeSource={RelativeSource AncestorType=UserControl}}"
|
||||
Classes.bold="{Binding State, RelativeSource={RelativeSource AncestorType=UserControl},
|
||||
Converter={StaticResource ResourceKey=IsStateConverter},
|
||||
ConverterParameter=Running}"
|
||||
/>
|
||||
</Grid>
|
||||
|
||||
|
@ -2,65 +2,29 @@
|
||||
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:cc="using:SPTInstaller.CustomControls"
|
||||
xmlns:convt="using:SPTInstaller.Converters"
|
||||
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
|
||||
x:Class="SPTInstaller.CustomControls.PreCheckItem">
|
||||
|
||||
|
||||
<UserControl.Resources>
|
||||
<convt:StatusSpinnerIsStateConverter x:Key="IsStateConverter"/>
|
||||
</UserControl.Resources>
|
||||
<UserControl.Styles>
|
||||
<Style Selector="Arc.running">
|
||||
<Setter Property="Stroke" Value="DodgerBlue"/>
|
||||
</Style>
|
||||
|
||||
<Style Selector="Arc">
|
||||
<Setter Property="Stroke" Value="Gray"/>
|
||||
<Setter Property="IsVisible" Value="{Binding IsPending, RelativeSource={RelativeSource AncestorType=UserControl}}"/>
|
||||
<Style.Animations>
|
||||
<Animation Duration="0:0:1" IterationCount="Infinite">
|
||||
<KeyFrame Cue="0%">
|
||||
<Setter Property="RotateTransform.Angle" Value="0"/>
|
||||
</KeyFrame>
|
||||
<KeyFrame Cue="100%">
|
||||
<Setter Property="RotateTransform.Angle" Value="360"/>
|
||||
</KeyFrame>
|
||||
</Animation>
|
||||
</Style.Animations>
|
||||
</Style>
|
||||
|
||||
<Style Selector="Label.bold">
|
||||
<Setter Property="FontWeight" Value="Bold"/>
|
||||
</Style>
|
||||
</UserControl.Styles>
|
||||
|
||||
|
||||
<Grid ColumnDefinitions="22, AUTO" Margin="3">
|
||||
<Canvas Margin="0 3 0 0"
|
||||
IsVisible="{Binding !IsPending, RelativeSource={RelativeSource AncestorType=UserControl}}">
|
||||
<Ellipse Fill="White" Height="15" Width="15" Canvas.Top="3" Canvas.Left="3"
|
||||
/>
|
||||
<Path StrokeThickness="2"
|
||||
Classes.passed="{Binding Passed, RelativeSource={RelativeSource AncestorType=UserControl}}"
|
||||
>
|
||||
<Classes.failed>
|
||||
<MultiBinding Converter="{x:Static BoolConverters.And}">
|
||||
<Binding Path="IsRequired"/>
|
||||
<Binding Path="!Passed"/>
|
||||
</MultiBinding>
|
||||
</Classes.failed>
|
||||
<Classes.warning>
|
||||
<MultiBinding Converter="{x:Static BoolConverters.And}">
|
||||
<Binding Path="!IsRequired"/>
|
||||
<Binding Path="!Passed"/>
|
||||
</MultiBinding>
|
||||
</Classes.warning>
|
||||
</Path>
|
||||
</Canvas>
|
||||
|
||||
<Arc StartAngle="280" SweepAngle="80" Margin="0 3 0 0" StrokeThickness="3"
|
||||
Width="20" Height="20" VerticalAlignment="Top"
|
||||
Classes.running="{Binding IsRunning, RelativeSource={RelativeSource AncestorType=UserControl}}"
|
||||
/>
|
||||
<Grid ColumnDefinitions="AUTO, AUTO" Margin="3">
|
||||
<cc:StatusSpinner State="{Binding State, RelativeSource={RelativeSource AncestorType=UserControl}}"/>
|
||||
|
||||
<Label Grid.Column="1"
|
||||
Content="{Binding PreCheckName, RelativeSource={RelativeSource AncestorType=UserControl}}"
|
||||
Classes.bold="{Binding IsRunning, RelativeSource={RelativeSource AncestorType=UserControl}}"
|
||||
Classes.bold="{Binding State, RelativeSource={RelativeSource AncestorType=UserControl}
|
||||
Converter={StaticResource ResourceKey=IsStateConverter},
|
||||
ConverterParameter=Running}"
|
||||
/>
|
||||
</Grid>
|
||||
</UserControl>
|
||||
|
@ -1,4 +1,4 @@
|
||||
using Avalonia;
|
||||
using Avalonia;
|
||||
using Avalonia.Controls;
|
||||
|
||||
namespace SPTInstaller.CustomControls;
|
||||
@ -19,33 +19,6 @@ public partial class PreCheckItem : UserControl
|
||||
public static readonly StyledProperty<string> PreCheckNameProperty =
|
||||
AvaloniaProperty.Register<PreCheckItem, string>(nameof(PreCheckName));
|
||||
|
||||
public bool IsRunning
|
||||
{
|
||||
get => GetValue(IsRunningProperty);
|
||||
set => SetValue(IsRunningProperty, value);
|
||||
}
|
||||
|
||||
public static readonly StyledProperty<bool> IsRunningProperty =
|
||||
AvaloniaProperty.Register<PreCheckItem, bool>(nameof(IsRunning));
|
||||
|
||||
public bool IsPending
|
||||
{
|
||||
get => GetValue(IsPendingProperty);
|
||||
set => SetValue(IsPendingProperty, value);
|
||||
}
|
||||
|
||||
public static readonly StyledProperty<bool> IsPendingProperty =
|
||||
AvaloniaProperty.Register<PreCheckItem, bool>(nameof(IsPending));
|
||||
|
||||
public bool Passed
|
||||
{
|
||||
get => GetValue(PassedProperty);
|
||||
set => SetValue(PassedProperty, value);
|
||||
}
|
||||
|
||||
public static readonly StyledProperty<bool> PassedProperty =
|
||||
AvaloniaProperty.Register<PreCheckItem, bool>(nameof(Passed));
|
||||
|
||||
public bool IsRequired
|
||||
{
|
||||
get => GetValue(IsRequiredProperty);
|
||||
@ -54,4 +27,13 @@ public partial class PreCheckItem : UserControl
|
||||
|
||||
public static readonly StyledProperty<bool> IsRequiredProperty =
|
||||
AvaloniaProperty.Register<PreCheckItem, bool>(nameof(IsRequired));
|
||||
|
||||
public StatusSpinner.SpinnerState State
|
||||
{
|
||||
get => GetValue(StateProperty);
|
||||
set => SetValue(StateProperty, value);
|
||||
}
|
||||
|
||||
public static readonly StyledProperty<StatusSpinner.SpinnerState> StateProperty =
|
||||
AvaloniaProperty.Register<PreCheckItem, StatusSpinner.SpinnerState>(nameof(State));
|
||||
}
|
30
SPTInstaller/Installer Tasks/PreChecks/TestPreCheck.cs
Normal file
30
SPTInstaller/Installer Tasks/PreChecks/TestPreCheck.cs
Normal file
@ -0,0 +1,30 @@
|
||||
using SPTInstaller.CustomControls;
|
||||
using SPTInstaller.Models;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace SPTInstaller.Installer_Tasks.PreChecks;
|
||||
public class TestPreCheck : PreCheckBase
|
||||
{
|
||||
private StatusSpinner.SpinnerState _endState;
|
||||
public static TestPreCheck FromRandomName(StatusSpinner.SpinnerState EndState) => new TestPreCheck($"{EndState} #{new Random().Next(0, 9999)}", EndState == StatusSpinner.SpinnerState.Error, EndState);
|
||||
|
||||
public TestPreCheck(string name, bool isRequired, StatusSpinner.SpinnerState endState) : base(name, isRequired)
|
||||
{
|
||||
_endState = endState;
|
||||
}
|
||||
|
||||
public override async Task<PreCheckResult> CheckOperation()
|
||||
{
|
||||
await Task.Delay(1000);
|
||||
|
||||
switch (_endState)
|
||||
{
|
||||
case StatusSpinner.SpinnerState.Error:
|
||||
return PreCheckResult.FromError("This is what a required precheck failing looks like");
|
||||
case StatusSpinner.SpinnerState.Warning:
|
||||
return PreCheckResult.FromError("This is what a non-required precheck failing looks like");
|
||||
default:
|
||||
return PreCheckResult.FromSuccess("This is what a successful precheck looks like");
|
||||
}
|
||||
}
|
||||
}
|
@ -1,4 +1,5 @@
|
||||
using System.Threading.Tasks;
|
||||
using SPTInstaller.CustomControls;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace SPTInstaller.Interfaces;
|
||||
|
||||
@ -7,12 +8,8 @@ public interface IPreCheck
|
||||
public string Id { get; }
|
||||
public string Name { get; }
|
||||
public bool IsRequired { get; }
|
||||
|
||||
public bool IsPending { get; set; }
|
||||
|
||||
public bool Passed { get; }
|
||||
|
||||
public string PreCheckDetails { get; }
|
||||
public StatusSpinner.SpinnerState State { get; set; }
|
||||
|
||||
public Task<IResult> RunCheck();
|
||||
}
|
@ -1,4 +1,5 @@
|
||||
using ReactiveUI;
|
||||
using SPTInstaller.CustomControls;
|
||||
using SPTInstaller.Interfaces;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Input;
|
||||
@ -28,25 +29,11 @@ public abstract class PreCheckBase : ReactiveObject, IPreCheck
|
||||
set => this.RaiseAndSetIfChanged(ref _required, value);
|
||||
}
|
||||
|
||||
private bool _passed;
|
||||
public bool Passed
|
||||
private StatusSpinner.SpinnerState _state;
|
||||
public StatusSpinner.SpinnerState State
|
||||
{
|
||||
get => _passed;
|
||||
set => this.RaiseAndSetIfChanged(ref _passed, value);
|
||||
}
|
||||
|
||||
private bool _isPending;
|
||||
public bool IsPending
|
||||
{
|
||||
get => _isPending;
|
||||
set => this.RaiseAndSetIfChanged(ref _isPending, value);
|
||||
}
|
||||
|
||||
private bool _isRunning;
|
||||
public bool IsRunning
|
||||
{
|
||||
get => _isRunning;
|
||||
set => this.RaiseAndSetIfChanged(ref _isRunning, value);
|
||||
get => _state;
|
||||
set => this.RaiseAndSetIfChanged(ref _state, value);
|
||||
}
|
||||
|
||||
private string _preCheckDetails;
|
||||
@ -89,12 +76,19 @@ public abstract class PreCheckBase : ReactiveObject, IPreCheck
|
||||
Id = Guid.NewGuid().ToString();
|
||||
}
|
||||
|
||||
private StatusSpinner.SpinnerState ProcessResult(PreCheckResult result) =>
|
||||
(result.Succeeded, IsRequired) switch
|
||||
{
|
||||
(true, _) => StatusSpinner.SpinnerState.OK,
|
||||
(false, false) => StatusSpinner.SpinnerState.Warning,
|
||||
(_, _) => StatusSpinner.SpinnerState.Error
|
||||
};
|
||||
|
||||
public async Task<IResult> RunCheck()
|
||||
{
|
||||
IsRunning = true;
|
||||
State = StatusSpinner.SpinnerState.Running;
|
||||
|
||||
var result = await CheckOperation();
|
||||
Passed = result.Succeeded;
|
||||
|
||||
PreCheckDetails = !string.IsNullOrWhiteSpace(result.Message)
|
||||
? result.Message
|
||||
@ -104,10 +98,9 @@ public abstract class PreCheckBase : ReactiveObject, IPreCheck
|
||||
ActionButtonCommand = result.ButtonPressedCommand;
|
||||
ActionButtonIsVisible = result.ActionButtonIsVisible;
|
||||
|
||||
IsRunning = false;
|
||||
IsPending = false;
|
||||
State = ProcessResult(result);
|
||||
|
||||
return Passed ? Result.FromSuccess() : Result.FromError($"PreCheck Failed: {Name}");
|
||||
return State == StatusSpinner.SpinnerState.OK ? Result.FromSuccess() : Result.FromError($"PreCheck Failed: {Name}");
|
||||
}
|
||||
|
||||
public abstract Task<PreCheckResult> CheckOperation();
|
||||
|
@ -4,6 +4,7 @@ using ReactiveUI;
|
||||
using Serilog;
|
||||
using Splat;
|
||||
using SPTInstaller.Controllers;
|
||||
using SPTInstaller.CustomControls;
|
||||
using SPTInstaller.Helpers;
|
||||
using SPTInstaller.Installer_Tasks;
|
||||
using SPTInstaller.Installer_Tasks.PreChecks;
|
||||
@ -31,10 +32,11 @@ internal class Program
|
||||
// Register all the things
|
||||
// Regestering as base classes so ReactiveUI works correctly. Doesn't seem to like the interfaces :(
|
||||
ServiceHelper.Register<InternalData>();
|
||||
|
||||
#if !TEST
|
||||
ServiceHelper.Register<PreCheckBase, NetFramework472PreCheck>();
|
||||
ServiceHelper.Register<PreCheckBase, NetCore6PreCheck>();
|
||||
|
||||
#if !TEST
|
||||
ServiceHelper.Register<PreCheckBase, FreeSpacePreCheck>();
|
||||
var logPath = Path.Join(Environment.CurrentDirectory, "spt-aki-installer_.log");
|
||||
|
||||
@ -52,10 +54,14 @@ internal class Program
|
||||
ServiceHelper.Register<InstallerTaskBase, CopyClientTask>();
|
||||
ServiceHelper.Register<InstallerTaskBase, SetupClientTask>();
|
||||
#else
|
||||
for (int i = 0; i < 5; i++)
|
||||
{
|
||||
Locator.CurrentMutable.RegisterConstant<InstallerTaskBase>(TestTask.FromRandomName());
|
||||
}
|
||||
for (int i = 0; i < 5; i++)
|
||||
{
|
||||
Locator.CurrentMutable.RegisterConstant<InstallerTaskBase>(TestTask.FromRandomName());
|
||||
}
|
||||
|
||||
Locator.CurrentMutable.RegisterConstant<PreCheckBase>(TestPreCheck.FromRandomName(StatusSpinner.SpinnerState.OK));
|
||||
Locator.CurrentMutable.RegisterConstant<PreCheckBase>(TestPreCheck.FromRandomName(StatusSpinner.SpinnerState.Warning));
|
||||
Locator.CurrentMutable.RegisterConstant<PreCheckBase>(TestPreCheck.FromRandomName(StatusSpinner.SpinnerState.Error));
|
||||
#endif
|
||||
|
||||
// need the interfaces for the controller and splat won't resolve them since we need to base classes in avalonia (what a mess), so doing it manually here
|
||||
|
@ -39,14 +39,12 @@
|
||||
<ItemsControl.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<cc:DetailedPreCheckItem PreCheckName="{Binding Name}"
|
||||
IsRunning="{Binding IsRunning}"
|
||||
IsPending="{Binding IsPending}"
|
||||
IsRequired="{Binding IsRequired}"
|
||||
Passed="{Binding Passed}"
|
||||
PreCheckDetails="{Binding PreCheckDetails}"
|
||||
ActionButtonCommand="{Binding ActionButtonCommand}"
|
||||
ActionButtonText="{Binding ActionButtonText}"
|
||||
ActionButtonIsVisible="{Binding ActionButtonIsVisible}"
|
||||
State="{Binding State}"
|
||||
/>
|
||||
</DataTemplate>
|
||||
</ItemsControl.ItemTemplate>
|
||||
|
@ -36,10 +36,8 @@
|
||||
<ItemsControl.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<cc:PreCheckItem PreCheckName="{Binding Name}"
|
||||
IsRunning="{Binding IsRunning}"
|
||||
IsPending="{Binding IsPending}"
|
||||
IsRequired="{Binding IsRequired}"
|
||||
Passed="{Binding Passed}"
|
||||
State="{Binding State}"
|
||||
/>
|
||||
</DataTemplate>
|
||||
</ItemsControl.ItemTemplate>
|
||||
|
Loading…
x
Reference in New Issue
Block a user