Browse Source

implemented package updater

- Packages are now injected & so is IPackageFactory
- Updater checks on load, so probably only once per launch? but should be fine
- Moved install button
- Multi-purpose install button
- probably more idk
pull/5/head
JT 1 year ago
parent
commit
8ae6d1f483
  1. 6
      StabilityMatrix/App.xaml.cs
  2. 2
      StabilityMatrix/Helper/EventManager.cs
  3. 10
      StabilityMatrix/Helper/IPackageFactory.cs
  4. 1
      StabilityMatrix/Helper/ISettingsManager.cs
  5. 22
      StabilityMatrix/Helper/PackageFactory.cs
  6. 13
      StabilityMatrix/Helper/SettingsManager.cs
  7. 23
      StabilityMatrix/InstallPage.xaml
  8. 9
      StabilityMatrix/MainWindow.xaml.cs
  9. 15
      StabilityMatrix/Models/BasePackage.cs
  10. 1
      StabilityMatrix/Models/InstalledPackage.cs
  11. 92
      StabilityMatrix/Models/Packages/A3WebUI.cs
  12. 14
      StabilityMatrix/Models/Packages/DankDiffusion.cs
  13. 106
      StabilityMatrix/ViewModels/InstallerViewModel.cs
  14. 6
      StabilityMatrix/ViewModels/LaunchViewModel.cs
  15. 7
      StabilityMatrix/ViewModels/MainWindowViewModel.cs

6
StabilityMatrix/App.xaml.cs

@ -5,12 +5,15 @@ using System.IO;
using System.Text.Json; using System.Text.Json;
using System.Text.Json.Serialization; using System.Text.Json.Serialization;
using System.Windows; using System.Windows;
using Windows.ApplicationModel;
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 Refit; using Refit;
using StabilityMatrix.Api; using StabilityMatrix.Api;
using StabilityMatrix.Helper; using StabilityMatrix.Helper;
using StabilityMatrix.Models;
using StabilityMatrix.Models.Packages;
using StabilityMatrix.Services; using StabilityMatrix.Services;
using StabilityMatrix.ViewModels; using StabilityMatrix.ViewModels;
using Wpf.Ui.Contracts; using Wpf.Ui.Contracts;
@ -46,6 +49,9 @@ namespace StabilityMatrix
serviceCollection.AddSingleton<InstallerViewModel>(); serviceCollection.AddSingleton<InstallerViewModel>();
serviceCollection.AddSingleton<TextToImageViewModel>(); serviceCollection.AddSingleton<TextToImageViewModel>();
serviceCollection.AddSingleton<IContentDialogService, ContentDialogService>(); serviceCollection.AddSingleton<IContentDialogService, ContentDialogService>();
serviceCollection.AddSingleton<IPackageFactory, PackageFactory>();
serviceCollection.AddSingleton<BasePackage, A3WebUI>();
serviceCollection.AddSingleton<BasePackage, DankDiffusion>();
serviceCollection.AddSingleton<ISnackbarService, SnackbarService>(); serviceCollection.AddSingleton<ISnackbarService, SnackbarService>();
serviceCollection.AddSingleton<ISettingsManager, SettingsManager>(); serviceCollection.AddSingleton<ISettingsManager, SettingsManager>();

2
StabilityMatrix/Helper/EventManager.cs

@ -12,5 +12,7 @@ public class EventManager
} }
public event EventHandler<int>? GlobalProgressChanged; public event EventHandler<int>? GlobalProgressChanged;
public event EventHandler<Type>? PageChangeRequested;
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);
} }

10
StabilityMatrix/Helper/IPackageFactory.cs

@ -0,0 +1,10 @@
using System.Collections.Generic;
using StabilityMatrix.Models;
namespace StabilityMatrix.Helper;
public interface IPackageFactory
{
IEnumerable<BasePackage> GetAllAvailablePackages();
BasePackage? FindPackageByName(string packageName);
}

1
StabilityMatrix/Helper/ISettingsManager.cs

@ -11,4 +11,5 @@ public interface ISettingsManager
void SetHasInstalledPip(bool hasInstalledPip); void SetHasInstalledPip(bool hasInstalledPip);
void SetHasInstalledVenv(bool hasInstalledVenv); void SetHasInstalledVenv(bool hasInstalledVenv);
void SetNavExpanded(bool navExpanded); void SetNavExpanded(bool navExpanded);
void UpdatePackageVersionNumber(string packageName, string newVersion);
} }

22
StabilityMatrix/Helper/PackageFactory.cs

@ -2,25 +2,25 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using StabilityMatrix.Models; using StabilityMatrix.Models;
using StabilityMatrix.Models.Packages;
namespace StabilityMatrix.Helper; namespace StabilityMatrix.Helper;
public static class PackageFactory public class PackageFactory : IPackageFactory
{ {
private static readonly List<BasePackage> AllPackages = new() private readonly IEnumerable<BasePackage> basePackages;
{
new A3WebUI(),
new DankDiffusion()
};
public static IEnumerable<BasePackage> GetAllAvailablePackages() public PackageFactory(IEnumerable<BasePackage> basePackages)
{
this.basePackages = basePackages;
}
public IEnumerable<BasePackage> GetAllAvailablePackages()
{ {
return AllPackages; return basePackages;
} }
public static BasePackage? FindPackageByName(string packageName) public BasePackage? FindPackageByName(string packageName)
{ {
return AllPackages.FirstOrDefault(x => x.Name.Equals(packageName, StringComparison.OrdinalIgnoreCase)); return basePackages.FirstOrDefault(x => x.Name.Equals(packageName, StringComparison.OrdinalIgnoreCase));
} }
} }

13
StabilityMatrix/Helper/SettingsManager.cs

@ -1,5 +1,6 @@
using System; using System;
using System.IO; using System.IO;
using System.Linq;
using System.Text.Json; using System.Text.Json;
using StabilityMatrix.Models; using StabilityMatrix.Models;
@ -74,6 +75,18 @@ public class SettingsManager : ISettingsManager
SaveSettings(); SaveSettings();
} }
public void UpdatePackageVersionNumber(string packageName, string? newVersion)
{
var package = Settings.InstalledPackages.FirstOrDefault(x => x.PackageName == packageName);
if (package == null || newVersion == null)
{
return;
}
package.PackageVersion = newVersion;
SaveSettings();
}
private void LoadSettings() private void LoadSettings()
{ {
var settingsContent = File.ReadAllText(SettingsPath); var settingsContent = File.ReadAllText(SettingsPath);

23
StabilityMatrix/InstallPage.xaml

@ -19,17 +19,18 @@
<RowDefinition Height="*" /> <RowDefinition Height="*" />
</Grid.RowDefinitions> </Grid.RowDefinitions>
<StackPanel Grid.Row="0" Orientation="Vertical"> <StackPanel Grid.Row="0" Orientation="Vertical"
<Button Content="Install" Command="{Binding InstallCommand}" Width="100" Height="50" Visibility="{Binding ProgressBarVisibility, FallbackValue=Visible}">
HorizontalAlignment="Center" />
<TextBlock Text="{Binding InstalledText}" HorizontalAlignment="Center" Padding="8" /> <ProgressBar Value="{Binding ProgressValue, FallbackValue=10}"
<ProgressBar Visibility="{Binding ProgressBarVisibility, FallbackValue=Visible}"
Value="{Binding ProgressValue, FallbackValue=10}"
IsIndeterminate="{Binding IsIndeterminate, FallbackValue=False}" IsIndeterminate="{Binding IsIndeterminate, FallbackValue=False}"
Maximum="100" Width="500" /> Maximum="100" Width="500" />
<TextBlock Text="{Binding ProgressText, FallbackValue=Installing...}"
HorizontalAlignment="Center" Padding="8" />
</StackPanel> </StackPanel>
<StackPanel Grid.Row="1" Orientation="Horizontal" Margin="16" HorizontalAlignment="Left" Height="400"> <StackPanel Grid.Row="1" Orientation="Horizontal"
Margin="16" HorizontalAlignment="Left">
<ListView ItemsSource="{Binding Packages}" <ListView ItemsSource="{Binding Packages}"
SelectedItem="{Binding SelectedPackage, Mode=TwoWay}"> SelectedItem="{Binding SelectedPackage, Mode=TwoWay}">
@ -67,6 +68,14 @@
<Run Text="{Binding SelectedPackage.GithubUrl, Mode=OneWay}" TextDecorations="Underline" /> <Run Text="{Binding SelectedPackage.GithubUrl, Mode=OneWay}" TextDecorations="Underline" />
</TextBlock> </TextBlock>
</ui:Hyperlink> </ui:Hyperlink>
<Button Content="{Binding InstallButtonText, FallbackValue=Install}"
Command="{Binding InstallCommand}"
IsEnabled="{Binding InstallButtonEnabled, FallbackValue=true}"
Width="100" Height="50"
Background="Green"
Margin="0,16,0,0"
VerticalAlignment="Top" />
</StackPanel> </StackPanel>
</StackPanel> </StackPanel>
</Grid> </Grid>

9
StabilityMatrix/MainWindow.xaml.cs

@ -1,3 +1,4 @@
using System;
using System.Diagnostics; using System.Diagnostics;
using System.Windows; using System.Windows;
using StabilityMatrix.Helper; using StabilityMatrix.Helper;
@ -5,6 +6,7 @@ using StabilityMatrix.ViewModels;
using Wpf.Ui.Contracts; using Wpf.Ui.Contracts;
using Wpf.Ui.Controls.Navigation; using Wpf.Ui.Controls.Navigation;
using Wpf.Ui.Controls.Window; using Wpf.Ui.Controls.Window;
using EventManager = StabilityMatrix.Helper.EventManager;
namespace StabilityMatrix namespace StabilityMatrix
{ {
@ -30,6 +32,13 @@ namespace StabilityMatrix
RootNavigation.SetPageService(pageService); RootNavigation.SetPageService(pageService);
contentDialogService.SetContentPresenter(RootContentDialog); contentDialogService.SetContentPresenter(RootContentDialog);
EventManager.Instance.PageChangeRequested += InstanceOnPageChangeRequested;
}
private void InstanceOnPageChangeRequested(object? sender, Type e)
{
RootNavigation.Navigate(e);
} }
private void MainWindow_OnLoaded(object sender, RoutedEventArgs e) private void MainWindow_OnLoaded(object sender, RoutedEventArgs e)

15
StabilityMatrix/Models/BasePackage.cs

@ -11,13 +11,13 @@ public abstract class BasePackage
public abstract string GithubUrl { get; } public abstract string GithubUrl { get; }
public abstract string LaunchCommand { get; } public abstract string LaunchCommand { get; }
public abstract string DefaultLaunchArguments { get; } public abstract string DefaultLaunchArguments { get; }
public virtual bool UpdateAvailable { get; set; }
public abstract Task<string?> DownloadPackage(bool isUpdate = false);
public abstract Task DownloadPackage(); public abstract Task InstallPackage(bool isUpdate = false);
public abstract Task InstallPackage();
public abstract Task RunPackage(string installedPackagePath, string arguments); public abstract Task RunPackage(string installedPackagePath, string arguments);
public abstract Task Shutdown(); public abstract Task Shutdown();
public abstract Task<bool> CheckForUpdates();
public abstract Task<string?> Update();
internal virtual string DownloadLocation => $"{Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData)}\\StabilityMatrix\\Packages\\{Name}.zip"; internal virtual string DownloadLocation => $"{Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData)}\\StabilityMatrix\\Packages\\{Name}.zip";
internal virtual string InstallLocation => $"{Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData)}\\StabilityMatrix\\Packages\\{Name}"; internal virtual string InstallLocation => $"{Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData)}\\StabilityMatrix\\Packages\\{Name}";
@ -26,6 +26,8 @@ public abstract class BasePackage
public event EventHandler<string>? DownloadComplete; public event EventHandler<string>? DownloadComplete;
public event EventHandler<int>? InstallProgressChanged; public event EventHandler<int>? InstallProgressChanged;
public event EventHandler<string>? InstallComplete; public event EventHandler<string>? InstallComplete;
public event EventHandler<int>? UpdateProgressChanged;
public event EventHandler<string>? UpdateComplete;
public event EventHandler<string>? ConsoleOutput; public event EventHandler<string>? ConsoleOutput;
public event EventHandler<int>? Exited; public event EventHandler<int>? Exited;
public event EventHandler<string>? StartupComplete; public event EventHandler<string>? StartupComplete;
@ -37,6 +39,9 @@ public abstract class BasePackage
public void OnConsoleOutput(string output) => ConsoleOutput?.Invoke(this, output); public void OnConsoleOutput(string output) => ConsoleOutput?.Invoke(this, output);
public void OnExit(int exitCode) => Exited?.Invoke(this, exitCode); public void OnExit(int exitCode) => Exited?.Invoke(this, exitCode);
public void OnStartupComplete(string url) => StartupComplete?.Invoke(this, url); public void OnStartupComplete(string url) => StartupComplete?.Invoke(this, url);
public void OnUpdateProgressChanged(int progress) => UpdateProgressChanged?.Invoke(this, progress);
public void OnUpdateComplete(string path) => UpdateComplete?.Invoke(this, path);
public string ByAuthor => $"By {Author}"; public string ByAuthor => $"By {Author}";
} }

1
StabilityMatrix/Models/InstalledPackage.cs

@ -19,5 +19,4 @@ public class InstalledPackage
public string? Path { get; set; } public string? Path { get; set; }
public string? LaunchCommand { get; set; } public string? LaunchCommand { get; set; }
} }

92
StabilityMatrix/Models/Packages/A3WebUI.cs

@ -2,6 +2,7 @@
using System.Diagnostics; using System.Diagnostics;
using System.IO; using System.IO;
using System.IO.Compression; using System.IO.Compression;
using System.Linq;
using System.Net.Http; using System.Net.Http;
using System.Net.Http.Headers; using System.Net.Http.Headers;
using System.Threading; using System.Threading;
@ -15,6 +16,7 @@ namespace StabilityMatrix.Models.Packages;
public class A3WebUI : BasePackage public class A3WebUI : BasePackage
{ {
private readonly ISettingsManager settingsManager;
private PyVenvRunner? venvRunner; private PyVenvRunner? venvRunner;
public override string Name => "stable-diffusion-webui"; public override string Name => "stable-diffusion-webui";
@ -24,11 +26,18 @@ public class A3WebUI : BasePackage
public override string LaunchCommand => "launch.py"; public override string LaunchCommand => "launch.py";
public override string DefaultLaunchArguments => $"{GetVramOption()} {GetXformersOption()}"; public override string DefaultLaunchArguments => $"{GetVramOption()} {GetXformersOption()}";
public override bool UpdateAvailable { get; set; } = false;
private static readonly Logger Logger = LogManager.GetCurrentClassLogger(); private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
private string webUrl = string.Empty; private string webUrl = string.Empty;
public override async Task DownloadPackage() public A3WebUI(ISettingsManager settingsManager)
{
this.settingsManager = settingsManager;
}
public override async Task<string?> DownloadPackage(bool isUpdate = false)
{ {
var githubApi = RestService.For<IGithubApi>("https://api.github.com"); var githubApi = RestService.For<IGithubApi>("https://api.github.com");
var latestRelease = await githubApi.GetLatestRelease("AUTOMATIC1111", "stable-diffusion-webui"); var latestRelease = await githubApi.GetLatestRelease("AUTOMATIC1111", "stable-diffusion-webui");
@ -69,24 +78,50 @@ public class A3WebUI : BasePackage
if (isIndeterminate) if (isIndeterminate)
{ {
OnDownloadProgressChanged(-1); if (isUpdate)
{
OnUpdateProgressChanged(-1);
}
else
{
OnDownloadProgressChanged(-1);
}
} }
else else
{ {
var progress = (int)(totalBytesRead * 100d / contentLength); var progress = (int)(totalBytesRead * 100d / contentLength);
Logger.Debug($"Progress; {progress}"); Logger.Debug($"Progress; {progress}");
OnDownloadProgressChanged(progress);
if (isUpdate)
{
OnUpdateProgressChanged(progress);
}
else
{
OnDownloadProgressChanged(progress);
}
} }
} }
await file.FlushAsync(); await file.FlushAsync();
OnDownloadComplete(DownloadLocation); OnDownloadComplete(DownloadLocation);
return latestRelease.TagName;
} }
public override Task InstallPackage() public override Task InstallPackage(bool isUpdate = false)
{ {
UnzipPackage(); UnzipPackage(isUpdate);
OnInstallComplete("Installation complete");
if (isUpdate)
{
OnUpdateComplete("Update complete");
}
else
{
OnInstallComplete("Installation complete");
}
return Task.CompletedTask; return Task.CompletedTask;
} }
@ -135,10 +170,40 @@ public class A3WebUI : BasePackage
return Task.CompletedTask; return Task.CompletedTask;
} }
public override async Task<bool> CheckForUpdates()
{
var currentVersion = settingsManager.Settings.InstalledPackages.FirstOrDefault(x => x.Name == Name)
?.PackageVersion;
if (string.IsNullOrWhiteSpace(currentVersion))
{
return false;
}
var githubApi = RestService.For<IGithubApi>("https://api.github.com");
var latestRelease = await githubApi.GetLatestRelease("AUTOMATIC1111", "stable-diffusion-webui");
UpdateAvailable = latestRelease.TagName != currentVersion;
return latestRelease.TagName != currentVersion;
}
public override async Task<string?> Update()
{
var version = await DownloadPackage(true);
await InstallPackage(true);
private void UnzipPackage() return version;
}
private void UnzipPackage(bool isUpdate = false)
{ {
OnInstallProgressChanged(0); if (isUpdate)
{
OnInstallProgressChanged(0);
}
else
{
OnUpdateProgressChanged(0);
}
Directory.CreateDirectory(InstallLocation); Directory.CreateDirectory(InstallLocation);
@ -170,9 +235,16 @@ public class A3WebUI : BasePackage
currentEntry++; currentEntry++;
var progressValue = (int)((double)currentEntry / totalEntries * 100); var progressValue = (int)((double)currentEntry / totalEntries * 100);
OnInstallProgressChanged(progressValue);
}
if (isUpdate)
{
OnUpdateProgressChanged(progressValue);
}
else
{
OnInstallProgressChanged(progressValue);
}
}
} }
private static string GetVramOption() private static string GetVramOption()

14
StabilityMatrix/Models/Packages/DankDiffusion.cs

@ -10,12 +10,12 @@ public class DankDiffusion : BasePackage
public override string GithubUrl => "https://github.com/mohnjiles/dank-diffusion"; public override string GithubUrl => "https://github.com/mohnjiles/dank-diffusion";
public override string LaunchCommand => ""; public override string LaunchCommand => "";
public override Task DownloadPackage() public override Task<string?> DownloadPackage(bool isUpdate = false)
{ {
throw new System.NotImplementedException(); throw new System.NotImplementedException();
} }
public override Task InstallPackage() public override Task InstallPackage(bool isUpdate = false)
{ {
throw new System.NotImplementedException(); throw new System.NotImplementedException();
} }
@ -30,5 +30,15 @@ public class DankDiffusion : BasePackage
throw new System.NotImplementedException(); throw new System.NotImplementedException();
} }
public override Task<bool> CheckForUpdates()
{
throw new System.NotImplementedException();
}
public override Task<string?> Update()
{
throw new System.NotImplementedException();
}
public override string DefaultLaunchArguments => ""; public override string DefaultLaunchArguments => "";
} }

106
StabilityMatrix/ViewModels/InstallerViewModel.cs

@ -6,9 +6,11 @@ using StabilityMatrix.Models;
using System.Diagnostics; using System.Diagnostics;
using System.Linq; using System.Linq;
using System.Windows; using System.Windows;
using System.Windows.Controls;
using CommunityToolkit.Mvvm.ComponentModel; using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input; using CommunityToolkit.Mvvm.Input;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using Wpf.Ui.Contracts;
using EventManager = StabilityMatrix.Helper.EventManager; using EventManager = StabilityMatrix.Helper.EventManager;
namespace StabilityMatrix.ViewModels; namespace StabilityMatrix.ViewModels;
@ -17,32 +19,62 @@ public partial class InstallerViewModel : ObservableObject
{ {
private readonly ILogger<InstallerViewModel> logger; private readonly ILogger<InstallerViewModel> logger;
private readonly ISettingsManager settingsManager; private readonly ISettingsManager settingsManager;
[ObservableProperty] [ObservableProperty]
[NotifyPropertyChangedFor(nameof(ProgressBarVisibility))] [NotifyPropertyChangedFor(nameof(ProgressBarVisibility))]
private int progressValue; private int progressValue;
[ObservableProperty] [ObservableProperty]
private BasePackage selectedPackage; private BasePackage selectedPackage;
[ObservableProperty] [ObservableProperty]
private string installedText; private string progressText;
[ObservableProperty] [ObservableProperty]
private bool isIndeterminate; private bool isIndeterminate;
[ObservableProperty] [ObservableProperty]
private Visibility packageInstalledVisibility; private Visibility packageInstalledVisibility;
[ObservableProperty]
private string installButtonText;
[ObservableProperty]
private bool installButtonEnabled;
[ObservableProperty]
[NotifyPropertyChangedFor(nameof(SelectedPackage))]
private bool updateAvailable;
public InstallerViewModel(ILogger<InstallerViewModel> logger, ISettingsManager settingsManager) public InstallerViewModel(ILogger<InstallerViewModel> logger, ISettingsManager settingsManager,
IPackageFactory packageFactory)
{ {
this.logger = logger; this.logger = logger;
this.settingsManager = settingsManager; this.settingsManager = settingsManager;
InstalledText = "shrug";
ProgressText = "shrug";
InstallButtonText = "Install";
installButtonEnabled = true;
ProgressValue = 0; ProgressValue = 0;
Packages = new ObservableCollection<BasePackage>(PackageFactory.GetAllAvailablePackages()); Packages = new ObservableCollection<BasePackage>(packageFactory.GetAllAvailablePackages());
SelectedPackage = Packages[0]; SelectedPackage = Packages[0];
} }
public Task OnLoaded() public async Task OnLoaded()
{ {
return Task.CompletedTask; var installedPackages = settingsManager.Settings.InstalledPackages;
if (installedPackages.Count == 0)
{
return;
}
foreach (var packageToUpdate in installedPackages
.Select(package => Packages.FirstOrDefault(x => x.Name == package.Name))
.Where(packageToUpdate => packageToUpdate != null))
{
await packageToUpdate!.CheckForUpdates();
OnSelectedPackageChanged(packageToUpdate);
}
} }
public ObservableCollection<BasePackage> Packages { get; } public ObservableCollection<BasePackage> Packages { get; }
@ -50,15 +82,32 @@ public partial class InstallerViewModel : ObservableObject
partial void OnSelectedPackageChanged(BasePackage value) partial void OnSelectedPackageChanged(BasePackage value)
{ {
var installed = settingsManager.Settings.InstalledPackages; var installed = settingsManager.Settings.InstalledPackages;
PackageInstalledVisibility = installed.FirstOrDefault(package => package.Name == value.Name) != null var isInstalled = installed.FirstOrDefault(package => package.Name == value.Name) != null;
? Visibility.Visible PackageInstalledVisibility = isInstalled ? Visibility.Visible : Visibility.Collapsed;
: Visibility.Collapsed; UpdateAvailable = value.UpdateAvailable;
InstallButtonText = value.UpdateAvailable ? "Update" : isInstalled ? "Launch" : "Install";
} }
public Visibility ProgressBarVisibility => ProgressValue > 0 || IsIndeterminate ? Visibility.Visible : Visibility.Collapsed; public Visibility ProgressBarVisibility => ProgressValue > 0 || IsIndeterminate ? Visibility.Visible : Visibility.Collapsed;
[RelayCommand] [RelayCommand]
private async Task Install() private async Task Install()
{
switch (InstallButtonText.ToLower())
{
case "install":
await ActuallyInstall();
break;
case "update":
await UpdateSelectedPackage();
break;
case "launch":
EventManager.Instance.RequestPageChange(typeof(LaunchPage));
break;
}
}
private async Task ActuallyInstall()
{ {
var installSuccess = await InstallGitIfNecessary(); var installSuccess = await InstallGitIfNecessary();
if (!installSuccess) if (!installSuccess)
@ -67,10 +116,10 @@ public partial class InstallerViewModel : ObservableObject
return; return;
} }
await DownloadPackage(); var version = await DownloadPackage();
await InstallPackage(); await InstallPackage();
InstalledText = "Installing dependencies..."; ProgressText = "Installing dependencies...";
await PyRunner.Initialize(); await PyRunner.Initialize();
if (!settingsManager.Settings.HasInstalledPip) if (!settingsManager.Settings.HasInstalledPip)
{ {
@ -84,7 +133,7 @@ public partial class InstallerViewModel : ObservableObject
settingsManager.SetHasInstalledVenv(true); settingsManager.SetHasInstalledVenv(true);
} }
InstalledText = "Done"; ProgressText = "Done";
IsIndeterminate = false; IsIndeterminate = false;
SelectedPackageOnProgressChanged(this, 100); SelectedPackageOnProgressChanged(this, 100);
@ -98,7 +147,7 @@ public partial class InstallerViewModel : ObservableObject
Path = SelectedPackage.InstallLocation, Path = SelectedPackage.InstallLocation,
Id = Guid.NewGuid(), Id = Guid.NewGuid(),
PackageName = SelectedPackage.Name, PackageName = SelectedPackage.Name,
PackageVersion = "idklol", PackageVersion = version,
LaunchCommand = SelectedPackage.LaunchCommand LaunchCommand = SelectedPackage.LaunchCommand
}; };
settingsManager.AddInstalledPackage(package); settingsManager.AddInstalledPackage(package);
@ -106,20 +155,35 @@ public partial class InstallerViewModel : ObservableObject
} }
} }
private async Task UpdateSelectedPackage()
{
ProgressText = "Updating...";
SelectedPackageOnProgressChanged(this, 0);
SelectedPackage.UpdateProgressChanged += SelectedPackageOnProgressChanged;
SelectedPackage.UpdateComplete += (_, s) => ProgressText = s;
var version = await SelectedPackage.Update();
settingsManager.UpdatePackageVersionNumber(SelectedPackage.Name, version);
SelectedPackage.UpdateAvailable = false;
UpdateAvailable = false;
InstallButtonText = "Launch";
SelectedPackageOnProgressChanged(this, 100);
}
private async Task DownloadPackage() private Task<string?> DownloadPackage()
{ {
SelectedPackage.DownloadProgressChanged += SelectedPackageOnProgressChanged; SelectedPackage.DownloadProgressChanged += SelectedPackageOnProgressChanged;
SelectedPackage.DownloadComplete += (_, _) => InstalledText = "Download Complete"; SelectedPackage.DownloadComplete += (_, _) => ProgressText = "Download Complete";
InstalledText = "Downloading package..."; ProgressText = "Downloading package...";
await SelectedPackage.DownloadPackage(); return SelectedPackage.DownloadPackage();
} }
private async Task InstallPackage() private async Task InstallPackage()
{ {
SelectedPackage.InstallProgressChanged += SelectedPackageOnProgressChanged; SelectedPackage.InstallProgressChanged += SelectedPackageOnProgressChanged;
SelectedPackage.InstallComplete += (_, _) => InstalledText = "Install Complete"; SelectedPackage.InstallComplete += (_, _) => ProgressText = "Install Complete";
InstalledText = "Installing package..."; ProgressText = "Installing package...";
await SelectedPackage.InstallPackage(); await SelectedPackage.InstallPackage();
} }
@ -154,7 +218,7 @@ public partial class InstallerViewModel : ObservableObject
} }
IsIndeterminate = true; IsIndeterminate = true;
InstalledText = "Installing Git..."; ProgressText = "Installing Git...";
using var installProcess = using var installProcess =
ProcessRunner.StartProcess("Assets\\Git-2.40.1-64-bit.exe", "/VERYSILENT /NORESTART"); ProcessRunner.StartProcess("Assets\\Git-2.40.1-64-bit.exe", "/VERYSILENT /NORESTART");
installProcess.OutputDataReceived += (sender, args) => { Debug.Write(args.Data); }; installProcess.OutputDataReceived += (sender, args) => { Debug.Write(args.Data); };

6
StabilityMatrix/ViewModels/LaunchViewModel.cs

@ -16,6 +16,7 @@ namespace StabilityMatrix.ViewModels;
public partial class LaunchViewModel : ObservableObject public partial class LaunchViewModel : ObservableObject
{ {
private readonly ISettingsManager settingsManager; private readonly ISettingsManager settingsManager;
private readonly IPackageFactory packageFactory;
private BasePackage? runningPackage; private BasePackage? runningPackage;
private bool clearingPackages = false; private bool clearingPackages = false;
@ -55,9 +56,10 @@ public partial class LaunchViewModel : ObservableObject
public event EventHandler? ScrollNeeded; public event EventHandler? ScrollNeeded;
public LaunchViewModel(ISettingsManager settingsManager) public LaunchViewModel(ISettingsManager settingsManager, IPackageFactory packageFactory)
{ {
this.settingsManager = settingsManager; this.settingsManager = settingsManager;
this.packageFactory = packageFactory;
SetProcessRunning(false); SetProcessRunning(false);
ToastNotificationManagerCompat.OnActivated += ToastNotificationManagerCompatOnOnActivated; ToastNotificationManagerCompat.OnActivated += ToastNotificationManagerCompatOnOnActivated;
@ -86,7 +88,7 @@ public partial class LaunchViewModel : ObservableObject
// Get path from package // Get path from package
var packagePath = SelectedPackage.Path!; var packagePath = SelectedPackage.Path!;
var basePackage = PackageFactory.FindPackageByName(SelectedPackage.Name!); var basePackage = packageFactory.FindPackageByName(SelectedPackage.Name!);
if (basePackage == null) if (basePackage == null)
{ {
throw new InvalidOperationException("Package not found"); throw new InvalidOperationException("Package not found");

7
StabilityMatrix/ViewModels/MainWindowViewModel.cs

@ -1,13 +1,12 @@
using System; using System;
using System.Threading.Tasks; using System.Threading.Tasks;
using System.Windows; using System.Windows;
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 CommunityToolkit.Mvvm.Input;
using Python.Runtime;
using StabilityMatrix.Helper; using StabilityMatrix.Helper;
using Wpf.Ui.Appearance; using Wpf.Ui.Appearance;
using Dispatcher = System.Windows.Threading.Dispatcher;
using EventManager = StabilityMatrix.Helper.EventManager; using EventManager = StabilityMatrix.Helper.EventManager;
namespace StabilityMatrix.ViewModels; namespace StabilityMatrix.ViewModels;
@ -40,6 +39,10 @@ public partial class MainWindowViewModel : ObservableObject
EventManager.Instance.GlobalProgressChanged += OnGlobalProgressChanged; EventManager.Instance.GlobalProgressChanged += OnGlobalProgressChanged;
} }
/// <summary>
/// Updates the taskbar progress bar value and state.
/// </summary>
/// <param name="progress">Progress value from 0 to 100</param>
private void OnGlobalProgressChanged(object? sender, int progress) private void OnGlobalProgressChanged(object? sender, int progress)
{ {
if (progress == -1) if (progress == -1)

Loading…
Cancel
Save