Browse Source

new one click installer dialog (wip)

pull/438/head
JT 10 months ago
parent
commit
e2b355e443
  1. 11
      StabilityMatrix.Avalonia/Controls/BetterContentDialog.cs
  2. 3
      StabilityMatrix.Avalonia/DesignData/DesignData.cs
  3. 61
      StabilityMatrix.Avalonia/ViewModels/Dialogs/NewOneClickInstallViewModel.cs
  4. 6
      StabilityMatrix.Avalonia/ViewModels/MainWindowViewModel.cs
  5. 199
      StabilityMatrix.Avalonia/Views/Dialogs/NewOneClickInstallDialog.axaml
  6. 46
      StabilityMatrix.Avalonia/Views/Dialogs/NewOneClickInstallDialog.axaml.cs
  7. 2
      StabilityMatrix.Avalonia/Views/PackageManager/PackageInstallBrowserView.axaml
  8. 8
      StabilityMatrix.Core/Models/Packages/FooocusMre.cs

11
StabilityMatrix.Avalonia/Controls/BetterContentDialog.cs

@ -144,6 +144,17 @@ public class BetterContentDialog : ContentDialog
set => SetValue(MaxDialogWidthProperty, value);
}
public static readonly StyledProperty<double> MinDialogHeightProperty = AvaloniaProperty.Register<
BetterContentDialog,
double
>("MinDialogHeight");
public double MinDialogHeight
{
get => GetValue(MaxDialogHeightProperty);
set => SetValue(MaxDialogHeightProperty, value);
}
public static readonly StyledProperty<double> MaxDialogHeightProperty = AvaloniaProperty.Register<
BetterContentDialog,
double

3
StabilityMatrix.Avalonia/DesignData/DesignData.cs

@ -444,6 +444,9 @@ public static class DesignData
public static HuggingFacePageViewModel HuggingFacePageViewModel =>
Services.GetRequiredService<HuggingFacePageViewModel>();
public static NewOneClickInstallViewModel NewOneClickInstallViewModel =>
Services.GetRequiredService<NewOneClickInstallViewModel>();
public static OutputsPageViewModel OutputsPageViewModel
{
get

61
StabilityMatrix.Avalonia/ViewModels/Dialogs/NewOneClickInstallViewModel.cs

@ -0,0 +1,61 @@
using System;
using System.ComponentModel;
using System.Linq;
using System.Reactive.Linq;
using System.Threading.Tasks;
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using DynamicData;
using DynamicData.Binding;
using StabilityMatrix.Avalonia.ViewModels.Base;
using StabilityMatrix.Avalonia.Views.Dialogs;
using StabilityMatrix.Core.Attributes;
using StabilityMatrix.Core.Helper.Factory;
using StabilityMatrix.Core.Models.Packages;
namespace StabilityMatrix.Avalonia.ViewModels.Dialogs;
[Transient]
[ManagedService]
public partial class NewOneClickInstallViewModel : ContentDialogViewModelBase
{
public SourceCache<BasePackage, string> AllPackagesCache { get; } = new(p => p.Author + p.Name);
public IObservableCollection<BasePackage> ShownPackages { get; set; } =
new ObservableCollectionExtended<BasePackage>();
[ObservableProperty]
private bool showIncompatiblePackages;
public NewOneClickInstallViewModel(IPackageFactory packageFactory)
{
var incompatiblePredicate = this.WhenPropertyChanged(vm => vm.ShowIncompatiblePackages)
.Select(_ => new Func<BasePackage, bool>(p => p.IsCompatible || ShowIncompatiblePackages))
.AsObservable();
AllPackagesCache
.Connect()
.DeferUntilLoaded()
.Filter(incompatiblePredicate)
.Filter(p => p.OfferInOneClickInstaller || ShowIncompatiblePackages)
.Sort(
SortExpressionComparer<BasePackage>
.Ascending(p => p.InstallerSortOrder)
.ThenByAscending(p => p.DisplayName)
)
.Bind(ShownPackages)
.Subscribe();
AllPackagesCache.AddOrUpdate(packageFactory.GetAllAvailablePackages());
}
[RelayCommand]
private async Task InstallComfyForInference()
{
var comfyPackage = ShownPackages.FirstOrDefault(x => x is ComfyUI);
if (comfyPackage != null)
{
// install
}
}
}

6
StabilityMatrix.Avalonia/ViewModels/MainWindowViewModel.cs

@ -128,13 +128,15 @@ public partial class MainWindowViewModel : ViewModelBase
if (Program.Args.DebugOneClickInstall || settingsManager.Settings.InstalledPackages.Count == 0)
{
var viewModel = dialogFactory.Get<OneClickInstallViewModel>();
var viewModel = dialogFactory.Get<NewOneClickInstallViewModel>();
var dialog = new BetterContentDialog
{
IsPrimaryButtonEnabled = false,
IsSecondaryButtonEnabled = false,
IsFooterVisible = false,
Content = new OneClickInstallDialog { DataContext = viewModel },
FullSizeDesired = true,
MinDialogHeight = 775,
Content = new NewOneClickInstallDialog { DataContext = viewModel },
};
EventManager.Instance.OneClickInstallFinished += (_, skipped) =>

199
StabilityMatrix.Avalonia/Views/Dialogs/NewOneClickInstallDialog.axaml

@ -0,0 +1,199 @@
<controls:UserControlBase xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:controls="clr-namespace:StabilityMatrix.Avalonia.Controls"
xmlns:dialogs="clr-namespace:StabilityMatrix.Avalonia.ViewModels.Dialogs"
xmlns:lang="clr-namespace:StabilityMatrix.Avalonia.Languages"
xmlns:mocks="clr-namespace:StabilityMatrix.Avalonia.DesignData"
xmlns:ui="clr-namespace:FluentAvalonia.UI.Controls;assembly=FluentAvalonia"
xmlns:input="clr-namespace:FluentAvalonia.UI.Input;assembly=FluentAvalonia"
xmlns:packages="clr-namespace:StabilityMatrix.Core.Models.Packages;assembly=StabilityMatrix.Core"
xmlns:models="clr-namespace:StabilityMatrix.Core.Models;assembly=StabilityMatrix.Core"
mc:Ignorable="d" d:DesignWidth="700" d:DesignHeight="725"
x:DataType="dialogs:NewOneClickInstallViewModel"
d:DataContext="{x:Static mocks:DesignData.NewOneClickInstallViewModel}"
x:Class="StabilityMatrix.Avalonia.Views.Dialogs.NewOneClickInstallDialog">
<controls:UserControlBase.Resources>
<!-- <input:StandardUICommand x:Key="PackageSelected" -->
<!-- Command="{Binding OnPackageSelected}" /> -->
<DataTemplate x:DataType="packages:BasePackage" x:Key="PackageTemplate">
<Button Padding="0"
HorizontalAlignment="Stretch"
HorizontalContentAlignment="Stretch"
Margin="4"
Classes="transparent-full"
CornerRadius="8"
Command="{StaticResource PackageSelected}"
CommandParameter="{Binding }">
<controls:Card Padding="8, 0">
<Grid ColumnDefinitions="Auto, *, Auto">
<controls:BetterAdvancedImage
Grid.Column="0"
MaxHeight="96"
MaxWidth="96"
Stretch="UniformToFill"
CornerRadius="4"
Source="{Binding PreviewImageUri}" />
<StackPanel Grid.Column="1" Orientation="Vertical">
<TextBlock Text="{Binding DisplayName}"
FontWeight="Light"
Margin="16,8,0,0"
FontSize="20" />
<TextBlock Text="{Binding ByAuthor}"
FontWeight="Light"
Margin="16,0,0,0"
FontSize="13" />
<TextBlock TextWrapping="Wrap"
Text="{Binding Blurb}"
FontWeight="Light"
Margin="16,8,0,8"
FontSize="14" />
<controls:Card Tag="{Binding InstallerSortOrder}"
HorizontalAlignment="Left"
Padding="4"
Margin="16, 0, 0, 8"
VerticalAlignment="Top">
<controls:Card.Styles>
<Style Selector="controls|Card[Tag=Recommended]">
<Setter Property="Background"
Value="{DynamicResource ThemeGreenColorTransparent}" />
<Setter Property="BorderBrush"
Value="{DynamicResource ThemeGreenColorTransparent}" />
<Style
Selector="^ /template/ ContentPresenter#PART_ContentPresenter">
<Setter Property="Foreground"
Value="{DynamicResource ButtonForeground}" />
</Style>
<Setter Property="Content">
<Template>
<TextBlock
FontWeight="Medium"
HorizontalAlignment="Center"
Text="Recommended"
TextAlignment="Center"
VerticalAlignment="Center" />
</Template>
</Setter>
</Style>
<Style Selector="controls|Card[Tag=Simple]">
<Setter Property="Background"
Value="{DynamicResource ThemeDarkBlueColor}" />
<Setter Property="BorderBrush"
Value="{DynamicResource ThemeDarkBlueColor}" />
<Setter Property="Content">
<Template>
<TextBlock
FontWeight="Medium"
HorizontalAlignment="Center"
Text="Simple"
TextAlignment="Center"
VerticalAlignment="Center" />
</Template>
</Setter>
</Style>
<Style Selector="controls|Card[Tag=Advanced]">
<Setter Property="Background"
Value="{DynamicResource ThemeOrangeColor}" />
<Setter Property="BorderBrush"
Value="{DynamicResource ThemeOrangeColor}" />
<Setter Property="Foreground"
Value="Black" />
<Setter Property="Content">
<Template>
<TextBlock
FontWeight="Medium"
HorizontalAlignment="Center"
Text="Advanced"
TextAlignment="Center"
VerticalAlignment="Center" />
</Template>
</Setter>
</Style>
<Style Selector="controls|Card">
<Setter Property="Background"
Value="{DynamicResource ThemeDarkRedColor}" />
<Setter Property="BorderBrush"
Value="{DynamicResource ThemeDarkRedColor}" />
<Setter Property="Content">
<Template>
<TextBlock
FontWeight="Medium"
HorizontalAlignment="Center"
Text="Expert"
TextAlignment="Center"
VerticalAlignment="Center" />
</Template>
</Setter>
</Style>
</controls:Card.Styles>
</controls:Card>
</StackPanel>
<ui:SymbolIcon Grid.Column="2"
HorizontalAlignment="Right"
VerticalAlignment="Center"
FontSize="24"
Symbol="ChevronRight" />
</Grid>
</controls:Card>
</Button>
</DataTemplate>
</controls:UserControlBase.Resources>
<StackPanel Orientation="Vertical" Margin="8">
<TextBlock Text="{x:Static lang:Resources.Text_WelcomeToStabilityMatrix}"
TextWrapping="Wrap"
Margin="8,0,8,0"
VerticalAlignment="Center" HorizontalAlignment="Center"
FontSize="36" FontWeight="Light" />
<TextBlock Text="{x:Static lang:Resources.Text_OneClickInstaller_SubHeader}"
TextWrapping="Wrap" TextAlignment="Center"
VerticalAlignment="Top" HorizontalAlignment="Center"
FontSize="16" FontWeight="Light" Margin="8"/>
<ScrollViewer Height="575"
Padding="8, 0">
<ItemsRepeater ItemsSource="{Binding ShownPackages}"
Name="PackagesRepeater">
<ItemsRepeater.Layout>
<StackLayout Orientation="Vertical" />
</ItemsRepeater.Layout>
<ItemsRepeater.ItemTemplate>
<StaticResource ResourceKey="PackageTemplate" />
</ItemsRepeater.ItemTemplate>
</ItemsRepeater>
</ScrollViewer>
<ui:TeachingTip
Name="InferenceTeachingTip"
MinWidth="100"
Title="Use ComfyUI with Inference"
Subtitle="A new built-in native Stable Diffusion experience, powered by ComfyUI"
ActionButtonContent="{x:Static lang:Resources.Action_Install}"
ActionButtonCommand="{Binding InstallComfyForInferenceCommand}"
CloseButtonContent="{x:Static lang:Resources.Action_Close}"
PreferredPlacement="RightTop"
Margin="8,0,0,0"
PlacementMargin="0,0,0,0"
TailVisibility="Auto">
<ui:TeachingTip.HeroContent>
<controls:BetterAdvancedImage
RenderOptions.BitmapInterpolationMode="HighQuality"
Source="https://cdn.lykos.ai/static/sc-inference-drag-load.gif"/>
</ui:TeachingTip.HeroContent>
</ui:TeachingTip>
<ToggleSwitch IsChecked="{Binding ShowIncompatiblePackages}"
Margin="6, 0"
OffContent="Show All Packages"
OnContent="Show All Packages"/>
</StackPanel>
</controls:UserControlBase>

46
StabilityMatrix.Avalonia/Views/Dialogs/NewOneClickInstallDialog.axaml.cs

@ -0,0 +1,46 @@
using System;
using System.Linq;
using Avalonia.Controls;
using Avalonia.Interactivity;
using FluentAvalonia.UI.Controls;
using KGySoft.CoreLibraries;
using StabilityMatrix.Avalonia.Controls;
using StabilityMatrix.Core.Models.Packages;
namespace StabilityMatrix.Avalonia.Views.Dialogs;
public partial class NewOneClickInstallDialog : UserControlBase
{
public NewOneClickInstallDialog()
{
InitializeComponent();
}
protected override void OnLoaded(RoutedEventArgs e)
{
base.OnLoaded(e);
var teachingTip =
this.FindControl<TeachingTip>("InferenceTeachingTip")
?? throw new InvalidOperationException("TeachingTip not found");
teachingTip.ActionButtonClick += (_, _) =>
{
teachingTip.IsOpen = false;
};
// Find ComfyUI listbox item
var listBox = this.FindControl<ItemsRepeater>("PackagesRepeater");
// Find ComfyUI listbox item
if (listBox?.ItemsSource?.Cast<BasePackage>().FirstOrDefault(p => p is ComfyUI) is { } comfy)
{
var comfyItem = listBox.TryGetElement(listBox?.ItemsSource?.IndexOf(comfy) ?? 0);
// comfyItem!.IsSelected = true;
teachingTip.Target = comfyItem;
teachingTip.IsOpen = true;
}
}
}

2
StabilityMatrix.Avalonia/Views/PackageManager/PackageInstallBrowserView.axaml

@ -20,7 +20,7 @@
<input:StandardUICommand x:Key="PackageSelected"
Command="{Binding OnPackageSelected}" />
<DataTemplate x:DataType="packages:BaseGitPackage" x:Key="PackageTemplate">
<DataTemplate x:DataType="packages:BasePackage" x:Key="PackageTemplate">
<Button Padding="0"
HorizontalAlignment="Stretch"
HorizontalContentAlignment="Stretch"

8
StabilityMatrix.Core/Models/Packages/FooocusMre.cs

@ -28,16 +28,20 @@ public class FooocusMre(
public override string LicenseType => "GPL-3.0";
public override string LicenseUrl => "https://github.com/MoonRide303/Fooocus-MRE/blob/moonride-main/LICENSE";
public override string LicenseUrl =>
"https://github.com/MoonRide303/Fooocus-MRE/blob/moonride-main/LICENSE";
public override string LaunchCommand => "launch.py";
public override Uri PreviewImageUri =>
new("https://user-images.githubusercontent.com/130458190/265366059-ce430ea0-0995-4067-98dd-cef1d7dc1ab6.png");
new(
"https://user-images.githubusercontent.com/130458190/265366059-ce430ea0-0995-4067-98dd-cef1d7dc1ab6.png"
);
public override string Disclaimer =>
"This package may no longer receive updates from its author. It may be removed from Stability Matrix in the future.";
public override PackageDifficulty InstallerSortOrder => PackageDifficulty.Impossible;
public override bool OfferInOneClickInstaller => false;
public override List<LaunchOptionDefinition> LaunchOptions =>
new()

Loading…
Cancel
Save