using System.Globalization; using System.Text.Json.Serialization; using Semver; using StabilityMatrix.Core.Converters.Json; namespace StabilityMatrix.Core.Models.Settings; [JsonSerializable(typeof(Settings))] public class Settings { public int? Version { get; set; } = 1; public bool FirstLaunchSetupComplete { get; set; } public string? Theme { get; set; } = "Dark"; public string? Language { get; set; } = GetDefaultCulture().Name; public List InstalledPackages { get; set; } = new(); [JsonPropertyName("ActiveInstalledPackage")] public Guid? ActiveInstalledPackageId { get; set; } /// /// The first installed package matching the /// or null if no matching package /// [JsonIgnore] public InstalledPackage? ActiveInstalledPackage { get => ActiveInstalledPackageId == null ? null : InstalledPackages.FirstOrDefault(x => x.Id == ActiveInstalledPackageId); set => ActiveInstalledPackageId = value?.Id; } public bool HasSeenWelcomeNotification { get; set; } public List? PathExtensions { get; set; } public string? WebApiHost { get; set; } public string? WebApiPort { get; set; } /// /// The last auto-update version that had a notification dismissed by the user /// [JsonConverter(typeof(SemVersionJsonConverter))] public SemVersion? LastSeenUpdateVersion { get; set; } // UI states public bool ModelBrowserNsfwEnabled { get; set; } public bool IsNavExpanded { get; set; } public bool IsImportAsConnected { get; set; } public bool ShowConnectedModelImages { get; set; } public SharedFolderType? SharedFolderVisibleCategories { get; set; } = SharedFolderType.StableDiffusion | SharedFolderType.Lora | SharedFolderType.LyCORIS; public WindowSettings? WindowSettings { get; set; } public ModelSearchOptions? ModelSearchOptions { get; set; } /// /// Whether prompt auto completion is enabled /// public bool IsPromptCompletionEnabled { get; set; } = true; /// /// Relative path to the tag completion CSV file from 'LibraryDir/Tags' /// public string? TagCompletionCsv { get; set; } /// /// Whether to remove underscores from completions /// public bool IsCompletionRemoveUnderscoresEnabled { get; set; } = true; /// /// Format for Inference output image file names /// public string? InferenceOutputImageFileNameFormat { get; set; } /// /// Whether the Inference Image Viewer shows pixel grids at high zoom levels /// public bool IsImageViewerPixelGridEnabled { get; set; } = true; public bool RemoveFolderLinksOnShutdown { get; set; } public bool IsDiscordRichPresenceEnabled { get; set; } public Dictionary? EnvironmentVariables { get; set; } public HashSet? InstalledModelHashes { get; set; } = new(); public float AnimationScale { get; set; } = 1.0f; public bool AutoScrollLaunchConsoleToEnd { get; set; } = true; public HashSet FavoriteModels { get; set; } = new(); public void RemoveInstalledPackageAndUpdateActive(InstalledPackage package) { RemoveInstalledPackageAndUpdateActive(package.Id); } public void RemoveInstalledPackageAndUpdateActive(Guid id) { InstalledPackages.RemoveAll(x => x.Id == id); UpdateActiveInstalledPackage(); } /// /// Update ActiveInstalledPackage if not valid /// uses first package or null if no packages /// public void UpdateActiveInstalledPackage() { // Empty packages - set to null if (InstalledPackages.Count == 0) { ActiveInstalledPackageId = null; } // Active package is not in package - set to first package else if (InstalledPackages.All(x => x.Id != ActiveInstalledPackageId)) { ActiveInstalledPackageId = InstalledPackages[0].Id; } } /// /// Return either the system default culture, if supported, or en-US /// /// public static CultureInfo GetDefaultCulture() { var supportedCultures = new[] { "en-US", "ja-JP", "zh-Hans", "zh-Hant" }; var systemCulture = CultureInfo.InstalledUICulture; if (systemCulture.Name.StartsWith("zh-Hans", StringComparison.OrdinalIgnoreCase)) { return new CultureInfo("zh-Hans"); } if (systemCulture.Name.StartsWith("zh-Hant")) { return new CultureInfo("zh-Hant"); } return supportedCultures.Contains(systemCulture.Name) ? systemCulture : new CultureInfo("en-US"); } }