Browse Source

Merge pull request #14 from ionite34/fix-listview-selection

pull/5/head
Ionite 2 years ago committed by GitHub
parent
commit
e7771833e2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 1
      StabilityMatrix/App.xaml.cs
  2. 3
      StabilityMatrix/Helper/ProcessRunner.cs
  3. 33
      StabilityMatrix/InstallPage.xaml
  4. 11
      StabilityMatrix/InstallPage.xaml.cs
  5. 29
      StabilityMatrix/Models/Packages/A3WebUI.cs
  6. 6
      StabilityMatrix/PyVenvRunner.cs
  7. 36
      StabilityMatrix/ViewModels/InstallerViewModel.cs

1
StabilityMatrix/App.xaml.cs

@ -31,6 +31,7 @@ namespace StabilityMatrix
serviceCollection.AddTransient<MainWindowViewModel>();
serviceCollection.AddSingleton<SettingsViewModel>();
serviceCollection.AddSingleton<LaunchViewModel>();
serviceCollection.AddSingleton<InstallerViewModel>();
serviceCollection.AddSingleton<IContentDialogService, ContentDialogService>();
serviceCollection.AddSingleton<ISnackbarService, SnackbarService>();
serviceCollection.AddSingleton<ISettingsManager, SettingsManager>();

3
StabilityMatrix/Helper/ProcessRunner.cs

@ -36,11 +36,13 @@ public static class ProcessRunner
process.StartInfo.Arguments = arguments;
process.StartInfo.UseShellExecute = false;
process.StartInfo.RedirectStandardOutput = true;
process.StartInfo.RedirectStandardError = true;
process.StartInfo.CreateNoWindow = true;
if (outputDataReceived != null)
{
process.OutputDataReceived += (_, args) => outputDataReceived(args.Data);
process.ErrorDataReceived += (_, args) => outputDataReceived(args.Data);
}
process.Start();
@ -48,6 +50,7 @@ public static class ProcessRunner
if (outputDataReceived != null)
{
process.BeginOutputReadLine();
process.BeginErrorReadLine();
}
return process;

33
StabilityMatrix/InstallPage.xaml

@ -20,14 +20,32 @@
</Page.DataContext>
<Grid Margin="16">
<StackPanel Orientation="Horizontal" Margin="16" HorizontalAlignment="Left" Height="400">
<ListView
ItemsSource="{Binding Packages}"
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<StackPanel Grid.Row="0" Orientation="Vertical">
<Button Content="Install" Command="{Binding InstallCommand}" Width="100" Height="50" HorizontalAlignment="Center"/>
<TextBlock Text="{Binding InstalledText}" HorizontalAlignment="Center" Padding="8"/>
<ProgressBar Visibility="{Binding ProgressBarVisibility, FallbackValue=Visible}" Value="{Binding ProgressValue, FallbackValue=10}"
IsIndeterminate="{Binding IsIndeterminate, FallbackValue=False}"
Maximum="100" Width="500"/>
</StackPanel>
<StackPanel Grid.Row="1" Orientation="Horizontal" Margin="16" HorizontalAlignment="Left" Height="400">
<ListView ItemsSource="{Binding Packages}"
SelectedItem="{Binding SelectedPackage, Mode=TwoWay}">
<ListView.Style>
<Style TargetType="ListView">
<Setter Property="Background" Value="#191919"/>
</Style>
</ListView.Style>
<ListView.ItemTemplate>
<DataTemplate DataType="{x:Type models:BasePackage}">
<StackPanel VerticalAlignment="Top" Margin="10,0,0,0">
<StackPanel VerticalAlignment="Top" Margin="8">
<TextBlock Text="{Binding DisplayName}" Margin="0,5,0,5" />
<TextBlock Text="{Binding ByAuthor}" Margin="0,0,0,5" />
</StackPanel>
@ -45,12 +63,5 @@
</ui:Hyperlink>
</StackPanel>
</StackPanel>
<StackPanel Orientation="Vertical">
<Button Content="Install" Command="{Binding InstallCommand}" Width="100" Height="50" HorizontalAlignment="Center"/>
<TextBlock Text="{Binding InstalledText}" HorizontalAlignment="Center" Padding="8"/>
<ProgressBar Visibility="{Binding ProgressBarVisibility}" Value="{Binding ProgressValue, FallbackValue=10}"
IsIndeterminate="{Binding IsIndeterminate, FallbackValue=True}"
Maximum="100" Width="500"/>
</StackPanel>
</Grid>
</Page>

11
StabilityMatrix/InstallPage.xaml.cs

@ -12,15 +12,18 @@ namespace StabilityMatrix
/// </summary>
public sealed partial class InstallPage : Page
{
public InstallPage()
{
private readonly InstallerViewModel viewModel;
public InstallPage(InstallerViewModel viewModel)
{
this.viewModel = viewModel;
InitializeComponent();
DataContext = new InstallerViewModel();
DataContext = viewModel;
}
private async void InstallPage_OnLoaded(object sender, RoutedEventArgs e)
{
await ((InstallerViewModel) DataContext).OnLoaded();
await viewModel.OnLoaded();
}
}
}

29
StabilityMatrix/Models/Packages/A3WebUI.cs

@ -3,6 +3,7 @@ using System.Diagnostics;
using System.IO;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Threading;
using System.Threading.Tasks;
using Refit;
using StabilityMatrix.Api;
@ -30,9 +31,20 @@ public class A3WebUI: BasePackage
using var client = new HttpClient {Timeout = TimeSpan.FromMinutes(5)};
client.DefaultRequestHeaders.UserAgent.Add(new ProductInfoHeaderValue("StabilityMatrix", "1.0"));
await using var file = new FileStream(DownloadLocation, FileMode.Create, FileAccess.Write, FileShare.None);
using var response = await client.GetAsync(downloadUrl, HttpCompletionOption.ResponseHeadersRead);
var length = response.Content.Headers.ContentLength;
long contentLength = 0;
var retryCount = 0;
var response = await client.GetAsync(downloadUrl, HttpCompletionOption.ResponseHeadersRead);
while (contentLength == 0 && retryCount++ < 5)
{
response = await client.GetAsync(downloadUrl, HttpCompletionOption.ResponseHeadersRead);
contentLength = response.Content.Headers.ContentLength ?? 0;
Debug.WriteLine("Retrying...");
Thread.Sleep(50);
}
var isIndeterminate = contentLength == 0;
await using var stream = await response.Content.ReadAsStreamAsync();
var totalBytesRead = 0;
while (true)
@ -44,9 +56,16 @@ public class A3WebUI: BasePackage
totalBytesRead += bytesRead;
var progress = (int) (totalBytesRead * 100d / length);
Debug.WriteLine($"Progress; {progress}");
OnDownloadProgressChanged(progress);
if (isIndeterminate)
{
OnDownloadProgressChanged(-1);
}
else
{
var progress = (int) (totalBytesRead * 100d / contentLength);
Debug.WriteLine($"Progress; {progress}");
OnDownloadProgressChanged(progress);
}
}
await file.FlushAsync();

6
StabilityMatrix/PyVenvRunner.cs

@ -53,11 +53,13 @@ public class PyVenvRunner: IDisposable
// Create venv
var venvProc = ProcessRunner.StartProcess(PyRunner.ExePath, "-m virtualenv " + RootPath);
await venvProc.WaitForExitAsync();
// Check return code
var returnCode = venvProc.ExitCode;
if (returnCode != 0)
{
var output = await venvProc.StandardOutput.ReadToEndAsync();
var output = await venvProc.StandardOutput.ReadToEndAsync();
output += await venvProc.StandardError.ReadToEndAsync();
throw new InvalidOperationException($"Venv creation failed with code {returnCode}: {output}");
}
}
@ -81,4 +83,4 @@ public class PyVenvRunner: IDisposable
Process?.Dispose();
GC.SuppressFinalize(this);
}
}
}

36
StabilityMatrix/ViewModels/InstallerViewModel.cs

@ -12,7 +12,7 @@ using CommunityToolkit.Mvvm.Input;
namespace StabilityMatrix.ViewModels;
internal class InstallerViewModel : INotifyPropertyChanged
public class InstallerViewModel : INotifyPropertyChanged
{
private string installedText;
private int progressValue;
@ -23,19 +23,20 @@ internal class InstallerViewModel : INotifyPropertyChanged
{
InstalledText = "shrug";
ProgressValue = 0;
Packages = new ObservableCollection<BasePackage>
{
new A3WebUI(),
new DankDiffusion()
};
SelectedPackage = Packages[0];
}
public Task OnLoaded()
{
SelectedPackage = Packages.First();
return Task.CompletedTask;
}
public static ObservableCollection<BasePackage> Packages => new()
{
new A3WebUI(),
new DankDiffusion()
};
public ObservableCollection<BasePackage> Packages { get; }
public string InstalledText
{
@ -81,9 +82,26 @@ internal class InstallerViewModel : INotifyPropertyChanged
}
}
public Visibility ProgressBarVisibility => ProgressValue > 0 ? Visibility.Visible : Visibility.Collapsed;
public Visibility ProgressBarVisibility => ProgressValue > 0 || IsIndeterminate ? Visibility.Visible : Visibility.Collapsed;
public AsyncRelayCommand InstallCommand => new(async () => await SelectedPackage.DownloadPackage());
public AsyncRelayCommand InstallCommand => new(async () =>
{
SelectedPackage.DownloadProgressChanged += (_, progress) =>
{
if (progress == -1)
{
IsIndeterminate = true;
ProgressValue = 1;
}
else
{
IsIndeterminate = false;
ProgressValue = progress;
}
};
SelectedPackage.DownloadComplete += (_, _) => InstalledText = "Download Complete";
await SelectedPackage.DownloadPackage();
});
private async Task<bool> InstallGitIfNecessary()
{
var gitOutput = await ProcessRunner.GetProcessOutputAsync("git", "--version");

Loading…
Cancel
Save