diff --git a/SPTInstaller/Assets/Styles.axaml b/SPTInstaller/Assets/Styles.axaml
index 7f446d4..d25af7c 100644
--- a/SPTInstaller/Assets/Styles.axaml
+++ b/SPTInstaller/Assets/Styles.axaml
@@ -211,20 +211,4 @@
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/SPTInstaller/Converters/StatusSpinnerIsProcessingConverter.cs b/SPTInstaller/Converters/StatusSpinnerIsProcessingConverter.cs
new file mode 100644
index 0000000..e0c391f
--- /dev/null
+++ b/SPTInstaller/Converters/StatusSpinnerIsProcessingConverter.cs
@@ -0,0 +1,26 @@
+using Avalonia.Data.Converters;
+using SPTInstaller.CustomControls;
+using System.Globalization;
+
+namespace SPTInstaller.Converters;
+public class StatusSpinnerIsProcessingConverter : IValueConverter
+{
+ public object? Convert(object? value, Type targetType, object? parameter, CultureInfo culture)
+ {
+ if (value is not StatusSpinner.SpinnerState state)
+ return null;
+
+
+ if (parameter is string parm && parm == "invert")
+ {
+ return state > 0;
+ }
+
+ return state <= 0;
+ }
+
+ public object? ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture)
+ {
+ return value;
+ }
+}
diff --git a/SPTInstaller/Converters/StatusSpinnerIsStateConverter.cs b/SPTInstaller/Converters/StatusSpinnerIsStateConverter.cs
new file mode 100644
index 0000000..d5951de
--- /dev/null
+++ b/SPTInstaller/Converters/StatusSpinnerIsStateConverter.cs
@@ -0,0 +1,26 @@
+using Avalonia.Data.Converters;
+using SPTInstaller.CustomControls;
+using System.Globalization;
+
+namespace SPTInstaller.Converters;
+public class StatusSpinnerIsStateConverter : IValueConverter
+{
+ public object? Convert(object? value, Type targetType, object? parameter, CultureInfo culture)
+ {
+ if (value == null || parameter == null)
+ return null;
+
+ if (value is not StatusSpinner.SpinnerState state)
+ return null;
+
+ if (parameter is not string stateName)
+ return null;
+
+ return state.ToString().ToLower() == stateName.ToLower();
+ }
+
+ public object? ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture)
+ {
+ return value;
+ }
+}
diff --git a/SPTInstaller/CustomControls/CacheInfo.axaml b/SPTInstaller/CustomControls/CacheInfo.axaml
new file mode 100644
index 0000000..7e61408
--- /dev/null
+++ b/SPTInstaller/CustomControls/CacheInfo.axaml
@@ -0,0 +1,8 @@
+
+ Welcome to Avalonia!
+
diff --git a/SPTInstaller/CustomControls/CacheInfo.axaml.cs b/SPTInstaller/CustomControls/CacheInfo.axaml.cs
new file mode 100644
index 0000000..94152b3
--- /dev/null
+++ b/SPTInstaller/CustomControls/CacheInfo.axaml.cs
@@ -0,0 +1,10 @@
+using Avalonia.Controls;
+
+namespace SPTInstaller.CustomControls;
+public partial class CacheInfo : UserControl
+{
+ public CacheInfo()
+ {
+ InitializeComponent();
+ }
+}
diff --git a/SPTInstaller/CustomControls/PreCheckItem.axaml b/SPTInstaller/CustomControls/PreCheckItem.axaml
index 98fce28..9d9a12b 100644
--- a/SPTInstaller/CustomControls/PreCheckItem.axaml
+++ b/SPTInstaller/CustomControls/PreCheckItem.axaml
@@ -36,7 +36,7 @@
IsVisible="{Binding !IsPending, RelativeSource={RelativeSource AncestorType=UserControl}}">
-
diff --git a/SPTInstaller/CustomControls/StatusSpinner.axaml b/SPTInstaller/CustomControls/StatusSpinner.axaml
new file mode 100644
index 0000000..c10b421
--- /dev/null
+++ b/SPTInstaller/CustomControls/StatusSpinner.axaml
@@ -0,0 +1,77 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/SPTInstaller/CustomControls/StatusSpinner.axaml.cs b/SPTInstaller/CustomControls/StatusSpinner.axaml.cs
new file mode 100644
index 0000000..d845467
--- /dev/null
+++ b/SPTInstaller/CustomControls/StatusSpinner.axaml.cs
@@ -0,0 +1,31 @@
+using Avalonia;
+using Avalonia.Controls;
+using Avalonia.ReactiveUI;
+
+namespace SPTInstaller.CustomControls;
+
+public partial class StatusSpinner : ReactiveUserControl
+{
+ public enum SpinnerState
+ {
+ Pending = -1,
+ Running = 0,
+ OK = 1,
+ Warning = 2,
+ Error = 3,
+ }
+
+ public StatusSpinner()
+ {
+ InitializeComponent();
+ }
+
+ public SpinnerState State
+ {
+ get => GetValue(StateProperty);
+ set => SetValue(StateProperty, value);
+ }
+
+ public static readonly StyledProperty StateProperty =
+ AvaloniaProperty.Register(nameof(State));
+}
diff --git a/SPTInstaller/Views/PreChecksView.axaml b/SPTInstaller/Views/PreChecksView.axaml
index 6dc74a3..7e1ce53 100644
--- a/SPTInstaller/Views/PreChecksView.axaml
+++ b/SPTInstaller/Views/PreChecksView.axaml
@@ -26,7 +26,7 @@
IsEnabled="{Binding AllowInstall}"
Command="{Binding StartInstallCommand}"
/>
-
+
@@ -44,6 +44,7 @@
+