Browse Source

hooked up import & open in browser buttons

pull/5/head
JT 1 year ago
parent
commit
f6890d4086
  1. 57
      StabilityMatrix/CheckpointBrowserPage.xaml
  2. 36
      StabilityMatrix/DesignData/MockCheckpointBrowserViewModel.cs
  3. 6
      StabilityMatrix/Models/Api/CivitFile.cs
  4. 23
      StabilityMatrix/Models/Api/CivitModelType.cs
  5. 2
      StabilityMatrix/Models/ISharedFolders.cs
  6. 3
      StabilityMatrix/Models/Packages/A3WebUI.cs
  7. 3
      StabilityMatrix/Models/SharedFolderType.cs
  8. 4
      StabilityMatrix/Models/SharedFolders.cs
  9. 54
      StabilityMatrix/ViewModels/CheckpointBrowserViewModel.cs
  10. 8
      StabilityMatrix/ViewModels/CheckpointManagerViewModel.cs

57
StabilityMatrix/CheckpointBrowserPage.xaml

@ -1,8 +1,8 @@
<Page <Page
Foreground="{DynamicResource TextFillColorPrimaryBrush}" Foreground="{DynamicResource TextFillColorPrimaryBrush}"
d:DataContext="{d:DesignInstance viewModels:CheckpointBrowserViewModel, d:DataContext="{d:DesignInstance designData:MockCheckpointBrowserViewModel,
IsDesignTimeCreatable=True}" IsDesignTimeCreatable=True}"
d:DesignHeight="500" d:DesignHeight="600"
d:DesignWidth="650" d:DesignWidth="650"
mc:Ignorable="d" mc:Ignorable="d"
ui:Design.Background="{DynamicResource ApplicationBackgroundBrush}" ui:Design.Background="{DynamicResource ApplicationBackgroundBrush}"
@ -17,6 +17,7 @@
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:api="clr-namespace:StabilityMatrix.Models.Api" xmlns:api="clr-namespace:StabilityMatrix.Models.Api"
x:Name="CheckpointBrowserPg"
xmlns:converters="clr-namespace:StabilityMatrix.Converters"> xmlns:converters="clr-namespace:StabilityMatrix.Converters">
<Page.Resources> <Page.Resources>
@ -42,26 +43,54 @@
Margin="0,2,0,0" Margin="0,2,0,0"
Text="{Binding ModelVersions[0].Name}" Text="{Binding ModelVersions[0].Name}"
VerticalAlignment="Center" /> VerticalAlignment="Center" />
<Image <Grid>
Source="{Binding ModelVersions[0].Images[0].Url, <Image
Converter={StaticResource UriToBitmapConverter}}" Source="{Binding ModelVersions[0].Images[0].Url,
Margin="0,8,0,8" Converter={StaticResource UriToBitmapConverter}}"
MaxHeight="300" Margin="0,8,0,8"
Stretch="UniformToFill" /> MaxHeight="300"
Stretch="UniformToFill" />
<ui:Button VerticalAlignment="Top"
HorizontalAlignment="Right"
Command="{Binding DataContext.OpenModelCommand, Source={x:Reference CheckpointBrowserPg}}"
CommandParameter="{Binding}"
Appearance="Info"
Margin="0,16,8,0">
<ui:SymbolIcon Symbol="Open48"/>
</ui:Button>
<Rectangle HorizontalAlignment="Stretch" VerticalAlignment="Stretch"
Margin="0,8,0,8"
Visibility="{Binding DataContext.ImportCommand.IsRunning,
Source={x:Reference CheckpointBrowserPg},
Converter={StaticResource BoolToVisibilityConverter}}"
Fill="#DD000000"/>
<StackPanel Orientation="Vertical" HorizontalAlignment="Stretch"
Visibility="{Binding DataContext.ImportCommand.IsRunning,
Source={x:Reference CheckpointBrowserPg},
Converter={StaticResource BoolToVisibilityConverter}}"
VerticalAlignment="Center">
<ui:ProgressRing Progress="{Binding DataContext.ImportProgress, Source={x:Reference CheckpointBrowserPg}}"
IsIndeterminate="False"
HorizontalAlignment="Center"
VerticalAlignment="Center"/>
<TextBlock Text="{Binding ImportStatus, FallbackValue=Importing...}"
HorizontalAlignment="Center"
Margin="0,8,0,0"
VerticalAlignment="Center"/>
</StackPanel>
</Grid>
<Grid> <Grid>
<Grid.ColumnDefinitions> <Grid.ColumnDefinitions>
<ColumnDefinition Width="1*"/> <ColumnDefinition Width="1*"/>
<ColumnDefinition Width="1*"/>
</Grid.ColumnDefinitions> </Grid.ColumnDefinitions>
<ui:Button Content="Import" <ui:Button Content="Import"
HorizontalAlignment="Stretch" HorizontalAlignment="Stretch"
Appearance="Primary" Appearance="Primary"
Command="{Binding DataContext.ImportCommand,
Source={x:Reference CheckpointBrowserPg}}"
CommandParameter="{Binding}"
Margin="0,8,0,0"/> Margin="0,8,0,0"/>
<ui:Button Grid.Column="1"
HorizontalAlignment="Stretch"
Content="Open in Browser"
Appearance="Secondary"
Margin="8,8,0,0"/>
</Grid> </Grid>
</StackPanel> </StackPanel>
</ui:Card> </ui:Card>

36
StabilityMatrix/DesignData/MockCheckpointBrowserViewModel.cs

@ -0,0 +1,36 @@
using System.Collections.ObjectModel;
using System.ComponentModel;
using StabilityMatrix.Models.Api;
using StabilityMatrix.ViewModels;
namespace StabilityMatrix.DesignData;
[DesignOnly(true)]
public class MockCheckpointBrowserViewModel : CheckpointBrowserViewModel
{
public MockCheckpointBrowserViewModel() : base(null!, null!)
{
CivitModels = new ObservableCollection<CivitModel>
{
new()
{
Name = "bb95 Furry Mix",
ModelVersions = new[]
{
new CivitModelVersion
{
Name = "v7.0",
Images = new[]
{
new CivitImage
{
Url =
"https://image.civitai.com/xG1nkqKTMzGDvpLrqFT7WA/1547f350-461a-4cd0-a753-0544aa81e4fc/width=450/00000-4137473915.jpeg"
}
}
}
}
}
};
}
}

6
StabilityMatrix/Models/Api/CivitFile.cs

@ -19,4 +19,10 @@ public class CivitFile
[JsonPropertyName("metadata")] [JsonPropertyName("metadata")]
public CivitFileMetadata Metadata { get; set; } public CivitFileMetadata Metadata { get; set; }
[JsonPropertyName("name")]
public string Name { get; set; }
[JsonPropertyName("downloadUrl")]
public string DownloadUrl { get; set; }
} }

23
StabilityMatrix/Models/Api/CivitModelType.cs

@ -1,4 +1,5 @@
using System.Diagnostics.CodeAnalysis; using System;
using System.Diagnostics.CodeAnalysis;
using System.Text.Json.Serialization; using System.Text.Json.Serialization;
namespace StabilityMatrix.Models.Api; namespace StabilityMatrix.Models.Api;
@ -17,3 +18,23 @@ public enum CivitModelType
Model, Model,
LoCon LoCon
} }
public static class CivitModelTypeExtensions
{
public static SharedFolderType ToSharedFolderType(this CivitModelType type)
{
return type switch
{
CivitModelType.Checkpoint => SharedFolderType.StableDiffusion,
CivitModelType.TextualInversion => SharedFolderType.TextualInversion,
CivitModelType.Hypernetwork => SharedFolderType.Hypernetwork,
//CivitModelType.AestheticGradient => expr,
CivitModelType.LORA => SharedFolderType.Lora,
CivitModelType.Controlnet => SharedFolderType.ControlNet,
//CivitModelType.Poses => expr,
CivitModelType.Model => SharedFolderType.StableDiffusion,
CivitModelType.LoCon => SharedFolderType.LyCORIS,
_ => throw new ArgumentOutOfRangeException(nameof(type), type, null)
};
}
}

2
StabilityMatrix/Models/ISharedFolders.cs

@ -4,7 +4,5 @@ namespace StabilityMatrix.Models;
public interface ISharedFolders public interface ISharedFolders
{ {
string SharedFoldersPath { get; }
string SharedFolderTypeToName(SharedFolderType folderType);
void SetupLinksForPackage(BasePackage basePackage, string installPath); void SetupLinksForPackage(BasePackage basePackage, string installPath);
} }

3
StabilityMatrix/Models/Packages/A3WebUI.cs

@ -41,6 +41,9 @@ public class A3WebUI : BaseGitPackage
[SharedFolderType.VAE] = "models/VAE", [SharedFolderType.VAE] = "models/VAE",
[SharedFolderType.DeepDanbooru] = "models/deepbooru", [SharedFolderType.DeepDanbooru] = "models/deepbooru",
[SharedFolderType.Karlo] = "models/karlo", [SharedFolderType.Karlo] = "models/karlo",
[SharedFolderType.TextualInversion] = "embeddings",
[SharedFolderType.Hypernetwork] = "models/hypernetworks",
[SharedFolderType.ControlNet] = "models/ControlNet"
}; };
public override List<LaunchOptionDefinition> LaunchOptions => new() public override List<LaunchOptionDefinition> LaunchOptions => new()

3
StabilityMatrix/Models/SharedFolderType.cs

@ -16,4 +16,7 @@ public enum SharedFolderType
ApproxVAE, ApproxVAE,
Karlo, Karlo,
DeepDanbooru, DeepDanbooru,
TextualInversion,
Hypernetwork,
ControlNet
} }

4
StabilityMatrix/Models/SharedFolders.cs

@ -10,11 +10,11 @@ public class SharedFolders : ISharedFolders
{ {
private const string SharedFoldersName = "Models"; private const string SharedFoldersName = "Models";
private static readonly Logger Logger = LogManager.GetCurrentClassLogger(); private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
public string SharedFoldersPath { get; } = public static string SharedFoldersPath =
Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "StabilityMatrix", Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "StabilityMatrix",
SharedFoldersName); SharedFoldersName);
public string SharedFolderTypeToName(SharedFolderType folderType) public static string SharedFolderTypeToName(SharedFolderType folderType)
{ {
return Enum.GetName(typeof(SharedFolderType), folderType)!; return Enum.GetName(typeof(SharedFolderType), folderType)!;
} }

54
StabilityMatrix/ViewModels/CheckpointBrowserViewModel.cs

@ -1,13 +1,17 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Collections.ObjectModel; using System.Collections.ObjectModel;
using System.Diagnostics;
using System.IO;
using System.Linq; using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
using CommunityToolkit.Mvvm.ComponentModel; using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input; using CommunityToolkit.Mvvm.Input;
using NLog; using NLog;
using StabilityMatrix.Api; using StabilityMatrix.Api;
using StabilityMatrix.Models;
using StabilityMatrix.Models.Api; using StabilityMatrix.Models.Api;
using StabilityMatrix.Services;
namespace StabilityMatrix.ViewModels; namespace StabilityMatrix.ViewModels;
@ -15,6 +19,7 @@ public partial class CheckpointBrowserViewModel : ObservableObject
{ {
private static readonly Logger Logger = LogManager.GetCurrentClassLogger(); private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
private readonly ICivitApi civitApi; private readonly ICivitApi civitApi;
private readonly IDownloadService downloadService;
private const int MaxModelsPerPage = 14; private const int MaxModelsPerPage = 14;
[ObservableProperty] private string? searchQuery; [ObservableProperty] private string? searchQuery;
@ -28,13 +33,18 @@ public partial class CheckpointBrowserViewModel : ObservableObject
[ObservableProperty] private bool hasSearched; [ObservableProperty] private bool hasSearched;
[ObservableProperty] private bool canGoToNextPage; [ObservableProperty] private bool canGoToNextPage;
[ObservableProperty] private bool canGoToPreviousPage; [ObservableProperty] private bool canGoToPreviousPage;
[ObservableProperty] private int importProgress;
[ObservableProperty] private string importStatus;
[ObservableProperty] private bool isIndeterminate;
public IEnumerable<CivitPeriod> AllCivitPeriods => Enum.GetValues(typeof(CivitPeriod)).Cast<CivitPeriod>(); public IEnumerable<CivitPeriod> AllCivitPeriods => Enum.GetValues(typeof(CivitPeriod)).Cast<CivitPeriod>();
public IEnumerable<CivitSortMode> AllSortModes => Enum.GetValues(typeof(CivitSortMode)).Cast<CivitSortMode>(); public IEnumerable<CivitSortMode> AllSortModes => Enum.GetValues(typeof(CivitSortMode)).Cast<CivitSortMode>();
public CheckpointBrowserViewModel(ICivitApi civitApi) public CheckpointBrowserViewModel(ICivitApi civitApi, IDownloadService downloadService)
{ {
this.civitApi = civitApi; this.civitApi = civitApi;
this.downloadService = downloadService;
SelectedPeriod = CivitPeriod.Month; SelectedPeriod = CivitPeriod.Month;
SortMode = CivitSortMode.HighestRated; SortMode = CivitSortMode.HighestRated;
HasSearched = false; HasSearched = false;
@ -89,6 +99,48 @@ public partial class CheckpointBrowserViewModel : ObservableObject
await TrySearchAgain(false); await TrySearchAgain(false);
} }
[RelayCommand]
private async Task Import(CivitModel model)
{
IsIndeterminate = false;
ImportStatus = "Downloading...";
var latestModelFile = model.ModelVersions[0].Files[0];
var downloadPath = Path.Combine(SharedFolders.SharedFoldersPath,
SharedFolders.SharedFolderTypeToName(model.Type.ToSharedFolderType()), latestModelFile.Name);
downloadService.DownloadProgressChanged += DownloadServiceOnDownloadProgressChanged;
downloadService.DownloadComplete += DownloadServiceOnDownloadComplete;
await downloadService.DownloadToFileAsync(latestModelFile.DownloadUrl, downloadPath);
downloadService.DownloadProgressChanged -= DownloadServiceOnDownloadProgressChanged;
downloadService.DownloadComplete -= DownloadServiceOnDownloadComplete;
}
private void DownloadServiceOnDownloadComplete(object? sender, ProgressReport e)
{
ImportStatus = "Import complete!";
ImportProgress = 100;
}
private void DownloadServiceOnDownloadProgressChanged(object? sender, ProgressReport e)
{
ImportProgress = (int)e.Percentage;
ImportStatus = $"Importing... {e.Percentage}%";
}
[RelayCommand]
private void OpenModel(CivitModel model)
{
Process.Start(new ProcessStartInfo
{
FileName = $"https://civitai.com/models/{model.Id}",
UseShellExecute = true
});
}
partial void OnShowNsfwChanged(bool oldValue, bool newValue) partial void OnShowNsfwChanged(bool oldValue, bool newValue)
{ {
TrySearchAgain(); TrySearchAgain();

8
StabilityMatrix/ViewModels/CheckpointManagerViewModel.cs

@ -23,17 +23,17 @@ public partial class CheckpointManagerViewModel : ObservableObject
public async Task OnLoaded() public async Task OnLoaded()
{ {
// Get all folders within the shared folder root // Get all folders within the shared folder root
if (string.IsNullOrWhiteSpace(sharedFolders.SharedFoldersPath)) if (string.IsNullOrWhiteSpace(SharedFolders.SharedFoldersPath))
{ {
return; return;
} }
// Skip if the shared folder root doesn't exist // Skip if the shared folder root doesn't exist
if (!Directory.Exists(sharedFolders.SharedFoldersPath)) if (!Directory.Exists(SharedFolders.SharedFoldersPath))
{ {
Logger.Debug($"Skipped shared folder index - {sharedFolders.SharedFoldersPath} doesn't exist"); Logger.Debug($"Skipped shared folder index - {SharedFolders.SharedFoldersPath} doesn't exist");
return; return;
} }
var folders = Directory.GetDirectories(sharedFolders.SharedFoldersPath); var folders = Directory.GetDirectories(SharedFolders.SharedFoldersPath);
CheckpointFolders.Clear(); CheckpointFolders.Clear();

Loading…
Cancel
Save