using System; using System.Collections.Generic; using System.Collections.Immutable; using System.Collections.ObjectModel; using System.Diagnostics.CodeAnalysis; using System.IO; using System.Linq; using System.Net.Http; using AvaloniaEdit.Utils; using Microsoft.Extensions.DependencyInjection; using StabilityMatrix.Avalonia.Controls.CodeCompletion; 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.Dialogs; using StabilityMatrix.Avalonia.ViewModels.PackageManager; using StabilityMatrix.Avalonia.ViewModels.Inference; using StabilityMatrix.Avalonia.ViewModels.Settings; using StabilityMatrix.Core.Api; using StabilityMatrix.Core.Database; using StabilityMatrix.Core.Helper; using StabilityMatrix.Core.Helper.Cache; using StabilityMatrix.Core.Helper.Factory; using StabilityMatrix.Core.Models; using StabilityMatrix.Core.Models.Api; using StabilityMatrix.Core.Models.Api.Comfy; using StabilityMatrix.Core.Models.Progress; using StabilityMatrix.Core.Python; using StabilityMatrix.Core.Services; using StabilityMatrix.Core.Updater; using CheckpointFile = StabilityMatrix.Avalonia.ViewModels.CheckpointManager.CheckpointFile; using CheckpointFolder = StabilityMatrix.Avalonia.ViewModels.CheckpointManager.CheckpointFolder; namespace StabilityMatrix.Avalonia.DesignData; [SuppressMessage("ReSharper", "MemberCanBePrivate.Global")] public static class DesignData { [NotNull] public static IServiceProvider? Services { get; set; } private static bool isInitialized; // This needs to be static method instead of static constructor // or else Avalonia analyzers won't work. public static void Initialize() { if (isInitialized) throw new InvalidOperationException("DesignData is already initialized."); var services = new ServiceCollection(); var activePackageId = Guid.NewGuid(); services.AddSingleton(_ => new MockSettingsManager { Settings = { InstalledPackages = new List { new() { Id = activePackageId, DisplayName = "My Installed Package", DisplayVersion = "v1.0.0", PackageName = "stable-diffusion-webui", PackageVersion = "v1.0.0", LibraryPath = $"Packages{Path.DirectorySeparatorChar}example-webui", LastUpdateCheck = DateTimeOffset.Now }, new() { Id = Guid.NewGuid(), DisplayName = "Dank Diffusion", PackageName = "ComfyUI", DisplayVersion = "main@ab73d4a", LibraryPath = $"Packages{Path.DirectorySeparatorChar}example-webui", LastUpdateCheck = DateTimeOffset.Now } }, ActiveInstalledPackageId = activePackageId } }); // General services services.AddLogging() .AddSingleton() .AddSingleton() .AddSingleton() .AddSingleton() .AddSingleton(); // Mock services services .AddSingleton() .AddSingleton() .AddSingleton() .AddSingleton() .AddSingleton() .AddSingleton() .AddSingleton() .AddSingleton() .AddSingleton(); // Placeholder services that nobody should need during design time services .AddSingleton(_ => null!) .AddSingleton(_ => null!) .AddSingleton(_ => null!) .AddSingleton(_ => null!) .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(); Services = services.BuildServiceProvider(); var dialogFactory = Services.GetRequiredService>(); var settingsManager = Services.GetRequiredService(); var downloadService = Services.GetRequiredService(); var modelFinder = Services.GetRequiredService(); var packageFactory = Services.GetRequiredService(); var notificationService = Services.GetRequiredService(); LaunchOptionsViewModel = Services.GetRequiredService(); LaunchOptionsViewModel.Cards = new[] { LaunchOptionCard.FromDefinition(new LaunchOptionDefinition { Name = "Host", Type = LaunchOptionType.String, Description = "The host name for the Web UI", DefaultValue = "localhost", Options = {"--host"} }), LaunchOptionCard.FromDefinition(new LaunchOptionDefinition { Name = "API", Type = LaunchOptionType.Bool, Options = {"--api"} }) }; LaunchOptionsViewModel.UpdateFilterCards(); InstallerViewModel = Services.GetRequiredService(); InstallerViewModel.AvailablePackages = packageFactory.GetAllAvailablePackages().ToImmutableArray(); InstallerViewModel.SelectedPackage = InstallerViewModel.AvailablePackages[0]; InstallerViewModel.ReleaseNotes = "## Release Notes\nThis is a test release note."; // Checkpoints page CheckpointsPageViewModel.CheckpointFolders = new ObservableCollection { new(settingsManager, downloadService, modelFinder) { Title = "StableDiffusion", DirectoryPath = "Models/StableDiffusion", CheckpointFiles = new AdvancedObservableList { new() { FilePath = "~/Models/StableDiffusion/electricity-light.safetensors", Title = "Auroral Background", PreviewImagePath = "https://image.civitai.com/xG1nkqKTMzGDvpLrqFT7WA/" + "78fd2a0a-42b6-42b0-9815-81cb11bb3d05/00009-2423234823.jpeg", ConnectedModel = new ConnectedModelInfo { VersionName = "Lightning Auroral", BaseModel = "SD 1.5", ModelName = "Auroral Background", ModelType = CivitModelType.Model, FileMetadata = new CivitFileMetadata { Format = CivitModelFormat.SafeTensor, Fp = CivitModelFpType.fp16, Size = CivitModelSize.pruned, } } }, new() { FilePath = "~/Models/Lora/model.safetensors", Title = "Some model" }, }, }, new(settingsManager, downloadService, modelFinder) { Title = "Lora", DirectoryPath = "Packages/Lora", SubFolders = new AdvancedObservableList() { new(settingsManager, downloadService, modelFinder) { Title = "StableDiffusion", DirectoryPath = "Packages/Lora/Subfolder", }, new(settingsManager, downloadService, modelFinder) { Title = "Lora", DirectoryPath = "Packages/StableDiffusion/Subfolder", } }, CheckpointFiles = new AdvancedObservableList { new() { FilePath = "~/Models/Lora/lora_v2.pt", Title = "Best Lora v2", } } } }; foreach (var folder in CheckpointsPageViewModel.CheckpointFolders) { folder.DisplayedCheckpointFiles = folder.CheckpointFiles; } CheckpointBrowserViewModel.ModelCards = new ObservableCollection { dialogFactory.Get(vm => { vm.CivitModel = new CivitModel { Name = "BB95 Furry Mix", Description = "A furry mix of BB95", }; }) }; NewCheckpointsPageViewModel.AllCheckpoints = new ObservableCollection { new() { FilePath = "~/Models/StableDiffusion/electricity-light.safetensors", Title = "Auroral Background", PreviewImagePath = "https://image.civitai.com/xG1nkqKTMzGDvpLrqFT7WA/" + "78fd2a0a-42b6-42b0-9815-81cb11bb3d05/00009-2423234823.jpeg", ConnectedModel = new ConnectedModelInfo { VersionName = "Lightning Auroral", BaseModel = "SD 1.5", ModelName = "Auroral Background", ModelType = CivitModelType.Model, FileMetadata = new CivitFileMetadata { Format = CivitModelFormat.SafeTensor, Fp = CivitModelFpType.fp16, Size = CivitModelSize.pruned, } } }, new() { FilePath = "~/Models/Lora/model.safetensors", Title = "Some model" } }; ProgressManagerViewModel.ProgressItems.AddRange(new ProgressItemViewModelBase[] { new ProgressItemViewModel(new ProgressItem(Guid.NewGuid(), "Test File.exe", new ProgressReport(0.5f, "Downloading..."))), new MockDownloadProgressItemViewModel("Test File 2.exe"), }); UpdateViewModel = Services.GetRequiredService(); UpdateViewModel.UpdateText = $"Stability Matrix v2.0.1 is now available! You currently have v2.0.0. Would you like to update now?"; UpdateViewModel.ReleaseNotes = "## v2.0.1\n- Fixed a bug\n- Added a feature\n- Removed a feature"; isInitialized = true; } [NotNull] public static InstallerViewModel? InstallerViewModel { get; private set; } [NotNull] public static LaunchOptionsViewModel? LaunchOptionsViewModel { get; private set; } [NotNull] public static UpdateViewModel? UpdateViewModel { get; private set; } public static ServiceManager DialogFactory => Services.GetRequiredService>(); public static MainWindowViewModel MainWindowViewModel => Services.GetRequiredService(); public static FirstLaunchSetupViewModel FirstLaunchSetupViewModel => Services.GetRequiredService(); public static LaunchPageViewModel LaunchPageViewModel => Services.GetRequiredService(); public static PackageManagerViewModel PackageManagerViewModel { get { var settings = Services.GetRequiredService(); var vm = Services.GetRequiredService(); vm.Packages = new ObservableCollection( settings.Settings.InstalledPackages.Select(p => DialogFactory.Get(viewModel => viewModel.Package = p))); vm.Packages.First().IsUpdateAvailable = true; return vm; } } public static CheckpointsPageViewModel CheckpointsPageViewModel => Services.GetRequiredService(); public static NewCheckpointsPageViewModel NewCheckpointsPageViewModel => Services.GetRequiredService(); public static SettingsViewModel SettingsViewModel => Services.GetRequiredService(); public static InferenceSettingsViewModel InferenceSettingsViewModel => Services.GetRequiredService(); public static CheckpointBrowserViewModel CheckpointBrowserViewModel => Services.GetRequiredService(); public static SelectModelVersionViewModel SelectModelVersionViewModel => DialogFactory.Get(vm => { // Sample data var sampleCivitVersions = new List { new() { Name = "BB95 Furry Mix", Description = "v1.0.0", BaseModel = "SD 1.5", Files = new List { new() { Name = "bb95-v100-uwu-reallylongfilename-v1234576802.safetensors", Type = CivitFileType.Model, Metadata = new CivitFileMetadata { Format = CivitModelFormat.SafeTensor, Fp = CivitModelFpType.fp16, Size = CivitModelSize.pruned } }, new() { Name = "bb95-v100-uwu-reallylongfilename-v1234576802-fp32.safetensors", Type = CivitFileType.Model, Metadata = new CivitFileMetadata { Format = CivitModelFormat.SafeTensor, Fp = CivitModelFpType.fp32, Size = CivitModelSize.full }, Hashes = new CivitFileHashes { BLAKE3 = "ABCD" } } } } }; var sampleViewModel = new ModelVersionViewModel(new HashSet {"ABCD"}, sampleCivitVersions[0]); // Sample data for dialogs vm.Versions = new List {sampleViewModel}; vm.SelectedVersionViewModel = sampleViewModel; }); public static OneClickInstallViewModel OneClickInstallViewModel => Services.GetRequiredService(); public static InferenceViewModel InferenceViewModel => Services.GetRequiredService(); public static SelectDataDirectoryViewModel SelectDataDirectoryViewModel => Services.GetRequiredService(); public static ProgressManagerViewModel ProgressManagerViewModel => Services.GetRequiredService(); public static ExceptionViewModel ExceptionViewModel => DialogFactory.Get(viewModel => { // Use try-catch to generate traceback information try { try { throw new OperationCanceledException("Example"); } catch (OperationCanceledException e) { throw new AggregateException(e); } } catch (AggregateException e) { viewModel.Exception = e; } }); public static EnvVarsViewModel EnvVarsViewModel => DialogFactory.Get( viewModel => { viewModel.EnvVars = new ObservableCollection { new("UWU", "TRUE"), }; }); public static InferenceTextToImageViewModel InferenceTextToImageViewModel => DialogFactory.Get(); public static RefreshBadgeViewModel RefreshBadgeViewModel => new() { State = ProgressState.Success }; public static SeedCardViewModel SeedCardViewModel => new(); public static SamplerCardViewModel SamplerCardViewModel => DialogFactory.Get(vm => { vm.Steps = 20; vm.CfgScale = 7; vm.IsDenoiseStrengthEnabled = false; vm.IsDimensionsEnabled = true; vm.SelectedSampler = new ComfySampler("euler"); }); public static SamplerCardViewModel SamplerCardViewModelScaleMode => DialogFactory.Get(vm => { vm.Steps = 20; vm.CfgScale = 7; vm.SelectedSampler = new ComfySampler("euler"); vm.IsDimensionsEnabled = false; vm.IsCfgScaleEnabled = false; vm.IsSamplerSelectionEnabled = false; vm.IsDenoiseStrengthEnabled = true; }); public static ModelCardViewModel ModelCardViewModel => DialogFactory.Get(); public static ImageGalleryCardViewModel ImageGalleryCardViewModel => DialogFactory.Get(vm => { vm.ImageSources.AddRange(new ImageSource[] { new(new Uri("https://image.civitai.com/xG1nkqKTMzGDvpLrqFT7WA/4a7e00a7-6f18-42d4-87c0-10e792df2640/width=1152")), new(new Uri("https://image.civitai.com/xG1nkqKTMzGDvpLrqFT7WA/a318ac1f-3ad0-48ac-98cc-79126febcc17/width=1024")), new(new Uri("https://image.civitai.com/xG1nkqKTMzGDvpLrqFT7WA/16588c94-6595-4be9-8806-d7e6e22d198c/width=1152")), }); }); public static PromptCardViewModel PromptCardViewModel => DialogFactory.Get(vm => { vm.PromptDocument.Text = "house, (high quality), [example], BREAK\n\n"; vm.NegativePromptDocument.Text = "blurry, jpeg artifacts"; }); public static StackCardViewModel StackCardViewModel => DialogFactory.Get(vm => { vm.AddCards(new LoadableViewModelBase[] { SamplerCardViewModel, SeedCardViewModel, }); }); public static StackExpanderViewModel StackExpanderViewModel => DialogFactory.Get(vm => { vm.Title = "Hires Fix"; vm.AddCards(new LoadableViewModelBase[] { SamplerCardViewModel, SeedCardViewModel, }); }); public static UpscalerCardViewModel UpscalerCardViewModel => DialogFactory.Get(); public static BatchSizeCardViewModel BatchSizeCardViewModel => DialogFactory.Get(); public static IList SampleCompletionData => new List { new TagCompletionData("test1", TagType.General), new TagCompletionData("test2", TagType.Artist), new TagCompletionData("test3", TagType.Character), new TagCompletionData("test4", TagType.Copyright), new TagCompletionData("test5", TagType.Species), new TagCompletionData("test_unknown", TagType.Invalid), }; public static CompletionList SampleCompletionList { get { var list = new CompletionList { IsFiltering = true }; list.CompletionData.AddRange(SampleCompletionData); list.FilteredCompletionData.AddRange(list.CompletionData); list.SelectItem("te", true); return list; } } public static ImageViewerViewModel ImageViewerViewModel => DialogFactory.Get(); public static Indexer Types => new(); public class Indexer { public object? this[string typeName] { get { var type = Type.GetType(typeName) ?? throw new ArgumentException($"Type {typeName} not found"); try { return Services.GetService(type); } catch (InvalidOperationException) { return Activator.CreateInstance(type); } } } } }