Browse Source

Merge pull request #44 from ionite34/one-click-dialog

pull/5/head
Ionite 1 year ago committed by GitHub
parent
commit
dd974f74e4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 2
      StabilityMatrix/App.xaml.cs
  2. 9
      StabilityMatrix/Helper/DialogFactory.cs
  3. 2
      StabilityMatrix/Helper/EventManager.cs
  4. 1
      StabilityMatrix/Helper/IDialogFactory.cs
  5. 3
      StabilityMatrix/Helper/PackageFactory.cs
  6. 3
      StabilityMatrix/LaunchOptionsDialog.xaml.cs
  7. 61
      StabilityMatrix/MainWindow.xaml
  8. 4
      StabilityMatrix/MainWindow.xaml.cs
  9. 3
      StabilityMatrix/Models/LaunchOptionDefinition.cs
  10. 1
      StabilityMatrix/Models/Packages/A3WebUI.cs
  11. 1
      StabilityMatrix/Models/Packages/BaseGitPackage.cs
  12. 4
      StabilityMatrix/Models/Packages/IArgParsable.cs
  13. 1
      StabilityMatrix/Models/Packages/VladAutomatic.cs
  14. 72
      StabilityMatrix/OneClickInstallDialog.xaml
  15. 24
      StabilityMatrix/OneClickInstallDialog.xaml.cs
  16. 1
      StabilityMatrix/Python/ArgParser.cs
  17. 5
      StabilityMatrix/StabilityMatrix.csproj
  18. 5
      StabilityMatrix/ViewModels/LaunchViewModel.cs
  19. 179
      StabilityMatrix/ViewModels/MainWindowViewModel.cs
  20. 162
      StabilityMatrix/ViewModels/OneClickInstallViewModel.cs

2
StabilityMatrix/App.xaml.cs

@ -9,7 +9,6 @@ using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using NLog.Extensions.Logging; using NLog.Extensions.Logging;
using NLog.Layouts;
using Polly; using Polly;
using Polly.Contrib.WaitAndRetry; using Polly.Contrib.WaitAndRetry;
using Polly.Extensions.Http; using Polly.Extensions.Http;
@ -78,6 +77,7 @@ namespace StabilityMatrix
serviceCollection.AddSingleton<PackageManagerViewModel>(); serviceCollection.AddSingleton<PackageManagerViewModel>();
serviceCollection.AddSingleton<TextToImageViewModel>(); serviceCollection.AddSingleton<TextToImageViewModel>();
serviceCollection.AddTransient<InstallerViewModel>(); serviceCollection.AddTransient<InstallerViewModel>();
serviceCollection.AddTransient<OneClickInstallViewModel>();
serviceCollection.AddSingleton<BasePackage, A3WebUI>(); serviceCollection.AddSingleton<BasePackage, A3WebUI>();
serviceCollection.AddSingleton<BasePackage, VladAutomatic>(); serviceCollection.AddSingleton<BasePackage, VladAutomatic>();

9
StabilityMatrix/Helper/DialogFactory.cs

@ -10,14 +10,16 @@ public class DialogFactory : IDialogFactory
private readonly IContentDialogService contentDialogService; private readonly IContentDialogService contentDialogService;
private readonly LaunchOptionsDialogViewModel launchOptionsDialogViewModel; private readonly LaunchOptionsDialogViewModel launchOptionsDialogViewModel;
private readonly InstallerViewModel installerViewModel; private readonly InstallerViewModel installerViewModel;
private readonly OneClickInstallViewModel oneClickInstallViewModel;
private readonly ISettingsManager settingsManager; private readonly ISettingsManager settingsManager;
public DialogFactory(IContentDialogService contentDialogService, LaunchOptionsDialogViewModel launchOptionsDialogViewModel, public DialogFactory(IContentDialogService contentDialogService, LaunchOptionsDialogViewModel launchOptionsDialogViewModel,
ISettingsManager settingsManager, InstallerViewModel installerViewModel) ISettingsManager settingsManager, InstallerViewModel installerViewModel, OneClickInstallViewModel oneClickInstallViewModel)
{ {
this.contentDialogService = contentDialogService; this.contentDialogService = contentDialogService;
this.launchOptionsDialogViewModel = launchOptionsDialogViewModel; this.launchOptionsDialogViewModel = launchOptionsDialogViewModel;
this.installerViewModel = installerViewModel; this.installerViewModel = installerViewModel;
this.oneClickInstallViewModel = oneClickInstallViewModel;
this.settingsManager = settingsManager; this.settingsManager = settingsManager;
} }
@ -33,6 +35,11 @@ public class DialogFactory : IDialogFactory
return new LaunchOptionsDialog(contentDialogService, launchOptionsDialogViewModel); return new LaunchOptionsDialog(contentDialogService, launchOptionsDialogViewModel);
} }
public OneClickInstallDialog CreateOneClickInstallDialog()
{
return new OneClickInstallDialog(contentDialogService, oneClickInstallViewModel);
}
public InstallerWindow CreateInstallerWindow() public InstallerWindow CreateInstallerWindow()
{ {
return new InstallerWindow(installerViewModel); return new InstallerWindow(installerViewModel);

2
StabilityMatrix/Helper/EventManager.cs

@ -15,8 +15,10 @@ public class EventManager
public event EventHandler<Type>? PageChangeRequested; public event EventHandler<Type>? PageChangeRequested;
public event EventHandler? InstalledPackagesChanged; public event EventHandler? InstalledPackagesChanged;
public event EventHandler? OneClickInstallFinished; public event EventHandler? OneClickInstallFinished;
public event EventHandler? TeachingTooltipNeeded;
public void OnGlobalProgressChanged(int progress) => GlobalProgressChanged?.Invoke(this, progress); public void OnGlobalProgressChanged(int progress) => GlobalProgressChanged?.Invoke(this, progress);
public void RequestPageChange(Type pageType) => PageChangeRequested?.Invoke(this, pageType); public void RequestPageChange(Type pageType) => PageChangeRequested?.Invoke(this, pageType);
public void OnInstalledPackagesChanged() => InstalledPackagesChanged?.Invoke(this, EventArgs.Empty); public void OnInstalledPackagesChanged() => InstalledPackagesChanged?.Invoke(this, EventArgs.Empty);
public void OnOneClickInstallFinished() => OneClickInstallFinished?.Invoke(this, EventArgs.Empty); public void OnOneClickInstallFinished() => OneClickInstallFinished?.Invoke(this, EventArgs.Empty);
public void OnTeachingTooltipNeeded() => TeachingTooltipNeeded?.Invoke(this, EventArgs.Empty);
} }

1
StabilityMatrix/Helper/IDialogFactory.cs

@ -7,4 +7,5 @@ public interface IDialogFactory
{ {
LaunchOptionsDialog CreateLaunchOptionsDialog(IEnumerable<LaunchOptionDefinition> definitions, InstalledPackage installedPackage); LaunchOptionsDialog CreateLaunchOptionsDialog(IEnumerable<LaunchOptionDefinition> definitions, InstalledPackage installedPackage);
InstallerWindow CreateInstallerWindow(); InstallerWindow CreateInstallerWindow();
OneClickInstallDialog CreateOneClickInstallDialog();
} }

3
StabilityMatrix/Helper/PackageFactory.cs

@ -1,5 +1,4 @@
using System; using System.Collections.Generic;
using System.Collections.Generic;
using System.Linq; using System.Linq;
using StabilityMatrix.Models; using StabilityMatrix.Models;

3
StabilityMatrix/LaunchOptionsDialog.xaml.cs

@ -1,8 +1,5 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics;
using System.Windows; using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using StabilityMatrix.Models; using StabilityMatrix.Models;
using StabilityMatrix.ViewModels; using StabilityMatrix.ViewModels;
using Wpf.Ui.Contracts; using Wpf.Ui.Contracts;

61
StabilityMatrix/MainWindow.xaml

@ -20,16 +20,7 @@
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:ui="http://schemas.lepo.co/wpfui/2022/xaml" xmlns:ui="http://schemas.lepo.co/wpfui/2022/xaml"
xmlns:viewModels="clr-namespace:StabilityMatrix.ViewModels" xmlns:viewModels="clr-namespace:StabilityMatrix.ViewModels"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
xmlns:converters="clr-namespace:StabilityMatrix.Converters">
<ui:FluentWindow.Resources>
<BooleanToVisibilityConverter x:Key="BoolToVisConverter" />
<converters:ValueConverterGroup x:Key="InvertAndVisibilitate">
<converters:BoolNegationConverter />
<BooleanToVisibilityConverter />
</converters:ValueConverterGroup>
</ui:FluentWindow.Resources>
<ui:FluentWindow.TaskbarItemInfo> <ui:FluentWindow.TaskbarItemInfo>
<TaskbarItemInfo ProgressState="{Binding ProgressState}" ProgressValue="{Binding ProgressValue}" /> <TaskbarItemInfo ProgressState="{Binding ProgressState}" ProgressValue="{Binding ProgressValue}" />
@ -46,10 +37,7 @@
<TextBlock Margin="16,8" Text="Stability Matrix" /> <TextBlock Margin="16,8" Text="Stability Matrix" />
</ui:TitleBar.Header> </ui:TitleBar.Header>
</ui:TitleBar> </ui:TitleBar>
<Grid Grid.Row="1" <Grid Grid.Row="1">
Visibility="{Binding IsAdvancedMode,
Converter={StaticResource BoolToVisConverter},
FallbackValue=Hidden}">
<ui:NavigationView <ui:NavigationView
IsBackButtonVisible="Collapsed" IsBackButtonVisible="Collapsed"
PaneClosed="RootNavigation_OnPaneClosed" PaneClosed="RootNavigation_OnPaneClosed"
@ -95,52 +83,7 @@
</ui:NavigationView.ContentOverlay> </ui:NavigationView.ContentOverlay>
</ui:NavigationView> </ui:NavigationView>
</Grid> </Grid>
<Grid Grid.Row="1"
Visibility="{Binding IsAdvancedMode,
Converter={StaticResource InvertAndVisibilitate},
FallbackValue=Visible}">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="1*"/>
<RowDefinition Height="0.25*"/>
</Grid.RowDefinitions>
<TextBlock Text="{Binding HeaderText}"
TextWrapping="Wrap"
VerticalAlignment="Top" HorizontalAlignment="Center"
FontSize="36" FontWeight="Light" Margin="8"/>
<TextBlock Grid.Row="1"
Text="{Binding SubHeaderText}"
TextWrapping="Wrap" TextAlignment="Center"
VerticalAlignment="Top" HorizontalAlignment="Center"
FontSize="16" FontWeight="Light" Margin="8">
</TextBlock>
<StackPanel Grid.Row="2" VerticalAlignment="Center">
<ProgressBar Maximum="100" Value="{Binding OneClickInstallProgress}"
Visibility="{Binding ProgressBarVisibility}"
IsIndeterminate="{Binding IsIndeterminate}"
Margin="16"/>
<ui:Button
Visibility="{Binding ShowInstallButton, Converter={StaticResource BoolToVisConverter}}"
Content="{Binding InstallButtonText, FallbackValue=Install}"
Command="{Binding InstallCommand}"
FontSize="32"
HorizontalAlignment="Center"
Margin="16"
Padding="16, 8, 16, 8" />
</StackPanel>
<Button Grid.Row="3"
Background="Transparent"
Visibility="{Binding ShowInstallButton, Converter={StaticResource BoolToVisConverter}}"
Command="{Binding ToggleAdvancedModeCommand}"
Content="Skip first-time setup"
FontSize="14"
HorizontalAlignment="Center"
Margin="16"
VerticalAlignment="Bottom" />
</Grid>
<ContentPresenter Grid.Row="1" x:Name="RootContentDialog" /> <ContentPresenter Grid.Row="1" x:Name="RootContentDialog" />
</Grid> </Grid>
</ui:FluentWindow> </ui:FluentWindow>

4
StabilityMatrix/MainWindow.xaml.cs

@ -42,11 +42,11 @@ namespace StabilityMatrix
RootNavigation.Navigate(e); RootNavigation.Navigate(e);
} }
private void MainWindow_OnLoaded(object sender, RoutedEventArgs e) private async void MainWindow_OnLoaded(object sender, RoutedEventArgs e)
{ {
RootNavigation.Navigate(typeof(LaunchPage)); RootNavigation.Navigate(typeof(LaunchPage));
mainWindowViewModel.OnLoaded();
RootNavigation.IsPaneOpen = settingsManager.Settings.IsNavExpanded; RootNavigation.IsPaneOpen = settingsManager.Settings.IsNavExpanded;
await mainWindowViewModel.OnLoaded();
} }
private void RootNavigation_OnPaneOpened(NavigationView sender, RoutedEventArgs args) private void RootNavigation_OnPaneOpened(NavigationView sender, RoutedEventArgs args)

3
StabilityMatrix/Models/LaunchOptionDefinition.cs

@ -1,5 +1,4 @@
using System; using System.Collections.Generic;
using System.Collections.Generic;
namespace StabilityMatrix.Models; namespace StabilityMatrix.Models;

1
StabilityMatrix/Models/Packages/A3WebUI.cs

@ -5,7 +5,6 @@ using System.IO;
using System.Linq; using System.Linq;
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
using System.Threading.Tasks; using System.Threading.Tasks;
using StabilityMatrix.Api;
using StabilityMatrix.Helper; using StabilityMatrix.Helper;
using StabilityMatrix.Helper.Cache; using StabilityMatrix.Helper.Cache;

1
StabilityMatrix/Models/Packages/BaseGitPackage.cs

@ -10,7 +10,6 @@ using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using NLog; using NLog;
using Refit; using Refit;
using StabilityMatrix.Api;
using StabilityMatrix.Helper; using StabilityMatrix.Helper;
using StabilityMatrix.Helper.Cache; using StabilityMatrix.Helper.Cache;
using StabilityMatrix.Models.Api; using StabilityMatrix.Models.Api;

4
StabilityMatrix/Models/Packages/IArgParsable.cs

@ -1,6 +1,4 @@
using System.Collections.Generic; namespace StabilityMatrix.Models.Packages;
namespace StabilityMatrix.Models.Packages;
/// <summary> /// <summary>
/// Supports parsing launch options from a python script. /// Supports parsing launch options from a python script.

1
StabilityMatrix/Models/Packages/VladAutomatic.cs

@ -4,7 +4,6 @@ using System.Diagnostics;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
using StabilityMatrix.Api;
using StabilityMatrix.Helper; using StabilityMatrix.Helper;
using StabilityMatrix.Helper.Cache; using StabilityMatrix.Helper.Cache;

72
StabilityMatrix/OneClickInstallDialog.xaml

@ -0,0 +1,72 @@
<ui:ContentDialog
CloseButtonText="Close"
Loaded="OneClickInstallDialog_OnLoaded"
Title="Stable Diffusion WebUI Installer"
d:DataContext="{d:DesignInstance Type=viewModels:OneClickInstallViewModel,
IsDesignTimeCreatable=True}"
d:DesignHeight="512"
d:DesignWidth="640"
mc:Ignorable="d"
ui:Design.Background="{DynamicResource ApplicationBackgroundBrush}"
ui:Design.Foreground="{DynamicResource TextFillColorPrimaryBrush}"
x:Class="StabilityMatrix.OneClickInstallDialog"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:StabilityMatrix"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:ui="http://schemas.lepo.co/wpfui/2022/xaml"
xmlns:viewModels="clr-namespace:StabilityMatrix.ViewModels"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<ui:ContentDialog.Resources>
<!-- ReSharper disable once Xaml.StaticResourceNotResolved -->
<Style BasedOn="{StaticResource {x:Type ui:ContentDialog}}" TargetType="{x:Type local:OneClickInstallDialog}" />
<BooleanToVisibilityConverter x:Key="BoolToVisConverter" />
</ui:ContentDialog.Resources>
<Grid MaxHeight="900" VerticalAlignment="Stretch">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="1*" />
<RowDefinition Height="0.25*" />
</Grid.RowDefinitions>
<TextBlock Text="{Binding HeaderText}"
TextWrapping="Wrap"
VerticalAlignment="Top" HorizontalAlignment="Center"
FontSize="36" FontWeight="Light" Margin="8" />
<TextBlock Grid.Row="1"
Text="{Binding SubHeaderText}"
TextWrapping="Wrap" TextAlignment="Center"
VerticalAlignment="Top" HorizontalAlignment="Center"
FontSize="16" FontWeight="Light" Margin="8">
</TextBlock>
<StackPanel Grid.Row="2" VerticalAlignment="Center">
<ProgressBar Maximum="100" Value="{Binding OneClickInstallProgress}"
Visibility="{Binding ProgressBarVisibility}"
IsIndeterminate="{Binding IsIndeterminate}"
Margin="16" />
<ui:Button
Visibility="{Binding ShowInstallButton, Converter={StaticResource BoolToVisConverter}}"
Content="Install"
Command="{Binding InstallCommand}"
FontSize="32"
HorizontalAlignment="Center"
Appearance="Primary"
Margin="16"
Padding="16, 8, 16, 8" />
</StackPanel>
<ui:Button Grid.Row="3"
Appearance="Transparent"
Visibility="{Binding ShowInstallButton, Converter={StaticResource BoolToVisConverter}}"
Command="{Binding ToggleAdvancedModeCommand}"
Content="Skip first-time setup"
FontSize="14"
HorizontalAlignment="Center"
Margin="16"
VerticalAlignment="Bottom" />
</Grid>
</ui:ContentDialog>

24
StabilityMatrix/OneClickInstallDialog.xaml.cs

@ -0,0 +1,24 @@
using System.Windows;
using StabilityMatrix.ViewModels;
using Wpf.Ui.Contracts;
using Wpf.Ui.Controls.ContentDialogControl;
namespace StabilityMatrix;
public partial class OneClickInstallDialog : ContentDialog
{
private readonly OneClickInstallViewModel viewModel;
public OneClickInstallDialog(IContentDialogService dialogService, OneClickInstallViewModel viewModel) : base(
dialogService.GetContentPresenter())
{
this.viewModel = viewModel;
InitializeComponent();
DataContext = viewModel;
}
private void OneClickInstallDialog_OnLoaded(object sender, RoutedEventArgs e)
{
//viewModel.OnLoad();
}
}

1
StabilityMatrix/Python/ArgParser.cs

@ -1,6 +1,5 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Globalization;
using System.Threading.Tasks; using System.Threading.Tasks;
using NLog; using NLog;
using Python.Runtime; using Python.Runtime;

5
StabilityMatrix/StabilityMatrix.csproj

@ -67,6 +67,11 @@
<XamlRuntime>Wpf</XamlRuntime> <XamlRuntime>Wpf</XamlRuntime>
<SubType>Designer</SubType> <SubType>Designer</SubType>
</Page> </Page>
<Page Update="OneClickInstallDialog.xaml">
<Generator>MSBuild:Compile</Generator>
<XamlRuntime>Wpf</XamlRuntime>
<SubType>Designer</SubType>
</Page>
</ItemGroup> </ItemGroup>
</Project> </Project>

5
StabilityMatrix/ViewModels/LaunchViewModel.cs

@ -1,5 +1,4 @@
using System; using System;
using System.Collections.Generic;
using System.Collections.ObjectModel; using System.Collections.ObjectModel;
using System.Diagnostics; using System.Diagnostics;
using System.Linq; using System.Linq;
@ -85,12 +84,12 @@ public partial class LaunchViewModel : ObservableObject
SetProcessRunning(false); SetProcessRunning(false);
EventManager.Instance.InstalledPackagesChanged += OnInstalledPackagesChanged; EventManager.Instance.InstalledPackagesChanged += OnInstalledPackagesChanged;
EventManager.Instance.OneClickInstallFinished += OnOneClickInstallFinished; EventManager.Instance.TeachingTooltipNeeded += OnTeachingTooltipNeeded;
ToastNotificationManagerCompat.OnActivated += ToastNotificationManagerCompatOnOnActivated; ToastNotificationManagerCompat.OnActivated += ToastNotificationManagerCompatOnOnActivated;
} }
private void OnOneClickInstallFinished(object? sender, EventArgs e) private void OnTeachingTooltipNeeded(object? sender, EventArgs e)
{ {
IsLaunchTeachingTipsOpen = true; IsLaunchTeachingTipsOpen = true;
} }

179
StabilityMatrix/ViewModels/MainWindowViewModel.cs

@ -1,16 +1,10 @@
using System; using System;
using System.Diagnostics;
using System.Linq; using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
using System.Windows;
using System.Windows.Threading; using System.Windows.Threading;
using System.Windows.Shell; using System.Windows.Shell;
using CommunityToolkit.Mvvm.ComponentModel; using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using Microsoft.Extensions.Logging;
using StabilityMatrix.Helper; using StabilityMatrix.Helper;
using StabilityMatrix.Models;
using StabilityMatrix.Python;
using Wpf.Ui.Appearance; using Wpf.Ui.Appearance;
using EventManager = StabilityMatrix.Helper.EventManager; using EventManager = StabilityMatrix.Helper.EventManager;
@ -19,37 +13,17 @@ namespace StabilityMatrix.ViewModels;
public partial class MainWindowViewModel : ObservableObject public partial class MainWindowViewModel : ObservableObject
{ {
private readonly ISettingsManager settingsManager; private readonly ISettingsManager settingsManager;
private readonly IPackageFactory packageFactory; private readonly IDialogFactory dialogFactory;
private readonly IPrerequisiteHelper prerequisiteHelper;
private readonly ILogger<MainWindowViewModel> logger;
private readonly IPyRunner pyRunner;
private const string DefaultPackageName = "stable-diffusion-webui";
public MainWindowViewModel(ISettingsManager settingsManager, IPackageFactory packageFactory, public MainWindowViewModel(ISettingsManager settingsManager, IDialogFactory dialogFactory)
IPrerequisiteHelper prerequisiteHelper, ILogger<MainWindowViewModel> logger, IPyRunner pyRunner)
{ {
this.settingsManager = settingsManager; this.settingsManager = settingsManager;
this.packageFactory = packageFactory; this.dialogFactory = dialogFactory;
this.prerequisiteHelper = prerequisiteHelper;
this.logger = logger;
this.pyRunner = pyRunner;
} }
[ObservableProperty]
private bool isAdvancedMode;
[ObservableProperty] [ObservableProperty]
private float progressValue; private float progressValue;
[ObservableProperty]
private string headerText;
[ObservableProperty]
private string subHeaderText;
[ObservableProperty]
[NotifyPropertyChangedFor(nameof(ProgressBarVisibility))]
private int oneClickInstallProgress;
[ObservableProperty] [ObservableProperty]
private bool isIndeterminate; private bool isIndeterminate;
@ -57,154 +31,27 @@ public partial class MainWindowViewModel : ObservableObject
[ObservableProperty] [ObservableProperty]
private TaskbarItemProgressState progressState; private TaskbarItemProgressState progressState;
[ObservableProperty]
private bool showInstallButton;
[ObservableProperty] public async Task OnLoaded()
private string installButtonText;
public Visibility ProgressBarVisibility => ProgressValue > 0 ? Visibility.Visible : Visibility.Collapsed;
private string webUrl = string.Empty;
public void OnLoaded()
{ {
SetTheme(); SetTheme();
ShowInstallButton = true;
EventManager.Instance.GlobalProgressChanged += OnGlobalProgressChanged; EventManager.Instance.GlobalProgressChanged += OnGlobalProgressChanged;
if (settingsManager.Settings.InstalledPackages.Any()) if (!settingsManager.Settings.InstalledPackages.Any())
{
IsAdvancedMode = true;
}
else
{ {
IsAdvancedMode = false; var dialog = dialogFactory.CreateOneClickInstallDialog();
InstallButtonText = "Install"; dialog.IsPrimaryButtonEnabled = false;
HeaderText = "Click the Install button below to get started!"; dialog.IsSecondaryButtonEnabled = false;
SubHeaderText = dialog.IsFooterVisible = false;
"This will install the latest version of Stable Diffusion WebUI by Automatic1111.\nIf you don't know what this means, don't worry, you'll be generating images soon!";
}
}
[RelayCommand]
private void ToggleAdvancedMode()
{
IsAdvancedMode = !IsAdvancedMode;
EventManager.Instance.RequestPageChange(typeof(PackageManagerPage));
}
[RelayCommand]
private async Task Install()
{
if (InstallButtonText == "Install")
{
ShowInstallButton = false;
await DoInstall();
ShowInstallButton = true;
}
else
{
ToggleAdvancedMode();
}
}
private async Task DoInstall() EventManager.Instance.OneClickInstallFinished += (_, _) =>
{
var a1111 = packageFactory.FindPackageByName(DefaultPackageName)!;
HeaderText = "Installing Stable Diffusion WebUI...";
// check git
var gitProcess = await prerequisiteHelper.InstallGitIfNecessary();
if (gitProcess != null) // git isn't installed
{ {
IsIndeterminate = true; dialog.Hide();
SubHeaderText = "Installing git..."; EventManager.Instance.OnTeachingTooltipNeeded();
await gitProcess.WaitForExitAsync();
if (gitProcess.ExitCode != 0)
{
HeaderText = "Installation failed";
SubHeaderText = "Error installing git. Please try again later.";
OneClickInstallProgress = 0;
logger.LogError($"Git install failed with exit code {gitProcess.ExitCode}");
}
}
SubHeaderText = "Installing prerequisites...";
IsIndeterminate = true;
if (!PyRunner.PipInstalled)
{
await pyRunner.SetupPip();
}
if (!PyRunner.VenvInstalled)
{
await pyRunner.InstallPackage("virtualenv");
}
IsIndeterminate = false;
// get latest version & download & install
SubHeaderText = "Getting latest version...";
var latestVersion = await a1111.GetLatestVersion();
a1111.InstallLocation += "\\stable-diffusion-webui";
await DownloadPackage(a1111, latestVersion);
await InstallPackage(a1111);
var package = new InstalledPackage
{
DisplayName = a1111.DisplayName,
Path = a1111.InstallLocation,
Id = Guid.NewGuid(),
PackageName = a1111.Name,
PackageVersion = latestVersion,
LaunchCommand = a1111.LaunchCommand,
LastUpdateCheck = DateTimeOffset.Now
}; };
settingsManager.AddInstalledPackage(package);
settingsManager.SetActiveInstalledPackage(package);
EventManager.Instance.OnInstalledPackagesChanged();
HeaderText = "Installation complete!";
OneClickInstallProgress = 100;
SubHeaderText = "Proceeding to Launch page in 3 seconds...";
await Task.Delay(1000);
SubHeaderText = "Proceeding to Launch page in 2 seconds...";
await Task.Delay(1000);
SubHeaderText = "Proceeding to Launch page in 1 second...";
await Task.Delay(1000);
IsAdvancedMode = true;
EventManager.Instance.OnOneClickInstallFinished();
}
private Task<string?> DownloadPackage(BasePackage selectedPackage, string version)
{
selectedPackage.DownloadProgressChanged += SelectedPackageOnProgressChanged;
selectedPackage.DownloadComplete += (_, _) => SubHeaderText = "Download Complete";
SubHeaderText = "Downloading package...";
return selectedPackage.DownloadPackage(version: version);
}
private async Task InstallPackage(BasePackage selectedPackage)
{
selectedPackage.InstallProgressChanged += SelectedPackageOnProgressChanged;
selectedPackage.InstallComplete += (_, _) => HeaderText = "Install Complete";
SubHeaderText = "Installing package...";
await selectedPackage.InstallPackage();
}
private void SelectedPackageOnProgressChanged(object? sender, int progress) await dialog.ShowAsync();
{
if (progress == -1)
{
IsIndeterminate = true;
} }
else
{
IsIndeterminate = false;
OneClickInstallProgress = progress;
}
OnGlobalProgressChanged(this, progress);
} }
/// <summary> /// <summary>

162
StabilityMatrix/ViewModels/OneClickInstallViewModel.cs

@ -0,0 +1,162 @@
using System;
using System.Threading.Tasks;
using System.Windows;
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using Microsoft.Extensions.Logging;
using StabilityMatrix.Helper;
using StabilityMatrix.Models;
using StabilityMatrix.Python;
using EventManager = StabilityMatrix.Helper.EventManager;
namespace StabilityMatrix.ViewModels;
public partial class OneClickInstallViewModel : ObservableObject
{
private readonly ISettingsManager settingsManager;
private readonly IPackageFactory packageFactory;
private readonly IPrerequisiteHelper prerequisiteHelper;
private readonly ILogger<MainWindowViewModel> logger;
private readonly IPyRunner pyRunner;
private const string DefaultPackageName = "stable-diffusion-webui";
[ObservableProperty] private string headerText;
[ObservableProperty] private string subHeaderText;
[ObservableProperty] private bool showInstallButton;
[ObservableProperty] private bool isIndeterminate;
[ObservableProperty]
[NotifyPropertyChangedFor(nameof(ProgressBarVisibility))]
private int oneClickInstallProgress;
public Visibility ProgressBarVisibility => OneClickInstallProgress > 0 ? Visibility.Visible : Visibility.Collapsed;
public OneClickInstallViewModel(ISettingsManager settingsManager, IPackageFactory packageFactory,
IPrerequisiteHelper prerequisiteHelper, ILogger<MainWindowViewModel> logger, IPyRunner pyRunner)
{
this.settingsManager = settingsManager;
this.packageFactory = packageFactory;
this.prerequisiteHelper = prerequisiteHelper;
this.logger = logger;
this.pyRunner = pyRunner;
HeaderText = "Click the Install button below to get started!";
SubHeaderText =
"This will install the latest version of Stable Diffusion WebUI by Automatic1111.\nIf you don't know what this means, don't worry, you'll be generating images soon!";
ShowInstallButton = true;
}
[RelayCommand]
private async Task Install()
{
ShowInstallButton = false;
await DoInstall();
ShowInstallButton = true;
}
[RelayCommand]
private Task ToggleAdvancedMode()
{
EventManager.Instance.OnOneClickInstallFinished();
return Task.CompletedTask;
}
private async Task DoInstall()
{
var a1111 = packageFactory.FindPackageByName(DefaultPackageName)!;
HeaderText = "Installing Stable Diffusion WebUI...";
// check git
var gitProcess = await prerequisiteHelper.InstallGitIfNecessary();
if (gitProcess != null) // git isn't installed
{
IsIndeterminate = true;
SubHeaderText = "Installing git...";
await gitProcess.WaitForExitAsync();
if (gitProcess.ExitCode != 0)
{
HeaderText = "Installation failed";
SubHeaderText = "Error installing git. Please try again later.";
OneClickInstallProgress = 0;
logger.LogError($"Git install failed with exit code {gitProcess.ExitCode}");
}
}
SubHeaderText = "Installing prerequisites...";
IsIndeterminate = true;
if (!PyRunner.PipInstalled)
{
await pyRunner.SetupPip();
}
if (!PyRunner.VenvInstalled)
{
await pyRunner.InstallPackage("virtualenv");
}
IsIndeterminate = false;
// get latest version & download & install
SubHeaderText = "Getting latest version...";
var latestVersion = await a1111.GetLatestVersion();
a1111.InstallLocation += "\\stable-diffusion-webui";
await DownloadPackage(a1111, latestVersion);
await InstallPackage(a1111);
var package = new InstalledPackage
{
DisplayName = a1111.DisplayName,
Path = a1111.InstallLocation,
Id = Guid.NewGuid(),
PackageName = a1111.Name,
PackageVersion = latestVersion,
LaunchCommand = a1111.LaunchCommand,
LastUpdateCheck = DateTimeOffset.Now
};
settingsManager.AddInstalledPackage(package);
settingsManager.SetActiveInstalledPackage(package);
EventManager.Instance.OnInstalledPackagesChanged();
HeaderText = "Installation complete!";
OneClickInstallProgress = 100;
SubHeaderText = "Proceeding to Launch page in 3 seconds...";
await Task.Delay(1000);
SubHeaderText = "Proceeding to Launch page in 2 seconds...";
await Task.Delay(1000);
SubHeaderText = "Proceeding to Launch page in 1 second...";
await Task.Delay(1000);
// should close dialog
EventManager.Instance.OnOneClickInstallFinished();
}
private Task<string?> DownloadPackage(BasePackage selectedPackage, string version)
{
selectedPackage.DownloadProgressChanged += SelectedPackageOnProgressChanged;
selectedPackage.DownloadComplete += (_, _) => SubHeaderText = "Download Complete";
SubHeaderText = "Downloading package...";
return selectedPackage.DownloadPackage(version: version);
}
private async Task InstallPackage(BasePackage selectedPackage)
{
selectedPackage.InstallProgressChanged += SelectedPackageOnProgressChanged;
selectedPackage.InstallComplete += (_, _) => HeaderText = "Install Complete";
SubHeaderText = "Installing package...";
await selectedPackage.InstallPackage();
}
private void SelectedPackageOnProgressChanged(object? sender, int progress)
{
if (progress == -1)
{
IsIndeterminate = true;
}
else
{
IsIndeterminate = false;
OneClickInstallProgress = progress;
}
EventManager.Instance.OnGlobalProgressChanged(progress);
}
}
Loading…
Cancel
Save