diff --git a/StabilityMatrix/CheckpointManagerPage.xaml b/StabilityMatrix/CheckpointManagerPage.xaml
index 58ae9128..051698a0 100644
--- a/StabilityMatrix/CheckpointManagerPage.xaml
+++ b/StabilityMatrix/CheckpointManagerPage.xaml
@@ -5,6 +5,8 @@
d:DesignHeight="1000"
d:DesignWidth="650"
mc:Ignorable="d"
+ ui:Design.Background="{DynamicResource ApplicationBackgroundBrush}"
+ ui:Design.Foreground="{DynamicResource TextFillColorPrimaryBrush}"
x:Class="StabilityMatrix.CheckpointManagerPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:converters="clr-namespace:StabilityMatrix.Converters"
@@ -13,6 +15,7 @@
xmlns:i="http://schemas.microsoft.com/xaml/behaviors"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:models="clr-namespace:StabilityMatrix.Models"
+ xmlns:system="clr-namespace:System;assembly=System.Runtime"
xmlns:ui="http://schemas.lepo.co/wpfui/2022/xaml"
xmlns:viewModels="clr-namespace:StabilityMatrix.ViewModels"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
@@ -26,6 +29,10 @@
+
+
+
+
+
+
+
+
+
+
+
-
+
-
+
-
+
+
+
-
+
-
+
-
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ TextTrimming="CharacterEllipsis"
+ TextWrapping="NoWrap" />
-
-
+
+
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
-
+
+ Margin="8"
+ Padding="8,8,8,16"
+ Visibility="{Binding IsCategoryEnabled, Converter={StaticResource BoolToVisibilityConverter}, FallbackValue=Visible}">
@@ -281,17 +359,90 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Margin="8,0,8,8" />
diff --git a/StabilityMatrix/DesignData/MockCheckpointFolder.cs b/StabilityMatrix/DesignData/MockCheckpointFolder.cs
new file mode 100644
index 00000000..e2dab9ff
--- /dev/null
+++ b/StabilityMatrix/DesignData/MockCheckpointFolder.cs
@@ -0,0 +1,10 @@
+using StabilityMatrix.Models;
+
+namespace StabilityMatrix.DesignData;
+
+public class MockCheckpointFolder : CheckpointFolder
+{
+ public MockCheckpointFolder() : base(null!, null!, useCategoryVisibility: false)
+ {
+ }
+}
diff --git a/StabilityMatrix/DesignData/MockCheckpointManagerViewModel.cs b/StabilityMatrix/DesignData/MockCheckpointManagerViewModel.cs
index 9c2ed59e..416cfd31 100644
--- a/StabilityMatrix/DesignData/MockCheckpointManagerViewModel.cs
+++ b/StabilityMatrix/DesignData/MockCheckpointManagerViewModel.cs
@@ -7,26 +7,26 @@ namespace StabilityMatrix.DesignData;
[DesignOnly(true)]
public class MockCheckpointManagerViewModel : CheckpointManagerViewModel
{
- public MockCheckpointManagerViewModel() : base(null!, null!)
+ public MockCheckpointManagerViewModel() : base(null!, null!, null!)
{
CheckpointFolders = new()
{
- new()
+ new MockCheckpointFolder
{
Title = "Stable Diffusion",
CheckpointFiles = new()
{
- new()
+ new(null!)
{
Title = "Stable Diffusion v1.5",
FilePath = "v1-5-pruned-emaonly.safetensors",
},
- new()
+ new(null!)
{
Title = "Scenery Mix",
FilePath = "scenery-mix.pt",
},
- new()
+ new(null!)
{
Title = "Some Model",
FilePath = "exr-v3.safetensors",
@@ -42,13 +42,13 @@ public class MockCheckpointManagerViewModel : CheckpointManagerViewModel
}
}
},
- new()
+ new(null!)
{
Title = "Painting e12",
FilePath = "painting-e12.pt",
ConnectedModel = new()
{
- ModelName = "Long Name Model (Stuff)",
+ ModelName = "Long Name Model (Stuff / More Content)",
VersionName = "v42-Advanced-Hybrid",
ModelDescription = "Example Description",
BaseModel = "SD 2.0",
@@ -60,18 +60,18 @@ public class MockCheckpointManagerViewModel : CheckpointManagerViewModel
},
}
},
- new()
+ new MockCheckpointFolder
{
Title = "Lora",
IsCurrentDragTarget = true,
CheckpointFiles = new()
{
- new()
+ new(null!)
{
Title = "Detail Tweaker LoRA",
FilePath = "add_detail.safetensors",
},
- new()
+ new(null!)
{
Title = "Armor Suit LoRa",
FilePath = "ArmorSuit_v1.safetensors",
diff --git a/StabilityMatrix/Helper/DialogFactory.cs b/StabilityMatrix/Helper/DialogFactory.cs
index df532ad5..fb7b7c79 100644
--- a/StabilityMatrix/Helper/DialogFactory.cs
+++ b/StabilityMatrix/Helper/DialogFactory.cs
@@ -1,8 +1,15 @@
using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+using System.Windows;
+using System.Windows.Controls;
using StabilityMatrix.Models;
using StabilityMatrix.Services;
using StabilityMatrix.ViewModels;
using Wpf.Ui.Contracts;
+using Wpf.Ui.Controls;
+using Wpf.Ui.Controls.ContentDialogControl;
+using TextBox = Wpf.Ui.Controls.TextBox;
namespace StabilityMatrix.Helper;
@@ -37,6 +44,84 @@ public class DialogFactory : IDialogFactory
return new LaunchOptionsDialog(contentDialogService, launchOptionsDialogViewModel);
}
+ ///
+ /// Creates a dialog that allows the user to enter text for each field name.
+ /// Return a list of strings that correspond to the field names.
+ /// If cancel is pressed, return null.
+ /// List of (fieldName, placeholder)
+ ///
+ public async Task?> ShowTextEntryDialog(string title,
+ IEnumerable<(string, string)> fields,
+ string closeButtonText = "Cancel",
+ string saveButtonText = "Save")
+ {
+ var dialog = contentDialogService.CreateDialog();
+ dialog.Title = title;
+ dialog.PrimaryButtonAppearance = ControlAppearance.Primary;
+ dialog.CloseButtonText = closeButtonText;
+ dialog.PrimaryButtonText = saveButtonText;
+ dialog.IsPrimaryButtonEnabled = true;
+
+ var textBoxes = new List();
+ var stackPanel = new StackPanel();
+ dialog.Content = stackPanel;
+
+ foreach (var (fieldName, fieldPlaceholder) in fields)
+ {
+ var textBox = new TextBox
+ {
+ PlaceholderText = fieldPlaceholder,
+ PlaceholderEnabled = true,
+ MinWidth = 200,
+ };
+ textBoxes.Add(textBox);
+ stackPanel.Children.Add(new Card
+ {
+ Content = new StackPanel
+ {
+ Children =
+ {
+ new TextBlock
+ {
+ Text = fieldName,
+ Margin = new Thickness(0, 0, 0, 4)
+ },
+ textBox
+ }
+ },
+ Margin = new Thickness(16)
+ });
+ }
+
+ var result = await dialog.ShowAsync();
+ if (result == ContentDialogResult.Primary)
+ {
+ return textBoxes.Select(x => x.Text).ToList();
+ }
+ return null;
+ }
+
+ ///
+ /// Creates and shows a confirmation dialog.
+ /// Return true if the user clicks the primary button.
+ ///
+ public async Task ShowConfirmationDialog(string title, string message, string closeButtonText = "Cancel", string primaryButtonText = "Confirm")
+ {
+ var dialog = contentDialogService.CreateDialog();
+ dialog.Title = title;
+ dialog.PrimaryButtonAppearance = ControlAppearance.Primary;
+ dialog.CloseButtonText = closeButtonText;
+ dialog.PrimaryButtonText = primaryButtonText;
+ dialog.IsPrimaryButtonEnabled = true;
+ dialog.Content = new TextBlock
+ {
+ Text = message,
+ Margin = new Thickness(16)
+ };
+ var result = await dialog.ShowAsync();
+ return result == ContentDialogResult.Primary;
+ }
+
public OneClickInstallDialog CreateOneClickInstallDialog()
{
return new OneClickInstallDialog(contentDialogService, oneClickInstallViewModel);
diff --git a/StabilityMatrix/Helper/IDialogFactory.cs b/StabilityMatrix/Helper/IDialogFactory.cs
index 16b5ea22..9276f52e 100644
--- a/StabilityMatrix/Helper/IDialogFactory.cs
+++ b/StabilityMatrix/Helper/IDialogFactory.cs
@@ -1,4 +1,5 @@
using System.Collections.Generic;
+using System.Threading.Tasks;
using StabilityMatrix.Models;
namespace StabilityMatrix.Helper;
@@ -8,4 +9,6 @@ public interface IDialogFactory
LaunchOptionsDialog CreateLaunchOptionsDialog(IEnumerable definitions, InstalledPackage installedPackage);
InstallerWindow CreateInstallerWindow();
OneClickInstallDialog CreateOneClickInstallDialog();
+ Task?> ShowTextEntryDialog(string title, IEnumerable<(string, string)> fieldNames,
+ string closeButtonText = "Cancel", string saveButtonText = "Save");
}
diff --git a/StabilityMatrix/Helper/ISettingsManager.cs b/StabilityMatrix/Helper/ISettingsManager.cs
index 4c5537d2..b9c72db1 100644
--- a/StabilityMatrix/Helper/ISettingsManager.cs
+++ b/StabilityMatrix/Helper/ISettingsManager.cs
@@ -40,4 +40,6 @@ public interface ISettingsManager
void SetModelsDirectory(string? directory);
void SetFirstLaunchSetupComplete(bool firstLaunchSetupCompleted);
void SetModelBrowserNsfwEnabled(bool value);
+ void SetSharedFolderCategoryVisible(SharedFolderType type, bool visible);
+ bool IsSharedFolderCategoryVisible(SharedFolderType type);
}
diff --git a/StabilityMatrix/Models/CheckpointFile.cs b/StabilityMatrix/Models/CheckpointFile.cs
index 3a47c641..caaa29f8 100644
--- a/StabilityMatrix/Models/CheckpointFile.cs
+++ b/StabilityMatrix/Models/CheckpointFile.cs
@@ -1,60 +1,83 @@
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
+using System.Collections.ObjectModel;
using System.Diagnostics;
+using System.Drawing;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
+using System.Windows;
using System.Windows.Media.Imaging;
+using System.Windows.Threading;
+using AsyncAwaitBestPractices;
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using NLog;
using StabilityMatrix.Extensions;
+using StabilityMatrix.Helper;
namespace StabilityMatrix.Models;
public partial class CheckpointFile : ObservableObject
{
private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
+ private readonly IDialogFactory dialogFactory;
+
// Event for when this file is deleted
public event EventHandler? Deleted;
///
/// Absolute path to the checkpoint file.
///
- public string FilePath { get; init; } = string.Empty;
+ [ObservableProperty]
+ [NotifyPropertyChangedFor(nameof(FileName))]
+ private string filePath = string.Empty;
///
/// Custom title for UI.
///
- [ObservableProperty] private string title = string.Empty;
+ [ObservableProperty]
+ private string title = string.Empty;
public string? PreviewImagePath { get; set; }
public BitmapImage? PreviewImage { get; set; }
public bool IsPreviewImageLoaded => PreviewImage != null;
- [ObservableProperty] private ConnectedModelInfo? connectedModel;
+ [ObservableProperty]
+ private ConnectedModelInfo? connectedModel;
public bool IsConnectedModel => ConnectedModel != null;
-
- [ObservableProperty] private string fpType = string.Empty;
- [ObservableProperty] private string baseModel = string.Empty;
[ObservableProperty] private bool isLoading;
public string FileName => Path.GetFileName(FilePath);
+ public ObservableCollection Badges { get; set; } = new();
+
private static readonly string[] SupportedCheckpointExtensions = { ".safetensors", ".pt", ".ckpt", ".pth", "bin" };
private static readonly string[] SupportedImageExtensions = { ".png", ".jpg", ".jpeg" };
private static readonly string[] SupportedMetadataExtensions = { ".json" };
+
+ public CheckpointFile(IDialogFactory dialogFactory)
+ {
+ this.dialogFactory = dialogFactory;
+ }
partial void OnConnectedModelChanged(ConnectedModelInfo? value)
{
- if (value == null) return;
// Update title, first check user defined, then connected model name
- Title = value.UserTitle ?? value.ModelName;
- // Update fp type and base model
- FpType = value.FileMetadata.Fp?.GetStringValue().ToUpperInvariant() ?? "";
- BaseModel = value.BaseModel ?? "";
+ Title = value?.UserTitle ?? value?.ModelName ?? string.Empty;
+ // Update badges
+ Badges.Clear();
+ var fpType = value.FileMetadata.Fp?.GetStringValue().ToUpperInvariant();
+ if (fpType != null)
+ {
+ Badges.Add(fpType);
+ }
+ if (!string.IsNullOrWhiteSpace(value.BaseModel))
+ {
+ Badges.Add(value.BaseModel);
+ }
}
[RelayCommand]
@@ -62,33 +85,69 @@ public partial class CheckpointFile : ObservableObject
{
if (File.Exists(FilePath))
{
- // Start progress ring
IsLoading = true;
- var timer = Stopwatch.StartNew();
try
{
+ await using var delay = new MinimumDelay(200, 500);
await Task.Run(() => File.Delete(FilePath));
if (PreviewImagePath != null && File.Exists(PreviewImagePath))
{
await Task.Run(() => File.Delete(PreviewImagePath));
}
- // If it was too fast, wait a bit to show progress ring
- var targetDelay = new Random().Next(200, 500);
- var elapsed = timer.ElapsedMilliseconds;
- if (elapsed < targetDelay)
- {
- await Task.Delay(targetDelay - (int) elapsed);
- }
}
- catch (IOException e)
+ catch (IOException ex)
{
- Logger.Error(e, $"Failed to delete checkpoint file: {FilePath}");
- IsLoading = false;
+ Logger.Warn($"Failed to delete checkpoint file {FilePath}: {ex.Message}");
return; // Don't delete from collection
}
+ finally
+ {
+ IsLoading = false;
+ }
}
Deleted?.Invoke(this, this);
- }
+ }
+
+ [RelayCommand]
+ private async Task RenameAsync()
+ {
+ var responses = await dialogFactory.ShowTextEntryDialog("Rename Model", new []
+ {
+ ("File Name", FileName)
+ });
+ var name = responses?.FirstOrDefault();
+ if (name == null) return;
+
+ // Rename file in OS
+ try
+ {
+ var newFilePath = Path.Combine(Path.GetDirectoryName(FilePath) ?? "", name);
+ File.Move(FilePath, newFilePath);
+ FilePath = newFilePath;
+ }
+ catch (Exception e)
+ {
+ Console.WriteLine(e);
+ throw;
+ }
+ }
+
+ // Loads image from path
+ private async Task LoadPreviewImage()
+ {
+ if (PreviewImagePath == null) return;
+ var bytes = await File.ReadAllBytesAsync(PreviewImagePath);
+ await Application.Current.Dispatcher.InvokeAsync(() =>
+ {
+ var bitmap = new BitmapImage();
+ using var ms = new MemoryStream(bytes);
+ bitmap.BeginInit();
+ bitmap.StreamSource = ms;
+ bitmap.CacheOption = BitmapCacheOption.OnLoad;
+ bitmap.EndInit();
+ PreviewImage = bitmap;
+ });
+ }
///
/// Indexes directory and yields all checkpoint files.
@@ -97,7 +156,7 @@ public partial class CheckpointFile : ObservableObject
/// - {filename}.preview.{image-extensions} (preview image)
/// - {filename}.cm-info.json (connected model info)
///
- public static IEnumerable FromDirectoryIndex(string directory, SearchOption searchOption = SearchOption.TopDirectoryOnly)
+ public static IEnumerable FromDirectoryIndex(IDialogFactory dialogFactory, string directory, SearchOption searchOption = SearchOption.TopDirectoryOnly)
{
// Get all files with supported extensions
var allExtensions = SupportedCheckpointExtensions
@@ -110,7 +169,7 @@ public partial class CheckpointFile : ObservableObject
foreach (var file in files.Keys.Where(k => SupportedCheckpointExtensions.Contains(Path.GetExtension(k))))
{
- var checkpointFile = new CheckpointFile
+ var checkpointFile = new CheckpointFile(dialogFactory)
{
Title = Path.GetFileNameWithoutExtension(file),
FilePath = Path.Combine(directory, file),
@@ -137,6 +196,7 @@ public partial class CheckpointFile : ObservableObject
if (previewImage != null)
{
checkpointFile.PreviewImagePath = Path.Combine(directory, previewImage);
+ checkpointFile.LoadPreviewImage().SafeFireAndForget();
}
yield return checkpointFile;
@@ -146,11 +206,11 @@ public partial class CheckpointFile : ObservableObject
///
/// Index with progress reporting.
///
- public static IEnumerable FromDirectoryIndex(string directory, IProgress progress,
+ public static IEnumerable FromDirectoryIndex(IDialogFactory dialogFactory, string directory, IProgress progress,
SearchOption searchOption = SearchOption.TopDirectoryOnly)
{
var current = 0ul;
- foreach (var checkpointFile in FromDirectoryIndex(directory, searchOption))
+ foreach (var checkpointFile in FromDirectoryIndex(dialogFactory, directory, searchOption))
{
current++;
progress.Report(new ProgressReport(current, "Indexing", checkpointFile.FileName));
diff --git a/StabilityMatrix/Models/CheckpointFolder.cs b/StabilityMatrix/Models/CheckpointFolder.cs
index 705c808c..65c6567a 100644
--- a/StabilityMatrix/Models/CheckpointFolder.cs
+++ b/StabilityMatrix/Models/CheckpointFolder.cs
@@ -15,15 +15,33 @@ namespace StabilityMatrix.Models;
public partial class CheckpointFolder : ObservableObject
{
+ private readonly IDialogFactory dialogFactory;
+ private readonly ISettingsManager settingsManager;
+ // ReSharper disable once FieldCanBeMadeReadOnly.Local
+ private bool useCategoryVisibility;
+
///
/// Absolute path to the folder.
///
public string DirectoryPath { get; init; } = string.Empty;
-
+
///
/// Custom title for UI.
///
- public string Title { get; init; } = string.Empty;
+ [ObservableProperty]
+ [NotifyPropertyChangedFor(nameof(FolderType))]
+ [NotifyPropertyChangedFor(nameof(TitleWithFilesCount))]
+ private string title = string.Empty;
+
+ private SharedFolderType FolderType => Enum.TryParse(Title, out SharedFolderType type)
+ ? type
+ : new SharedFolderType();
+
+ ///
+ /// True if the category is enabled for the manager page.
+ ///
+ [ObservableProperty]
+ private bool isCategoryEnabled = true;
[ObservableProperty]
[NotifyPropertyChangedFor(nameof(IsDragBlurEnabled))]
@@ -32,24 +50,51 @@ public partial class CheckpointFolder : ObservableObject
[ObservableProperty]
[NotifyPropertyChangedFor(nameof(IsDragBlurEnabled))]
private bool isImportInProgress;
-
+
public bool IsDragBlurEnabled => IsCurrentDragTarget || IsImportInProgress;
+ public string TitleWithFilesCount => CheckpointFiles.Any() ? $"{Title} ({CheckpointFiles.Count})" : Title;
public ProgressViewModel Progress { get; } = new();
- public ObservableCollection CheckpointFiles { get; set; } = new();
+ public ObservableCollection CheckpointFiles { get; init; } = new();
public RelayCommand OnPreviewDragEnterCommand => new(() => IsCurrentDragTarget = true);
public RelayCommand OnPreviewDragLeaveCommand => new(() => IsCurrentDragTarget = false);
- public CheckpointFolder()
+ public CheckpointFolder(IDialogFactory dialogFactory, ISettingsManager settingsManager, bool useCategoryVisibility = true)
{
+ this.dialogFactory = dialogFactory;
+ this.settingsManager = settingsManager;
+ this.useCategoryVisibility = useCategoryVisibility;
CheckpointFiles.CollectionChanged += OnCheckpointFilesChanged;
}
+ ///
+ /// When title is set, set the category enabled state from settings.
+ ///
+ // ReSharper disable once UnusedParameterInPartialMethod
+ partial void OnTitleChanged(string value)
+ {
+ if (!useCategoryVisibility) return;
+ IsCategoryEnabled = settingsManager.IsSharedFolderCategoryVisible(FolderType);
+ }
+
+ ///
+ /// When toggling the category enabled state, save it to settings.
+ ///
+ partial void OnIsCategoryEnabledChanged(bool value)
+ {
+ if (!useCategoryVisibility) return;
+ if (value != settingsManager.IsSharedFolderCategoryVisible(FolderType))
+ {
+ settingsManager.SetSharedFolderCategoryVisible(FolderType, value);
+ }
+ }
+
// On collection changes
private void OnCheckpointFilesChanged(object? sender, NotifyCollectionChangedEventArgs e)
{
+ OnPropertyChanged(nameof(TitleWithFilesCount));
if (e.NewItems == null) return;
// On new added items, add event handler for deletion
foreach (CheckpointFile item in e.NewItems)
@@ -73,9 +118,8 @@ public partial class CheckpointFolder : ObservableObject
{
IsImportInProgress = true;
IsCurrentDragTarget = false;
-
- var files = e.Data.GetData(DataFormats.FileDrop) as string[];
- if (files == null || files.Length < 1)
+
+ if (e.Data.GetData(DataFormats.FileDrop) is not string[] files || files.Length < 1)
{
IsImportInProgress = false;
return;
@@ -129,8 +173,8 @@ public partial class CheckpointFolder : ObservableObject
{
var checkpointFiles = await (progress switch
{
- null => Task.Run(() => CheckpointFile.FromDirectoryIndex(DirectoryPath)),
- _ => Task.Run(() => CheckpointFile.FromDirectoryIndex(DirectoryPath, progress))
+ null => Task.Run(() => CheckpointFile.FromDirectoryIndex(dialogFactory, DirectoryPath)),
+ _ => Task.Run(() => CheckpointFile.FromDirectoryIndex(dialogFactory, DirectoryPath, progress))
});
CheckpointFiles.Clear();
diff --git a/StabilityMatrix/Models/Settings.cs b/StabilityMatrix/Models/Settings.cs
index 4d716d9e..6ddb3f71 100644
--- a/StabilityMatrix/Models/Settings.cs
+++ b/StabilityMatrix/Models/Settings.cs
@@ -23,6 +23,11 @@ public class Settings
public string ModelsDirectory { get; set; } = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "StabilityMatrix", "Models");
public bool ModelBrowserNsfwEnabled { get; set; }
+ public SharedFolderType? SharedFolderVisibleCategories { get; set; } =
+ SharedFolderType.StableDiffusion |
+ SharedFolderType.Lora |
+ SharedFolderType.LyCORIS;
+
public InstalledPackage? GetActiveInstalledPackage()
{
return InstalledPackages.FirstOrDefault(x => x.Id == ActiveInstalledPackage);
diff --git a/StabilityMatrix/ViewModels/CheckpointManagerViewModel.cs b/StabilityMatrix/ViewModels/CheckpointManagerViewModel.cs
index a4261c04..3fda6787 100644
--- a/StabilityMatrix/ViewModels/CheckpointManagerViewModel.cs
+++ b/StabilityMatrix/ViewModels/CheckpointManagerViewModel.cs
@@ -15,12 +15,14 @@ public partial class CheckpointManagerViewModel : ObservableObject
private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
private readonly ISharedFolders sharedFolders;
private readonly ISettingsManager settingsManager;
+ private readonly IDialogFactory dialogFactory;
public ObservableCollection CheckpointFolders { get; set; } = new();
- public CheckpointManagerViewModel(ISharedFolders sharedFolders, ISettingsManager settingsManager)
+ public CheckpointManagerViewModel(ISharedFolders sharedFolders, ISettingsManager settingsManager, IDialogFactory dialogFactory)
{
this.sharedFolders = sharedFolders;
this.settingsManager = settingsManager;
+ this.dialogFactory = dialogFactory;
}
public async Task OnLoaded()
@@ -46,7 +48,11 @@ public partial class CheckpointManagerViewModel : ObservableObject
// Index all folders
var tasks = folders.Select(f => Task.Run(async () =>
{
- var checkpointFolder = new CheckpointFolder {Title = Path.GetFileName(f), DirectoryPath = f};
+ var checkpointFolder = new CheckpointFolder(dialogFactory, settingsManager)
+ {
+ Title = Path.GetFileName(f),
+ DirectoryPath = f
+ };
await checkpointFolder.IndexAsync();
indexedFolders.Add(checkpointFolder);
})).ToList();
diff --git a/StabilityMatrix/ViewModels/TextToImageViewModel.cs b/StabilityMatrix/ViewModels/TextToImageViewModel.cs
index 05790b40..6c4c52e1 100644
--- a/StabilityMatrix/ViewModels/TextToImageViewModel.cs
+++ b/StabilityMatrix/ViewModels/TextToImageViewModel.cs
@@ -103,7 +103,7 @@ public partial class TextToImageViewModel : ObservableObject
logger.LogWarning("Skipped model folder index - {SdModelsDir} does not exist", sdModelsDir);
return;
}
- DiffusionCheckpointFolder = new CheckpointFolder
+ DiffusionCheckpointFolder = new CheckpointFolder(null!, null!) // TODO: refactor to not use view models
{
Title = Path.GetFileName(sdModelsDir),
DirectoryPath = sdModelsDir