From a425279bdc57ddb61621c2bc876862e1470650b9 Mon Sep 17 00:00:00 2001 From: JT Date: Sat, 21 Oct 2023 19:45:43 -0700 Subject: [PATCH 1/2] inject via attributes & fix package update check & update nuget packages --- ...tabilityMatrix.Avalonia.Diagnostics.csproj | 8 +- .../BetterEntranceNavigationTransition.cs | 8 +- .../ItemsRepeaterArrangeAnimation.cs | 1 - StabilityMatrix.Avalonia/App.axaml.cs | 288 ++++++------------ .../Behaviors/TextEditorCompletionBehavior.cs | 2 - .../Behaviors/TextEditorToolTipBehavior.cs | 1 - .../Controls/AdvancedImageBox.axaml.cs | 1 - .../Controls/BatchSizeCard.axaml.cs | 10 +- .../Controls/BetterContentDialog.cs | 3 - .../Controls/CodeCompletion/CompletionData.cs | 4 - .../CodeCompletion/CompletionIcons.cs | 4 +- .../Controls/CodeCompletion/CompletionList.cs | 4 - .../CodeCompletion/CompletionWindow.axaml.cs | 2 - .../CodeCompletion/ICompletionData.cs | 2 - .../Controls/Dock/DockUserControlBase.cs | 2 - .../Controls/FASymbolIconSource.cs | 29 +- .../Controls/FreeUCard.axaml.cs | 2 + .../Controls/ImageFolderCard.axaml.cs | 2 + .../Controls/ImageGalleryCard.axaml.cs | 6 +- .../Controls/LineDashFrame.cs | 1 - .../Controls/ModelCard.axaml.cs | 10 +- .../Controls/Paginator.axaml.cs | 1 - .../Controls/PromptCard.axaml.cs | 2 + .../Controls/RefreshBadge.axaml.cs | 2 + .../Controls/SamplerCard.axaml.cs | 6 +- .../Controls/SeedCard.axaml.cs | 6 +- .../Controls/SelectImageCard.axaml.cs | 5 +- .../Controls/SharpenCard.axaml.cs | 6 +- .../Controls/StackCard.axaml.cs | 8 +- .../Controls/StackExpander.axaml.cs | 2 + .../Controls/UpscalerCard.axaml.cs | 5 +- .../DesignData/DesignData.cs | 13 +- StabilityMatrix.Avalonia/DialogHelper.cs | 3 - .../Helpers/PngDataHelper.cs | 1 - .../Helpers/TagCsvParser.cs | 19 +- .../Helpers/TextEditorConfigs.cs | 1 - .../Models/Inference/FileNameFormat.cs | 1 - .../Inference/FileNameFormatProvider.cs | 1 - .../Models/Inference/Prompt.cs | 1 - .../Models/Inference/StackExpanderModel.cs | 1 - .../Models/Inference/ViewState.cs | 3 +- .../Models/SharedState.cs | 5 +- .../TagCompletion/CompletionProvider.cs | 3 +- .../TagCompletion/TextCompletionRequest.cs | 4 +- .../Models/TagCompletion/TokenizerProvider.cs | 2 + .../Services/IInferenceClientManager.cs | 1 - .../Services/InferenceClientManager.cs | 3 +- .../Services/NavigationService.cs | 4 +- .../Services/NotificationService.cs | 32 +- .../Services/ServiceManager.cs | 15 + .../StabilityMatrix.Avalonia.csproj | 34 +-- .../Styles/ThemeColors.cs | 3 +- .../Base/InferenceTabViewModelBase.cs | 1 - .../Base/ProgressItemViewModelBase.cs | 1 - .../CheckpointBrowserCardViewModel.cs | 3 + .../ViewModels/CheckpointBrowserViewModel.cs | 4 +- .../CheckpointManager/CheckpointFile.cs | 3 + .../CheckpointManager/CheckpointFolder.cs | 3 + .../ViewModels/CheckpointsPageViewModel.cs | 1 + .../Dialogs/DownloadResourceViewModel.cs | 2 + .../ViewModels/Dialogs/EnvVarsViewModel.cs | 2 + .../ViewModels/Dialogs/ExceptionViewModel.cs | 2 + .../Dialogs/ImageViewerViewModel.cs | 2 + .../InferenceConnectionHelpViewModel.cs | 3 +- .../ViewModels/Dialogs/InstallerViewModel.cs | 3 + .../Dialogs/LaunchOptionsViewModel.cs | 2 + .../Dialogs/OneClickInstallViewModel.cs | 4 +- .../Dialogs/PackageImportViewModel.cs | 2 + .../Dialogs/SelectDataDirectoryViewModel.cs | 2 + .../Dialogs/SelectModelVersionViewModel.cs | 8 +- .../ViewModels/Dialogs/UpdateViewModel.cs | 2 + .../ViewModels/FirstLaunchSetupViewModel.cs | 2 + .../Inference/BatchSizeCardViewModel.cs | 2 + .../Inference/FreeUCardViewModel.cs | 2 + .../Inference/IImageGalleryComponent.cs | 4 +- .../Inference/ImageFolderCardViewModel.cs | 2 + .../Inference/ImageGalleryCardViewModel.cs | 2 + .../InferenceImageUpscaleViewModel.cs | 5 +- .../InferenceTextToImageViewModel.cs | 2 + .../Inference/ModelCardViewModel.cs | 2 + .../Inference/PromptCardViewModel.cs | 11 +- .../Inference/SamplerCardViewModel.cs | 2 + .../ViewModels/Inference/SeedCardViewModel.cs | 2 + .../Inference/SelectImageCardViewModel.cs | 3 +- .../Inference/SharpenCardViewModel.cs | 2 + .../Inference/StackCardViewModel.cs | 2 + .../Inference/StackExpanderViewModel.cs | 2 + .../Inference/UpscalerCardViewModel.cs | 2 + .../ViewModels/InferenceViewModel.cs | 3 +- .../ViewModels/LaunchPageViewModel.cs | 1 + .../ViewModels/NewCheckpointsPageViewModel.cs | 3 +- .../OutputsPage/OutputImageViewModel.cs | 3 +- .../ViewModels/OutputsPageViewModel.cs | 6 +- .../PackageManager/PackageCardViewModel.cs | 3 + .../ViewModels/PackageManagerViewModel.cs | 46 ++- .../Progress/ProgressManagerViewModel.cs | 2 + .../ViewModels/RefreshBadgeViewModel.cs | 2 + .../Settings/InferenceSettingsViewModel.cs | 9 +- .../ViewModels/SettingsViewModel.cs | 8 +- .../Views/CheckpointBrowserPage.axaml.cs | 2 + .../Views/CheckpointsPage.axaml.cs | 13 +- .../Dialogs/DownloadResourceDialog.axaml.cs | 5 +- .../Views/Dialogs/EnvVarsDialog.axaml.cs | 2 + .../Views/Dialogs/ExceptionDialog.axaml.cs | 6 +- .../Views/Dialogs/ImageViewerDialog.axaml.cs | 3 +- .../InferenceConnectionHelpDialog.axaml.cs | 5 +- .../Dialogs/LaunchOptionsDialog.axaml.cs | 2 + .../Dialogs/OneClickInstallDialog.axaml.cs | 1 - .../Dialogs/PackageImportDialog.axaml.cs | 2 + .../SelectDataDirectoryDialog.axaml.cs | 2 + .../Views/Dialogs/UpdateDialog.axaml.cs | 4 +- .../Views/FirstLaunchSetupWindow.axaml.cs | 6 +- .../InferenceImageUpscaleView.axaml.cs | 2 + .../InferenceTextToImageView.axaml.cs | 2 + .../Views/InferencePage.axaml.cs | 2 + .../Views/LaunchPageView.axaml.cs | 2 + .../Views/MainWindow.axaml.cs | 3 +- .../Views/NewCheckpointsPage.axaml.cs | 2 + .../Views/OutputsPage.axaml | 6 +- .../Views/OutputsPage.axaml.cs | 7 +- .../Views/PackageManagerPage.axaml.cs | 2 + .../Views/ProgressManagerPage.axaml.cs | 2 + .../Settings/InferenceSettingsPage.axaml.cs | 7 +- .../Views/SettingsPage.axaml.cs | 2 + .../Attributes/ManagedServiceAttribute.cs | 4 + .../Attributes/SingletonAttribute.cs | 14 + .../Attributes/TransientAttribute.cs | 14 + .../Helper/Cache/GithubApiCache.cs | 48 +-- .../Helper/Factory/PackageFactory.cs | 9 +- StabilityMatrix.Core/Helper/ModelFinder.cs | 46 ++- StabilityMatrix.Core/Helper/SharedFolders.cs | 2 + .../Models/Packages/A3WebUI.cs | 2 + .../Models/Packages/ComfyUI.cs | 2 + .../Models/Packages/Fooocus.cs | 2 + .../Models/Packages/FooocusMre.cs | 2 + .../Models/Packages/InvokeAI.cs | 2 + .../Packages/StableDiffusionDirectMl.cs | 2 + .../Models/Packages/StableDiffusionUx.cs | 2 + .../Models/Packages/VladAutomatic.cs | 2 + .../Models/Packages/VoltaML.cs | 2 + .../Models/TrackedDownload.cs | 158 ++++++---- StabilityMatrix.Core/Python/PyRunner.cs | 121 +++++--- .../Services/DownloadService.cs | 2 + .../Services/ImageIndexService.cs | 2 + .../Services/ModelIndexService.cs | 2 + .../Services/SettingsManager.cs | 2 + .../StabilityMatrix.Core.csproj | 30 +- StabilityMatrix.Core/Updater/UpdateHelper.cs | 2 + .../StabilityMatrix.Tests.csproj | 8 +- 149 files changed, 743 insertions(+), 599 deletions(-) create mode 100644 StabilityMatrix.Core/Attributes/ManagedServiceAttribute.cs create mode 100644 StabilityMatrix.Core/Attributes/SingletonAttribute.cs create mode 100644 StabilityMatrix.Core/Attributes/TransientAttribute.cs diff --git a/StabilityMatrix.Avalonia.Diagnostics/StabilityMatrix.Avalonia.Diagnostics.csproj b/StabilityMatrix.Avalonia.Diagnostics/StabilityMatrix.Avalonia.Diagnostics.csproj index cfbcd729..75091167 100644 --- a/StabilityMatrix.Avalonia.Diagnostics/StabilityMatrix.Avalonia.Diagnostics.csproj +++ b/StabilityMatrix.Avalonia.Diagnostics/StabilityMatrix.Avalonia.Diagnostics.csproj @@ -19,12 +19,12 @@ - - + + - - + + diff --git a/StabilityMatrix.Avalonia/Animations/BetterEntranceNavigationTransition.cs b/StabilityMatrix.Avalonia/Animations/BetterEntranceNavigationTransition.cs index fef4f8db..66a66152 100644 --- a/StabilityMatrix.Avalonia/Animations/BetterEntranceNavigationTransition.cs +++ b/StabilityMatrix.Avalonia/Animations/BetterEntranceNavigationTransition.cs @@ -1,12 +1,10 @@ using System; using System.Threading; -using AsyncAwaitBestPractices; using Avalonia; using Avalonia.Animation; using Avalonia.Animation.Easings; using Avalonia.Media; using Avalonia.Styling; -using FluentAvalonia.UI.Media.Animation; namespace StabilityMatrix.Avalonia.Animations; @@ -23,7 +21,7 @@ public class BetterEntranceNavigationTransition : BaseTransitionInfo /// Gets or sets the Vertical Offset used when animating /// public double FromVerticalOffset { get; set; } = 100; - + public override async void RunAnimation(Animatable ctrl, CancellationToken cancellationToken) { var animation = new Animation @@ -36,7 +34,7 @@ public class BetterEntranceNavigationTransition : BaseTransitionInfo Setters = { new Setter(Visual.OpacityProperty, 0.0), - new Setter(TranslateTransform.XProperty,FromHorizontalOffset), + new Setter(TranslateTransform.XProperty, FromHorizontalOffset), new Setter(TranslateTransform.YProperty, FromVerticalOffset) }, Cue = new Cue(0d) @@ -46,7 +44,7 @@ public class BetterEntranceNavigationTransition : BaseTransitionInfo Setters = { new Setter(Visual.OpacityProperty, 1d), - new Setter(TranslateTransform.XProperty,0.0), + new Setter(TranslateTransform.XProperty, 0.0), new Setter(TranslateTransform.YProperty, 0.0) }, Cue = new Cue(1d) diff --git a/StabilityMatrix.Avalonia/Animations/ItemsRepeaterArrangeAnimation.cs b/StabilityMatrix.Avalonia/Animations/ItemsRepeaterArrangeAnimation.cs index 507d9872..7014e63f 100644 --- a/StabilityMatrix.Avalonia/Animations/ItemsRepeaterArrangeAnimation.cs +++ b/StabilityMatrix.Avalonia/Animations/ItemsRepeaterArrangeAnimation.cs @@ -2,7 +2,6 @@ using Avalonia; using Avalonia.Controls; using Avalonia.Rendering.Composition; -using Avalonia.Rendering.Composition.Animations; namespace StabilityMatrix.Avalonia.Animations; diff --git a/StabilityMatrix.Avalonia/App.axaml.cs b/StabilityMatrix.Avalonia/App.axaml.cs index f09b0fe0..b0cd7885 100644 --- a/StabilityMatrix.Avalonia/App.axaml.cs +++ b/StabilityMatrix.Avalonia/App.axaml.cs @@ -39,42 +39,25 @@ using Polly.Extensions.Http; using Polly.Timeout; using Refit; using Sentry; -using StabilityMatrix.Avalonia.Controls; using StabilityMatrix.Avalonia.DesignData; using StabilityMatrix.Avalonia.Helpers; using StabilityMatrix.Avalonia.Languages; -using StabilityMatrix.Avalonia.Models; -using StabilityMatrix.Avalonia.Models.TagCompletion; using StabilityMatrix.Avalonia.Services; using StabilityMatrix.Avalonia.ViewModels; using StabilityMatrix.Avalonia.ViewModels.Base; -using StabilityMatrix.Avalonia.ViewModels.CheckpointBrowser; -using StabilityMatrix.Avalonia.ViewModels.CheckpointManager; -using StabilityMatrix.Avalonia.ViewModels.Dialogs; -using StabilityMatrix.Avalonia.ViewModels.Inference; -using StabilityMatrix.Avalonia.ViewModels.PackageManager; using StabilityMatrix.Avalonia.ViewModels.Progress; -using StabilityMatrix.Avalonia.ViewModels.Settings; using StabilityMatrix.Avalonia.Views; -using StabilityMatrix.Avalonia.Views.Dialogs; -using StabilityMatrix.Avalonia.Views.Inference; -using StabilityMatrix.Avalonia.Views.Settings; using StabilityMatrix.Core.Api; +using StabilityMatrix.Core.Attributes; using StabilityMatrix.Core.Converters.Json; using StabilityMatrix.Core.Database; using StabilityMatrix.Core.Extensions; using StabilityMatrix.Core.Helper; -using StabilityMatrix.Core.Helper.Cache; -using StabilityMatrix.Core.Helper.Factory; using StabilityMatrix.Core.Models.Api; using StabilityMatrix.Core.Models.Configs; using StabilityMatrix.Core.Models.FileInterfaces; -using StabilityMatrix.Core.Models.PackageModification; -using StabilityMatrix.Core.Models.Packages; using StabilityMatrix.Core.Models.Settings; -using StabilityMatrix.Core.Python; using StabilityMatrix.Core.Services; -using StabilityMatrix.Core.Updater; using Application = Avalonia.Application; using DrawingColor = System.Drawing.Color; using LogLevel = Microsoft.Extensions.Logging.LogLevel; @@ -249,19 +232,6 @@ public sealed class App : Application internal static void ConfigurePageViewModels(IServiceCollection services) { - services - .AddSingleton() - .AddSingleton() - .AddSingleton() - .AddSingleton() - .AddSingleton() - .AddSingleton() - .AddSingleton() - .AddSingleton() - .AddSingleton() - .AddSingleton() - .AddSingleton(); - services.AddSingleton( provider => new MainWindowViewModel( @@ -289,189 +259,103 @@ public sealed class App : Application services.AddSingleton(p => p.GetRequiredService()); } - internal static void ConfigureDialogViewModels(IServiceCollection services) + internal static void ConfigureDialogViewModels( + IServiceCollection services, + Type[] exportedTypes + ) { - // Dialog view models (transient) - services.AddTransient(); - services.AddTransient(); - services.AddTransient(); - services.AddTransient(); - services.AddTransient(); - services.AddTransient(); - services.AddTransient(); - services.AddTransient(); - services.AddTransient(); - services.AddTransient(); - services.AddTransient(); - - // Dialog view models (singleton) - services.AddSingleton(); - services.AddSingleton(); - - // Other transients (usually sub view models) - services.AddTransient(); - services.AddTransient(); - services.AddTransient(); - services.AddTransient(); - services.AddTransient(); - services.AddTransient(); - - // Global progress - services.AddSingleton(); - - // Controls - services.AddTransient(); - - // Inference controls - services.AddTransient(); - services.AddTransient(); - services.AddTransient(); - services.AddTransient(); - services.AddTransient(); - services.AddTransient(); - services.AddTransient(); - services.AddTransient(); - services.AddTransient(); - services.AddTransient(); - services.AddTransient(); - services.AddTransient(); - services.AddTransient(); - // Dialog factory - services.AddSingleton>( - provider => - new ServiceManager() - .Register(provider.GetRequiredService) - .Register(provider.GetRequiredService) - .Register(provider.GetRequiredService) - .Register(provider.GetRequiredService) - .Register(provider.GetRequiredService) - .Register(provider.GetRequiredService) - .Register(provider.GetRequiredService) - .Register(provider.GetRequiredService) - .Register(provider.GetRequiredService) - .Register(provider.GetRequiredService) - .Register(provider.GetRequiredService) - .Register(provider.GetRequiredService) - .Register(provider.GetRequiredService) - .Register(provider.GetRequiredService) - .Register(provider.GetRequiredService) - .Register(provider.GetRequiredService) - .Register(provider.GetRequiredService) - .Register(provider.GetRequiredService) - .Register(provider.GetRequiredService) - .Register(provider.GetRequiredService) - .Register(provider.GetRequiredService) - .Register(provider.GetRequiredService) - .Register(provider.GetRequiredService) - .Register(provider.GetRequiredService) - .Register(provider.GetRequiredService) - .Register(provider.GetRequiredService) - .Register(provider.GetRequiredService) - .Register(provider.GetRequiredService) - .Register(provider.GetRequiredService) - .Register(provider.GetRequiredService) - .Register(provider.GetRequiredService) - .Register(provider.GetRequiredService) - .Register(provider.GetRequiredService) - .Register(provider.GetRequiredService) - ); - } + services.AddSingleton>(provider => + { + var serviceManager = new ServiceManager(); + + var serviceManagedTypes = exportedTypes + .Select( + t => + new + { + t, + attributes = t.GetCustomAttributes( + typeof(ManagedServiceAttribute), + true + ) + } + ) + .Where(t1 => t1.attributes is { Length: > 0 }) + .Select(t1 => t1.t) + .ToList(); - internal static void ConfigureViews(IServiceCollection services) - { - // Pages - services.AddSingleton(); - services.AddSingleton(); - services.AddSingleton(); - services.AddSingleton(); - services.AddSingleton(); - services.AddSingleton(); - services.AddSingleton(); - services.AddSingleton(); - services.AddSingleton(); - services.AddSingleton(); - - // Inference tabs - services.AddTransient(); - services.AddTransient(); - - // Inference controls - services.AddTransient(); - services.AddTransient(); - services.AddTransient(); - services.AddTransient(); - services.AddTransient(); - services.AddTransient(); - services.AddTransient(); - services.AddTransient(); - services.AddTransient(); - services.AddTransient(); - services.AddTransient(); - services.AddTransient(); - services.AddTransient(); - - // Dialogs - services.AddTransient(); - services.AddTransient(); - services.AddTransient(); - services.AddTransient(); - services.AddTransient(); - services.AddTransient(); - services.AddTransient(); - services.AddTransient(); - services.AddTransient(); - - // Controls - services.AddTransient(); - - // Windows - services.AddSingleton(); - services.AddSingleton(); - } + foreach (var type in serviceManagedTypes) + { + ViewModelBase? GetInstance() => provider.GetRequiredService(type) as ViewModelBase; + serviceManager.Register(type, GetInstance); + } - internal static void ConfigurePackages(IServiceCollection services) - { - services.AddSingleton(); - services.AddSingleton(); - services.AddSingleton(); - services.AddSingleton(); - services.AddSingleton(); - services.AddSingleton(); - services.AddSingleton(); - services.AddSingleton(); - services.AddSingleton(); + return serviceManager; + }); } - private static IServiceCollection ConfigureServices() + internal static IServiceCollection ConfigureServices() { var services = new ServiceCollection(); - services.AddMemoryCache(); + var exportedTypes = AppDomain.CurrentDomain + .GetAssemblies() + .Where(a => a.FullName?.StartsWith("StabilityMatrix") == true) + .SelectMany(a => a.GetExportedTypes()) + .ToArray(); + + var transientTypes = exportedTypes + .Select( + t => new { t, attributes = t.GetCustomAttributes(typeof(TransientAttribute), true) } + ) + .Where( + t1 => + t1.attributes is { Length: > 0 } + && !t1.t.Name.Contains("Mock", StringComparison.OrdinalIgnoreCase) + ) + .Select(t1 => new { Type = t1.t, Attribute = (TransientAttribute)t1.attributes[0] }); + + foreach (var typePair in transientTypes) + { + if (typePair.Attribute.InterfaceType is null) + { + services.AddTransient(typePair.Type); + } + else + { + services.AddTransient(typePair.Attribute.InterfaceType, typePair.Type); + } + } + + var singletonTypes = exportedTypes + .Select( + t => new { t, attributes = t.GetCustomAttributes(typeof(SingletonAttribute), true) } + ) + .Where( + t1 => + t1.attributes is { Length: > 0 } + && !t1.t.Name.Contains("Mock", StringComparison.OrdinalIgnoreCase) + ) + .Select(t1 => new { Type = t1.t, Attribute = (SingletonAttribute)t1.attributes[0] }); + + foreach (var typePair in singletonTypes) + { + if (typePair.Attribute.InterfaceType is null) + { + services.AddSingleton(typePair.Type); + } + else + { + services.AddSingleton(typePair.Attribute.InterfaceType, typePair.Type); + } + } + ConfigurePageViewModels(services); - ConfigureDialogViewModels(services); - ConfigurePackages(services); + ConfigureDialogViewModels(services, exportedTypes); // Other services - services.AddSingleton(); - services.AddSingleton(); - services.AddSingleton(); - services.AddSingleton(); - services.AddSingleton(); - services.AddSingleton(); - services.AddSingleton(); - services.AddSingleton(); - services.AddSingleton(); - services.AddSingleton(); - services.AddSingleton(); - services.AddSingleton(); - services.AddSingleton(); - services.AddSingleton(); - services.AddSingleton(); - services.AddTransient(); - services.AddSingleton(); - services.AddSingleton(); services.AddSingleton( provider => (IDisposable)provider.GetRequiredService() @@ -499,8 +383,6 @@ public sealed class App : Application services.AddSingleton(); } - ConfigureViews(services); - if (Design.IsDesignMode) { services.AddSingleton(); diff --git a/StabilityMatrix.Avalonia/Behaviors/TextEditorCompletionBehavior.cs b/StabilityMatrix.Avalonia/Behaviors/TextEditorCompletionBehavior.cs index b046d5d8..376563c4 100644 --- a/StabilityMatrix.Avalonia/Behaviors/TextEditorCompletionBehavior.cs +++ b/StabilityMatrix.Avalonia/Behaviors/TextEditorCompletionBehavior.cs @@ -2,9 +2,7 @@ using System; using System.Diagnostics.CodeAnalysis; using System.Linq; using System.Runtime.CompilerServices; -using System.Threading.Tasks; using Avalonia; -using Avalonia.Controls; using Avalonia.Input; using Avalonia.Threading; using Avalonia.Xaml.Interactivity; diff --git a/StabilityMatrix.Avalonia/Behaviors/TextEditorToolTipBehavior.cs b/StabilityMatrix.Avalonia/Behaviors/TextEditorToolTipBehavior.cs index 6c1411a1..2f624104 100644 --- a/StabilityMatrix.Avalonia/Behaviors/TextEditorToolTipBehavior.cs +++ b/StabilityMatrix.Avalonia/Behaviors/TextEditorToolTipBehavior.cs @@ -3,7 +3,6 @@ using System.Diagnostics.CodeAnalysis; using System.Linq; using Avalonia; using Avalonia.Controls; -using Avalonia.Controls.Presenters; using Avalonia.Input; using Avalonia.Media; using Avalonia.Xaml.Interactivity; diff --git a/StabilityMatrix.Avalonia/Controls/AdvancedImageBox.axaml.cs b/StabilityMatrix.Avalonia/Controls/AdvancedImageBox.axaml.cs index 8d8f7e72..80704547 100644 --- a/StabilityMatrix.Avalonia/Controls/AdvancedImageBox.axaml.cs +++ b/StabilityMatrix.Avalonia/Controls/AdvancedImageBox.axaml.cs @@ -22,7 +22,6 @@ using AsyncAwaitBestPractices; using AsyncImageLoader; using Avalonia; using Avalonia.Controls; -using Avalonia.Controls.Metadata; using Avalonia.Controls.Presenters; using Avalonia.Controls.Primitives; using Avalonia.Input; diff --git a/StabilityMatrix.Avalonia/Controls/BatchSizeCard.axaml.cs b/StabilityMatrix.Avalonia/Controls/BatchSizeCard.axaml.cs index ea7d573f..92e65bbd 100644 --- a/StabilityMatrix.Avalonia/Controls/BatchSizeCard.axaml.cs +++ b/StabilityMatrix.Avalonia/Controls/BatchSizeCard.axaml.cs @@ -1,9 +1,7 @@ -using Avalonia; -using Avalonia.Controls; -using Avalonia.Controls.Primitives; +using Avalonia.Controls.Primitives; +using StabilityMatrix.Core.Attributes; namespace StabilityMatrix.Avalonia.Controls; -public class BatchSizeCard : TemplatedControl -{ -} \ No newline at end of file +[Transient] +public class BatchSizeCard : TemplatedControl { } diff --git a/StabilityMatrix.Avalonia/Controls/BetterContentDialog.cs b/StabilityMatrix.Avalonia/Controls/BetterContentDialog.cs index 5556bc38..8d5649a2 100644 --- a/StabilityMatrix.Avalonia/Controls/BetterContentDialog.cs +++ b/StabilityMatrix.Avalonia/Controls/BetterContentDialog.cs @@ -1,6 +1,5 @@ using System; using System.Diagnostics.CodeAnalysis; -using System.Drawing; using System.Reflection; using AsyncAwaitBestPractices; using Avalonia; @@ -11,8 +10,6 @@ using Avalonia.Interactivity; using Avalonia.Threading; using FluentAvalonia.UI.Controls; using StabilityMatrix.Avalonia.ViewModels.Base; -using StabilityMatrix.Avalonia.ViewModels.Dialogs; -using Brushes = Avalonia.Media.Brushes; namespace StabilityMatrix.Avalonia.Controls; diff --git a/StabilityMatrix.Avalonia/Controls/CodeCompletion/CompletionData.cs b/StabilityMatrix.Avalonia/Controls/CodeCompletion/CompletionData.cs index 615e09e8..fa9197f7 100644 --- a/StabilityMatrix.Avalonia/Controls/CodeCompletion/CompletionData.cs +++ b/StabilityMatrix.Avalonia/Controls/CodeCompletion/CompletionData.cs @@ -1,9 +1,5 @@ using System; -using System.Diagnostics; -using System.Diagnostics.CodeAnalysis; -using Avalonia.Controls; using Avalonia.Controls.Documents; -using Avalonia.Media; using AvaloniaEdit.Document; using AvaloniaEdit.Editing; using StabilityMatrix.Avalonia.Models; diff --git a/StabilityMatrix.Avalonia/Controls/CodeCompletion/CompletionIcons.cs b/StabilityMatrix.Avalonia/Controls/CodeCompletion/CompletionIcons.cs index 75f9dfdb..33144df8 100644 --- a/StabilityMatrix.Avalonia/Controls/CodeCompletion/CompletionIcons.cs +++ b/StabilityMatrix.Avalonia/Controls/CodeCompletion/CompletionIcons.cs @@ -1,6 +1,4 @@ -using System; -using System.Diagnostics.CodeAnalysis; -using Projektanker.Icons.Avalonia; +using System.Diagnostics.CodeAnalysis; using StabilityMatrix.Avalonia.Models; using StabilityMatrix.Avalonia.Models.TagCompletion; using StabilityMatrix.Avalonia.Styles; diff --git a/StabilityMatrix.Avalonia/Controls/CodeCompletion/CompletionList.cs b/StabilityMatrix.Avalonia/Controls/CodeCompletion/CompletionList.cs index 6eaadc03..355676e6 100644 --- a/StabilityMatrix.Avalonia/Controls/CodeCompletion/CompletionList.cs +++ b/StabilityMatrix.Avalonia/Controls/CodeCompletion/CompletionList.cs @@ -20,10 +20,8 @@ using System; using System.Collections.Generic; using System.Collections.Immutable; using System.Collections.ObjectModel; -using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.Linq; -using System.Runtime.CompilerServices; using Avalonia; using Avalonia.Controls; using Avalonia.Controls.Primitives; @@ -31,8 +29,6 @@ using Avalonia.Input; using Avalonia.Interactivity; using Avalonia.Markup.Xaml.Templates; using AvaloniaEdit.Utils; -using StabilityMatrix.Avalonia.Models.TagCompletion; -using StabilityMatrix.Core.Extensions; using StabilityMatrix.Core.Helper; namespace StabilityMatrix.Avalonia.Controls.CodeCompletion; diff --git a/StabilityMatrix.Avalonia/Controls/CodeCompletion/CompletionWindow.axaml.cs b/StabilityMatrix.Avalonia/Controls/CodeCompletion/CompletionWindow.axaml.cs index 88cbce8b..92155288 100644 --- a/StabilityMatrix.Avalonia/Controls/CodeCompletion/CompletionWindow.axaml.cs +++ b/StabilityMatrix.Avalonia/Controls/CodeCompletion/CompletionWindow.axaml.cs @@ -18,8 +18,6 @@ using System; using System.Diagnostics; -using System.Threading.Tasks; -using AsyncAwaitBestPractices; using Avalonia; using Avalonia.Controls; using Avalonia.Controls.Primitives; diff --git a/StabilityMatrix.Avalonia/Controls/CodeCompletion/ICompletionData.cs b/StabilityMatrix.Avalonia/Controls/CodeCompletion/ICompletionData.cs index 2d24ca55..eeb9f592 100644 --- a/StabilityMatrix.Avalonia/Controls/CodeCompletion/ICompletionData.cs +++ b/StabilityMatrix.Avalonia/Controls/CodeCompletion/ICompletionData.cs @@ -19,10 +19,8 @@ using System; using System.Diagnostics.CodeAnalysis; using Avalonia.Controls.Documents; -using Avalonia.Media; using AvaloniaEdit.Document; using AvaloniaEdit.Editing; -using FluentAvalonia.UI.Controls; using StabilityMatrix.Avalonia.Models; namespace StabilityMatrix.Avalonia.Controls.CodeCompletion; diff --git a/StabilityMatrix.Avalonia/Controls/Dock/DockUserControlBase.cs b/StabilityMatrix.Avalonia/Controls/Dock/DockUserControlBase.cs index d634c0cc..7325ff60 100644 --- a/StabilityMatrix.Avalonia/Controls/Dock/DockUserControlBase.cs +++ b/StabilityMatrix.Avalonia/Controls/Dock/DockUserControlBase.cs @@ -1,5 +1,4 @@ using System; -using System.Text.Json; using System.Text.Json.Nodes; using System.Threading.Tasks; using Avalonia; @@ -9,7 +8,6 @@ using Avalonia.Controls.Primitives; using Avalonia.Threading; using Dock.Avalonia.Controls; using Dock.Model; -using Dock.Model.Avalonia.Json; using Dock.Model.Core; using Dock.Serializer; using StabilityMatrix.Avalonia.Models.Inference; diff --git a/StabilityMatrix.Avalonia/Controls/FASymbolIconSource.cs b/StabilityMatrix.Avalonia/Controls/FASymbolIconSource.cs index bc5c84e6..d853d724 100644 --- a/StabilityMatrix.Avalonia/Controls/FASymbolIconSource.cs +++ b/StabilityMatrix.Avalonia/Controls/FASymbolIconSource.cs @@ -15,12 +15,14 @@ namespace StabilityMatrix.Avalonia.Controls; [SuppressMessage("ReSharper", "PropertyCanBeMadeInitOnly.Global")] public class FASymbolIconSource : PathIconSource { - public static readonly StyledProperty SymbolProperty = - AvaloniaProperty.Register(nameof(Symbol)); - - public static readonly StyledProperty FontSizeProperty = TextElement.FontSizeProperty.AddOwner(); + public static readonly StyledProperty SymbolProperty = AvaloniaProperty.Register< + FASymbolIconSource, + string + >(nameof(Symbol)); + + public static readonly StyledProperty FontSizeProperty = + TextElement.FontSizeProperty.AddOwner(); - public FASymbolIconSource() { Stretch = Stretch.None; @@ -52,11 +54,11 @@ public class FASymbolIconSource : PathIconSource private void InvalidateData() { - var path = IconProvider.Current.GetIconPath(Symbol); + var path = IconProvider.Current.GetIcon(Symbol).Path; var geometry = Geometry.Parse(path); - + var scale = FontSize / 20; - + Data = geometry; // TODO: Scaling not working Data.Transform = new ScaleTransform(scale, scale); @@ -74,14 +76,15 @@ public class FASymbolIconSourceConverter : TypeConverter return base.CanConvertFrom(context, sourceType); } - public override object? ConvertFrom(ITypeDescriptorContext? context, CultureInfo? culture, object value) + public override object? ConvertFrom( + ITypeDescriptorContext? context, + CultureInfo? culture, + object value + ) { return value switch { - string val => new FASymbolIconSource - { - Symbol = val, - }, + string val => new FASymbolIconSource { Symbol = val, }, _ => base.ConvertFrom(context, culture, value) }; } diff --git a/StabilityMatrix.Avalonia/Controls/FreeUCard.axaml.cs b/StabilityMatrix.Avalonia/Controls/FreeUCard.axaml.cs index 555b87d4..500eaf7a 100644 --- a/StabilityMatrix.Avalonia/Controls/FreeUCard.axaml.cs +++ b/StabilityMatrix.Avalonia/Controls/FreeUCard.axaml.cs @@ -1,5 +1,7 @@ using Avalonia.Controls.Primitives; +using StabilityMatrix.Core.Attributes; namespace StabilityMatrix.Avalonia.Controls; +[Transient] public class FreeUCard : TemplatedControl { } diff --git a/StabilityMatrix.Avalonia/Controls/ImageFolderCard.axaml.cs b/StabilityMatrix.Avalonia/Controls/ImageFolderCard.axaml.cs index b36e1fe1..838fe085 100644 --- a/StabilityMatrix.Avalonia/Controls/ImageFolderCard.axaml.cs +++ b/StabilityMatrix.Avalonia/Controls/ImageFolderCard.axaml.cs @@ -1,7 +1,9 @@ using Avalonia.Input; +using StabilityMatrix.Core.Attributes; namespace StabilityMatrix.Avalonia.Controls; +[Transient] public class ImageFolderCard : DropTargetTemplatedControlBase { /// diff --git a/StabilityMatrix.Avalonia/Controls/ImageGalleryCard.axaml.cs b/StabilityMatrix.Avalonia/Controls/ImageGalleryCard.axaml.cs index f36dff78..cef9024e 100644 --- a/StabilityMatrix.Avalonia/Controls/ImageGalleryCard.axaml.cs +++ b/StabilityMatrix.Avalonia/Controls/ImageGalleryCard.axaml.cs @@ -1,7 +1,7 @@ using Avalonia.Controls.Primitives; +using StabilityMatrix.Core.Attributes; namespace StabilityMatrix.Avalonia.Controls; -public class ImageGalleryCard : TemplatedControl -{ -} +[Transient] +public class ImageGalleryCard : TemplatedControl { } diff --git a/StabilityMatrix.Avalonia/Controls/LineDashFrame.cs b/StabilityMatrix.Avalonia/Controls/LineDashFrame.cs index 1356d513..efb410da 100644 --- a/StabilityMatrix.Avalonia/Controls/LineDashFrame.cs +++ b/StabilityMatrix.Avalonia/Controls/LineDashFrame.cs @@ -2,7 +2,6 @@ using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; using Avalonia; -using Avalonia.Controls; using Avalonia.Media; using FluentAvalonia.UI.Controls; diff --git a/StabilityMatrix.Avalonia/Controls/ModelCard.axaml.cs b/StabilityMatrix.Avalonia/Controls/ModelCard.axaml.cs index e997a874..622f1cbe 100644 --- a/StabilityMatrix.Avalonia/Controls/ModelCard.axaml.cs +++ b/StabilityMatrix.Avalonia/Controls/ModelCard.axaml.cs @@ -1,9 +1,7 @@ -using Avalonia; -using Avalonia.Controls; -using Avalonia.Controls.Primitives; +using Avalonia.Controls.Primitives; +using StabilityMatrix.Core.Attributes; namespace StabilityMatrix.Avalonia.Controls; -public class ModelCard : TemplatedControl -{ -} \ No newline at end of file +[Transient] +public class ModelCard : TemplatedControl { } diff --git a/StabilityMatrix.Avalonia/Controls/Paginator.axaml.cs b/StabilityMatrix.Avalonia/Controls/Paginator.axaml.cs index 9342ec12..ef1f1114 100644 --- a/StabilityMatrix.Avalonia/Controls/Paginator.axaml.cs +++ b/StabilityMatrix.Avalonia/Controls/Paginator.axaml.cs @@ -2,7 +2,6 @@ using System.Windows.Input; using Avalonia; using Avalonia.Controls.Primitives; -using AvaloniaEdit.Utils; using CommunityToolkit.Mvvm.Input; namespace StabilityMatrix.Avalonia.Controls; diff --git a/StabilityMatrix.Avalonia/Controls/PromptCard.axaml.cs b/StabilityMatrix.Avalonia/Controls/PromptCard.axaml.cs index 47a02af1..38300cff 100644 --- a/StabilityMatrix.Avalonia/Controls/PromptCard.axaml.cs +++ b/StabilityMatrix.Avalonia/Controls/PromptCard.axaml.cs @@ -6,9 +6,11 @@ using AvaloniaEdit; using AvaloniaEdit.Editing; using AvaloniaEdit.Utils; using StabilityMatrix.Avalonia.Helpers; +using StabilityMatrix.Core.Attributes; namespace StabilityMatrix.Avalonia.Controls; +[Transient] public class PromptCard : TemplatedControl { /// diff --git a/StabilityMatrix.Avalonia/Controls/RefreshBadge.axaml.cs b/StabilityMatrix.Avalonia/Controls/RefreshBadge.axaml.cs index f5620f12..1943c3ae 100644 --- a/StabilityMatrix.Avalonia/Controls/RefreshBadge.axaml.cs +++ b/StabilityMatrix.Avalonia/Controls/RefreshBadge.axaml.cs @@ -1,7 +1,9 @@ using Avalonia.Markup.Xaml; +using StabilityMatrix.Core.Attributes; namespace StabilityMatrix.Avalonia.Controls; +[Transient] public partial class RefreshBadge : UserControlBase { public RefreshBadge() diff --git a/StabilityMatrix.Avalonia/Controls/SamplerCard.axaml.cs b/StabilityMatrix.Avalonia/Controls/SamplerCard.axaml.cs index 7e732e0f..ace972b1 100644 --- a/StabilityMatrix.Avalonia/Controls/SamplerCard.axaml.cs +++ b/StabilityMatrix.Avalonia/Controls/SamplerCard.axaml.cs @@ -1,7 +1,7 @@ using Avalonia.Controls.Primitives; +using StabilityMatrix.Core.Attributes; namespace StabilityMatrix.Avalonia.Controls; -public class SamplerCard : TemplatedControl -{ -} +[Transient] +public class SamplerCard : TemplatedControl { } diff --git a/StabilityMatrix.Avalonia/Controls/SeedCard.axaml.cs b/StabilityMatrix.Avalonia/Controls/SeedCard.axaml.cs index f08853dd..06d164e9 100644 --- a/StabilityMatrix.Avalonia/Controls/SeedCard.axaml.cs +++ b/StabilityMatrix.Avalonia/Controls/SeedCard.axaml.cs @@ -1,7 +1,7 @@ using Avalonia.Controls.Primitives; +using StabilityMatrix.Core.Attributes; namespace StabilityMatrix.Avalonia.Controls; -public class SeedCard : TemplatedControl -{ -} +[Transient] +public class SeedCard : TemplatedControl { } diff --git a/StabilityMatrix.Avalonia/Controls/SelectImageCard.axaml.cs b/StabilityMatrix.Avalonia/Controls/SelectImageCard.axaml.cs index dd748696..726cf414 100644 --- a/StabilityMatrix.Avalonia/Controls/SelectImageCard.axaml.cs +++ b/StabilityMatrix.Avalonia/Controls/SelectImageCard.axaml.cs @@ -1,3 +1,6 @@ -namespace StabilityMatrix.Avalonia.Controls; +using StabilityMatrix.Core.Attributes; +namespace StabilityMatrix.Avalonia.Controls; + +[Transient] public class SelectImageCard : DropTargetTemplatedControlBase { } diff --git a/StabilityMatrix.Avalonia/Controls/SharpenCard.axaml.cs b/StabilityMatrix.Avalonia/Controls/SharpenCard.axaml.cs index 6fd22370..4c2a250d 100644 --- a/StabilityMatrix.Avalonia/Controls/SharpenCard.axaml.cs +++ b/StabilityMatrix.Avalonia/Controls/SharpenCard.axaml.cs @@ -1,7 +1,7 @@ -using Avalonia; -using Avalonia.Controls; -using Avalonia.Controls.Primitives; +using Avalonia.Controls.Primitives; +using StabilityMatrix.Core.Attributes; namespace StabilityMatrix.Avalonia.Controls; +[Transient] public class SharpenCard : TemplatedControl { } diff --git a/StabilityMatrix.Avalonia/Controls/StackCard.axaml.cs b/StabilityMatrix.Avalonia/Controls/StackCard.axaml.cs index c8374349..2341a96d 100644 --- a/StabilityMatrix.Avalonia/Controls/StackCard.axaml.cs +++ b/StabilityMatrix.Avalonia/Controls/StackCard.axaml.cs @@ -1,14 +1,18 @@ using System.Diagnostics.CodeAnalysis; using Avalonia; using Avalonia.Controls.Primitives; +using StabilityMatrix.Core.Attributes; namespace StabilityMatrix.Avalonia.Controls; [SuppressMessage("ReSharper", "MemberCanBePrivate.Global")] +[Transient] public class StackCard : TemplatedControl { - public static readonly StyledProperty SpacingProperty = AvaloniaProperty.Register( - "Spacing", 8); + public static readonly StyledProperty SpacingProperty = AvaloniaProperty.Register< + StackCard, + int + >("Spacing", 8); public int Spacing { diff --git a/StabilityMatrix.Avalonia/Controls/StackExpander.axaml.cs b/StabilityMatrix.Avalonia/Controls/StackExpander.axaml.cs index 3fb2304b..38208891 100644 --- a/StabilityMatrix.Avalonia/Controls/StackExpander.axaml.cs +++ b/StabilityMatrix.Avalonia/Controls/StackExpander.axaml.cs @@ -1,8 +1,10 @@ using Avalonia; using Avalonia.Controls.Primitives; +using StabilityMatrix.Core.Attributes; namespace StabilityMatrix.Avalonia.Controls; +[Transient] public class StackExpander : TemplatedControl { public static readonly StyledProperty SpacingProperty = AvaloniaProperty.Register< diff --git a/StabilityMatrix.Avalonia/Controls/UpscalerCard.axaml.cs b/StabilityMatrix.Avalonia/Controls/UpscalerCard.axaml.cs index 083d09fa..7e2e2327 100644 --- a/StabilityMatrix.Avalonia/Controls/UpscalerCard.axaml.cs +++ b/StabilityMatrix.Avalonia/Controls/UpscalerCard.axaml.cs @@ -1,13 +1,14 @@ -using System; -using AsyncAwaitBestPractices; +using AsyncAwaitBestPractices; using Avalonia.Controls; using Avalonia.Controls.Primitives; using FluentAvalonia.UI.Controls; using StabilityMatrix.Avalonia.ViewModels.Inference; +using StabilityMatrix.Core.Attributes; using StabilityMatrix.Core.Models.Api.Comfy; namespace StabilityMatrix.Avalonia.Controls; +[Transient] public class UpscalerCard : TemplatedControl { /// diff --git a/StabilityMatrix.Avalonia/DesignData/DesignData.cs b/StabilityMatrix.Avalonia/DesignData/DesignData.cs index a9a6e9c2..eb24fccb 100644 --- a/StabilityMatrix.Avalonia/DesignData/DesignData.cs +++ b/StabilityMatrix.Avalonia/DesignData/DesignData.cs @@ -1,6 +1,5 @@ using System; using System.Collections.Generic; -using System.Collections.Immutable; using System.Collections.ObjectModel; using System.Diagnostics.CodeAnalysis; using System.IO; @@ -9,7 +8,6 @@ using System.Text; using AvaloniaEdit.Utils; using DynamicData.Binding; using Microsoft.Extensions.DependencyInjection; -using StabilityMatrix.Avalonia.Controls; using StabilityMatrix.Avalonia.Controls.CodeCompletion; using StabilityMatrix.Avalonia.Models; using StabilityMatrix.Avalonia.Models.TagCompletion; @@ -56,7 +54,7 @@ public static class DesignData if (isInitialized) throw new InvalidOperationException("DesignData is already initialized."); - var services = new ServiceCollection(); + var services = App.ConfigureServices(); var activePackageId = Guid.NewGuid(); services.AddSingleton( @@ -120,8 +118,7 @@ public static class DesignData .AddSingleton() .AddSingleton() .AddSingleton() - .AddSingleton() - .AddSingleton(); + .AddSingleton(); // Placeholder services that nobody should need during design time services @@ -132,12 +129,6 @@ public static class DesignData .AddSingleton(_ => null!) .AddSingleton(_ => null!); - // Using some default service implementations from App - App.ConfigurePackages(services); - App.ConfigurePageViewModels(services); - App.ConfigureDialogViewModels(services); - App.ConfigureViews(services); - // Override Launch page with mock services.Remove(ServiceDescriptor.Singleton()); services.AddSingleton(); diff --git a/StabilityMatrix.Avalonia/DialogHelper.cs b/StabilityMatrix.Avalonia/DialogHelper.cs index 15397e48..b244afe3 100644 --- a/StabilityMatrix.Avalonia/DialogHelper.cs +++ b/StabilityMatrix.Avalonia/DialogHelper.cs @@ -14,11 +14,9 @@ using Avalonia.Media; using Avalonia.Threading; using AvaloniaEdit; using AvaloniaEdit.TextMate; -using CommunityToolkit.Mvvm.ComponentModel.__Internals; using CommunityToolkit.Mvvm.Input; using FluentAvalonia.UI.Controls; using Markdown.Avalonia; -using Markdown.Avalonia.SyntaxHigh.Extensions; using NLog; using Refit; using StabilityMatrix.Avalonia.Controls; @@ -26,7 +24,6 @@ using StabilityMatrix.Avalonia.Helpers; using StabilityMatrix.Core.Exceptions; using StabilityMatrix.Core.Extensions; using StabilityMatrix.Core.Models; -using StabilityMatrix.Core.Models.Database; using StabilityMatrix.Core.Services; using TextMateSharp.Grammars; using Process = FuzzySharp.Process; diff --git a/StabilityMatrix.Avalonia/Helpers/PngDataHelper.cs b/StabilityMatrix.Avalonia/Helpers/PngDataHelper.cs index aa31add4..1d729cfe 100644 --- a/StabilityMatrix.Avalonia/Helpers/PngDataHelper.cs +++ b/StabilityMatrix.Avalonia/Helpers/PngDataHelper.cs @@ -3,7 +3,6 @@ using System.IO; using System.Linq; using System.Text; using System.Text.Json; -using Avalonia; using Force.Crc32; using StabilityMatrix.Avalonia.Models; using StabilityMatrix.Core.Models; diff --git a/StabilityMatrix.Avalonia/Helpers/TagCsvParser.cs b/StabilityMatrix.Avalonia/Helpers/TagCsvParser.cs index 1afa66e9..414fc1a5 100644 --- a/StabilityMatrix.Avalonia/Helpers/TagCsvParser.cs +++ b/StabilityMatrix.Avalonia/Helpers/TagCsvParser.cs @@ -1,24 +1,21 @@ using System.Collections.Generic; -using System.Data.Common; -using System.Globalization; using System.IO; using System.Threading.Tasks; using StabilityMatrix.Avalonia.Models.TagCompletion; using Sylvan.Data.Csv; using Sylvan; -using Sylvan.Data; namespace StabilityMatrix.Avalonia.Helpers; public class TagCsvParser { private readonly Stream stream; - + public TagCsvParser(Stream stream) { this.stream = stream; } - + public async IAsyncEnumerable ParseAsync() { var pool = new StringPool(); @@ -27,10 +24,10 @@ public class TagCsvParser StringFactory = pool.GetString, HasHeaders = false, }; - + using var textReader = new StreamReader(stream); await using var dataReader = await CsvDataReader.CreateAsync(textReader, options); - + while (await dataReader.ReadAsync()) { var entry = new TagCsvEntry @@ -42,7 +39,7 @@ public class TagCsvParser }; yield return entry; } - + /*var dataBinderOptions = new DataBinderOptions { BindingMode = DataBindingMode.Any @@ -54,17 +51,17 @@ public class TagCsvParser public async Task> GetDictionaryAsync() { var dict = new Dictionary(); - + await foreach (var entry in ParseAsync()) { if (entry.Name is null || entry.Type is null) { continue; } - + dict.Add(entry.Name, entry); } - + return dict; } } diff --git a/StabilityMatrix.Avalonia/Helpers/TextEditorConfigs.cs b/StabilityMatrix.Avalonia/Helpers/TextEditorConfigs.cs index 21139027..95543d51 100644 --- a/StabilityMatrix.Avalonia/Helpers/TextEditorConfigs.cs +++ b/StabilityMatrix.Avalonia/Helpers/TextEditorConfigs.cs @@ -1,5 +1,4 @@ using System.IO; -using System.Reflection; using Avalonia.Media; using AvaloniaEdit; using AvaloniaEdit.TextMate; diff --git a/StabilityMatrix.Avalonia/Models/Inference/FileNameFormat.cs b/StabilityMatrix.Avalonia/Models/Inference/FileNameFormat.cs index b20f6c48..5017ab38 100644 --- a/StabilityMatrix.Avalonia/Models/Inference/FileNameFormat.cs +++ b/StabilityMatrix.Avalonia/Models/Inference/FileNameFormat.cs @@ -1,7 +1,6 @@ using System; using System.Collections.Generic; using System.Collections.Immutable; -using System.ComponentModel.DataAnnotations; using System.Diagnostics.CodeAnalysis; using System.Linq; diff --git a/StabilityMatrix.Avalonia/Models/Inference/FileNameFormatProvider.cs b/StabilityMatrix.Avalonia/Models/Inference/FileNameFormatProvider.cs index 1422efa1..e8c13f79 100644 --- a/StabilityMatrix.Avalonia/Models/Inference/FileNameFormatProvider.cs +++ b/StabilityMatrix.Avalonia/Models/Inference/FileNameFormatProvider.cs @@ -1,6 +1,5 @@ using System; using System.Collections.Generic; -using System.Collections.Immutable; using System.ComponentModel.DataAnnotations; using System.Diagnostics.Contracts; using System.Linq; diff --git a/StabilityMatrix.Avalonia/Models/Inference/Prompt.cs b/StabilityMatrix.Avalonia/Models/Inference/Prompt.cs index c4c76fa4..4c18bd81 100644 --- a/StabilityMatrix.Avalonia/Models/Inference/Prompt.cs +++ b/StabilityMatrix.Avalonia/Models/Inference/Prompt.cs @@ -1,6 +1,5 @@ using System; using System.Collections.Generic; -using System.ComponentModel.DataAnnotations; using System.Diagnostics.CodeAnalysis; using System.Globalization; using System.IO; diff --git a/StabilityMatrix.Avalonia/Models/Inference/StackExpanderModel.cs b/StabilityMatrix.Avalonia/Models/Inference/StackExpanderModel.cs index 5c782de4..e361207b 100644 --- a/StabilityMatrix.Avalonia/Models/Inference/StackExpanderModel.cs +++ b/StabilityMatrix.Avalonia/Models/Inference/StackExpanderModel.cs @@ -1,5 +1,4 @@ using System.Text.Json.Serialization; -using StabilityMatrix.Avalonia.ViewModels.Inference; namespace StabilityMatrix.Avalonia.Models.Inference; diff --git a/StabilityMatrix.Avalonia/Models/Inference/ViewState.cs b/StabilityMatrix.Avalonia/Models/Inference/ViewState.cs index f736fdd8..689fe144 100644 --- a/StabilityMatrix.Avalonia/Models/Inference/ViewState.cs +++ b/StabilityMatrix.Avalonia/Models/Inference/ViewState.cs @@ -1,5 +1,4 @@ -using System.Text.Json.Nodes; -using System.Text.Json.Serialization; +using System.Text.Json.Serialization; namespace StabilityMatrix.Avalonia.Models.Inference; diff --git a/StabilityMatrix.Avalonia/Models/SharedState.cs b/StabilityMatrix.Avalonia/Models/SharedState.cs index d2dd8fe1..17fd3288 100644 --- a/StabilityMatrix.Avalonia/Models/SharedState.cs +++ b/StabilityMatrix.Avalonia/Models/SharedState.cs @@ -1,14 +1,17 @@ using CommunityToolkit.Mvvm.ComponentModel; +using StabilityMatrix.Core.Attributes; namespace StabilityMatrix.Avalonia.Models; /// /// Singleton DI service for observable shared UI state. /// +[Singleton] public partial class SharedState : ObservableObject { /// /// Whether debug mode enabled from settings page version tap. /// - [ObservableProperty] private bool isDebugMode; + [ObservableProperty] + private bool isDebugMode; } diff --git a/StabilityMatrix.Avalonia/Models/TagCompletion/CompletionProvider.cs b/StabilityMatrix.Avalonia/Models/TagCompletion/CompletionProvider.cs index 1b4395a4..5b03207d 100644 --- a/StabilityMatrix.Avalonia/Models/TagCompletion/CompletionProvider.cs +++ b/StabilityMatrix.Avalonia/Models/TagCompletion/CompletionProvider.cs @@ -1,6 +1,5 @@ using System; using System.Collections.Generic; -using System.Collections.Immutable; using System.Diagnostics; using System.Linq; using System.Text.RegularExpressions; @@ -16,6 +15,7 @@ using NLog; using StabilityMatrix.Avalonia.Controls.CodeCompletion; using StabilityMatrix.Avalonia.Helpers; using StabilityMatrix.Avalonia.Services; +using StabilityMatrix.Core.Attributes; using StabilityMatrix.Core.Extensions; using StabilityMatrix.Core.Helper; using StabilityMatrix.Core.Models; @@ -26,6 +26,7 @@ using StabilityMatrix.Core.Services; namespace StabilityMatrix.Avalonia.Models.TagCompletion; +[Singleton(typeof(ICompletionProvider))] public partial class CompletionProvider : ICompletionProvider { private static readonly Logger Logger = LogManager.GetCurrentClassLogger(); diff --git a/StabilityMatrix.Avalonia/Models/TagCompletion/TextCompletionRequest.cs b/StabilityMatrix.Avalonia/Models/TagCompletion/TextCompletionRequest.cs index c93df5fa..fea2490c 100644 --- a/StabilityMatrix.Avalonia/Models/TagCompletion/TextCompletionRequest.cs +++ b/StabilityMatrix.Avalonia/Models/TagCompletion/TextCompletionRequest.cs @@ -1,6 +1,4 @@ -using System.Collections.Generic; -using AvaloniaEdit.Document; -using StabilityMatrix.Core.Models.Tokens; +using StabilityMatrix.Core.Models.Tokens; namespace StabilityMatrix.Avalonia.Models.TagCompletion; diff --git a/StabilityMatrix.Avalonia/Models/TagCompletion/TokenizerProvider.cs b/StabilityMatrix.Avalonia/Models/TagCompletion/TokenizerProvider.cs index 74b22d44..2181e5df 100644 --- a/StabilityMatrix.Avalonia/Models/TagCompletion/TokenizerProvider.cs +++ b/StabilityMatrix.Avalonia/Models/TagCompletion/TokenizerProvider.cs @@ -1,10 +1,12 @@ using System.Diagnostics.CodeAnalysis; using StabilityMatrix.Avalonia.Extensions; +using StabilityMatrix.Core.Attributes; using TextMateSharp.Grammars; using TextMateSharp.Registry; namespace StabilityMatrix.Avalonia.Models.TagCompletion; +[Singleton(typeof(ITokenizerProvider))] public class TokenizerProvider : ITokenizerProvider { private readonly Registry registry = new(new RegistryOptions(ThemeName.DarkPlus)); diff --git a/StabilityMatrix.Avalonia/Services/IInferenceClientManager.cs b/StabilityMatrix.Avalonia/Services/IInferenceClientManager.cs index bc6afaff..f40990fa 100644 --- a/StabilityMatrix.Avalonia/Services/IInferenceClientManager.cs +++ b/StabilityMatrix.Avalonia/Services/IInferenceClientManager.cs @@ -1,5 +1,4 @@ using System; -using System.Collections.Generic; using System.ComponentModel; using System.Diagnostics.CodeAnalysis; using System.Threading; diff --git a/StabilityMatrix.Avalonia/Services/InferenceClientManager.cs b/StabilityMatrix.Avalonia/Services/InferenceClientManager.cs index 17023dfa..8254e467 100644 --- a/StabilityMatrix.Avalonia/Services/InferenceClientManager.cs +++ b/StabilityMatrix.Avalonia/Services/InferenceClientManager.cs @@ -1,6 +1,5 @@ using System; using System.Diagnostics.CodeAnalysis; -using System.IO; using System.Linq; using System.Threading; using System.Threading.Tasks; @@ -14,6 +13,7 @@ using SkiaSharp; using StabilityMatrix.Avalonia.Models; using StabilityMatrix.Avalonia.Models.TagCompletion; using StabilityMatrix.Core.Api; +using StabilityMatrix.Core.Attributes; using StabilityMatrix.Core.Helper; using StabilityMatrix.Core.Inference; using StabilityMatrix.Core.Models; @@ -28,6 +28,7 @@ namespace StabilityMatrix.Avalonia.Services; /// Manager for the current inference client /// Has observable shared properties for shared info like model names /// +[Singleton(typeof(IInferenceClientManager))] public partial class InferenceClientManager : ObservableObject, IInferenceClientManager { private readonly ILogger logger; diff --git a/StabilityMatrix.Avalonia/Services/NavigationService.cs b/StabilityMatrix.Avalonia/Services/NavigationService.cs index 4cc47881..b9fb1952 100644 --- a/StabilityMatrix.Avalonia/Services/NavigationService.cs +++ b/StabilityMatrix.Avalonia/Services/NavigationService.cs @@ -1,6 +1,4 @@ using System; -using System.Collections.Generic; -using System.Diagnostics; using System.Linq; using FluentAvalonia.UI.Controls; using FluentAvalonia.UI.Media.Animation; @@ -8,10 +6,12 @@ using FluentAvalonia.UI.Navigation; using StabilityMatrix.Avalonia.Animations; using StabilityMatrix.Avalonia.ViewModels; using StabilityMatrix.Avalonia.ViewModels.Base; +using StabilityMatrix.Core.Attributes; using StabilityMatrix.Core.Services; namespace StabilityMatrix.Avalonia.Services; +[Singleton(typeof(INavigationService))] public class NavigationService : INavigationService { private Frame? _frame; diff --git a/StabilityMatrix.Avalonia/Services/NotificationService.cs b/StabilityMatrix.Avalonia/Services/NotificationService.cs index 1bb664b9..88a3d815 100644 --- a/StabilityMatrix.Avalonia/Services/NotificationService.cs +++ b/StabilityMatrix.Avalonia/Services/NotificationService.cs @@ -3,20 +3,24 @@ using System.Threading.Tasks; using Avalonia; using Avalonia.Controls; using Avalonia.Controls.Notifications; +using StabilityMatrix.Core.Attributes; using StabilityMatrix.Core.Models; namespace StabilityMatrix.Avalonia.Services; +[Singleton(typeof(INotificationService))] public class NotificationService : INotificationService { private WindowNotificationManager? notificationManager; - + public void Initialize( - Visual? visual, + Visual? visual, NotificationPosition position = NotificationPosition.BottomRight, - int maxItems = 4) + int maxItems = 4 + ) { - if (notificationManager is not null) return; + if (notificationManager is not null) + return; notificationManager = new WindowNotificationManager(TopLevel.GetTopLevel(visual)) { Position = position, @@ -30,28 +34,31 @@ public class NotificationService : INotificationService } public void Show( - string title, + string title, string message, NotificationType appearance = NotificationType.Information, - TimeSpan? expiration = null) + TimeSpan? expiration = null + ) { Show(new Notification(title, message, appearance, expiration)); } public void ShowPersistent( - string title, + string title, string message, - NotificationType appearance = NotificationType.Information) + NotificationType appearance = NotificationType.Information + ) { Show(new Notification(title, message, appearance, TimeSpan.Zero)); } - + /// public async Task> TryAsync( Task task, string title = "Error", string? message = null, - NotificationType appearance = NotificationType.Error) + NotificationType appearance = NotificationType.Error + ) { try { @@ -63,13 +70,14 @@ public class NotificationService : INotificationService return TaskResult.FromException(e); } } - + /// public async Task> TryAsync( Task task, string title = "Error", string? message = null, - NotificationType appearance = NotificationType.Error) + NotificationType appearance = NotificationType.Error + ) { try { diff --git a/StabilityMatrix.Avalonia/Services/ServiceManager.cs b/StabilityMatrix.Avalonia/Services/ServiceManager.cs index 26d604f4..4b21c294 100644 --- a/StabilityMatrix.Avalonia/Services/ServiceManager.cs +++ b/StabilityMatrix.Avalonia/Services/ServiceManager.cs @@ -256,4 +256,19 @@ public class ServiceManager return new BetterContentDialog { Content = view }; } + + public void Register(Type type, Func providerFunc) + { + lock (providers) + { + if (instances.ContainsKey(type) || providers.ContainsKey(type)) + { + throw new ArgumentException( + $"Service of type {type} is already registered for {typeof(T)}" + ); + } + + providers[type] = providerFunc; + } + } } diff --git a/StabilityMatrix.Avalonia/StabilityMatrix.Avalonia.csproj b/StabilityMatrix.Avalonia/StabilityMatrix.Avalonia.csproj index f057618d..82b8fde9 100644 --- a/StabilityMatrix.Avalonia/StabilityMatrix.Avalonia.csproj +++ b/StabilityMatrix.Avalonia/StabilityMatrix.Avalonia.csproj @@ -23,47 +23,47 @@ - - - + + + - + - + - + - - + + - + - + - - - + + + - + - - + + - + diff --git a/StabilityMatrix.Avalonia/Styles/ThemeColors.cs b/StabilityMatrix.Avalonia/Styles/ThemeColors.cs index 5df260c2..c59b9d53 100644 --- a/StabilityMatrix.Avalonia/Styles/ThemeColors.cs +++ b/StabilityMatrix.Avalonia/Styles/ThemeColors.cs @@ -1,5 +1,4 @@ -using Avalonia; -using Avalonia.Media; +using Avalonia.Media; namespace StabilityMatrix.Avalonia.Styles; diff --git a/StabilityMatrix.Avalonia/ViewModels/Base/InferenceTabViewModelBase.cs b/StabilityMatrix.Avalonia/ViewModels/Base/InferenceTabViewModelBase.cs index 4b6eee86..bc1d60ff 100644 --- a/StabilityMatrix.Avalonia/ViewModels/Base/InferenceTabViewModelBase.cs +++ b/StabilityMatrix.Avalonia/ViewModels/Base/InferenceTabViewModelBase.cs @@ -9,7 +9,6 @@ using AsyncAwaitBestPractices; using Avalonia.Controls; using Avalonia.Controls.Notifications; using Avalonia.Input; -using Avalonia.Interactivity; using Avalonia.Platform.Storage; using Avalonia.Threading; using CommunityToolkit.Mvvm.ComponentModel; diff --git a/StabilityMatrix.Avalonia/ViewModels/Base/ProgressItemViewModelBase.cs b/StabilityMatrix.Avalonia/ViewModels/Base/ProgressItemViewModelBase.cs index e4e458d8..0d06e87f 100644 --- a/StabilityMatrix.Avalonia/ViewModels/Base/ProgressItemViewModelBase.cs +++ b/StabilityMatrix.Avalonia/ViewModels/Base/ProgressItemViewModelBase.cs @@ -1,5 +1,4 @@ using System; -using System.Threading.Tasks; using CommunityToolkit.Mvvm.ComponentModel; namespace StabilityMatrix.Avalonia.ViewModels.Base; diff --git a/StabilityMatrix.Avalonia/ViewModels/CheckpointBrowser/CheckpointBrowserCardViewModel.cs b/StabilityMatrix.Avalonia/ViewModels/CheckpointBrowser/CheckpointBrowserCardViewModel.cs index a4785ae6..fc383fba 100644 --- a/StabilityMatrix.Avalonia/ViewModels/CheckpointBrowser/CheckpointBrowserCardViewModel.cs +++ b/StabilityMatrix.Avalonia/ViewModels/CheckpointBrowser/CheckpointBrowserCardViewModel.cs @@ -17,6 +17,7 @@ using StabilityMatrix.Avalonia.Services; using StabilityMatrix.Avalonia.ViewModels.Base; using StabilityMatrix.Avalonia.ViewModels.Dialogs; using StabilityMatrix.Avalonia.Views.Dialogs; +using StabilityMatrix.Core.Attributes; using StabilityMatrix.Core.Extensions; using StabilityMatrix.Core.Models; using StabilityMatrix.Core.Models.Api; @@ -27,6 +28,8 @@ using StabilityMatrix.Core.Services; namespace StabilityMatrix.Avalonia.ViewModels.CheckpointBrowser; +[ManagedService] +[Transient] public partial class CheckpointBrowserCardViewModel : Base.ProgressViewModel { private static readonly Logger Logger = LogManager.GetCurrentClassLogger(); diff --git a/StabilityMatrix.Avalonia/ViewModels/CheckpointBrowserViewModel.cs b/StabilityMatrix.Avalonia/ViewModels/CheckpointBrowserViewModel.cs index 2ecfc90e..e7659258 100644 --- a/StabilityMatrix.Avalonia/ViewModels/CheckpointBrowserViewModel.cs +++ b/StabilityMatrix.Avalonia/ViewModels/CheckpointBrowserViewModel.cs @@ -5,16 +5,13 @@ using System.ComponentModel; using System.Diagnostics; using System.Linq; using System.Net.Http; -using System.Reactive; using System.Reactive.Linq; -using System.Reactive.Threading.Tasks; using System.Threading; using System.Threading.Tasks; using AsyncAwaitBestPractices; using Avalonia.Collections; using Avalonia.Controls; using Avalonia.Controls.Notifications; -using AvaloniaEdit.Utils; using CommunityToolkit.Mvvm.ComponentModel; using CommunityToolkit.Mvvm.Input; using FluentAvalonia.UI.Controls; @@ -42,6 +39,7 @@ using SymbolIconSource = FluentIcons.FluentAvalonia.SymbolIconSource; namespace StabilityMatrix.Avalonia.ViewModels; [View(typeof(CheckpointBrowserPage))] +[Singleton] public partial class CheckpointBrowserViewModel : PageViewModelBase { private static readonly Logger Logger = LogManager.GetCurrentClassLogger(); diff --git a/StabilityMatrix.Avalonia/ViewModels/CheckpointManager/CheckpointFile.cs b/StabilityMatrix.Avalonia/ViewModels/CheckpointManager/CheckpointFile.cs index f1260f93..e9fa06a2 100644 --- a/StabilityMatrix.Avalonia/ViewModels/CheckpointManager/CheckpointFile.cs +++ b/StabilityMatrix.Avalonia/ViewModels/CheckpointManager/CheckpointFile.cs @@ -10,6 +10,7 @@ using CommunityToolkit.Mvvm.Input; using FluentAvalonia.UI.Controls; using NLog; using StabilityMatrix.Avalonia.ViewModels.Base; +using StabilityMatrix.Core.Attributes; using StabilityMatrix.Core.Extensions; using StabilityMatrix.Core.Helper; using StabilityMatrix.Core.Models; @@ -19,6 +20,8 @@ using StabilityMatrix.Core.Processes; namespace StabilityMatrix.Avalonia.ViewModels.CheckpointManager; +[ManagedService] +[Transient] public partial class CheckpointFile : ViewModelBase { private static readonly Logger Logger = LogManager.GetCurrentClassLogger(); diff --git a/StabilityMatrix.Avalonia/ViewModels/CheckpointManager/CheckpointFolder.cs b/StabilityMatrix.Avalonia/ViewModels/CheckpointManager/CheckpointFolder.cs index 398aaf64..cfa1f327 100644 --- a/StabilityMatrix.Avalonia/ViewModels/CheckpointManager/CheckpointFolder.cs +++ b/StabilityMatrix.Avalonia/ViewModels/CheckpointManager/CheckpointFolder.cs @@ -17,6 +17,7 @@ using DynamicData.Binding; using FluentAvalonia.UI.Controls; using StabilityMatrix.Avalonia.Services; using StabilityMatrix.Avalonia.ViewModels.Base; +using StabilityMatrix.Core.Attributes; using StabilityMatrix.Core.Extensions; using StabilityMatrix.Core.Helper; using StabilityMatrix.Core.Models; @@ -27,6 +28,8 @@ using StabilityMatrix.Core.Services; namespace StabilityMatrix.Avalonia.ViewModels.CheckpointManager; +[ManagedService] +[Transient] public partial class CheckpointFolder : ViewModelBase { private readonly ISettingsManager settingsManager; diff --git a/StabilityMatrix.Avalonia/ViewModels/CheckpointsPageViewModel.cs b/StabilityMatrix.Avalonia/ViewModels/CheckpointsPageViewModel.cs index c77b92d2..86b7fdd3 100644 --- a/StabilityMatrix.Avalonia/ViewModels/CheckpointsPageViewModel.cs +++ b/StabilityMatrix.Avalonia/ViewModels/CheckpointsPageViewModel.cs @@ -24,6 +24,7 @@ using SymbolIconSource = FluentIcons.FluentAvalonia.SymbolIconSource; namespace StabilityMatrix.Avalonia.ViewModels; [View(typeof(CheckpointsPage))] +[Singleton] public partial class CheckpointsPageViewModel : PageViewModelBase { private static readonly Logger Logger = LogManager.GetCurrentClassLogger(); diff --git a/StabilityMatrix.Avalonia/ViewModels/Dialogs/DownloadResourceViewModel.cs b/StabilityMatrix.Avalonia/ViewModels/Dialogs/DownloadResourceViewModel.cs index aaf2aaa0..47625eaf 100644 --- a/StabilityMatrix.Avalonia/ViewModels/Dialogs/DownloadResourceViewModel.cs +++ b/StabilityMatrix.Avalonia/ViewModels/Dialogs/DownloadResourceViewModel.cs @@ -16,6 +16,8 @@ using StabilityMatrix.Core.Services; namespace StabilityMatrix.Avalonia.ViewModels.Dialogs; [View(typeof(DownloadResourceDialog))] +[ManagedService] +[Transient] public partial class DownloadResourceViewModel : ContentDialogViewModelBase { private readonly IDownloadService downloadService; diff --git a/StabilityMatrix.Avalonia/ViewModels/Dialogs/EnvVarsViewModel.cs b/StabilityMatrix.Avalonia/ViewModels/Dialogs/EnvVarsViewModel.cs index 55fa73b5..cab1a11a 100644 --- a/StabilityMatrix.Avalonia/ViewModels/Dialogs/EnvVarsViewModel.cs +++ b/StabilityMatrix.Avalonia/ViewModels/Dialogs/EnvVarsViewModel.cs @@ -12,6 +12,8 @@ using StabilityMatrix.Core.Models; namespace StabilityMatrix.Avalonia.ViewModels.Dialogs; [View(typeof(EnvVarsViewModel))] +[ManagedService] +[Transient] public partial class EnvVarsViewModel : ContentDialogViewModelBase { [ObservableProperty] diff --git a/StabilityMatrix.Avalonia/ViewModels/Dialogs/ExceptionViewModel.cs b/StabilityMatrix.Avalonia/ViewModels/Dialogs/ExceptionViewModel.cs index 5c0b9427..f5c390d5 100644 --- a/StabilityMatrix.Avalonia/ViewModels/Dialogs/ExceptionViewModel.cs +++ b/StabilityMatrix.Avalonia/ViewModels/Dialogs/ExceptionViewModel.cs @@ -6,6 +6,8 @@ using StabilityMatrix.Core.Attributes; namespace StabilityMatrix.Avalonia.ViewModels.Dialogs; [View(typeof(ExceptionDialog))] +[ManagedService] +[Transient] public partial class ExceptionViewModel : ViewModelBase { public Exception? Exception { get; set; } diff --git a/StabilityMatrix.Avalonia/ViewModels/Dialogs/ImageViewerViewModel.cs b/StabilityMatrix.Avalonia/ViewModels/Dialogs/ImageViewerViewModel.cs index 821d8f5b..c07824e7 100644 --- a/StabilityMatrix.Avalonia/ViewModels/Dialogs/ImageViewerViewModel.cs +++ b/StabilityMatrix.Avalonia/ViewModels/Dialogs/ImageViewerViewModel.cs @@ -21,6 +21,8 @@ using Size = StabilityMatrix.Core.Helper.Size; namespace StabilityMatrix.Avalonia.ViewModels.Dialogs; [View(typeof(ImageViewerDialog))] +[ManagedService] +[Transient] public partial class ImageViewerViewModel : ContentDialogViewModelBase { [ObservableProperty] diff --git a/StabilityMatrix.Avalonia/ViewModels/Dialogs/InferenceConnectionHelpViewModel.cs b/StabilityMatrix.Avalonia/ViewModels/Dialogs/InferenceConnectionHelpViewModel.cs index ac0d1dc1..351f9a64 100644 --- a/StabilityMatrix.Avalonia/ViewModels/Dialogs/InferenceConnectionHelpViewModel.cs +++ b/StabilityMatrix.Avalonia/ViewModels/Dialogs/InferenceConnectionHelpViewModel.cs @@ -6,7 +6,6 @@ using Avalonia.Threading; using CommunityToolkit.Mvvm.ComponentModel; using CommunityToolkit.Mvvm.Input; using FluentAvalonia.UI.Controls; -using StabilityMatrix.Avalonia.Animations; using StabilityMatrix.Avalonia.Controls; using StabilityMatrix.Avalonia.Languages; using StabilityMatrix.Avalonia.Services; @@ -23,6 +22,8 @@ using StabilityMatrix.Core.Services; namespace StabilityMatrix.Avalonia.ViewModels.Dialogs; [View(typeof(InferenceConnectionHelpDialog))] +[ManagedService] +[Transient] public partial class InferenceConnectionHelpViewModel : ContentDialogViewModelBase { private readonly ISettingsManager settingsManager; diff --git a/StabilityMatrix.Avalonia/ViewModels/Dialogs/InstallerViewModel.cs b/StabilityMatrix.Avalonia/ViewModels/Dialogs/InstallerViewModel.cs index 54ba9a54..d156def6 100644 --- a/StabilityMatrix.Avalonia/ViewModels/Dialogs/InstallerViewModel.cs +++ b/StabilityMatrix.Avalonia/ViewModels/Dialogs/InstallerViewModel.cs @@ -19,6 +19,7 @@ using StabilityMatrix.Avalonia.Controls; using StabilityMatrix.Avalonia.Languages; using StabilityMatrix.Avalonia.Services; using StabilityMatrix.Avalonia.ViewModels.Base; +using StabilityMatrix.Core.Attributes; using StabilityMatrix.Core.Helper; using StabilityMatrix.Core.Helper.Factory; using StabilityMatrix.Core.Models; @@ -31,6 +32,8 @@ using StabilityMatrix.Core.Services; namespace StabilityMatrix.Avalonia.ViewModels.Dialogs; +[ManagedService] +[Transient] public partial class InstallerViewModel : ContentDialogViewModelBase { private static readonly Logger Logger = LogManager.GetCurrentClassLogger(); diff --git a/StabilityMatrix.Avalonia/ViewModels/Dialogs/LaunchOptionsViewModel.cs b/StabilityMatrix.Avalonia/ViewModels/Dialogs/LaunchOptionsViewModel.cs index a4d2e4a6..303d4462 100644 --- a/StabilityMatrix.Avalonia/ViewModels/Dialogs/LaunchOptionsViewModel.cs +++ b/StabilityMatrix.Avalonia/ViewModels/Dialogs/LaunchOptionsViewModel.cs @@ -17,6 +17,8 @@ using StabilityMatrix.Core.Models; namespace StabilityMatrix.Avalonia.ViewModels.Dialogs; [View(typeof(LaunchOptionsDialog))] +[ManagedService] +[Transient] public partial class LaunchOptionsViewModel : ContentDialogViewModelBase { private readonly ILogger logger; diff --git a/StabilityMatrix.Avalonia/ViewModels/Dialogs/OneClickInstallViewModel.cs b/StabilityMatrix.Avalonia/ViewModels/Dialogs/OneClickInstallViewModel.cs index 008da6eb..155e2297 100644 --- a/StabilityMatrix.Avalonia/ViewModels/Dialogs/OneClickInstallViewModel.cs +++ b/StabilityMatrix.Avalonia/ViewModels/Dialogs/OneClickInstallViewModel.cs @@ -10,17 +10,19 @@ using Microsoft.Extensions.Logging; using StabilityMatrix.Avalonia.Languages; using StabilityMatrix.Avalonia.Services; using StabilityMatrix.Avalonia.ViewModels.Base; +using StabilityMatrix.Core.Attributes; using StabilityMatrix.Core.Helper; using StabilityMatrix.Core.Helper.Factory; using StabilityMatrix.Core.Models; using StabilityMatrix.Core.Models.PackageModification; using StabilityMatrix.Core.Models.Packages; -using StabilityMatrix.Core.Models.Progress; using StabilityMatrix.Core.Python; using StabilityMatrix.Core.Services; namespace StabilityMatrix.Avalonia.ViewModels.Dialogs; +[ManagedService] +[Transient] public partial class OneClickInstallViewModel : ContentDialogViewModelBase { private readonly ISettingsManager settingsManager; diff --git a/StabilityMatrix.Avalonia/ViewModels/Dialogs/PackageImportViewModel.cs b/StabilityMatrix.Avalonia/ViewModels/Dialogs/PackageImportViewModel.cs index 915c2a2f..06ff94de 100644 --- a/StabilityMatrix.Avalonia/ViewModels/Dialogs/PackageImportViewModel.cs +++ b/StabilityMatrix.Avalonia/ViewModels/Dialogs/PackageImportViewModel.cs @@ -23,6 +23,8 @@ using StabilityMatrix.Core.Services; namespace StabilityMatrix.Avalonia.ViewModels.Dialogs; [View(typeof(PackageImportDialog))] +[ManagedService] +[Transient] public partial class PackageImportViewModel : ContentDialogViewModelBase { private static readonly Logger Logger = LogManager.GetCurrentClassLogger(); diff --git a/StabilityMatrix.Avalonia/ViewModels/Dialogs/SelectDataDirectoryViewModel.cs b/StabilityMatrix.Avalonia/ViewModels/Dialogs/SelectDataDirectoryViewModel.cs index 15fa1e48..9c20bdf0 100644 --- a/StabilityMatrix.Avalonia/ViewModels/Dialogs/SelectDataDirectoryViewModel.cs +++ b/StabilityMatrix.Avalonia/ViewModels/Dialogs/SelectDataDirectoryViewModel.cs @@ -19,6 +19,8 @@ using StabilityMatrix.Core.Services; namespace StabilityMatrix.Avalonia.ViewModels.Dialogs; [View(typeof(SelectDataDirectoryDialog))] +[ManagedService] +[Transient] public partial class SelectDataDirectoryViewModel : ContentDialogViewModelBase { private static readonly Logger Logger = LogManager.GetCurrentClassLogger(); diff --git a/StabilityMatrix.Avalonia/ViewModels/Dialogs/SelectModelVersionViewModel.cs b/StabilityMatrix.Avalonia/ViewModels/Dialogs/SelectModelVersionViewModel.cs index 77eac510..c3f10931 100644 --- a/StabilityMatrix.Avalonia/ViewModels/Dialogs/SelectModelVersionViewModel.cs +++ b/StabilityMatrix.Avalonia/ViewModels/Dialogs/SelectModelVersionViewModel.cs @@ -1,19 +1,19 @@ -using System; -using System.Collections.Generic; +using System.Collections.Generic; using System.Collections.ObjectModel; using System.Linq; -using System.Threading.Tasks; using Avalonia.Media.Imaging; -using Avalonia.Platform; using Avalonia.Threading; using CommunityToolkit.Mvvm.ComponentModel; using FluentAvalonia.UI.Controls; using StabilityMatrix.Avalonia.Models; using StabilityMatrix.Avalonia.ViewModels.Base; +using StabilityMatrix.Core.Attributes; using StabilityMatrix.Core.Services; namespace StabilityMatrix.Avalonia.ViewModels.Dialogs; +[ManagedService] +[Transient] public partial class SelectModelVersionViewModel : ContentDialogViewModelBase { private readonly ISettingsManager settingsManager; diff --git a/StabilityMatrix.Avalonia/ViewModels/Dialogs/UpdateViewModel.cs b/StabilityMatrix.Avalonia/ViewModels/Dialogs/UpdateViewModel.cs index 8710295a..8ee671a1 100644 --- a/StabilityMatrix.Avalonia/ViewModels/Dialogs/UpdateViewModel.cs +++ b/StabilityMatrix.Avalonia/ViewModels/Dialogs/UpdateViewModel.cs @@ -22,6 +22,8 @@ using StabilityMatrix.Core.Updater; namespace StabilityMatrix.Avalonia.ViewModels.Dialogs; [View(typeof(UpdateDialog))] +[ManagedService] +[Singleton] public partial class UpdateViewModel : ContentDialogViewModelBase { private readonly ISettingsManager settingsManager; diff --git a/StabilityMatrix.Avalonia/ViewModels/FirstLaunchSetupViewModel.cs b/StabilityMatrix.Avalonia/ViewModels/FirstLaunchSetupViewModel.cs index 25a6faed..0ddc9f9c 100644 --- a/StabilityMatrix.Avalonia/ViewModels/FirstLaunchSetupViewModel.cs +++ b/StabilityMatrix.Avalonia/ViewModels/FirstLaunchSetupViewModel.cs @@ -11,6 +11,8 @@ using StabilityMatrix.Core.Helper; namespace StabilityMatrix.Avalonia.ViewModels; [View(typeof(FirstLaunchSetupWindow))] +[ManagedService] +[Singleton] public partial class FirstLaunchSetupViewModel : ViewModelBase { [ObservableProperty] diff --git a/StabilityMatrix.Avalonia/ViewModels/Inference/BatchSizeCardViewModel.cs b/StabilityMatrix.Avalonia/ViewModels/Inference/BatchSizeCardViewModel.cs index d18d22bd..12a1d0e9 100644 --- a/StabilityMatrix.Avalonia/ViewModels/Inference/BatchSizeCardViewModel.cs +++ b/StabilityMatrix.Avalonia/ViewModels/Inference/BatchSizeCardViewModel.cs @@ -6,6 +6,8 @@ using StabilityMatrix.Core.Attributes; namespace StabilityMatrix.Avalonia.ViewModels.Inference; [View(typeof(BatchSizeCard))] +[ManagedService] +[Transient] public partial class BatchSizeCardViewModel : LoadableViewModelBase { [ObservableProperty] diff --git a/StabilityMatrix.Avalonia/ViewModels/Inference/FreeUCardViewModel.cs b/StabilityMatrix.Avalonia/ViewModels/Inference/FreeUCardViewModel.cs index 059975d3..91b09866 100644 --- a/StabilityMatrix.Avalonia/ViewModels/Inference/FreeUCardViewModel.cs +++ b/StabilityMatrix.Avalonia/ViewModels/Inference/FreeUCardViewModel.cs @@ -7,6 +7,8 @@ using StabilityMatrix.Core.Attributes; namespace StabilityMatrix.Avalonia.ViewModels.Inference; [View(typeof(FreeUCard))] +[ManagedService] +[Transient] public partial class FreeUCardViewModel : LoadableViewModelBase { [ObservableProperty] diff --git a/StabilityMatrix.Avalonia/ViewModels/Inference/IImageGalleryComponent.cs b/StabilityMatrix.Avalonia/ViewModels/Inference/IImageGalleryComponent.cs index eab2a345..65f9fa0a 100644 --- a/StabilityMatrix.Avalonia/ViewModels/Inference/IImageGalleryComponent.cs +++ b/StabilityMatrix.Avalonia/ViewModels/Inference/IImageGalleryComponent.cs @@ -1,6 +1,4 @@ -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; +using System.Linq; using StabilityMatrix.Avalonia.Models; namespace StabilityMatrix.Avalonia.ViewModels.Inference; diff --git a/StabilityMatrix.Avalonia/ViewModels/Inference/ImageFolderCardViewModel.cs b/StabilityMatrix.Avalonia/ViewModels/Inference/ImageFolderCardViewModel.cs index 53524153..f4b52375 100644 --- a/StabilityMatrix.Avalonia/ViewModels/Inference/ImageFolderCardViewModel.cs +++ b/StabilityMatrix.Avalonia/ViewModels/Inference/ImageFolderCardViewModel.cs @@ -32,6 +32,8 @@ using SortDirection = DynamicData.Binding.SortDirection; namespace StabilityMatrix.Avalonia.ViewModels.Inference; [View(typeof(ImageFolderCard))] +[ManagedService] +[Transient] public partial class ImageFolderCardViewModel : ViewModelBase { private readonly ILogger logger; diff --git a/StabilityMatrix.Avalonia/ViewModels/Inference/ImageGalleryCardViewModel.cs b/StabilityMatrix.Avalonia/ViewModels/Inference/ImageGalleryCardViewModel.cs index a8f5920c..93497d43 100644 --- a/StabilityMatrix.Avalonia/ViewModels/Inference/ImageGalleryCardViewModel.cs +++ b/StabilityMatrix.Avalonia/ViewModels/Inference/ImageGalleryCardViewModel.cs @@ -23,6 +23,8 @@ using StabilityMatrix.Core.Services; namespace StabilityMatrix.Avalonia.ViewModels.Inference; [View(typeof(ImageGalleryCard))] +[ManagedService] +[Transient] public partial class ImageGalleryCardViewModel : ViewModelBase { private static readonly Logger Logger = LogManager.GetCurrentClassLogger(); diff --git a/StabilityMatrix.Avalonia/ViewModels/Inference/InferenceImageUpscaleViewModel.cs b/StabilityMatrix.Avalonia/ViewModels/Inference/InferenceImageUpscaleViewModel.cs index d97cf780..d2a196e6 100644 --- a/StabilityMatrix.Avalonia/ViewModels/Inference/InferenceImageUpscaleViewModel.cs +++ b/StabilityMatrix.Avalonia/ViewModels/Inference/InferenceImageUpscaleViewModel.cs @@ -1,13 +1,10 @@ using System; using System.Diagnostics.CodeAnalysis; -using System.Drawing; using System.Linq; using System.Text.Json.Serialization; using System.Threading; using System.Threading.Tasks; using AsyncAwaitBestPractices; -using Avalonia.Controls.Shapes; -using Avalonia.Threading; using DynamicData.Binding; using NLog; using StabilityMatrix.Avalonia.Extensions; @@ -28,6 +25,8 @@ namespace StabilityMatrix.Avalonia.ViewModels.Inference; [View(typeof(InferenceImageUpscaleView), persistent: true)] [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicProperties)] +[ManagedService] +[Transient] public class InferenceImageUpscaleViewModel : InferenceGenerationViewModelBase { private static readonly Logger Logger = LogManager.GetCurrentClassLogger(); diff --git a/StabilityMatrix.Avalonia/ViewModels/Inference/InferenceTextToImageViewModel.cs b/StabilityMatrix.Avalonia/ViewModels/Inference/InferenceTextToImageViewModel.cs index 36ab0ac0..5c121026 100644 --- a/StabilityMatrix.Avalonia/ViewModels/Inference/InferenceTextToImageViewModel.cs +++ b/StabilityMatrix.Avalonia/ViewModels/Inference/InferenceTextToImageViewModel.cs @@ -26,6 +26,8 @@ using InferenceTextToImageView = StabilityMatrix.Avalonia.Views.Inference.Infere namespace StabilityMatrix.Avalonia.ViewModels.Inference; [View(typeof(InferenceTextToImageView), persistent: true)] +[ManagedService] +[Transient] public class InferenceTextToImageViewModel : InferenceGenerationViewModelBase, IParametersLoadableState diff --git a/StabilityMatrix.Avalonia/ViewModels/Inference/ModelCardViewModel.cs b/StabilityMatrix.Avalonia/ViewModels/Inference/ModelCardViewModel.cs index f4db9a4a..ed55236b 100644 --- a/StabilityMatrix.Avalonia/ViewModels/Inference/ModelCardViewModel.cs +++ b/StabilityMatrix.Avalonia/ViewModels/Inference/ModelCardViewModel.cs @@ -12,6 +12,8 @@ using StabilityMatrix.Core.Models; namespace StabilityMatrix.Avalonia.ViewModels.Inference; [View(typeof(ModelCard))] +[ManagedService] +[Transient] public partial class ModelCardViewModel : LoadableViewModelBase, IParametersLoadableState { [ObservableProperty] diff --git a/StabilityMatrix.Avalonia/ViewModels/Inference/PromptCardViewModel.cs b/StabilityMatrix.Avalonia/ViewModels/Inference/PromptCardViewModel.cs index a7b76ad0..26e8acf8 100644 --- a/StabilityMatrix.Avalonia/ViewModels/Inference/PromptCardViewModel.cs +++ b/StabilityMatrix.Avalonia/ViewModels/Inference/PromptCardViewModel.cs @@ -1,15 +1,9 @@ -using System; -using System.Collections.Generic; -using System.Collections.Immutable; -using System.Diagnostics; -using System.Linq; -using System.Text; +using System.Text; using System.Text.Json; using System.Text.Json.Nodes; using System.Threading.Tasks; using AvaloniaEdit; using AvaloniaEdit.Document; -using AvaloniaEdit.Editing; using CommunityToolkit.Mvvm.ComponentModel; using CommunityToolkit.Mvvm.Input; using StabilityMatrix.Avalonia.Controls; @@ -20,7 +14,6 @@ using StabilityMatrix.Avalonia.Models.TagCompletion; using StabilityMatrix.Avalonia.ViewModels.Base; using StabilityMatrix.Core.Attributes; using StabilityMatrix.Core.Exceptions; -using StabilityMatrix.Core.Extensions; using StabilityMatrix.Core.Helper.Cache; using StabilityMatrix.Core.Models; using StabilityMatrix.Core.Services; @@ -28,6 +21,8 @@ using StabilityMatrix.Core.Services; namespace StabilityMatrix.Avalonia.ViewModels.Inference; [View(typeof(PromptCard))] +[ManagedService] +[Transient] public partial class PromptCardViewModel : LoadableViewModelBase, IParametersLoadableState { private readonly IModelIndexService modelIndexService; diff --git a/StabilityMatrix.Avalonia/ViewModels/Inference/SamplerCardViewModel.cs b/StabilityMatrix.Avalonia/ViewModels/Inference/SamplerCardViewModel.cs index 1d70fa42..8d52ebe9 100644 --- a/StabilityMatrix.Avalonia/ViewModels/Inference/SamplerCardViewModel.cs +++ b/StabilityMatrix.Avalonia/ViewModels/Inference/SamplerCardViewModel.cs @@ -13,6 +13,8 @@ using StabilityMatrix.Core.Models.Api.Comfy; namespace StabilityMatrix.Avalonia.ViewModels.Inference; [View(typeof(SamplerCard))] +[ManagedService] +[Transient] public partial class SamplerCardViewModel : LoadableViewModelBase, IParametersLoadableState { [ObservableProperty] diff --git a/StabilityMatrix.Avalonia/ViewModels/Inference/SeedCardViewModel.cs b/StabilityMatrix.Avalonia/ViewModels/Inference/SeedCardViewModel.cs index 6c52c4db..1f0a9fa4 100644 --- a/StabilityMatrix.Avalonia/ViewModels/Inference/SeedCardViewModel.cs +++ b/StabilityMatrix.Avalonia/ViewModels/Inference/SeedCardViewModel.cs @@ -10,6 +10,8 @@ using StabilityMatrix.Core.Attributes; namespace StabilityMatrix.Avalonia.ViewModels.Inference; [View(typeof(SeedCard))] +[ManagedService] +[Transient] public partial class SeedCardViewModel : LoadableViewModelBase { [ObservableProperty, NotifyPropertyChangedFor(nameof(RandomizeButtonToolTip))] diff --git a/StabilityMatrix.Avalonia/ViewModels/Inference/SelectImageCardViewModel.cs b/StabilityMatrix.Avalonia/ViewModels/Inference/SelectImageCardViewModel.cs index 67d69673..7639bc14 100644 --- a/StabilityMatrix.Avalonia/ViewModels/Inference/SelectImageCardViewModel.cs +++ b/StabilityMatrix.Avalonia/ViewModels/Inference/SelectImageCardViewModel.cs @@ -1,7 +1,6 @@ using System; using System.Collections.Generic; using System.Drawing; -using System.Text.Json; using System.Linq; using Avalonia.Input; using Avalonia.Media; @@ -19,6 +18,8 @@ using StabilityMatrix.Core.Models.Database; namespace StabilityMatrix.Avalonia.ViewModels.Inference; [View(typeof(SelectImageCard))] +[ManagedService] +[Transient] public partial class SelectImageCardViewModel : ViewModelBase, IDropTarget { private static readonly Logger Logger = LogManager.GetCurrentClassLogger(); diff --git a/StabilityMatrix.Avalonia/ViewModels/Inference/SharpenCardViewModel.cs b/StabilityMatrix.Avalonia/ViewModels/Inference/SharpenCardViewModel.cs index 98a1f933..90a67a12 100644 --- a/StabilityMatrix.Avalonia/ViewModels/Inference/SharpenCardViewModel.cs +++ b/StabilityMatrix.Avalonia/ViewModels/Inference/SharpenCardViewModel.cs @@ -7,6 +7,8 @@ using StabilityMatrix.Core.Attributes; namespace StabilityMatrix.Avalonia.ViewModels.Inference; [View(typeof(SharpenCard))] +[ManagedService] +[Transient] public partial class SharpenCardViewModel : LoadableViewModelBase { [Range(1, 31)] diff --git a/StabilityMatrix.Avalonia/ViewModels/Inference/StackCardViewModel.cs b/StabilityMatrix.Avalonia/ViewModels/Inference/StackCardViewModel.cs index 763054b2..a037a30c 100644 --- a/StabilityMatrix.Avalonia/ViewModels/Inference/StackCardViewModel.cs +++ b/StabilityMatrix.Avalonia/ViewModels/Inference/StackCardViewModel.cs @@ -8,6 +8,8 @@ using StabilityMatrix.Core.Extensions; namespace StabilityMatrix.Avalonia.ViewModels.Inference; [View(typeof(StackCard))] +[ManagedService] +[Transient] public class StackCardViewModel : StackViewModelBase { /// diff --git a/StabilityMatrix.Avalonia/ViewModels/Inference/StackExpanderViewModel.cs b/StabilityMatrix.Avalonia/ViewModels/Inference/StackExpanderViewModel.cs index 2b4e3c2e..29fe9750 100644 --- a/StabilityMatrix.Avalonia/ViewModels/Inference/StackExpanderViewModel.cs +++ b/StabilityMatrix.Avalonia/ViewModels/Inference/StackExpanderViewModel.cs @@ -11,6 +11,8 @@ using StabilityMatrix.Core.Extensions; namespace StabilityMatrix.Avalonia.ViewModels.Inference; [View(typeof(StackExpander))] +[ManagedService] +[Transient] public partial class StackExpanderViewModel : StackViewModelBase { [ObservableProperty] diff --git a/StabilityMatrix.Avalonia/ViewModels/Inference/UpscalerCardViewModel.cs b/StabilityMatrix.Avalonia/ViewModels/Inference/UpscalerCardViewModel.cs index ceef75c6..02ef8a83 100644 --- a/StabilityMatrix.Avalonia/ViewModels/Inference/UpscalerCardViewModel.cs +++ b/StabilityMatrix.Avalonia/ViewModels/Inference/UpscalerCardViewModel.cs @@ -20,6 +20,8 @@ using StabilityMatrix.Core.Services; namespace StabilityMatrix.Avalonia.ViewModels.Inference; [View(typeof(UpscalerCard))] +[ManagedService] +[Transient] public partial class UpscalerCardViewModel : LoadableViewModelBase { private readonly INotificationService notificationService; diff --git a/StabilityMatrix.Avalonia/ViewModels/InferenceViewModel.cs b/StabilityMatrix.Avalonia/ViewModels/InferenceViewModel.cs index 47513a99..33320aab 100644 --- a/StabilityMatrix.Avalonia/ViewModels/InferenceViewModel.cs +++ b/StabilityMatrix.Avalonia/ViewModels/InferenceViewModel.cs @@ -9,7 +9,6 @@ using System.Threading.Tasks; using AsyncAwaitBestPractices; using Avalonia.Controls; using Avalonia.Controls.Notifications; -using Avalonia.Controls.Shapes; using Avalonia.Platform.Storage; using Avalonia.Threading; using CommunityToolkit.Mvvm.ComponentModel; @@ -23,7 +22,6 @@ using StabilityMatrix.Avalonia.ViewModels.Base; using StabilityMatrix.Avalonia.ViewModels.Dialogs; using StabilityMatrix.Avalonia.ViewModels.Inference; using StabilityMatrix.Avalonia.Views; -using StabilityMatrix.Core.Api; using StabilityMatrix.Core.Attributes; using StabilityMatrix.Core.Database; using StabilityMatrix.Core.Extensions; @@ -43,6 +41,7 @@ namespace StabilityMatrix.Avalonia.ViewModels; [Preload] [View(typeof(InferencePage))] +[Singleton] public partial class InferenceViewModel : PageViewModelBase { private static readonly Logger Logger = LogManager.GetCurrentClassLogger(); diff --git a/StabilityMatrix.Avalonia/ViewModels/LaunchPageViewModel.cs b/StabilityMatrix.Avalonia/ViewModels/LaunchPageViewModel.cs index 87c7ea3f..b9ed79ab 100644 --- a/StabilityMatrix.Avalonia/ViewModels/LaunchPageViewModel.cs +++ b/StabilityMatrix.Avalonia/ViewModels/LaunchPageViewModel.cs @@ -40,6 +40,7 @@ using SymbolIconSource = FluentIcons.FluentAvalonia.SymbolIconSource; namespace StabilityMatrix.Avalonia.ViewModels; [View(typeof(LaunchPageView))] +[Singleton] public partial class LaunchPageViewModel : PageViewModelBase, IDisposable, IAsyncDisposable { private readonly ILogger logger; diff --git a/StabilityMatrix.Avalonia/ViewModels/NewCheckpointsPageViewModel.cs b/StabilityMatrix.Avalonia/ViewModels/NewCheckpointsPageViewModel.cs index b165aef0..283494f7 100644 --- a/StabilityMatrix.Avalonia/ViewModels/NewCheckpointsPageViewModel.cs +++ b/StabilityMatrix.Avalonia/ViewModels/NewCheckpointsPageViewModel.cs @@ -2,14 +2,12 @@ using System.Collections.Generic; using System.Collections.Immutable; using System.Collections.ObjectModel; -using System.IO; using System.Linq; using System.Net.Http; using System.Threading.Tasks; using AsyncAwaitBestPractices; using Avalonia.Controls; using Avalonia.Controls.Notifications; -using AvaloniaEdit.Utils; using CommunityToolkit.Mvvm.ComponentModel; using FluentAvalonia.UI.Controls; using Microsoft.Extensions.Logging; @@ -35,6 +33,7 @@ using SymbolIconSource = FluentIcons.FluentAvalonia.SymbolIconSource; namespace StabilityMatrix.Avalonia.ViewModels; [View(typeof(NewCheckpointsPage))] +[Singleton] public partial class NewCheckpointsPageViewModel : PageViewModelBase { private readonly ILogger logger; diff --git a/StabilityMatrix.Avalonia/ViewModels/OutputsPage/OutputImageViewModel.cs b/StabilityMatrix.Avalonia/ViewModels/OutputsPage/OutputImageViewModel.cs index 1102d0ab..30ce380e 100644 --- a/StabilityMatrix.Avalonia/ViewModels/OutputsPage/OutputImageViewModel.cs +++ b/StabilityMatrix.Avalonia/ViewModels/OutputsPage/OutputImageViewModel.cs @@ -1,5 +1,4 @@ -using System; -using CommunityToolkit.Mvvm.ComponentModel; +using CommunityToolkit.Mvvm.ComponentModel; using StabilityMatrix.Avalonia.ViewModels.Base; using StabilityMatrix.Core.Models.Database; diff --git a/StabilityMatrix.Avalonia/ViewModels/OutputsPageViewModel.cs b/StabilityMatrix.Avalonia/ViewModels/OutputsPageViewModel.cs index 8caab91b..9bc6b447 100644 --- a/StabilityMatrix.Avalonia/ViewModels/OutputsPageViewModel.cs +++ b/StabilityMatrix.Avalonia/ViewModels/OutputsPageViewModel.cs @@ -5,11 +5,9 @@ using System.Diagnostics; using System.IO; using System.Linq; using System.Reactive.Linq; -using System.Threading; using System.Threading.Tasks; using AsyncAwaitBestPractices; using AsyncImageLoader; -using Avalonia; using Avalonia.Controls; using Avalonia.Threading; using CommunityToolkit.Mvvm.ComponentModel; @@ -24,7 +22,6 @@ using StabilityMatrix.Avalonia.Models; using StabilityMatrix.Avalonia.Services; using StabilityMatrix.Avalonia.ViewModels.Base; using StabilityMatrix.Avalonia.ViewModels.Dialogs; -using StabilityMatrix.Avalonia.ViewModels.Inference; using StabilityMatrix.Avalonia.ViewModels.OutputsPage; using StabilityMatrix.Core.Attributes; using StabilityMatrix.Core.Helper; @@ -40,6 +37,7 @@ using SymbolIconSource = FluentIcons.FluentAvalonia.SymbolIconSource; namespace StabilityMatrix.Avalonia.ViewModels; [View(typeof(Views.OutputsPage))] +[Singleton] public partial class OutputsPageViewModel : PageViewModelBase { private readonly ISettingsManager settingsManager; @@ -143,7 +141,7 @@ public partial class OutputsPageViewModel : PageViewModelBase if (!settingsManager.IsLibraryDirSet) return; - + Directory.CreateDirectory(settingsManager.ImagesDirectory); var packageCategories = settingsManager.Settings.InstalledPackages .Where(x => !x.UseSharedOutputFolder) diff --git a/StabilityMatrix.Avalonia/ViewModels/PackageManager/PackageCardViewModel.cs b/StabilityMatrix.Avalonia/ViewModels/PackageManager/PackageCardViewModel.cs index f72b8824..09948e4d 100644 --- a/StabilityMatrix.Avalonia/ViewModels/PackageManager/PackageCardViewModel.cs +++ b/StabilityMatrix.Avalonia/ViewModels/PackageManager/PackageCardViewModel.cs @@ -14,6 +14,7 @@ using StabilityMatrix.Avalonia.Services; using StabilityMatrix.Avalonia.ViewModels.Base; using StabilityMatrix.Avalonia.ViewModels.Dialogs; using StabilityMatrix.Avalonia.Views.Dialogs; +using StabilityMatrix.Core.Attributes; using StabilityMatrix.Core.Extensions; using StabilityMatrix.Core.Helper; using StabilityMatrix.Core.Helper.Factory; @@ -26,6 +27,8 @@ using StabilityMatrix.Core.Services; namespace StabilityMatrix.Avalonia.ViewModels.PackageManager; +[ManagedService] +[Transient] public partial class PackageCardViewModel : ProgressViewModel { private readonly ILogger logger; diff --git a/StabilityMatrix.Avalonia/ViewModels/PackageManagerViewModel.cs b/StabilityMatrix.Avalonia/ViewModels/PackageManagerViewModel.cs index d68a7676..1ef6a3c4 100644 --- a/StabilityMatrix.Avalonia/ViewModels/PackageManagerViewModel.cs +++ b/StabilityMatrix.Avalonia/ViewModels/PackageManagerViewModel.cs @@ -8,9 +8,11 @@ using AsyncAwaitBestPractices; using Avalonia.Controls; using Avalonia.Controls.Notifications; using Avalonia.Controls.Primitives; +using Avalonia.Threading; using DynamicData; using DynamicData.Binding; using FluentAvalonia.UI.Controls; +using Microsoft.Extensions.Logging; using StabilityMatrix.Avalonia.Controls; using StabilityMatrix.Avalonia.Services; using StabilityMatrix.Avalonia.ViewModels.Base; @@ -20,7 +22,6 @@ using StabilityMatrix.Avalonia.Views; using StabilityMatrix.Avalonia.Views.Dialogs; using StabilityMatrix.Core.Attributes; using StabilityMatrix.Core.Helper; -using StabilityMatrix.Core.Helper.Factory; using StabilityMatrix.Core.Models; using StabilityMatrix.Core.Models.FileInterfaces; using StabilityMatrix.Core.Models.PackageModification; @@ -36,12 +37,13 @@ namespace StabilityMatrix.Avalonia.ViewModels; /// [View(typeof(PackageManagerPage))] +[Singleton] public partial class PackageManagerViewModel : PageViewModelBase { private readonly ISettingsManager settingsManager; - private readonly IPackageFactory packageFactory; private readonly ServiceManager dialogFactory; private readonly INotificationService notificationService; + private readonly ILogger logger; public override string Title => "Packages"; public override IconSource IconSource => @@ -63,17 +65,19 @@ public partial class PackageManagerViewModel : PageViewModelBase public IObservableCollection PackageCards { get; } = new ObservableCollectionExtended(); + + private DispatcherTimer timer; + public PackageManagerViewModel( ISettingsManager settingsManager, - IPackageFactory packageFactory, ServiceManager dialogFactory, - INotificationService notificationService - ) + INotificationService notificationService, + ILogger logger) { this.settingsManager = settingsManager; - this.packageFactory = packageFactory; this.dialogFactory = dialogFactory; this.notificationService = notificationService; + this.logger = logger; EventManager.Instance.InstalledPackagesChanged += OnInstalledPackagesChanged; @@ -94,6 +98,13 @@ public partial class PackageManagerViewModel : PageViewModelBase ) .Bind(PackageCards) .Subscribe(); + + timer = new DispatcherTimer + { + Interval = TimeSpan.FromSeconds(5), + IsEnabled = true + }; + timer.Tick += async (_, _) => await CheckPackagesForUpdates(); } public void SetPackages(IEnumerable packages) @@ -118,6 +129,14 @@ public partial class PackageManagerViewModel : PageViewModelBase var currentUnknown = await Task.Run(IndexUnknownPackages); unknownInstalledPackages.Edit(s => s.Load(currentUnknown)); + + timer.Start(); + } + + public override void OnUnloaded() + { + timer.Stop(); + base.OnUnloaded(); } public async Task ShowInstallDialog(BasePackage? selectedPackage = null) @@ -159,6 +178,21 @@ public partial class PackageManagerViewModel : PageViewModelBase } } + private async Task CheckPackagesForUpdates() + { + foreach (var package in PackageCards) + { + try + { + await package.OnLoadedAsync(); + } + catch + { + logger.LogWarning("Failed to check for updates for {Package}", package?.Package?.PackageName); + } + } + } + private IEnumerable IndexUnknownPackages() { var packageDir = new DirectoryPath(settingsManager.LibraryDir).JoinDir("Packages"); diff --git a/StabilityMatrix.Avalonia/ViewModels/Progress/ProgressManagerViewModel.cs b/StabilityMatrix.Avalonia/ViewModels/Progress/ProgressManagerViewModel.cs index fc0a8a41..445f0e0c 100644 --- a/StabilityMatrix.Avalonia/ViewModels/Progress/ProgressManagerViewModel.cs +++ b/StabilityMatrix.Avalonia/ViewModels/Progress/ProgressManagerViewModel.cs @@ -22,6 +22,8 @@ using SymbolIconSource = FluentIcons.FluentAvalonia.SymbolIconSource; namespace StabilityMatrix.Avalonia.ViewModels.Progress; [View(typeof(ProgressManagerPage))] +[ManagedService] +[Singleton] public partial class ProgressManagerViewModel : PageViewModelBase { private readonly INotificationService notificationService; diff --git a/StabilityMatrix.Avalonia/ViewModels/RefreshBadgeViewModel.cs b/StabilityMatrix.Avalonia/ViewModels/RefreshBadgeViewModel.cs index 10ee1194..2cac7d48 100644 --- a/StabilityMatrix.Avalonia/ViewModels/RefreshBadgeViewModel.cs +++ b/StabilityMatrix.Avalonia/ViewModels/RefreshBadgeViewModel.cs @@ -16,6 +16,8 @@ namespace StabilityMatrix.Avalonia.ViewModels; [View(typeof(RefreshBadge))] [SuppressMessage("ReSharper", "MemberCanBePrivate.Global")] +[ManagedService] +[Transient] public partial class RefreshBadgeViewModel : ViewModelBase { private static readonly Logger Logger = LogManager.GetCurrentClassLogger(); diff --git a/StabilityMatrix.Avalonia/ViewModels/Settings/InferenceSettingsViewModel.cs b/StabilityMatrix.Avalonia/ViewModels/Settings/InferenceSettingsViewModel.cs index cec925fb..80d5c7ba 100644 --- a/StabilityMatrix.Avalonia/ViewModels/Settings/InferenceSettingsViewModel.cs +++ b/StabilityMatrix.Avalonia/ViewModels/Settings/InferenceSettingsViewModel.cs @@ -1,12 +1,9 @@ -using CommunityToolkit.Mvvm.ComponentModel; -using StabilityMatrix.Avalonia.ViewModels.Base; +using StabilityMatrix.Avalonia.ViewModels.Base; using StabilityMatrix.Avalonia.Views.Settings; using StabilityMatrix.Core.Attributes; namespace StabilityMatrix.Avalonia.ViewModels.Settings; [View(typeof(InferenceSettingsPage))] -public partial class InferenceSettingsViewModel : ViewModelBase -{ - -} +[Singleton] +public partial class InferenceSettingsViewModel : ViewModelBase { } diff --git a/StabilityMatrix.Avalonia/ViewModels/SettingsViewModel.cs b/StabilityMatrix.Avalonia/ViewModels/SettingsViewModel.cs index 850a397c..74dc145b 100644 --- a/StabilityMatrix.Avalonia/ViewModels/SettingsViewModel.cs +++ b/StabilityMatrix.Avalonia/ViewModels/SettingsViewModel.cs @@ -13,7 +13,6 @@ using System.Reflection; using System.Text; using System.Text.Json; using System.Threading.Tasks; -using AsyncAwaitBestPractices; using Avalonia; using Avalonia.Controls.Notifications; using Avalonia.Controls.Primitives; @@ -53,6 +52,7 @@ using SymbolIconSource = FluentIcons.FluentAvalonia.SymbolIconSource; namespace StabilityMatrix.Avalonia.ViewModels; [View(typeof(SettingsPage))] +[Singleton] public partial class SettingsViewModel : PageViewModelBase { private static readonly Logger Logger = LogManager.GetCurrentClassLogger(); @@ -229,7 +229,7 @@ public partial class SettingsViewModel : PageViewModelBase .Subscribe(formatProperty => { var provider = FileNameFormatProvider.GetSample(); - var template = formatProperty.Value; + var template = formatProperty.Value ?? string.Empty; if ( !string.IsNullOrEmpty(template) @@ -282,11 +282,11 @@ public partial class SettingsViewModel : PageViewModelBase } public static ValidationResult ValidateOutputImageFileNameFormat( - string format, + string? format, ValidationContext context ) { - return FileNameFormatProvider.GetSample().Validate(format); + return FileNameFormatProvider.GetSample().Validate(format ?? string.Empty); } partial void OnSelectedThemeChanged(string? value) diff --git a/StabilityMatrix.Avalonia/Views/CheckpointBrowserPage.axaml.cs b/StabilityMatrix.Avalonia/Views/CheckpointBrowserPage.axaml.cs index f61dae4c..34e0887a 100644 --- a/StabilityMatrix.Avalonia/Views/CheckpointBrowserPage.axaml.cs +++ b/StabilityMatrix.Avalonia/Views/CheckpointBrowserPage.axaml.cs @@ -1,8 +1,10 @@ using Avalonia.Markup.Xaml; using StabilityMatrix.Avalonia.Controls; +using StabilityMatrix.Core.Attributes; namespace StabilityMatrix.Avalonia.Views; +[Singleton] public partial class CheckpointBrowserPage : UserControlBase { public CheckpointBrowserPage() diff --git a/StabilityMatrix.Avalonia/Views/CheckpointsPage.axaml.cs b/StabilityMatrix.Avalonia/Views/CheckpointsPage.axaml.cs index 3cccca86..1e9765a7 100644 --- a/StabilityMatrix.Avalonia/Views/CheckpointsPage.axaml.cs +++ b/StabilityMatrix.Avalonia/Views/CheckpointsPage.axaml.cs @@ -2,16 +2,18 @@ using Avalonia.Input; using Avalonia.Markup.Xaml; using StabilityMatrix.Avalonia.Controls; +using StabilityMatrix.Core.Attributes; using CheckpointFolder = StabilityMatrix.Avalonia.ViewModels.CheckpointManager.CheckpointFolder; namespace StabilityMatrix.Avalonia.Views; +[Singleton] public partial class CheckpointsPage : UserControlBase { public CheckpointsPage() { InitializeComponent(); - + AddHandler(DragDrop.DragEnterEvent, OnDragEnter); AddHandler(DragDrop.DragLeaveEvent, OnDragExit); AddHandler(DragDrop.DropEvent, OnDrop); @@ -21,6 +23,7 @@ public partial class CheckpointsPage : UserControlBase { AvaloniaXamlLoader.Load(this); } + private static async void OnDrop(object? sender, DragEventArgs e) { var sourceDataContext = (e.Source as Control)?.DataContext; @@ -29,7 +32,7 @@ public partial class CheckpointsPage : UserControlBase await folder.OnDrop(e); } } - + private static void OnDragExit(object? sender, DragEventArgs e) { var sourceDataContext = (e.Source as Control)?.DataContext; @@ -38,7 +41,7 @@ public partial class CheckpointsPage : UserControlBase folder.IsCurrentDragTarget = false; } } - + private static void OnDragEnter(object? sender, DragEventArgs e) { // Only allow Copy or Link as Drop Operations. @@ -47,9 +50,9 @@ public partial class CheckpointsPage : UserControlBase // Only allow if the dragged data contains text or filenames. if (!e.Data.Contains(DataFormats.Text) && !e.Data.Contains(DataFormats.Files)) { - e.DragEffects = DragDropEffects.None; + e.DragEffects = DragDropEffects.None; } - + // Forward to view model var sourceDataContext = (e.Source as Control)?.DataContext; if (sourceDataContext is CheckpointFolder folder) diff --git a/StabilityMatrix.Avalonia/Views/Dialogs/DownloadResourceDialog.axaml.cs b/StabilityMatrix.Avalonia/Views/Dialogs/DownloadResourceDialog.axaml.cs index 22d34516..3928f022 100644 --- a/StabilityMatrix.Avalonia/Views/Dialogs/DownloadResourceDialog.axaml.cs +++ b/StabilityMatrix.Avalonia/Views/Dialogs/DownloadResourceDialog.axaml.cs @@ -1,12 +1,13 @@ -using Avalonia; -using Avalonia.Controls; +using Avalonia.Controls; using Avalonia.Input; using Avalonia.Markup.Xaml; using StabilityMatrix.Avalonia.ViewModels.Dialogs; +using StabilityMatrix.Core.Attributes; using StabilityMatrix.Core.Processes; namespace StabilityMatrix.Avalonia.Views.Dialogs; +[Transient] public partial class DownloadResourceDialog : UserControl { public DownloadResourceDialog() diff --git a/StabilityMatrix.Avalonia/Views/Dialogs/EnvVarsDialog.axaml.cs b/StabilityMatrix.Avalonia/Views/Dialogs/EnvVarsDialog.axaml.cs index 63068706..3c54d2c2 100644 --- a/StabilityMatrix.Avalonia/Views/Dialogs/EnvVarsDialog.axaml.cs +++ b/StabilityMatrix.Avalonia/Views/Dialogs/EnvVarsDialog.axaml.cs @@ -1,8 +1,10 @@ using Avalonia.Markup.Xaml; using StabilityMatrix.Avalonia.Controls; +using StabilityMatrix.Core.Attributes; namespace StabilityMatrix.Avalonia.Views.Dialogs; +[Transient] public partial class EnvVarsDialog : UserControlBase { public EnvVarsDialog() diff --git a/StabilityMatrix.Avalonia/Views/Dialogs/ExceptionDialog.axaml.cs b/StabilityMatrix.Avalonia/Views/Dialogs/ExceptionDialog.axaml.cs index bbd91996..b2bf44ad 100644 --- a/StabilityMatrix.Avalonia/Views/Dialogs/ExceptionDialog.axaml.cs +++ b/StabilityMatrix.Avalonia/Views/Dialogs/ExceptionDialog.axaml.cs @@ -3,15 +3,17 @@ using Avalonia.Interactivity; using Avalonia.Markup.Xaml; using FluentAvalonia.UI.Windowing; using StabilityMatrix.Avalonia.Controls; +using StabilityMatrix.Core.Attributes; namespace StabilityMatrix.Avalonia.Views.Dialogs; +[Transient] public partial class ExceptionDialog : AppWindowBase { public ExceptionDialog() { InitializeComponent(); - + TitleBar.ExtendsContentIntoTitleBar = true; TitleBar.TitleBarHitTestType = TitleBarHitTestType.Complex; } @@ -20,7 +22,7 @@ public partial class ExceptionDialog : AppWindowBase { AvaloniaXamlLoader.Load(this); } - + [SuppressMessage("ReSharper", "UnusedParameter.Local")] private void ExitButton_OnClick(object? sender, RoutedEventArgs e) { diff --git a/StabilityMatrix.Avalonia/Views/Dialogs/ImageViewerDialog.axaml.cs b/StabilityMatrix.Avalonia/Views/Dialogs/ImageViewerDialog.axaml.cs index 7af815c6..fc921fee 100644 --- a/StabilityMatrix.Avalonia/Views/Dialogs/ImageViewerDialog.axaml.cs +++ b/StabilityMatrix.Avalonia/Views/Dialogs/ImageViewerDialog.axaml.cs @@ -1,10 +1,11 @@ using Avalonia; using Avalonia.Input; -using Avalonia.Interactivity; using StabilityMatrix.Avalonia.Controls; +using StabilityMatrix.Core.Attributes; namespace StabilityMatrix.Avalonia.Views.Dialogs; +[Transient] public partial class ImageViewerDialog : UserControlBase { public static readonly StyledProperty IsFooterEnabledProperty = AvaloniaProperty.Register< diff --git a/StabilityMatrix.Avalonia/Views/Dialogs/InferenceConnectionHelpDialog.axaml.cs b/StabilityMatrix.Avalonia/Views/Dialogs/InferenceConnectionHelpDialog.axaml.cs index fc0e45d5..b2568572 100644 --- a/StabilityMatrix.Avalonia/Views/Dialogs/InferenceConnectionHelpDialog.axaml.cs +++ b/StabilityMatrix.Avalonia/Views/Dialogs/InferenceConnectionHelpDialog.axaml.cs @@ -1,9 +1,10 @@ -using Avalonia; -using Avalonia.Controls; +using Avalonia.Controls; using Avalonia.Markup.Xaml; +using StabilityMatrix.Core.Attributes; namespace StabilityMatrix.Avalonia.Views.Dialogs; +[Transient] public partial class InferenceConnectionHelpDialog : UserControl { public InferenceConnectionHelpDialog() diff --git a/StabilityMatrix.Avalonia/Views/Dialogs/LaunchOptionsDialog.axaml.cs b/StabilityMatrix.Avalonia/Views/Dialogs/LaunchOptionsDialog.axaml.cs index 84d4d3a6..5dd11fc4 100644 --- a/StabilityMatrix.Avalonia/Views/Dialogs/LaunchOptionsDialog.axaml.cs +++ b/StabilityMatrix.Avalonia/Views/Dialogs/LaunchOptionsDialog.axaml.cs @@ -1,8 +1,10 @@ using Avalonia.Controls; using Avalonia.Markup.Xaml; +using StabilityMatrix.Core.Attributes; namespace StabilityMatrix.Avalonia.Views.Dialogs; +[Transient] public partial class LaunchOptionsDialog : UserControl { public LaunchOptionsDialog() diff --git a/StabilityMatrix.Avalonia/Views/Dialogs/OneClickInstallDialog.axaml.cs b/StabilityMatrix.Avalonia/Views/Dialogs/OneClickInstallDialog.axaml.cs index 23c8a034..d615eddc 100644 --- a/StabilityMatrix.Avalonia/Views/Dialogs/OneClickInstallDialog.axaml.cs +++ b/StabilityMatrix.Avalonia/Views/Dialogs/OneClickInstallDialog.axaml.cs @@ -3,7 +3,6 @@ using System.Linq; using Avalonia.Controls; using Avalonia.Controls.Primitives; using Avalonia.Interactivity; -using Avalonia.Markup.Xaml; using FluentAvalonia.UI.Controls; using StabilityMatrix.Core.Models.Packages; diff --git a/StabilityMatrix.Avalonia/Views/Dialogs/PackageImportDialog.axaml.cs b/StabilityMatrix.Avalonia/Views/Dialogs/PackageImportDialog.axaml.cs index a5f8cf50..7123dfa9 100644 --- a/StabilityMatrix.Avalonia/Views/Dialogs/PackageImportDialog.axaml.cs +++ b/StabilityMatrix.Avalonia/Views/Dialogs/PackageImportDialog.axaml.cs @@ -1,8 +1,10 @@ using Avalonia.Markup.Xaml; using StabilityMatrix.Avalonia.Controls; +using StabilityMatrix.Core.Attributes; namespace StabilityMatrix.Avalonia.Views.Dialogs; +[Transient] public partial class PackageImportDialog : UserControlBase { public PackageImportDialog() diff --git a/StabilityMatrix.Avalonia/Views/Dialogs/SelectDataDirectoryDialog.axaml.cs b/StabilityMatrix.Avalonia/Views/Dialogs/SelectDataDirectoryDialog.axaml.cs index 3e874a83..f9eb3bf1 100644 --- a/StabilityMatrix.Avalonia/Views/Dialogs/SelectDataDirectoryDialog.axaml.cs +++ b/StabilityMatrix.Avalonia/Views/Dialogs/SelectDataDirectoryDialog.axaml.cs @@ -1,8 +1,10 @@ using Avalonia.Markup.Xaml; using StabilityMatrix.Avalonia.Controls; +using StabilityMatrix.Core.Attributes; namespace StabilityMatrix.Avalonia.Views.Dialogs; +[Transient] public partial class SelectDataDirectoryDialog : UserControlBase { public SelectDataDirectoryDialog() diff --git a/StabilityMatrix.Avalonia/Views/Dialogs/UpdateDialog.axaml.cs b/StabilityMatrix.Avalonia/Views/Dialogs/UpdateDialog.axaml.cs index 33d2b218..94ac9c31 100644 --- a/StabilityMatrix.Avalonia/Views/Dialogs/UpdateDialog.axaml.cs +++ b/StabilityMatrix.Avalonia/Views/Dialogs/UpdateDialog.axaml.cs @@ -1,8 +1,10 @@ using Avalonia.Controls; using Avalonia.Markup.Xaml; +using StabilityMatrix.Core.Attributes; namespace StabilityMatrix.Avalonia.Views.Dialogs; +[Transient] public partial class UpdateDialog : UserControl { public UpdateDialog() @@ -14,4 +16,4 @@ public partial class UpdateDialog : UserControl { AvaloniaXamlLoader.Load(this); } -} \ No newline at end of file +} diff --git a/StabilityMatrix.Avalonia/Views/FirstLaunchSetupWindow.axaml.cs b/StabilityMatrix.Avalonia/Views/FirstLaunchSetupWindow.axaml.cs index f02ea254..e3a9cf7f 100644 --- a/StabilityMatrix.Avalonia/Views/FirstLaunchSetupWindow.axaml.cs +++ b/StabilityMatrix.Avalonia/Views/FirstLaunchSetupWindow.axaml.cs @@ -1,13 +1,13 @@ -using System; -using System.Diagnostics.CodeAnalysis; -using Avalonia; +using System.Diagnostics.CodeAnalysis; using Avalonia.Interactivity; using Avalonia.Markup.Xaml; using FluentAvalonia.UI.Controls; using StabilityMatrix.Avalonia.Controls; +using StabilityMatrix.Core.Attributes; namespace StabilityMatrix.Avalonia.Views; +[Singleton] public partial class FirstLaunchSetupWindow : AppWindowBase { public ContentDialogResult Result { get; private set; } diff --git a/StabilityMatrix.Avalonia/Views/Inference/InferenceImageUpscaleView.axaml.cs b/StabilityMatrix.Avalonia/Views/Inference/InferenceImageUpscaleView.axaml.cs index eaa6a883..0e13e9d4 100644 --- a/StabilityMatrix.Avalonia/Views/Inference/InferenceImageUpscaleView.axaml.cs +++ b/StabilityMatrix.Avalonia/Views/Inference/InferenceImageUpscaleView.axaml.cs @@ -1,7 +1,9 @@ using StabilityMatrix.Avalonia.Controls.Dock; +using StabilityMatrix.Core.Attributes; namespace StabilityMatrix.Avalonia.Views.Inference; +[Transient] public partial class InferenceImageUpscaleView : DockUserControlBase { public InferenceImageUpscaleView() diff --git a/StabilityMatrix.Avalonia/Views/Inference/InferenceTextToImageView.axaml.cs b/StabilityMatrix.Avalonia/Views/Inference/InferenceTextToImageView.axaml.cs index 11784fe4..d9116275 100644 --- a/StabilityMatrix.Avalonia/Views/Inference/InferenceTextToImageView.axaml.cs +++ b/StabilityMatrix.Avalonia/Views/Inference/InferenceTextToImageView.axaml.cs @@ -1,7 +1,9 @@ using StabilityMatrix.Avalonia.Controls.Dock; +using StabilityMatrix.Core.Attributes; namespace StabilityMatrix.Avalonia.Views.Inference; +[Transient] public partial class InferenceTextToImageView : DockUserControlBase { public InferenceTextToImageView() diff --git a/StabilityMatrix.Avalonia/Views/InferencePage.axaml.cs b/StabilityMatrix.Avalonia/Views/InferencePage.axaml.cs index 7dd4e5ed..05e4eb76 100644 --- a/StabilityMatrix.Avalonia/Views/InferencePage.axaml.cs +++ b/StabilityMatrix.Avalonia/Views/InferencePage.axaml.cs @@ -7,9 +7,11 @@ using FluentAvalonia.UI.Controls; using StabilityMatrix.Avalonia.Controls; using StabilityMatrix.Avalonia.Models; using StabilityMatrix.Avalonia.ViewModels; +using StabilityMatrix.Core.Attributes; namespace StabilityMatrix.Avalonia.Views; +[Singleton] public partial class InferencePage : UserControlBase { private Button? _addButton; diff --git a/StabilityMatrix.Avalonia/Views/LaunchPageView.axaml.cs b/StabilityMatrix.Avalonia/Views/LaunchPageView.axaml.cs index bf5b132d..74e8d450 100644 --- a/StabilityMatrix.Avalonia/Views/LaunchPageView.axaml.cs +++ b/StabilityMatrix.Avalonia/Views/LaunchPageView.axaml.cs @@ -6,11 +6,13 @@ using Avalonia.Threading; using AvaloniaEdit; using AvaloniaEdit.TextMate; using StabilityMatrix.Avalonia.Controls; +using StabilityMatrix.Core.Attributes; using StabilityMatrix.Core.Helper; using TextMateSharp.Grammars; namespace StabilityMatrix.Avalonia.Views; +[Singleton] public partial class LaunchPageView : UserControlBase { private const int LineOffset = 5; diff --git a/StabilityMatrix.Avalonia/Views/MainWindow.axaml.cs b/StabilityMatrix.Avalonia/Views/MainWindow.axaml.cs index 1854ebcc..2e9d5f27 100644 --- a/StabilityMatrix.Avalonia/Views/MainWindow.axaml.cs +++ b/StabilityMatrix.Avalonia/Views/MainWindow.axaml.cs @@ -3,7 +3,6 @@ using System.Collections.Generic; using System.ComponentModel; using System.Diagnostics.CodeAnalysis; using System.IO; -using AsyncAwaitBestPractices; using AsyncImageLoader; using Avalonia; using Avalonia.Controls; @@ -30,6 +29,7 @@ using StabilityMatrix.Avalonia.Languages; using StabilityMatrix.Avalonia.Services; using StabilityMatrix.Avalonia.ViewModels; using StabilityMatrix.Avalonia.ViewModels.Base; +using StabilityMatrix.Core.Attributes; using StabilityMatrix.Core.Helper; using StabilityMatrix.Core.Models.Update; using StabilityMatrix.Core.Processes; @@ -40,6 +40,7 @@ using StabilityMatrix.Avalonia.Diagnostics.Views; namespace StabilityMatrix.Avalonia.Views; [SuppressMessage("ReSharper", "UnusedParameter.Local")] +[Singleton] public partial class MainWindow : AppWindowBase { private readonly INotificationService notificationService; diff --git a/StabilityMatrix.Avalonia/Views/NewCheckpointsPage.axaml.cs b/StabilityMatrix.Avalonia/Views/NewCheckpointsPage.axaml.cs index 28d9880a..9cad2f3e 100644 --- a/StabilityMatrix.Avalonia/Views/NewCheckpointsPage.axaml.cs +++ b/StabilityMatrix.Avalonia/Views/NewCheckpointsPage.axaml.cs @@ -1,7 +1,9 @@ using StabilityMatrix.Avalonia.Controls; +using StabilityMatrix.Core.Attributes; namespace StabilityMatrix.Avalonia.Views; +[Singleton] public partial class NewCheckpointsPage : UserControlBase { public NewCheckpointsPage() diff --git a/StabilityMatrix.Avalonia/Views/OutputsPage.axaml b/StabilityMatrix.Avalonia/Views/OutputsPage.axaml index 6a17f7b1..b0748d53 100644 --- a/StabilityMatrix.Avalonia/Views/OutputsPage.axaml +++ b/StabilityMatrix.Avalonia/Views/OutputsPage.axaml @@ -72,11 +72,11 @@ + Text="{x:Static lang:Resources.Action_Search}"/> @@ -129,7 +129,7 @@ ItemsSource="{Binding Outputs}" VerticalAlignment="Top"> - + diff --git a/StabilityMatrix.Avalonia/Views/OutputsPage.axaml.cs b/StabilityMatrix.Avalonia/Views/OutputsPage.axaml.cs index e14c5818..e484018f 100644 --- a/StabilityMatrix.Avalonia/Views/OutputsPage.axaml.cs +++ b/StabilityMatrix.Avalonia/Views/OutputsPage.axaml.cs @@ -1,10 +1,9 @@ -using Avalonia; -using Avalonia.Controls; -using Avalonia.Markup.Xaml; -using StabilityMatrix.Avalonia.Controls; +using StabilityMatrix.Avalonia.Controls; +using StabilityMatrix.Core.Attributes; namespace StabilityMatrix.Avalonia.Views; +[Singleton] public partial class OutputsPage : UserControlBase { public OutputsPage() diff --git a/StabilityMatrix.Avalonia/Views/PackageManagerPage.axaml.cs b/StabilityMatrix.Avalonia/Views/PackageManagerPage.axaml.cs index 075df5bd..5282b885 100644 --- a/StabilityMatrix.Avalonia/Views/PackageManagerPage.axaml.cs +++ b/StabilityMatrix.Avalonia/Views/PackageManagerPage.axaml.cs @@ -5,10 +5,12 @@ using FluentAvalonia.UI.Controls; using FluentAvalonia.UI.Navigation; using StabilityMatrix.Avalonia.Controls; using StabilityMatrix.Avalonia.ViewModels; +using StabilityMatrix.Core.Attributes; using StabilityMatrix.Core.Models.Packages; namespace StabilityMatrix.Avalonia.Views; +[Singleton] public partial class PackageManagerPage : UserControlBase { public PackageManagerPage() diff --git a/StabilityMatrix.Avalonia/Views/ProgressManagerPage.axaml.cs b/StabilityMatrix.Avalonia/Views/ProgressManagerPage.axaml.cs index e412bab7..c96b7f03 100644 --- a/StabilityMatrix.Avalonia/Views/ProgressManagerPage.axaml.cs +++ b/StabilityMatrix.Avalonia/Views/ProgressManagerPage.axaml.cs @@ -1,8 +1,10 @@ using Avalonia.Markup.Xaml; using StabilityMatrix.Avalonia.Controls; +using StabilityMatrix.Core.Attributes; namespace StabilityMatrix.Avalonia.Views; +[Singleton] public partial class ProgressManagerPage : UserControlBase { public ProgressManagerPage() diff --git a/StabilityMatrix.Avalonia/Views/Settings/InferenceSettingsPage.axaml.cs b/StabilityMatrix.Avalonia/Views/Settings/InferenceSettingsPage.axaml.cs index 54f41701..20cf1dd1 100644 --- a/StabilityMatrix.Avalonia/Views/Settings/InferenceSettingsPage.axaml.cs +++ b/StabilityMatrix.Avalonia/Views/Settings/InferenceSettingsPage.axaml.cs @@ -1,9 +1,10 @@ -using Avalonia; -using Avalonia.Controls; +using Avalonia.Controls; using Avalonia.Markup.Xaml; +using StabilityMatrix.Core.Attributes; namespace StabilityMatrix.Avalonia.Views.Settings; +[Singleton] public partial class InferenceSettingsPage : UserControl { public InferenceSettingsPage() @@ -15,4 +16,4 @@ public partial class InferenceSettingsPage : UserControl { AvaloniaXamlLoader.Load(this); } -} \ No newline at end of file +} diff --git a/StabilityMatrix.Avalonia/Views/SettingsPage.axaml.cs b/StabilityMatrix.Avalonia/Views/SettingsPage.axaml.cs index 323a47cf..ba3d18c9 100644 --- a/StabilityMatrix.Avalonia/Views/SettingsPage.axaml.cs +++ b/StabilityMatrix.Avalonia/Views/SettingsPage.axaml.cs @@ -1,8 +1,10 @@ using Avalonia.Markup.Xaml; using StabilityMatrix.Avalonia.Controls; +using StabilityMatrix.Core.Attributes; namespace StabilityMatrix.Avalonia.Views; +[Singleton] public partial class SettingsPage : UserControlBase { public SettingsPage() diff --git a/StabilityMatrix.Core/Attributes/ManagedServiceAttribute.cs b/StabilityMatrix.Core/Attributes/ManagedServiceAttribute.cs new file mode 100644 index 00000000..1d78f9f7 --- /dev/null +++ b/StabilityMatrix.Core/Attributes/ManagedServiceAttribute.cs @@ -0,0 +1,4 @@ +namespace StabilityMatrix.Core.Attributes; + +[AttributeUsage(AttributeTargets.Class)] +public class ManagedServiceAttribute : Attribute { } diff --git a/StabilityMatrix.Core/Attributes/SingletonAttribute.cs b/StabilityMatrix.Core/Attributes/SingletonAttribute.cs new file mode 100644 index 00000000..f6897601 --- /dev/null +++ b/StabilityMatrix.Core/Attributes/SingletonAttribute.cs @@ -0,0 +1,14 @@ +namespace StabilityMatrix.Core.Attributes; + +[AttributeUsage(AttributeTargets.Class)] +public class SingletonAttribute : Attribute +{ + public Type? InterfaceType { get; init; } + + public SingletonAttribute() { } + + public SingletonAttribute(Type interfaceType) + { + InterfaceType = interfaceType; + } +} diff --git a/StabilityMatrix.Core/Attributes/TransientAttribute.cs b/StabilityMatrix.Core/Attributes/TransientAttribute.cs new file mode 100644 index 00000000..e3d7e081 --- /dev/null +++ b/StabilityMatrix.Core/Attributes/TransientAttribute.cs @@ -0,0 +1,14 @@ +namespace StabilityMatrix.Core.Attributes; + +[AttributeUsage(AttributeTargets.Class)] +public class TransientAttribute : Attribute +{ + public Type? InterfaceType { get; init; } + + public TransientAttribute() { } + + public TransientAttribute(Type interfaceType) + { + InterfaceType = interfaceType; + } +} diff --git a/StabilityMatrix.Core/Helper/Cache/GithubApiCache.cs b/StabilityMatrix.Core/Helper/Cache/GithubApiCache.cs index 10c498bc..1c2e3e11 100644 --- a/StabilityMatrix.Core/Helper/Cache/GithubApiCache.cs +++ b/StabilityMatrix.Core/Helper/Cache/GithubApiCache.cs @@ -1,9 +1,11 @@ using Octokit; +using StabilityMatrix.Core.Attributes; using StabilityMatrix.Core.Database; using StabilityMatrix.Core.Models.Database; namespace StabilityMatrix.Core.Helper.Cache; +[Singleton(typeof(IGithubApiCache))] public class GithubApiCache : IGithubApiCache { private readonly ILiteDbContext dbContext; @@ -30,7 +32,7 @@ public class GithubApiCache : IGithubApiCache { return null; } - + var cacheEntry = new GithubCacheEntry { CacheKey = cacheKey, @@ -55,7 +57,7 @@ public class GithubApiCache : IGithubApiCache { return new List().OrderByDescending(x => x.CreatedAt); } - + var newCacheEntry = new GithubCacheEntry { CacheKey = cacheKey, @@ -80,18 +82,20 @@ public class GithubApiCache : IGithubApiCache { return new List(); } - - var newCacheEntry = new GithubCacheEntry - { - CacheKey = cacheKey, - Branches = branches - }; + + var newCacheEntry = new GithubCacheEntry { CacheKey = cacheKey, Branches = branches }; await dbContext.UpsertGithubCacheEntry(newCacheEntry); return newCacheEntry.Branches; } - public async Task?> GetAllCommits(string username, string repository, string branch, int page = 1, int perPage = 10) + public async Task?> GetAllCommits( + string username, + string repository, + string branch, + int page = 1, + int perPage = 10 + ) { var cacheKey = $"Commits-{username}-{repository}-{branch}-{page}-{perPage}"; var cacheEntry = await dbContext.GetGithubCacheEntry(cacheKey); @@ -100,18 +104,23 @@ public class GithubApiCache : IGithubApiCache return cacheEntry.Commits; } - var commits = await githubApi.Repository.Commit.GetAll(username, repository, new CommitRequest {Sha = branch}, new ApiOptions - { - PageCount = page, - PageSize = perPage, - StartPage = page - }); - + var commits = await githubApi.Repository.Commit.GetAll( + username, + repository, + new CommitRequest { Sha = branch }, + new ApiOptions + { + PageCount = page, + PageSize = perPage, + StartPage = page + } + ); + if (commits == null) { return new List(); } - + var newCacheEntry = new GithubCacheEntry { CacheKey = cacheKey, @@ -121,6 +130,7 @@ public class GithubApiCache : IGithubApiCache return newCacheEntry.Commits; } - - private bool IsCacheExpired(DateTimeOffset expiration) => expiration.Add(cacheDuration) < DateTimeOffset.UtcNow; + + private bool IsCacheExpired(DateTimeOffset expiration) => + expiration.Add(cacheDuration) < DateTimeOffset.UtcNow; } diff --git a/StabilityMatrix.Core/Helper/Factory/PackageFactory.cs b/StabilityMatrix.Core/Helper/Factory/PackageFactory.cs index ec819e05..7949bed6 100644 --- a/StabilityMatrix.Core/Helper/Factory/PackageFactory.cs +++ b/StabilityMatrix.Core/Helper/Factory/PackageFactory.cs @@ -1,7 +1,9 @@ -using StabilityMatrix.Core.Models.Packages; +using StabilityMatrix.Core.Attributes; +using StabilityMatrix.Core.Models.Packages; namespace StabilityMatrix.Core.Helper.Factory; +[Singleton(typeof(IPackageFactory))] public class PackageFactory : IPackageFactory { /// @@ -13,7 +15,7 @@ public class PackageFactory : IPackageFactory { this.basePackages = basePackages.ToDictionary(x => x.Name); } - + public IEnumerable GetAllAvailablePackages() { return basePackages.Values; @@ -21,8 +23,7 @@ public class PackageFactory : IPackageFactory public BasePackage? FindPackageByName(string? packageName) { - return packageName == null ? null : - basePackages.GetValueOrDefault(packageName); + return packageName == null ? null : basePackages.GetValueOrDefault(packageName); } public BasePackage? this[string packageName] => basePackages[packageName]; diff --git a/StabilityMatrix.Core/Helper/ModelFinder.cs b/StabilityMatrix.Core/Helper/ModelFinder.cs index 36576766..001383c7 100644 --- a/StabilityMatrix.Core/Helper/ModelFinder.cs +++ b/StabilityMatrix.Core/Helper/ModelFinder.cs @@ -1,20 +1,26 @@ using NLog; using Refit; using StabilityMatrix.Core.Api; +using StabilityMatrix.Core.Attributes; using StabilityMatrix.Core.Database; using StabilityMatrix.Core.Models.Api; namespace StabilityMatrix.Core.Helper; // return Model, ModelVersion, ModelFile -public record struct ModelSearchResult(CivitModel Model, CivitModelVersion ModelVersion, CivitFile ModelFile); +public record struct ModelSearchResult( + CivitModel Model, + CivitModelVersion ModelVersion, + CivitFile ModelFile +); +[Singleton] public class ModelFinder { private static readonly Logger Logger = LogManager.GetCurrentClassLogger(); private readonly ILiteDbContext liteDbContext; private readonly ICivitApi civitApi; - + public ModelFinder(ILiteDbContext liteDbContext, ICivitApi civitApi) { this.liteDbContext = liteDbContext; @@ -30,12 +36,13 @@ public class ModelFinder return null; } - var file = version.Files! - .First(file => file.Hashes.BLAKE3?.ToLowerInvariant() == hashBlake3); - + var file = version.Files!.First( + file => file.Hashes.BLAKE3?.ToLowerInvariant() == hashBlake3 + ); + return new ModelSearchResult(model, version, file); } - + // Finds a model using Civit API using file hash public async Task RemoteFindModel(string hashBlake3) { @@ -43,23 +50,30 @@ public class ModelFinder try { var versionResponse = await civitApi.GetModelVersionByHash(hashBlake3); - - Logger.Info("Found version {VersionId} with model id {ModelId}", - versionResponse.Id, versionResponse.ModelId); + + Logger.Info( + "Found version {VersionId} with model id {ModelId}", + versionResponse.Id, + versionResponse.ModelId + ); var model = await civitApi.GetModelById(versionResponse.ModelId); - + // VersionResponse is not actually the full data of ModelVersion, so find it again var version = model.ModelVersions!.First(version => version.Id == versionResponse.Id); - - var file = versionResponse.Files - .First(file => file.Hashes.BLAKE3?.ToLowerInvariant() == hashBlake3); - + + var file = versionResponse.Files.First( + file => file.Hashes.BLAKE3?.ToLowerInvariant() == hashBlake3 + ); + return new ModelSearchResult(model, version, file); } catch (ApiException e) { - Logger.Info("Could not find remote model version using hash {Hash}: {Error}", - hashBlake3, e.Message); + Logger.Info( + "Could not find remote model version using hash {Hash}: {Error}", + hashBlake3, + e.Message + ); return null; } } diff --git a/StabilityMatrix.Core/Helper/SharedFolders.cs b/StabilityMatrix.Core/Helper/SharedFolders.cs index e9406527..2e2f2115 100644 --- a/StabilityMatrix.Core/Helper/SharedFolders.cs +++ b/StabilityMatrix.Core/Helper/SharedFolders.cs @@ -1,4 +1,5 @@ using NLog; +using StabilityMatrix.Core.Attributes; using StabilityMatrix.Core.Extensions; using StabilityMatrix.Core.Helper.Factory; using StabilityMatrix.Core.Models; @@ -9,6 +10,7 @@ using StabilityMatrix.Core.Services; namespace StabilityMatrix.Core.Helper; +[Singleton(typeof(ISharedFolders))] public class SharedFolders : ISharedFolders { private static readonly Logger Logger = LogManager.GetCurrentClassLogger(); diff --git a/StabilityMatrix.Core/Models/Packages/A3WebUI.cs b/StabilityMatrix.Core/Models/Packages/A3WebUI.cs index d6549b42..665d68c6 100644 --- a/StabilityMatrix.Core/Models/Packages/A3WebUI.cs +++ b/StabilityMatrix.Core/Models/Packages/A3WebUI.cs @@ -2,6 +2,7 @@ using System.Text.Json.Nodes; using System.Text.RegularExpressions; using NLog; +using StabilityMatrix.Core.Attributes; using StabilityMatrix.Core.Helper; using StabilityMatrix.Core.Helper.Cache; using StabilityMatrix.Core.Models.FileInterfaces; @@ -12,6 +13,7 @@ using StabilityMatrix.Core.Services; namespace StabilityMatrix.Core.Models.Packages; +[Singleton(typeof(BasePackage))] public class A3WebUI : BaseGitPackage { private static readonly Logger Logger = LogManager.GetCurrentClassLogger(); diff --git a/StabilityMatrix.Core/Models/Packages/ComfyUI.cs b/StabilityMatrix.Core/Models/Packages/ComfyUI.cs index 2072e2b5..2fe22438 100644 --- a/StabilityMatrix.Core/Models/Packages/ComfyUI.cs +++ b/StabilityMatrix.Core/Models/Packages/ComfyUI.cs @@ -1,6 +1,7 @@ using System.Diagnostics; using System.Text.RegularExpressions; using NLog; +using StabilityMatrix.Core.Attributes; using StabilityMatrix.Core.Helper; using StabilityMatrix.Core.Helper.Cache; using StabilityMatrix.Core.Models.FileInterfaces; @@ -14,6 +15,7 @@ using YamlDotNet.Serialization.NamingConventions; namespace StabilityMatrix.Core.Models.Packages; +[Singleton(typeof(BasePackage))] public class ComfyUI : BaseGitPackage { private static readonly Logger Logger = LogManager.GetCurrentClassLogger(); diff --git a/StabilityMatrix.Core/Models/Packages/Fooocus.cs b/StabilityMatrix.Core/Models/Packages/Fooocus.cs index 92d894ed..2319a4c7 100644 --- a/StabilityMatrix.Core/Models/Packages/Fooocus.cs +++ b/StabilityMatrix.Core/Models/Packages/Fooocus.cs @@ -1,5 +1,6 @@ using System.Diagnostics; using System.Text.RegularExpressions; +using StabilityMatrix.Core.Attributes; using StabilityMatrix.Core.Helper; using StabilityMatrix.Core.Helper.Cache; using StabilityMatrix.Core.Models.FileInterfaces; @@ -9,6 +10,7 @@ using StabilityMatrix.Core.Services; namespace StabilityMatrix.Core.Models.Packages; +[Singleton(typeof(BasePackage))] public class Fooocus : BaseGitPackage { public Fooocus( diff --git a/StabilityMatrix.Core/Models/Packages/FooocusMre.cs b/StabilityMatrix.Core/Models/Packages/FooocusMre.cs index 952e3460..62732ffd 100644 --- a/StabilityMatrix.Core/Models/Packages/FooocusMre.cs +++ b/StabilityMatrix.Core/Models/Packages/FooocusMre.cs @@ -1,5 +1,6 @@ using System.Diagnostics; using System.Text.RegularExpressions; +using StabilityMatrix.Core.Attributes; using StabilityMatrix.Core.Helper; using StabilityMatrix.Core.Helper.Cache; using StabilityMatrix.Core.Models.FileInterfaces; @@ -9,6 +10,7 @@ using StabilityMatrix.Core.Services; namespace StabilityMatrix.Core.Models.Packages; +[Singleton(typeof(BasePackage))] public class FooocusMre : BaseGitPackage { public FooocusMre( diff --git a/StabilityMatrix.Core/Models/Packages/InvokeAI.cs b/StabilityMatrix.Core/Models/Packages/InvokeAI.cs index 4d64e26a..ebb4b722 100644 --- a/StabilityMatrix.Core/Models/Packages/InvokeAI.cs +++ b/StabilityMatrix.Core/Models/Packages/InvokeAI.cs @@ -1,6 +1,7 @@ using System.Globalization; using System.Text.RegularExpressions; using NLog; +using StabilityMatrix.Core.Attributes; using StabilityMatrix.Core.Extensions; using StabilityMatrix.Core.Helper; using StabilityMatrix.Core.Helper.Cache; @@ -12,6 +13,7 @@ using StabilityMatrix.Core.Services; namespace StabilityMatrix.Core.Models.Packages; +[Singleton(typeof(BasePackage))] public class InvokeAI : BaseGitPackage { private static readonly Logger Logger = LogManager.GetCurrentClassLogger(); diff --git a/StabilityMatrix.Core/Models/Packages/StableDiffusionDirectMl.cs b/StabilityMatrix.Core/Models/Packages/StableDiffusionDirectMl.cs index 56f1cf6e..eefe5ca7 100644 --- a/StabilityMatrix.Core/Models/Packages/StableDiffusionDirectMl.cs +++ b/StabilityMatrix.Core/Models/Packages/StableDiffusionDirectMl.cs @@ -2,6 +2,7 @@ using System.Text.Json.Nodes; using System.Text.RegularExpressions; using NLog; +using StabilityMatrix.Core.Attributes; using StabilityMatrix.Core.Helper; using StabilityMatrix.Core.Helper.Cache; using StabilityMatrix.Core.Models.FileInterfaces; @@ -12,6 +13,7 @@ using StabilityMatrix.Core.Services; namespace StabilityMatrix.Core.Models.Packages; +[Singleton(typeof(BasePackage))] public class StableDiffusionDirectMl : BaseGitPackage { private static readonly Logger Logger = LogManager.GetCurrentClassLogger(); diff --git a/StabilityMatrix.Core/Models/Packages/StableDiffusionUx.cs b/StabilityMatrix.Core/Models/Packages/StableDiffusionUx.cs index 1cd83385..5eb3461f 100644 --- a/StabilityMatrix.Core/Models/Packages/StableDiffusionUx.cs +++ b/StabilityMatrix.Core/Models/Packages/StableDiffusionUx.cs @@ -2,6 +2,7 @@ using System.Text.Json.Nodes; using System.Text.RegularExpressions; using NLog; +using StabilityMatrix.Core.Attributes; using StabilityMatrix.Core.Helper; using StabilityMatrix.Core.Helper.Cache; using StabilityMatrix.Core.Models.FileInterfaces; @@ -12,6 +13,7 @@ using StabilityMatrix.Core.Services; namespace StabilityMatrix.Core.Models.Packages; +[Singleton(typeof(BasePackage))] public class StableDiffusionUx : BaseGitPackage { private static readonly Logger Logger = LogManager.GetCurrentClassLogger(); diff --git a/StabilityMatrix.Core/Models/Packages/VladAutomatic.cs b/StabilityMatrix.Core/Models/Packages/VladAutomatic.cs index 882bced9..7c4e7e26 100644 --- a/StabilityMatrix.Core/Models/Packages/VladAutomatic.cs +++ b/StabilityMatrix.Core/Models/Packages/VladAutomatic.cs @@ -4,6 +4,7 @@ using System.Text.Json; using System.Text.Json.Nodes; using System.Text.RegularExpressions; using NLog; +using StabilityMatrix.Core.Attributes; using StabilityMatrix.Core.Helper; using StabilityMatrix.Core.Helper.Cache; using StabilityMatrix.Core.Models.FileInterfaces; @@ -14,6 +15,7 @@ using StabilityMatrix.Core.Services; namespace StabilityMatrix.Core.Models.Packages; +[Singleton(typeof(BasePackage))] public class VladAutomatic : BaseGitPackage { private static readonly Logger Logger = LogManager.GetCurrentClassLogger(); diff --git a/StabilityMatrix.Core/Models/Packages/VoltaML.cs b/StabilityMatrix.Core/Models/Packages/VoltaML.cs index e058be90..85c8dfe6 100644 --- a/StabilityMatrix.Core/Models/Packages/VoltaML.cs +++ b/StabilityMatrix.Core/Models/Packages/VoltaML.cs @@ -1,4 +1,5 @@ using System.Text.RegularExpressions; +using StabilityMatrix.Core.Attributes; using StabilityMatrix.Core.Helper; using StabilityMatrix.Core.Helper.Cache; using StabilityMatrix.Core.Models.Progress; @@ -8,6 +9,7 @@ using StabilityMatrix.Core.Services; namespace StabilityMatrix.Core.Models.Packages; +[Singleton(typeof(BasePackage))] public class VoltaML : BaseGitPackage { public override string Name => "voltaML-fast-stable-diffusion"; diff --git a/StabilityMatrix.Core/Models/TrackedDownload.cs b/StabilityMatrix.Core/Models/TrackedDownload.cs index 2411b95c..f8a36bd7 100644 --- a/StabilityMatrix.Core/Models/TrackedDownload.cs +++ b/StabilityMatrix.Core/Models/TrackedDownload.cs @@ -13,39 +13,40 @@ namespace StabilityMatrix.Core.Models; public class TrackedDownload { private static readonly Logger Logger = LogManager.GetCurrentClassLogger(); - + [JsonIgnore] private IDownloadService? downloadService; - + [JsonIgnore] private Task? downloadTask; - + [JsonIgnore] private CancellationTokenSource? downloadCancellationTokenSource; - + [JsonIgnore] private CancellationTokenSource? downloadPauseTokenSource; - + [JsonIgnore] private CancellationTokenSource AggregateCancellationTokenSource => CancellationTokenSource.CreateLinkedTokenSource( downloadCancellationTokenSource?.Token ?? CancellationToken.None, - downloadPauseTokenSource?.Token ?? CancellationToken.None); - + downloadPauseTokenSource?.Token ?? CancellationToken.None + ); + public required Guid Id { get; init; } - + public required Uri SourceUrl { get; init; } - + public Uri? RedirectedUrl { get; init; } - + public required DirectoryPath DownloadDirectory { get; init; } - + public required string FileName { get; init; } - + public required string TempFileName { get; init; } - + public string? ExpectedHashSha256 { get; set; } - + [JsonIgnore] [MemberNotNullWhen(true, nameof(ExpectedHashSha256))] public bool ValidateHash => ExpectedHashSha256 is not null; @@ -54,22 +55,22 @@ public class TrackedDownload public ProgressState ProgressState { get; set; } = ProgressState.Inactive; public List ExtraCleanupFileNames { get; init; } = new(); - + // Used for restoring progress on load public long DownloadedBytes { get; set; } public long TotalBytes { get; set; } - + /// /// Optional context action to be invoked on completion /// public IContextAction? ContextAction { get; set; } - + [JsonIgnore] public Exception? Exception { get; private set; } - + #region Events private WeakEventManager? progressUpdateEventManager; - + public event EventHandler ProgressUpdate { add @@ -79,18 +80,18 @@ public class TrackedDownload } remove => progressUpdateEventManager?.RemoveEventHandler(value); } - + protected void OnProgressUpdate(ProgressReport e) { // Update downloaded and total bytes DownloadedBytes = Convert.ToInt64(e.Current); TotalBytes = Convert.ToInt64(e.Total); - + progressUpdateEventManager?.RaiseEvent(this, e, nameof(ProgressUpdate)); } - + private WeakEventManager? progressStateChangedEventManager; - + public event EventHandler ProgressStateChanged { add @@ -100,13 +101,13 @@ public class TrackedDownload } remove => progressStateChangedEventManager?.RemoveEventHandler(value); } - + protected void OnProgressStateChanged(ProgressState e) { progressStateChangedEventManager?.RaiseEvent(this, e, nameof(ProgressStateChanged)); } #endregion - + [MemberNotNull(nameof(downloadService))] private void EnsureDownloadService() { @@ -119,42 +120,59 @@ public class TrackedDownload private async Task StartDownloadTask(long resumeFromByte, CancellationToken cancellationToken) { var progress = new Progress(OnProgressUpdate); - - await downloadService!.ResumeDownloadToFileAsync( - SourceUrl.ToString(), - DownloadDirectory.JoinFile(TempFileName), - resumeFromByte, - progress, - cancellationToken: cancellationToken).ConfigureAwait(false); - + try + { + await downloadService! + .ResumeDownloadToFileAsync( + SourceUrl.ToString(), + DownloadDirectory.JoinFile(TempFileName), + resumeFromByte, + progress, + cancellationToken: cancellationToken + ) + .ConfigureAwait(false); + } + catch (Exception e) + { + Logger.Warn(e); + } + // If hash validation is enabled, validate the hash if (ValidateHash) { - OnProgressUpdate(new ProgressReport(0, isIndeterminate: true, type: ProgressType.Hashing)); - var hash = await FileHash.GetSha256Async(DownloadDirectory.JoinFile(TempFileName), progress).ConfigureAwait(false); + OnProgressUpdate( + new ProgressReport(0, isIndeterminate: true, type: ProgressType.Hashing) + ); + var hash = await FileHash + .GetSha256Async(DownloadDirectory.JoinFile(TempFileName), progress) + .ConfigureAwait(false); if (hash != ExpectedHashSha256?.ToLowerInvariant()) { - throw new Exception($"Hash validation for {FileName} failed, expected {ExpectedHashSha256} but got {hash}"); + throw new Exception( + $"Hash validation for {FileName} failed, expected {ExpectedHashSha256} but got {hash}" + ); } } } - + public void Start() { if (ProgressState != ProgressState.Inactive) { - throw new InvalidOperationException($"Download state must be inactive to start, not {ProgressState}"); + throw new InvalidOperationException( + $"Download state must be inactive to start, not {ProgressState}" + ); } Logger.Debug("Starting download {Download}", FileName); - + EnsureDownloadService(); - + downloadCancellationTokenSource = new CancellationTokenSource(); downloadPauseTokenSource = new CancellationTokenSource(); - + downloadTask = StartDownloadTask(0, AggregateCancellationTokenSource.Token) .ContinueWith(OnDownloadTaskCompleted); - + ProgressState = ProgressState.Working; OnProgressStateChanged(ProgressState); } @@ -163,27 +181,31 @@ public class TrackedDownload { if (ProgressState != ProgressState.Inactive) { - Logger.Warn("Attempted to resume download {Download} but it is not paused ({State})", FileName, ProgressState); + Logger.Warn( + "Attempted to resume download {Download} but it is not paused ({State})", + FileName, + ProgressState + ); } Logger.Debug("Resuming download {Download}", FileName); - + // Read the temp file to get the current size var tempSize = 0L; - + var tempFile = DownloadDirectory.JoinFile(TempFileName); if (tempFile.Exists) { tempSize = tempFile.Info.Length; } - + EnsureDownloadService(); - + downloadCancellationTokenSource = new CancellationTokenSource(); downloadPauseTokenSource = new CancellationTokenSource(); - + downloadTask = StartDownloadTask(tempSize, AggregateCancellationTokenSource.Token) .ContinueWith(OnDownloadTaskCompleted); - + ProgressState = ProgressState.Working; OnProgressStateChanged(ProgressState); } @@ -192,22 +214,30 @@ public class TrackedDownload { if (ProgressState != ProgressState.Working) { - Logger.Warn("Attempted to pause download {Download} but it is not in progress ({State})", FileName, ProgressState); + Logger.Warn( + "Attempted to pause download {Download} but it is not in progress ({State})", + FileName, + ProgressState + ); return; } - + Logger.Debug("Pausing download {Download}", FileName); downloadPauseTokenSource?.Cancel(); } - + public void Cancel() { if (ProgressState is not (ProgressState.Working or ProgressState.Inactive)) { - Logger.Warn("Attempted to cancel download {Download} but it is not in progress ({State})", FileName, ProgressState); + Logger.Warn( + "Attempted to cancel download {Download} but it is not in progress ({State})", + FileName, + ProgressState + ); return; } - + Logger.Debug("Cancelling download {Download}", FileName); // Cancel token if it exists @@ -219,7 +249,7 @@ public class TrackedDownload else { DoCleanup(); - + ProgressState = ProgressState.Cancelled; OnProgressStateChanged(ProgressState); } @@ -238,7 +268,7 @@ public class TrackedDownload { Logger.Warn("Failed to delete temp file {TempFile}", TempFileName); } - + foreach (var extraFile in ExtraCleanupFileNames) { try @@ -251,7 +281,7 @@ public class TrackedDownload } } } - + /// /// Invoked by the task's completion callback /// @@ -272,7 +302,9 @@ public class TrackedDownload } else { - throw new InvalidOperationException("Download task was cancelled but neither cancellation token was cancelled."); + throw new InvalidOperationException( + "Download task was cancelled but neither cancellation token was cancelled." + ); } } // For faulted @@ -293,23 +325,23 @@ public class TrackedDownload if (ProgressState is ProgressState.Failed or ProgressState.Cancelled) { DoCleanup(); - } + } else if (ProgressState == ProgressState.Success) { // Move the temp file to the final file DownloadDirectory.JoinFile(TempFileName).MoveTo(DownloadDirectory.JoinFile(FileName)); } - + // For pause, just do nothing - + OnProgressStateChanged(ProgressState); - + // Dispose of the task and cancellation token downloadTask = null; downloadCancellationTokenSource = null; downloadPauseTokenSource = null; } - + public void SetDownloadService(IDownloadService service) { downloadService = service; diff --git a/StabilityMatrix.Core/Python/PyRunner.cs b/StabilityMatrix.Core/Python/PyRunner.cs index e3e3dac0..ea7268d6 100644 --- a/StabilityMatrix.Core/Python/PyRunner.cs +++ b/StabilityMatrix.Core/Python/PyRunner.cs @@ -1,6 +1,7 @@ using System.Diagnostics.CodeAnalysis; using NLog; using Python.Runtime; +using StabilityMatrix.Core.Attributes; using StabilityMatrix.Core.Extensions; using StabilityMatrix.Core.Helper; using StabilityMatrix.Core.Models; @@ -11,42 +12,57 @@ using StabilityMatrix.Core.Python.Interop; namespace StabilityMatrix.Core.Python; [SuppressMessage("ReSharper", "NotAccessedPositionalProperty.Global")] -public record struct PyVersionInfo(int Major, int Minor, int Micro, string ReleaseLevel, int Serial); +public record struct PyVersionInfo( + int Major, + int Minor, + int Micro, + string ReleaseLevel, + int Serial +); [SuppressMessage("ReSharper", "MemberCanBePrivate.Global")] +[Singleton(typeof(IPyRunner))] public class PyRunner : IPyRunner { private static readonly Logger Logger = LogManager.GetCurrentClassLogger(); - + // Set by ISettingsManager.TryFindLibrary() public static DirectoryPath HomeDir { get; set; } = string.Empty; - + // This is same for all platforms public const string PythonDirName = "Python310"; - - public static string PythonDir => Path.Combine(GlobalConfig.LibraryDir, "Assets", PythonDirName); + + public static string PythonDir => + Path.Combine(GlobalConfig.LibraryDir, "Assets", PythonDirName); /// /// Path to the Python Linked library relative from the Python directory. /// - public static string RelativePythonDllPath => Compat.Switch( - (PlatformKind.Windows, "python310.dll"), - (PlatformKind.Linux, Path.Combine("lib", "libpython3.10.so")), - (PlatformKind.MacOS, Path.Combine("lib", "libpython3.10.dylib"))); + public static string RelativePythonDllPath => + Compat.Switch( + (PlatformKind.Windows, "python310.dll"), + (PlatformKind.Linux, Path.Combine("lib", "libpython3.10.so")), + (PlatformKind.MacOS, Path.Combine("lib", "libpython3.10.dylib")) + ); public static string PythonDllPath => Path.Combine(PythonDir, RelativePythonDllPath); - public static string PythonExePath => Compat.Switch( - (PlatformKind.Windows, Path.Combine(PythonDir, "python.exe")), - (PlatformKind.Linux, Path.Combine(PythonDir, "bin", "python3")), - (PlatformKind.MacOS, Path.Combine(PythonDir, "bin", "python3"))); - public static string PipExePath => Compat.Switch( - (PlatformKind.Windows, Path.Combine(PythonDir, "Scripts", "pip.exe")), - (PlatformKind.Linux, Path.Combine(PythonDir, "bin", "pip3")), - (PlatformKind.MacOS, Path.Combine(PythonDir, "bin", "pip3"))); - + public static string PythonExePath => + Compat.Switch( + (PlatformKind.Windows, Path.Combine(PythonDir, "python.exe")), + (PlatformKind.Linux, Path.Combine(PythonDir, "bin", "python3")), + (PlatformKind.MacOS, Path.Combine(PythonDir, "bin", "python3")) + ); + public static string PipExePath => + Compat.Switch( + (PlatformKind.Windows, Path.Combine(PythonDir, "Scripts", "pip.exe")), + (PlatformKind.Linux, Path.Combine(PythonDir, "bin", "pip3")), + (PlatformKind.MacOS, Path.Combine(PythonDir, "bin", "pip3")) + ); + public static string GetPipPath => Path.Combine(PythonDir, "get-pip.pyc"); - public static string VenvPath => Path.Combine(PythonDir, "Scripts", "virtualenv" + Compat.ExeExtension); + public static string VenvPath => + Path.Combine(PythonDir, "Scripts", "virtualenv" + Compat.ExeExtension); public static bool PipInstalled => File.Exists(PipExePath); public static bool VenvInstalled => File.Exists(VenvPath); @@ -55,7 +71,7 @@ public class PyRunner : IPyRunner public PyIOStream? StdOutStream; public PyIOStream? StdErrStream; - + /// $ /// Initializes the Python runtime using the embedded dll. /// Can be called with no effect after initialization. @@ -63,10 +79,11 @@ public class PyRunner : IPyRunner /// Thrown if Python DLL not found. public async Task Initialize() { - if (PythonEngine.IsInitialized) return; - + if (PythonEngine.IsInitialized) + return; + Logger.Info("Setting PYTHONHOME={PythonDir}", PythonDir.ToRepr()); - + // Append Python path to PATH var newEnvPath = Compat.GetEnvPathWithExtensions(PythonDir); Logger.Debug("Setting PATH={NewEnvPath}", newEnvPath.ToRepr()); @@ -78,7 +95,7 @@ public class PyRunner : IPyRunner { throw new FileNotFoundException("Python linked library not found", PythonDllPath); } - + Runtime.PythonDLL = PythonDllPath; PythonEngine.PythonHome = PythonDir; PythonEngine.Initialize(); @@ -88,12 +105,14 @@ public class PyRunner : IPyRunner StdOutStream = new PyIOStream(); StdErrStream = new PyIOStream(); await RunInThreadWithLock(() => - { - var sys = Py.Import("sys") as PyModule ?? - throw new NullReferenceException("sys module not found"); - sys.Set("stdout", StdOutStream); - sys.Set("stderr", StdErrStream); - }).ConfigureAwait(false); + { + var sys = + Py.Import("sys") as PyModule + ?? throw new NullReferenceException("sys module not found"); + sys.Set("stdout", StdOutStream); + sys.Set("stderr", StdErrStream); + }) + .ConfigureAwait(false); } /// @@ -129,19 +148,26 @@ public class PyRunner : IPyRunner /// Time limit for waiting on PyRunning lock. /// Cancellation token. /// cancelToken was canceled, or waitTimeout expired. - public async Task RunInThreadWithLock(Func func, TimeSpan? waitTimeout = null, CancellationToken cancelToken = default) + public async Task RunInThreadWithLock( + Func func, + TimeSpan? waitTimeout = null, + CancellationToken cancelToken = default + ) { // Wait to acquire PyRunning lock await PyRunning.WaitAsync(cancelToken).ConfigureAwait(false); try { - return await Task.Run(() => - { - using (Py.GIL()) + return await Task.Run( + () => { - return func(); - } - }, cancelToken); + using (Py.GIL()) + { + return func(); + } + }, + cancelToken + ); } finally { @@ -156,19 +182,26 @@ public class PyRunner : IPyRunner /// Time limit for waiting on PyRunning lock. /// Cancellation token. /// cancelToken was canceled, or waitTimeout expired. - public async Task RunInThreadWithLock(Action action, TimeSpan? waitTimeout = null, CancellationToken cancelToken = default) + public async Task RunInThreadWithLock( + Action action, + TimeSpan? waitTimeout = null, + CancellationToken cancelToken = default + ) { // Wait to acquire PyRunning lock await PyRunning.WaitAsync(cancelToken).ConfigureAwait(false); try { - await Task.Run(() => - { - using (Py.GIL()) + await Task.Run( + () => { - action(); - } - }, cancelToken); + using (Py.GIL()) + { + action(); + } + }, + cancelToken + ); } finally { diff --git a/StabilityMatrix.Core/Services/DownloadService.cs b/StabilityMatrix.Core/Services/DownloadService.cs index 7e0be15a..91dbb573 100644 --- a/StabilityMatrix.Core/Services/DownloadService.cs +++ b/StabilityMatrix.Core/Services/DownloadService.cs @@ -1,10 +1,12 @@ using System.Net.Http.Headers; using Microsoft.Extensions.Logging; using Polly.Contrib.WaitAndRetry; +using StabilityMatrix.Core.Attributes; using StabilityMatrix.Core.Models.Progress; namespace StabilityMatrix.Core.Services; +[Singleton(typeof(IDownloadService))] public class DownloadService : IDownloadService { private readonly ILogger logger; diff --git a/StabilityMatrix.Core/Services/ImageIndexService.cs b/StabilityMatrix.Core/Services/ImageIndexService.cs index a8d734a4..2e917e63 100644 --- a/StabilityMatrix.Core/Services/ImageIndexService.cs +++ b/StabilityMatrix.Core/Services/ImageIndexService.cs @@ -3,6 +3,7 @@ using System.Diagnostics; using AsyncAwaitBestPractices; using DynamicData; using Microsoft.Extensions.Logging; +using StabilityMatrix.Core.Attributes; using StabilityMatrix.Core.Helper; using StabilityMatrix.Core.Models; using StabilityMatrix.Core.Models.Database; @@ -10,6 +11,7 @@ using StabilityMatrix.Core.Models.FileInterfaces; namespace StabilityMatrix.Core.Services; +[Singleton(typeof(IImageIndexService))] public class ImageIndexService : IImageIndexService { private readonly ILogger logger; diff --git a/StabilityMatrix.Core/Services/ModelIndexService.cs b/StabilityMatrix.Core/Services/ModelIndexService.cs index a70dff68..dec7eeb9 100644 --- a/StabilityMatrix.Core/Services/ModelIndexService.cs +++ b/StabilityMatrix.Core/Services/ModelIndexService.cs @@ -1,6 +1,7 @@ using System.Diagnostics; using AsyncAwaitBestPractices; using Microsoft.Extensions.Logging; +using StabilityMatrix.Core.Attributes; using StabilityMatrix.Core.Database; using StabilityMatrix.Core.Extensions; using StabilityMatrix.Core.Helper; @@ -10,6 +11,7 @@ using StabilityMatrix.Core.Models.FileInterfaces; namespace StabilityMatrix.Core.Services; +[Singleton(typeof(IModelIndexService))] public class ModelIndexService : IModelIndexService { private readonly ILogger logger; diff --git a/StabilityMatrix.Core/Services/SettingsManager.cs b/StabilityMatrix.Core/Services/SettingsManager.cs index 30695720..c2d30524 100644 --- a/StabilityMatrix.Core/Services/SettingsManager.cs +++ b/StabilityMatrix.Core/Services/SettingsManager.cs @@ -7,6 +7,7 @@ using System.Text.Json.Serialization; using AsyncAwaitBestPractices; using NLog; using Refit; +using StabilityMatrix.Core.Attributes; using StabilityMatrix.Core.Helper; using StabilityMatrix.Core.Models; using StabilityMatrix.Core.Models.FileInterfaces; @@ -15,6 +16,7 @@ using StabilityMatrix.Core.Python; namespace StabilityMatrix.Core.Services; +[Singleton(typeof(ISettingsManager))] public class SettingsManager : ISettingsManager { private static readonly Logger Logger = LogManager.GetCurrentClassLogger(); diff --git a/StabilityMatrix.Core/StabilityMatrix.Core.csproj b/StabilityMatrix.Core/StabilityMatrix.Core.csproj index 1f95863e..1a78f975 100644 --- a/StabilityMatrix.Core/StabilityMatrix.Core.csproj +++ b/StabilityMatrix.Core/StabilityMatrix.Core.csproj @@ -15,34 +15,34 @@ - + - + - - - - - + + + + + - - + + - + - + - - - - + + + + diff --git a/StabilityMatrix.Core/Updater/UpdateHelper.cs b/StabilityMatrix.Core/Updater/UpdateHelper.cs index 401736c1..325af086 100644 --- a/StabilityMatrix.Core/Updater/UpdateHelper.cs +++ b/StabilityMatrix.Core/Updater/UpdateHelper.cs @@ -2,6 +2,7 @@ using System.Text.Json; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; +using StabilityMatrix.Core.Attributes; using StabilityMatrix.Core.Extensions; using StabilityMatrix.Core.Helper; using StabilityMatrix.Core.Models.Configs; @@ -12,6 +13,7 @@ using StabilityMatrix.Core.Services; namespace StabilityMatrix.Core.Updater; +[Singleton(typeof(IUpdateHelper))] public class UpdateHelper : IUpdateHelper { private readonly ILogger logger; diff --git a/StabilityMatrix.Tests/StabilityMatrix.Tests.csproj b/StabilityMatrix.Tests/StabilityMatrix.Tests.csproj index e82a92a8..f604bbea 100644 --- a/StabilityMatrix.Tests/StabilityMatrix.Tests.csproj +++ b/StabilityMatrix.Tests/StabilityMatrix.Tests.csproj @@ -11,18 +11,18 @@ - + - + - + all runtime; build; native; contentfiles; analyzers; buildtransitive - + From 465d74d569afebc8fab597b47df704c489e5202f Mon Sep 17 00:00:00 2001 From: JT Date: Sat, 21 Oct 2023 19:58:08 -0700 Subject: [PATCH 2/2] fix update check timer --- .../ViewModels/Dialogs/ExceptionViewModel.cs | 4 +- .../ViewModels/FirstLaunchSetupViewModel.cs | 25 ++-- .../Inference/StackCardViewModel.cs | 19 +-- .../Inference/StackExpanderViewModel.cs | 30 ++-- .../ViewModels/NewCheckpointsPageViewModel.cs | 128 ++++++++++++------ .../ViewModels/OutputsPageViewModel.cs | 2 +- .../ViewModels/PackageManagerViewModel.cs | 20 +-- .../ViewModels/RefreshBadgeViewModel.cs | 58 ++++---- 8 files changed, 170 insertions(+), 116 deletions(-) diff --git a/StabilityMatrix.Avalonia/ViewModels/Dialogs/ExceptionViewModel.cs b/StabilityMatrix.Avalonia/ViewModels/Dialogs/ExceptionViewModel.cs index f5c390d5..42e8a6d6 100644 --- a/StabilityMatrix.Avalonia/ViewModels/Dialogs/ExceptionViewModel.cs +++ b/StabilityMatrix.Avalonia/ViewModels/Dialogs/ExceptionViewModel.cs @@ -11,8 +11,8 @@ namespace StabilityMatrix.Avalonia.ViewModels.Dialogs; public partial class ExceptionViewModel : ViewModelBase { public Exception? Exception { get; set; } - + public string? Message => Exception?.Message; - + public string? ExceptionType => Exception?.GetType().Name ?? ""; } diff --git a/StabilityMatrix.Avalonia/ViewModels/FirstLaunchSetupViewModel.cs b/StabilityMatrix.Avalonia/ViewModels/FirstLaunchSetupViewModel.cs index 0ddc9f9c..54463c21 100644 --- a/StabilityMatrix.Avalonia/ViewModels/FirstLaunchSetupViewModel.cs +++ b/StabilityMatrix.Avalonia/ViewModels/FirstLaunchSetupViewModel.cs @@ -22,14 +22,17 @@ public partial class FirstLaunchSetupViewModel : ViewModelBase private string gpuInfoText = string.Empty; [ObservableProperty] - private RefreshBadgeViewModel checkHardwareBadge = new() - { - WorkingToolTipText = "We're checking some hardware specifications to determine compatibility.", - SuccessToolTipText = "Everything looks good!", - FailToolTipText = "We recommend a GPU with CUDA support for the best experience. " + - "You can continue without one, but some packages may not work, and inference may be slower.", - FailColorBrush = ThemeColors.ThemeYellow, - }; + private RefreshBadgeViewModel checkHardwareBadge = + new() + { + WorkingToolTipText = + "We're checking some hardware specifications to determine compatibility.", + SuccessToolTipText = "Everything looks good!", + FailToolTipText = + "We recommend a GPU with CUDA support for the best experience. " + + "You can continue without one, but some packages may not work, and inference may be slower.", + FailColorBrush = ThemeColors.ThemeYellow, + }; public FirstLaunchSetupViewModel() { @@ -45,14 +48,16 @@ public partial class FirstLaunchSetupViewModel : ViewModelBase gpuInfo = await Task.Run(() => HardwareHelper.IterGpuInfo().ToArray()); } // First Nvidia GPU - var activeGpu = gpuInfo.FirstOrDefault(gpu => gpu.Name?.ToLowerInvariant().Contains("nvidia") ?? false); + var activeGpu = gpuInfo.FirstOrDefault( + gpu => gpu.Name?.ToLowerInvariant().Contains("nvidia") ?? false + ); var isNvidia = activeGpu is not null; // Otherwise first GPU activeGpu ??= gpuInfo.FirstOrDefault(); GpuInfoText = activeGpu is null ? "No GPU detected" : $"{activeGpu.Name} ({Size.FormatBytes(activeGpu.MemoryBytes)})"; - + return isNvidia; } diff --git a/StabilityMatrix.Avalonia/ViewModels/Inference/StackCardViewModel.cs b/StabilityMatrix.Avalonia/ViewModels/Inference/StackCardViewModel.cs index a037a30c..49e7b810 100644 --- a/StabilityMatrix.Avalonia/ViewModels/Inference/StackCardViewModel.cs +++ b/StabilityMatrix.Avalonia/ViewModels/Inference/StackCardViewModel.cs @@ -16,14 +16,16 @@ public class StackCardViewModel : StackViewModelBase public override void LoadStateFromJsonObject(JsonObject state) { var model = DeserializeModel(state); - - if (model.Cards is null) return; - + + if (model.Cards is null) + return; + foreach (var (i, card) in model.Cards.Enumerate()) { // Ignore if more than cards than we have - if (i > Cards.Count - 1) break; - + if (i > Cards.Count - 1) + break; + Cards[i].LoadStateFromJsonObject(card); } } @@ -31,9 +33,8 @@ public class StackCardViewModel : StackViewModelBase /// public override JsonObject SaveStateToJsonObject() { - return SerializeModel(new StackCardModel - { - Cards = Cards.Select(x => x.SaveStateToJsonObject()).ToList() - }); + return SerializeModel( + new StackCardModel { Cards = Cards.Select(x => x.SaveStateToJsonObject()).ToList() } + ); } } diff --git a/StabilityMatrix.Avalonia/ViewModels/Inference/StackExpanderViewModel.cs b/StabilityMatrix.Avalonia/ViewModels/Inference/StackExpanderViewModel.cs index 29fe9750..9eef7ad6 100644 --- a/StabilityMatrix.Avalonia/ViewModels/Inference/StackExpanderViewModel.cs +++ b/StabilityMatrix.Avalonia/ViewModels/Inference/StackExpanderViewModel.cs @@ -18,23 +18,25 @@ public partial class StackExpanderViewModel : StackViewModelBase [ObservableProperty] [property: JsonIgnore] private string? title; - - [ObservableProperty] + + [ObservableProperty] private bool isEnabled; - + /// public override void LoadStateFromJsonObject(JsonObject state) { var model = DeserializeModel(state); IsEnabled = model.IsEnabled; - - if (model.Cards is null) return; - + + if (model.Cards is null) + return; + foreach (var (i, card) in model.Cards.Enumerate()) { // Ignore if more than cards than we have - if (i > Cards.Count - 1) break; - + if (i > Cards.Count - 1) + break; + Cards[i].LoadStateFromJsonObject(card); } } @@ -42,10 +44,12 @@ public partial class StackExpanderViewModel : StackViewModelBase /// public override JsonObject SaveStateToJsonObject() { - return SerializeModel(new StackExpanderModel - { - IsEnabled = IsEnabled, - Cards = Cards.Select(x => x.SaveStateToJsonObject()).ToList() - }); + return SerializeModel( + new StackExpanderModel + { + IsEnabled = IsEnabled, + Cards = Cards.Select(x => x.SaveStateToJsonObject()).ToList() + } + ); } } diff --git a/StabilityMatrix.Avalonia/ViewModels/NewCheckpointsPageViewModel.cs b/StabilityMatrix.Avalonia/ViewModels/NewCheckpointsPageViewModel.cs index 283494f7..87ebb0f5 100644 --- a/StabilityMatrix.Avalonia/ViewModels/NewCheckpointsPageViewModel.cs +++ b/StabilityMatrix.Avalonia/ViewModels/NewCheckpointsPageViewModel.cs @@ -43,12 +43,17 @@ public partial class NewCheckpointsPageViewModel : PageViewModelBase private readonly ServiceManager dialogFactory; private readonly INotificationService notificationService; public override string Title => "Checkpoint Manager"; - public override IconSource IconSource => new SymbolIconSource - {Symbol = Symbol.Cellular5g, IsFilled = true}; + public override IconSource IconSource => + new SymbolIconSource { Symbol = Symbol.Cellular5g, IsFilled = true }; - public NewCheckpointsPageViewModel(ILogger logger, - ISettingsManager settingsManager, ILiteDbContext liteDbContext, ICivitApi civitApi, - ServiceManager dialogFactory, INotificationService notificationService) + public NewCheckpointsPageViewModel( + ILogger logger, + ISettingsManager settingsManager, + ILiteDbContext liteDbContext, + ICivitApi civitApi, + ServiceManager dialogFactory, + INotificationService notificationService + ) { this.logger = logger; this.settingsManager = settingsManager; @@ -62,23 +67,27 @@ public partial class NewCheckpointsPageViewModel : PageViewModelBase [NotifyPropertyChangedFor(nameof(ConnectedCheckpoints))] [NotifyPropertyChangedFor(nameof(NonConnectedCheckpoints))] private ObservableCollection allCheckpoints = new(); - + [ObservableProperty] private ObservableCollection civitModels = new(); - public ObservableCollection ConnectedCheckpoints => new( - AllCheckpoints.Where(x => x.IsConnectedModel) - .OrderBy(x => x.ConnectedModel!.ModelName) - .ThenBy(x => x.ModelType) - .GroupBy(x => x.ConnectedModel!.ModelId) - .Select(x => x.First())); + public ObservableCollection ConnectedCheckpoints => + new( + AllCheckpoints + .Where(x => x.IsConnectedModel) + .OrderBy(x => x.ConnectedModel!.ModelName) + .ThenBy(x => x.ModelType) + .GroupBy(x => x.ConnectedModel!.ModelId) + .Select(x => x.First()) + ); - public ObservableCollection NonConnectedCheckpoints => new( - AllCheckpoints.Where(x => !x.IsConnectedModel).OrderBy(x => x.ModelType)); + public ObservableCollection NonConnectedCheckpoints => + new(AllCheckpoints.Where(x => !x.IsConnectedModel).OrderBy(x => x.ModelType)); public override async Task OnLoadedAsync() { - if (Design.IsDesignMode) return; + if (Design.IsDesignMode) + return; var files = CheckpointFile.GetAllCheckpointFiles(settingsManager.ModelsDirectory); AllCheckpoints = new ObservableCollection(files); @@ -88,17 +97,17 @@ public partial class NewCheckpointsPageViewModel : PageViewModelBase { CommaSeparatedModelIds = string.Join(',', connectedModelIds) }; - + // See if query is cached var cachedQuery = await liteDbContext.CivitModelQueryCache .IncludeAll() .FindByIdAsync(ObjectHash.GetMd5Guid(modelRequest)); - + // If cached, update model cards if (cachedQuery is not null) { CivitModels = new ObservableCollection(cachedQuery.Items); - + // Start remote query (background mode) // Skip when last query was less than 2 min ago var timeSinceCache = DateTimeOffset.UtcNow - cachedQuery.InsertedAt; @@ -112,24 +121,34 @@ public partial class NewCheckpointsPageViewModel : PageViewModelBase await CivitQuery(modelRequest); } } - + public async Task ShowVersionDialog(int modelId) { var model = CivitModels.FirstOrDefault(m => m.Id == modelId); if (model == null) { - notificationService.Show(new Notification("Model has no versions available", - "This model has no versions available for download", NotificationType.Warning)); + notificationService.Show( + new Notification( + "Model has no versions available", + "This model has no versions available for download", + NotificationType.Warning + ) + ); return; } var versions = model.ModelVersions; if (versions is null || versions.Count == 0) { - notificationService.Show(new Notification("Model has no versions available", - "This model has no versions available for download", NotificationType.Warning)); + notificationService.Show( + new Notification( + "Model has no versions available", + "This model has no versions available for download", + NotificationType.Warning + ) + ); return; } - + var dialog = new BetterContentDialog { Title = model.Name, @@ -138,19 +157,21 @@ public partial class NewCheckpointsPageViewModel : PageViewModelBase IsFooterVisible = false, MaxDialogWidth = 750, }; - + var viewModel = dialogFactory.Get(); viewModel.Dialog = dialog; - viewModel.Versions = versions.Select(version => - new ModelVersionViewModel( - settingsManager.Settings.InstalledModelHashes ?? new HashSet(), version)) + viewModel.Versions = versions + .Select( + version => + new ModelVersionViewModel( + settingsManager.Settings.InstalledModelHashes ?? new HashSet(), + version + ) + ) .ToImmutableArray(); viewModel.SelectedVersionViewModel = viewModel.Versions[0]; - - dialog.Content = new SelectModelVersionDialog - { - DataContext = viewModel - }; + + dialog.Content = new SelectModelVersionDialog { DataContext = viewModel }; var result = await dialog.ShowAsync(); @@ -170,8 +191,10 @@ public partial class NewCheckpointsPageViewModel : PageViewModelBase var modelResponse = await civitApi.GetModels(request); var models = modelResponse.Items; // Filter out unknown model types and archived/taken-down models - models = models.Where(m => m.Type.ConvertTo() > 0) - .Where(m => m.Mode == null).ToList(); + models = models + .Where(m => m.Type.ConvertTo() > 0) + .Where(m => m.Mode == null) + .ToList(); // Database update calls will invoke `OnModelsUpdated` // Add to database @@ -185,7 +208,8 @@ public partial class NewCheckpointsPageViewModel : PageViewModelBase Request = request, Items = models, Metadata = modelResponse.Metadata - }); + } + ); if (cacheNew) { @@ -194,26 +218,42 @@ public partial class NewCheckpointsPageViewModel : PageViewModelBase } catch (OperationCanceledException) { - notificationService.Show(new Notification("Request to CivitAI timed out", - "Could not check for checkpoint updates. Please try again later.")); + notificationService.Show( + new Notification( + "Request to CivitAI timed out", + "Could not check for checkpoint updates. Please try again later." + ) + ); logger.LogWarning($"CivitAI query timed out ({request})"); } catch (HttpRequestException e) { - notificationService.Show(new Notification("CivitAI can't be reached right now", - "Could not check for checkpoint updates. Please try again later.")); + notificationService.Show( + new Notification( + "CivitAI can't be reached right now", + "Could not check for checkpoint updates. Please try again later." + ) + ); logger.LogWarning(e, $"CivitAI query HttpRequestException ({request})"); } catch (ApiException e) { - notificationService.Show(new Notification("CivitAI can't be reached right now", - "Could not check for checkpoint updates. Please try again later.")); + notificationService.Show( + new Notification( + "CivitAI can't be reached right now", + "Could not check for checkpoint updates. Please try again later." + ) + ); logger.LogWarning(e, $"CivitAI query ApiException ({request})"); } catch (Exception e) { - notificationService.Show(new Notification("CivitAI can't be reached right now", - $"Unknown exception during CivitAI query: {e.GetType().Name}")); + notificationService.Show( + new Notification( + "CivitAI can't be reached right now", + $"Unknown exception during CivitAI query: {e.GetType().Name}" + ) + ); logger.LogError(e, $"CivitAI query unknown exception ({request})"); } } diff --git a/StabilityMatrix.Avalonia/ViewModels/OutputsPageViewModel.cs b/StabilityMatrix.Avalonia/ViewModels/OutputsPageViewModel.cs index 9bc6b447..3429bb59 100644 --- a/StabilityMatrix.Avalonia/ViewModels/OutputsPageViewModel.cs +++ b/StabilityMatrix.Avalonia/ViewModels/OutputsPageViewModel.cs @@ -141,7 +141,7 @@ public partial class OutputsPageViewModel : PageViewModelBase if (!settingsManager.IsLibraryDirSet) return; - + Directory.CreateDirectory(settingsManager.ImagesDirectory); var packageCategories = settingsManager.Settings.InstalledPackages .Where(x => !x.UseSharedOutputFolder) diff --git a/StabilityMatrix.Avalonia/ViewModels/PackageManagerViewModel.cs b/StabilityMatrix.Avalonia/ViewModels/PackageManagerViewModel.cs index 1ef6a3c4..5578a5f7 100644 --- a/StabilityMatrix.Avalonia/ViewModels/PackageManagerViewModel.cs +++ b/StabilityMatrix.Avalonia/ViewModels/PackageManagerViewModel.cs @@ -65,14 +65,14 @@ public partial class PackageManagerViewModel : PageViewModelBase public IObservableCollection PackageCards { get; } = new ObservableCollectionExtended(); - private DispatcherTimer timer; public PackageManagerViewModel( ISettingsManager settingsManager, ServiceManager dialogFactory, INotificationService notificationService, - ILogger logger) + ILogger logger + ) { this.settingsManager = settingsManager; this.dialogFactory = dialogFactory; @@ -99,11 +99,7 @@ public partial class PackageManagerViewModel : PageViewModelBase .Bind(PackageCards) .Subscribe(); - timer = new DispatcherTimer - { - Interval = TimeSpan.FromSeconds(5), - IsEnabled = true - }; + timer = new DispatcherTimer { Interval = TimeSpan.FromMinutes(15), IsEnabled = true }; timer.Tick += async (_, _) => await CheckPackagesForUpdates(); } @@ -129,7 +125,7 @@ public partial class PackageManagerViewModel : PageViewModelBase var currentUnknown = await Task.Run(IndexUnknownPackages); unknownInstalledPackages.Edit(s => s.Load(currentUnknown)); - + timer.Start(); } @@ -186,9 +182,13 @@ public partial class PackageManagerViewModel : PageViewModelBase { await package.OnLoadedAsync(); } - catch + catch (Exception e) { - logger.LogWarning("Failed to check for updates for {Package}", package?.Package?.PackageName); + logger.LogError( + e, + "Failed to check for updates for {Package}", + package?.Package?.PackageName + ); } } } diff --git a/StabilityMatrix.Avalonia/ViewModels/RefreshBadgeViewModel.cs b/StabilityMatrix.Avalonia/ViewModels/RefreshBadgeViewModel.cs index 2cac7d48..b624f1e6 100644 --- a/StabilityMatrix.Avalonia/ViewModels/RefreshBadgeViewModel.cs +++ b/StabilityMatrix.Avalonia/ViewModels/RefreshBadgeViewModel.cs @@ -21,7 +21,7 @@ namespace StabilityMatrix.Avalonia.ViewModels; public partial class RefreshBadgeViewModel : ViewModelBase { private static readonly Logger Logger = LogManager.GetCurrentClassLogger(); - + public string WorkingToolTipText { get; set; } = "Loading..."; public string SuccessToolTipText { get; set; } = "Success"; public string InactiveToolTipText { get; set; } = ""; @@ -34,7 +34,7 @@ public partial class RefreshBadgeViewModel : ViewModelBase public IBrush SuccessColorBrush { get; set; } = ThemeColors.ThemeGreen; public IBrush InactiveColorBrush { get; set; } = ThemeColors.ThemeYellow; public IBrush FailColorBrush { get; set; } = ThemeColors.ThemeYellow; - + public Func>? RefreshFunc { get; set; } [ObservableProperty] @@ -43,7 +43,7 @@ public partial class RefreshBadgeViewModel : ViewModelBase [NotifyPropertyChangedFor(nameof(CurrentToolTip))] [NotifyPropertyChangedFor(nameof(Icon))] private ProgressState state; - + public bool IsWorking => State == ProgressState.Working; /*public ControlAppearance Appearance => State switch @@ -53,36 +53,40 @@ public partial class RefreshBadgeViewModel : ViewModelBase ProgressState.Failed => ControlAppearance.Danger, _ => ControlAppearance.Secondary };*/ - - public IBrush ColorBrush => State switch - { - ProgressState.Success => SuccessColorBrush, - ProgressState.Inactive => InactiveColorBrush, - ProgressState.Failed => FailColorBrush, - _ => Brushes.Gray - }; - public string CurrentToolTip => State switch - { - ProgressState.Working => WorkingToolTipText, - ProgressState.Success => SuccessToolTipText, - ProgressState.Inactive => InactiveToolTipText, - ProgressState.Failed => FailToolTipText, - _ => "" - }; - - public Symbol Icon => State switch - { - ProgressState.Success => SuccessIcon, - ProgressState.Failed => FailIcon, - _ => InactiveIcon - }; + public IBrush ColorBrush => + State switch + { + ProgressState.Success => SuccessColorBrush, + ProgressState.Inactive => InactiveColorBrush, + ProgressState.Failed => FailColorBrush, + _ => Brushes.Gray + }; + + public string CurrentToolTip => + State switch + { + ProgressState.Working => WorkingToolTipText, + ProgressState.Success => SuccessToolTipText, + ProgressState.Inactive => InactiveToolTipText, + ProgressState.Failed => FailToolTipText, + _ => "" + }; + + public Symbol Icon => + State switch + { + ProgressState.Success => SuccessIcon, + ProgressState.Failed => FailIcon, + _ => InactiveIcon + }; [RelayCommand] private async Task Refresh() { Logger.Info("Running refresh command..."); - if (RefreshFunc == null) return; + if (RefreshFunc == null) + return; State = ProgressState.Working; try