Multi-Platform Package Manager for Stable Diffusion
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

109 lines
3.2 KiB

using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.ComponentModel;
using System.Linq;
using System.Reactive.Linq;
using System.Threading;
using CommunityToolkit.Mvvm.ComponentModel;
using FuzzySharp;
using Microsoft.Extensions.Logging;
using StabilityMatrix.Avalonia.ViewModels.Base;
using StabilityMatrix.Avalonia.Views.Dialogs;
using StabilityMatrix.Core.Attributes;
using StabilityMatrix.Core.Helper.Cache;
using StabilityMatrix.Core.Models;
namespace StabilityMatrix.Avalonia.ViewModels.Dialogs;
[View(typeof(LaunchOptionsDialog))]
[ManagedService]
[Transient]
public partial class LaunchOptionsViewModel : ContentDialogViewModelBase
{
private readonly ILogger<LaunchOptionsViewModel> logger;
private readonly LRUCache<string, ImmutableList<LaunchOptionCard>> cache = new(100);
[ObservableProperty]
private string title = "Launch Options";
[ObservableProperty]
private bool isSearchBoxEnabled = true;
[ObservableProperty]
private string searchText = string.Empty;
[ObservableProperty]
private IReadOnlyList<LaunchOptionCard>? filteredCards;
public IReadOnlyList<LaunchOptionCard>? Cards { get; set; }
/// <summary>
/// Return cards that match the search text
/// </summary>
private IReadOnlyList<LaunchOptionCard>? GetFilteredCards(string? text)
{
if (string.IsNullOrWhiteSpace(text) || text.Length < 2)
{
return Cards;
}
// Try cache
if (cache.Get(text, out var cachedCards))
{
return cachedCards!;
}
var searchCard = new LaunchOptionCard
{
Title = text.ToLowerInvariant(),
Type = LaunchOptionType.Bool,
Options = Array.Empty<LaunchOption>()
};
var extracted = Process.ExtractTop(searchCard, Cards, c => c.Title.ToLowerInvariant());
var results = extracted.Where(r => r.Score > 40).Select(r => r.Value).ToImmutableList();
cache.Add(text, results);
return results;
}
public void UpdateFilterCards() => FilteredCards = GetFilteredCards(SearchText);
public LaunchOptionsViewModel(ILogger<LaunchOptionsViewModel> logger)
{
this.logger = logger;
Observable
.FromEventPattern<PropertyChangedEventArgs>(this, nameof(PropertyChanged))
.Where(x => x.EventArgs.PropertyName == nameof(SearchText))
.Throttle(TimeSpan.FromMilliseconds(50))
.Select(_ => SearchText)
.ObserveOn(SynchronizationContext.Current!)
.Subscribe(
text => FilteredCards = GetFilteredCards(text),
err => logger.LogError(err, "Error while filtering launch options")
);
}
public override void OnLoaded()
{
base.OnLoaded();
UpdateFilterCards();
}
/// <summary>
/// Export the current cards options to a list of strings
/// </summary>
public List<LaunchOption> AsLaunchArgs()
{
var launchArgs = new List<LaunchOption>();
if (Cards is null)
return launchArgs;
foreach (var card in Cards)
{
launchArgs.AddRange(card.Options);
}
return launchArgs;
}
}