JT
11 months ago
28 changed files with 1281 additions and 94 deletions
@ -0,0 +1,88 @@ |
|||||||
|
using System; |
||||||
|
using System.Collections.Generic; |
||||||
|
using System.Linq; |
||||||
|
using Avalonia.Threading; |
||||||
|
using CommunityToolkit.Mvvm.ComponentModel; |
||||||
|
using FluentAvalonia.UI.Controls; |
||||||
|
using Microsoft.Extensions.Logging; |
||||||
|
using StabilityMatrix.Avalonia.Animations; |
||||||
|
using StabilityMatrix.Avalonia.Services; |
||||||
|
using StabilityMatrix.Avalonia.ViewModels.Base; |
||||||
|
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.Packages; |
||||||
|
using StabilityMatrix.Core.Python; |
||||||
|
using StabilityMatrix.Core.Services; |
||||||
|
|
||||||
|
namespace StabilityMatrix.Avalonia.ViewModels.Dialogs; |
||||||
|
|
||||||
|
[View(typeof(NewInstallerDialog))] |
||||||
|
[Transient, ManagedService] |
||||||
|
public partial class NewInstallerDialogViewModel : PageViewModelBase |
||||||
|
{ |
||||||
|
private readonly INavigationService<NewPackageManagerViewModel> packageNavigationService; |
||||||
|
private readonly ISettingsManager settingsManager; |
||||||
|
private readonly INotificationService notificationService; |
||||||
|
private readonly ILogger<PackageInstallDetailViewModel> logger; |
||||||
|
private readonly IPyRunner pyRunner; |
||||||
|
private readonly IPrerequisiteHelper prerequisiteHelper; |
||||||
|
|
||||||
|
[ObservableProperty] |
||||||
|
private IEnumerable<BasePackage> inferencePackages; |
||||||
|
|
||||||
|
[ObservableProperty] |
||||||
|
private IEnumerable<BasePackage> trainingPackages; |
||||||
|
|
||||||
|
public NewInstallerDialogViewModel( |
||||||
|
IPackageFactory packageFactory, |
||||||
|
INavigationService<NewPackageManagerViewModel> packageNavigationService, |
||||||
|
ISettingsManager settingsManager, |
||||||
|
INotificationService notificationService, |
||||||
|
ILogger<PackageInstallDetailViewModel> logger, |
||||||
|
IPyRunner pyRunner, |
||||||
|
IPrerequisiteHelper prerequisiteHelper |
||||||
|
) |
||||||
|
{ |
||||||
|
this.packageNavigationService = packageNavigationService; |
||||||
|
this.settingsManager = settingsManager; |
||||||
|
this.notificationService = notificationService; |
||||||
|
this.logger = logger; |
||||||
|
this.pyRunner = pyRunner; |
||||||
|
this.prerequisiteHelper = prerequisiteHelper; |
||||||
|
inferencePackages = packageFactory |
||||||
|
.GetPackagesByType(PackageType.SdInference) |
||||||
|
.OrderBy(p => p.InstallerSortOrder); |
||||||
|
trainingPackages = packageFactory |
||||||
|
.GetPackagesByType(PackageType.SdTraining) |
||||||
|
.OrderBy(p => p.InstallerSortOrder); |
||||||
|
} |
||||||
|
|
||||||
|
public override string Title => "Add Package"; |
||||||
|
public override IconSource IconSource => new SymbolIconSource { Symbol = Symbol.Add }; |
||||||
|
|
||||||
|
public void OnPackageSelected(BaseGitPackage package) |
||||||
|
{ |
||||||
|
if (package is null) |
||||||
|
{ |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
var vm = new PackageInstallDetailViewModel( |
||||||
|
package, |
||||||
|
settingsManager, |
||||||
|
notificationService, |
||||||
|
logger, |
||||||
|
pyRunner, |
||||||
|
prerequisiteHelper, |
||||||
|
packageNavigationService |
||||||
|
); |
||||||
|
|
||||||
|
Dispatcher.UIThread.Post( |
||||||
|
() => packageNavigationService.NavigateTo(vm, BetterSlideNavigationTransition.PageSlideFromRight), |
||||||
|
DispatcherPriority.Send |
||||||
|
); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,13 @@ |
|||||||
|
using CommunityToolkit.Mvvm.ComponentModel; |
||||||
|
using StabilityMatrix.Avalonia.ViewModels.Base; |
||||||
|
using StabilityMatrix.Core.Models.Packages.Extensions; |
||||||
|
|
||||||
|
namespace StabilityMatrix.Avalonia.ViewModels; |
||||||
|
|
||||||
|
public partial class ExtensionViewModel() : ViewModelBase |
||||||
|
{ |
||||||
|
[ObservableProperty] |
||||||
|
private bool isSelected; |
||||||
|
|
||||||
|
public ExtensionBase Extension { get; init; } |
||||||
|
} |
@ -0,0 +1,66 @@ |
|||||||
|
using System.Collections.Generic; |
||||||
|
using System.Collections.ObjectModel; |
||||||
|
using CommunityToolkit.Mvvm.ComponentModel; |
||||||
|
using DynamicData; |
||||||
|
using FluentAvalonia.UI.Controls; |
||||||
|
using StabilityMatrix.Avalonia.Services; |
||||||
|
using StabilityMatrix.Avalonia.ViewModels.Base; |
||||||
|
using StabilityMatrix.Avalonia.ViewModels.Dialogs; |
||||||
|
using StabilityMatrix.Avalonia.Views; |
||||||
|
using StabilityMatrix.Core.Attributes; |
||||||
|
using Symbol = FluentIcons.Common.Symbol; |
||||||
|
using SymbolIconSource = FluentIcons.FluentAvalonia.SymbolIconSource; |
||||||
|
|
||||||
|
namespace StabilityMatrix.Avalonia.ViewModels; |
||||||
|
|
||||||
|
[View(typeof(NewPackageManagerPage))] |
||||||
|
[Singleton] |
||||||
|
public partial class NewPackageManagerViewModel : PageViewModelBase |
||||||
|
{ |
||||||
|
public override string Title => "Packages"; |
||||||
|
public override IconSource IconSource => new SymbolIconSource { Symbol = Symbol.Box, IsFilled = true }; |
||||||
|
|
||||||
|
public IReadOnlyList<PageViewModelBase> SubPages { get; } |
||||||
|
|
||||||
|
[ObservableProperty] |
||||||
|
private ObservableCollection<PageViewModelBase> currentPagePath = []; |
||||||
|
|
||||||
|
[ObservableProperty] |
||||||
|
private PageViewModelBase? currentPage; |
||||||
|
|
||||||
|
public NewPackageManagerViewModel(ServiceManager<ViewModelBase> vmFactory) |
||||||
|
{ |
||||||
|
SubPages = new PageViewModelBase[] |
||||||
|
{ |
||||||
|
vmFactory.Get<PackageManagerViewModel>(), |
||||||
|
vmFactory.Get<NewInstallerDialogViewModel>(), |
||||||
|
}; |
||||||
|
|
||||||
|
CurrentPagePath.AddRange(SubPages); |
||||||
|
|
||||||
|
CurrentPage = SubPages[0]; |
||||||
|
} |
||||||
|
|
||||||
|
partial void OnCurrentPageChanged(PageViewModelBase? value) |
||||||
|
{ |
||||||
|
if (value is null) |
||||||
|
{ |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
if (value is PackageManagerViewModel) |
||||||
|
{ |
||||||
|
CurrentPagePath.Clear(); |
||||||
|
CurrentPagePath.Add(value); |
||||||
|
} |
||||||
|
else if (value is PackageInstallDetailViewModel) |
||||||
|
{ |
||||||
|
CurrentPagePath.Add(value); |
||||||
|
} |
||||||
|
else |
||||||
|
{ |
||||||
|
CurrentPagePath.Clear(); |
||||||
|
CurrentPagePath.AddRange(new[] { SubPages[0], value }); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,276 @@ |
|||||||
|
using System; |
||||||
|
using System.Collections.Generic; |
||||||
|
using System.Collections.ObjectModel; |
||||||
|
using System.IO; |
||||||
|
using System.Linq; |
||||||
|
using System.Threading.Tasks; |
||||||
|
using AsyncAwaitBestPractices; |
||||||
|
using Avalonia.Controls; |
||||||
|
using Avalonia.Controls.Notifications; |
||||||
|
using CommunityToolkit.Mvvm.ComponentModel; |
||||||
|
using CommunityToolkit.Mvvm.Input; |
||||||
|
using FluentAvalonia.UI.Controls; |
||||||
|
using Microsoft.Extensions.Logging; |
||||||
|
using StabilityMatrix.Avalonia.Extensions; |
||||||
|
using StabilityMatrix.Avalonia.Languages; |
||||||
|
using StabilityMatrix.Avalonia.Services; |
||||||
|
using StabilityMatrix.Avalonia.ViewModels.Base; |
||||||
|
using StabilityMatrix.Avalonia.Views; |
||||||
|
using StabilityMatrix.Core.Attributes; |
||||||
|
using StabilityMatrix.Core.Helper; |
||||||
|
using StabilityMatrix.Core.Models; |
||||||
|
using StabilityMatrix.Core.Models.Database; |
||||||
|
using StabilityMatrix.Core.Models.FileInterfaces; |
||||||
|
using StabilityMatrix.Core.Models.PackageModification; |
||||||
|
using StabilityMatrix.Core.Models.Packages; |
||||||
|
using StabilityMatrix.Core.Python; |
||||||
|
using StabilityMatrix.Core.Services; |
||||||
|
using SymbolIconSource = FluentIcons.FluentAvalonia.SymbolIconSource; |
||||||
|
|
||||||
|
namespace StabilityMatrix.Avalonia.ViewModels; |
||||||
|
|
||||||
|
[View(typeof(PackageInstallDetailView))] |
||||||
|
public partial class PackageInstallDetailViewModel( |
||||||
|
BaseGitPackage package, |
||||||
|
ISettingsManager settingsManager, |
||||||
|
INotificationService notificationService, |
||||||
|
ILogger<PackageInstallDetailViewModel> logger, |
||||||
|
IPyRunner pyRunner, |
||||||
|
IPrerequisiteHelper prerequisiteHelper, |
||||||
|
INavigationService<NewPackageManagerViewModel> packageNavigationService |
||||||
|
) : PageViewModelBase |
||||||
|
{ |
||||||
|
public BaseGitPackage SelectedPackage { get; } = package; |
||||||
|
public override string Title { get; } = package.DisplayName; |
||||||
|
public override IconSource IconSource => new SymbolIconSource(); |
||||||
|
|
||||||
|
public string FullInstallPath => Path.Combine(settingsManager.LibraryDir, "Packages", InstallName); |
||||||
|
public bool ShowReleaseMode => SelectedPackage.ShouldIgnoreReleases == false; |
||||||
|
|
||||||
|
public string ReleaseLabelText => IsReleaseMode ? Resources.Label_Version : Resources.Label_Branch; |
||||||
|
|
||||||
|
public bool ShowTorchVersionOptions => SelectedTorchVersion != TorchVersion.None; |
||||||
|
public bool ShowExtensions => SelectedPackage.AvailableExtensions.Any(); |
||||||
|
|
||||||
|
[ObservableProperty] |
||||||
|
[NotifyPropertyChangedFor(nameof(FullInstallPath))] |
||||||
|
private string installName = package.DisplayName; |
||||||
|
|
||||||
|
[ObservableProperty] |
||||||
|
private bool showDuplicateWarning; |
||||||
|
|
||||||
|
[ObservableProperty] |
||||||
|
[NotifyPropertyChangedFor(nameof(ReleaseLabelText))] |
||||||
|
private bool isReleaseMode; |
||||||
|
|
||||||
|
[ObservableProperty] |
||||||
|
private IEnumerable<PackageVersion> availableVersions = new List<PackageVersion>(); |
||||||
|
|
||||||
|
[ObservableProperty] |
||||||
|
private PackageVersion? selectedVersion; |
||||||
|
|
||||||
|
[ObservableProperty] |
||||||
|
private SharedFolderMethod selectedSharedFolderMethod; |
||||||
|
|
||||||
|
[ObservableProperty] |
||||||
|
[NotifyPropertyChangedFor(nameof(ShowTorchVersionOptions))] |
||||||
|
private TorchVersion selectedTorchVersion; |
||||||
|
|
||||||
|
[ObservableProperty] |
||||||
|
private ObservableCollection<GitCommit>? availableCommits; |
||||||
|
|
||||||
|
[ObservableProperty] |
||||||
|
private GitCommit? selectedCommit; |
||||||
|
|
||||||
|
[ObservableProperty] |
||||||
|
private ObservableCollection<ExtensionViewModel> availableExtensions = []; |
||||||
|
|
||||||
|
private PackageVersionOptions? allOptions; |
||||||
|
|
||||||
|
public override async Task OnLoadedAsync() |
||||||
|
{ |
||||||
|
if (Design.IsDesignMode) |
||||||
|
return; |
||||||
|
|
||||||
|
OnInstallNameChanged(InstallName); |
||||||
|
AvailableExtensions = new ObservableCollection<ExtensionViewModel>( |
||||||
|
SelectedPackage.AvailableExtensions.Select(p => new ExtensionViewModel { Extension = p }) |
||||||
|
); |
||||||
|
|
||||||
|
allOptions = await SelectedPackage.GetAllVersionOptions(); |
||||||
|
if (ShowReleaseMode) |
||||||
|
{ |
||||||
|
IsReleaseMode = true; |
||||||
|
} |
||||||
|
else |
||||||
|
{ |
||||||
|
UpdateVersions(); |
||||||
|
await UpdateCommits(SelectedPackage.MainBranch); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
[RelayCommand] |
||||||
|
private async Task Install() |
||||||
|
{ |
||||||
|
if (string.IsNullOrWhiteSpace(InstallName)) |
||||||
|
{ |
||||||
|
notificationService.Show( |
||||||
|
new Notification( |
||||||
|
"Package name is empty", |
||||||
|
"Please enter a name for the package", |
||||||
|
NotificationType.Error |
||||||
|
) |
||||||
|
); |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
var setPackageInstallingStep = new SetPackageInstallingStep(settingsManager, InstallName); |
||||||
|
|
||||||
|
var installLocation = Path.Combine(settingsManager.LibraryDir, "Packages", InstallName); |
||||||
|
if (Directory.Exists(installLocation)) |
||||||
|
{ |
||||||
|
var installPath = new DirectoryPath(installLocation); |
||||||
|
await installPath.DeleteVerboseAsync(logger); |
||||||
|
} |
||||||
|
|
||||||
|
var prereqStep = new SetupPrerequisitesStep(prerequisiteHelper, pyRunner); |
||||||
|
|
||||||
|
var downloadOptions = new DownloadPackageVersionOptions(); |
||||||
|
var installedVersion = new InstalledPackageVersion(); |
||||||
|
if (IsReleaseMode) |
||||||
|
{ |
||||||
|
downloadOptions.VersionTag = |
||||||
|
SelectedVersion?.TagName ?? throw new NullReferenceException("Selected version is null"); |
||||||
|
downloadOptions.IsLatest = AvailableVersions?.First().TagName == downloadOptions.VersionTag; |
||||||
|
downloadOptions.IsPrerelease = SelectedVersion.IsPrerelease; |
||||||
|
|
||||||
|
installedVersion.InstalledReleaseVersion = downloadOptions.VersionTag; |
||||||
|
installedVersion.IsPrerelease = SelectedVersion.IsPrerelease; |
||||||
|
} |
||||||
|
else |
||||||
|
{ |
||||||
|
downloadOptions.CommitHash = |
||||||
|
SelectedCommit?.Sha ?? throw new NullReferenceException("Selected commit is null"); |
||||||
|
downloadOptions.BranchName = |
||||||
|
SelectedVersion?.TagName ?? throw new NullReferenceException("Selected version is null"); |
||||||
|
downloadOptions.IsLatest = AvailableCommits?.First().Sha == SelectedCommit.Sha; |
||||||
|
|
||||||
|
installedVersion.InstalledBranch = |
||||||
|
SelectedVersion?.TagName ?? throw new NullReferenceException("Selected version is null"); |
||||||
|
installedVersion.InstalledCommitSha = downloadOptions.CommitHash; |
||||||
|
} |
||||||
|
|
||||||
|
var downloadStep = new DownloadPackageVersionStep(SelectedPackage, installLocation, downloadOptions); |
||||||
|
var installStep = new InstallPackageStep( |
||||||
|
SelectedPackage, |
||||||
|
SelectedTorchVersion, |
||||||
|
SelectedSharedFolderMethod, |
||||||
|
downloadOptions, |
||||||
|
installLocation |
||||||
|
); |
||||||
|
var installExtensionSteps = AvailableExtensions |
||||||
|
.Where(e => e.IsSelected) |
||||||
|
.Select( |
||||||
|
e => |
||||||
|
new InstallExtensionStep( |
||||||
|
e.Extension, |
||||||
|
Path.Combine(installLocation, SelectedPackage.ExtensionsFolderName) |
||||||
|
) |
||||||
|
) |
||||||
|
.ToList(); |
||||||
|
|
||||||
|
var setupModelFoldersStep = new SetupModelFoldersStep( |
||||||
|
SelectedPackage, |
||||||
|
SelectedSharedFolderMethod, |
||||||
|
installLocation |
||||||
|
); |
||||||
|
|
||||||
|
var package = new InstalledPackage |
||||||
|
{ |
||||||
|
DisplayName = InstallName, |
||||||
|
LibraryPath = Path.Combine("Packages", InstallName), |
||||||
|
Id = Guid.NewGuid(), |
||||||
|
PackageName = SelectedPackage.Name, |
||||||
|
Version = installedVersion, |
||||||
|
LaunchCommand = SelectedPackage.LaunchCommand, |
||||||
|
LastUpdateCheck = DateTimeOffset.Now, |
||||||
|
PreferredTorchVersion = SelectedTorchVersion, |
||||||
|
PreferredSharedFolderMethod = SelectedSharedFolderMethod |
||||||
|
}; |
||||||
|
|
||||||
|
var addInstalledPackageStep = new AddInstalledPackageStep(settingsManager, package); |
||||||
|
|
||||||
|
var steps = new List<IPackageStep> |
||||||
|
{ |
||||||
|
setPackageInstallingStep, |
||||||
|
prereqStep, |
||||||
|
downloadStep, |
||||||
|
installStep, |
||||||
|
}; |
||||||
|
|
||||||
|
if (installExtensionSteps.Count > 0) |
||||||
|
{ |
||||||
|
steps.AddRange(installExtensionSteps); |
||||||
|
} |
||||||
|
|
||||||
|
steps.Add(setupModelFoldersStep); |
||||||
|
steps.Add(addInstalledPackageStep); |
||||||
|
|
||||||
|
var runner = new PackageModificationRunner { ShowDialogOnStart = true }; |
||||||
|
EventManager.Instance.OnPackageInstallProgressAdded(runner); |
||||||
|
await runner.ExecuteSteps(steps.ToList()); |
||||||
|
|
||||||
|
if (!runner.Failed) |
||||||
|
{ |
||||||
|
EventManager.Instance.OnInstalledPackagesChanged(); |
||||||
|
notificationService.Show( |
||||||
|
"Package Install Complete", |
||||||
|
$"{InstallName} installed successfully", |
||||||
|
NotificationType.Success |
||||||
|
); |
||||||
|
packageNavigationService.GoBack(); |
||||||
|
packageNavigationService.GoBack(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
private void UpdateVersions() |
||||||
|
{ |
||||||
|
AvailableVersions = |
||||||
|
IsReleaseMode && ShowReleaseMode ? allOptions.AvailableVersions : allOptions.AvailableBranches; |
||||||
|
|
||||||
|
SelectedVersion = !IsReleaseMode |
||||||
|
? AvailableVersions?.FirstOrDefault(x => x.TagName == SelectedPackage.MainBranch) |
||||||
|
?? AvailableVersions?.FirstOrDefault() |
||||||
|
: AvailableVersions?.FirstOrDefault(); |
||||||
|
} |
||||||
|
|
||||||
|
private async Task UpdateCommits(string branchName) |
||||||
|
{ |
||||||
|
var commits = await SelectedPackage.GetAllCommits(branchName); |
||||||
|
if (commits != null) |
||||||
|
{ |
||||||
|
AvailableCommits = new ObservableCollection<GitCommit>(commits); |
||||||
|
SelectedCommit = AvailableCommits.FirstOrDefault(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
partial void OnInstallNameChanged(string? value) |
||||||
|
{ |
||||||
|
ShowDuplicateWarning = settingsManager.Settings.InstalledPackages.Any( |
||||||
|
p => p.LibraryPath == $"Packages{Path.DirectorySeparatorChar}{value}" |
||||||
|
); |
||||||
|
} |
||||||
|
|
||||||
|
partial void OnIsReleaseModeChanged(bool value) |
||||||
|
{ |
||||||
|
UpdateVersions(); |
||||||
|
} |
||||||
|
|
||||||
|
partial void OnSelectedVersionChanged(PackageVersion? value) |
||||||
|
{ |
||||||
|
if (IsReleaseMode) |
||||||
|
return; |
||||||
|
|
||||||
|
UpdateCommits(value?.TagName ?? SelectedPackage.MainBranch).SafeFireAndForget(); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,233 @@ |
|||||||
|
<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:mocks="clr-namespace:StabilityMatrix.Avalonia.DesignData" |
||||||
|
xmlns:packages="clr-namespace:StabilityMatrix.Core.Models.Packages;assembly=StabilityMatrix.Core" |
||||||
|
xmlns:models="clr-namespace:StabilityMatrix.Core.Models;assembly=StabilityMatrix.Core" |
||||||
|
xmlns:controls1="clr-namespace:FluentAvalonia.UI.Controls;assembly=FluentAvalonia" |
||||||
|
xmlns:input="clr-namespace:FluentAvalonia.UI.Input;assembly=FluentAvalonia" |
||||||
|
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450" |
||||||
|
x:DataType="dialogs:NewInstallerDialogViewModel" |
||||||
|
d:DataContext="{x:Static mocks:DesignData.NewInstallerDialogViewModel}" |
||||||
|
x:Class="StabilityMatrix.Avalonia.Views.Dialogs.NewInstallerDialog"> |
||||||
|
|
||||||
|
<controls:UserControlBase.Resources> |
||||||
|
<input:StandardUICommand x:Key="PackageSelected" |
||||||
|
Command="{Binding OnPackageSelected}"/> |
||||||
|
|
||||||
|
<DataTemplate x:DataType="packages:BaseGitPackage" x:Key="PackageTemplate"> |
||||||
|
<Button Padding="0" |
||||||
|
HorizontalAlignment="Stretch" |
||||||
|
HorizontalContentAlignment="Stretch" |
||||||
|
Margin="4" |
||||||
|
Classes="transparent-full" |
||||||
|
CornerRadius="8" |
||||||
|
Command="{StaticResource PackageSelected}" |
||||||
|
CommandParameter="{Binding }"> |
||||||
|
<controls:Card> |
||||||
|
|
||||||
|
<Grid RowDefinitions="Auto, Auto, Auto, Auto" |
||||||
|
ColumnDefinitions="Auto, *, Auto"> |
||||||
|
<controls:BetterAdvancedImage |
||||||
|
Grid.Row="0" |
||||||
|
Grid.RowSpan="4" |
||||||
|
Grid.Column="0" |
||||||
|
MaxHeight="128" |
||||||
|
MaxWidth="128" |
||||||
|
Stretch="UniformToFill" |
||||||
|
CornerRadius="4" |
||||||
|
Source="{Binding PreviewImageUri}" /> |
||||||
|
<TextBlock Grid.Row="0" |
||||||
|
Grid.Column="1" |
||||||
|
Text="{Binding DisplayName}" |
||||||
|
FontWeight="Light" |
||||||
|
Margin="16,0,0,0" |
||||||
|
FontSize="20" /> |
||||||
|
<TextBlock Grid.Row="1" |
||||||
|
Grid.Column="1" |
||||||
|
Text="{Binding ByAuthor}" |
||||||
|
FontWeight="Light" |
||||||
|
Margin="16,-4,0,0" |
||||||
|
FontSize="13" /> |
||||||
|
|
||||||
|
<TextBlock Grid.Row="0" |
||||||
|
Grid.RowSpan="4" |
||||||
|
Grid.Column="1" |
||||||
|
TextWrapping="Wrap" |
||||||
|
Text="{Binding Blurb}" |
||||||
|
FontWeight="Light" |
||||||
|
Margin="16,0,0,0" |
||||||
|
VerticalAlignment="Center" |
||||||
|
FontSize="16" /> |
||||||
|
|
||||||
|
<ItemsRepeater Grid.Column="1" |
||||||
|
Grid.Row="3" |
||||||
|
Margin="16, 8, 0, 8" |
||||||
|
ItemsSource="{Binding AvailableTorchVersions}"> |
||||||
|
<ItemsRepeater.Layout> |
||||||
|
<StackLayout Orientation="Horizontal" /> |
||||||
|
</ItemsRepeater.Layout> |
||||||
|
<ItemsRepeater.ItemTemplate> |
||||||
|
<DataTemplate DataType="{x:Type models:TorchVersion}"> |
||||||
|
<controls:Card |
||||||
|
Tag="{Binding }" |
||||||
|
HorizontalAlignment="Left" |
||||||
|
Padding="4" |
||||||
|
Margin="0,0,8,0" |
||||||
|
VerticalAlignment="Top"> |
||||||
|
|
||||||
|
<controls:Card.Styles> |
||||||
|
<Style Selector="controls|Card[Tag=Cuda]"> |
||||||
|
<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="NVIDIA" |
||||||
|
TextAlignment="Center" |
||||||
|
VerticalAlignment="Center" /> |
||||||
|
</Template> |
||||||
|
</Setter> |
||||||
|
</Style> |
||||||
|
<Style Selector="controls|Card[Tag=Rocm]"> |
||||||
|
<Setter Property="Background" |
||||||
|
Value="{DynamicResource ThemeDarkRedColor}" /> |
||||||
|
<Setter Property="BorderBrush" |
||||||
|
Value="{DynamicResource ThemeDarkRedColor}" /> |
||||||
|
<Style |
||||||
|
Selector="^ /template/ ContentPresenter#PART_ContentPresenter"> |
||||||
|
<Setter Property="Foreground" |
||||||
|
Value="{DynamicResource ButtonForeground}" /> |
||||||
|
</Style> |
||||||
|
<Setter Property="Content"> |
||||||
|
<Template> |
||||||
|
<TextBlock |
||||||
|
FontWeight="Medium" |
||||||
|
HorizontalAlignment="Center" |
||||||
|
Text="AMD (Linux)" |
||||||
|
TextAlignment="Center" |
||||||
|
VerticalAlignment="Center" |
||||||
|
ToolTip.Tip="For AMD GPUs that support ROCm on Linux" /> |
||||||
|
</Template> |
||||||
|
</Setter> |
||||||
|
</Style> |
||||||
|
<Style Selector="controls|Card[Tag=DirectMl]"> |
||||||
|
<Setter Property="Background" |
||||||
|
Value="{DynamicResource ThemeDarkBlueColor}" /> |
||||||
|
<Setter Property="BorderBrush" |
||||||
|
Value="{DynamicResource ThemeDarkBlueColor}" /> |
||||||
|
<Setter Property="Content"> |
||||||
|
<Template> |
||||||
|
<TextBlock |
||||||
|
FontWeight="Medium" |
||||||
|
HorizontalAlignment="Center" |
||||||
|
Text="DirectML" |
||||||
|
TextAlignment="Center" |
||||||
|
VerticalAlignment="Center" |
||||||
|
ToolTip.Tip="For any DirectX compatible GPU on Windows" /> |
||||||
|
</Template> |
||||||
|
</Setter> |
||||||
|
</Style> |
||||||
|
<Style Selector="controls|Card[Tag=Mps]"> |
||||||
|
<Setter Property="Background" Value="White" /> |
||||||
|
<Setter Property="BorderBrush" Value="White" /> |
||||||
|
<Style |
||||||
|
Selector="^ /template/ ContentPresenter#PART_ContentPresenter"> |
||||||
|
<Setter Property="Foreground" |
||||||
|
Value="{DynamicResource ButtonForeground}" /> |
||||||
|
</Style> |
||||||
|
<Setter Property="Content"> |
||||||
|
<Template> |
||||||
|
<TextBlock |
||||||
|
FontWeight="Medium" |
||||||
|
HorizontalAlignment="Center" |
||||||
|
Text="macOS" |
||||||
|
TextAlignment="Center" |
||||||
|
Foreground="Black" |
||||||
|
VerticalAlignment="Center" /> |
||||||
|
</Template> |
||||||
|
</Setter> |
||||||
|
</Style> |
||||||
|
<Style Selector="controls|Card[Tag=Cpu]"> |
||||||
|
<Setter Property="Background" |
||||||
|
Value="{DynamicResource ThemeBlueGreyColor}" /> |
||||||
|
<Setter Property="BorderBrush" |
||||||
|
Value="{DynamicResource ThemeBlueGreyColor}" /> |
||||||
|
<Style |
||||||
|
Selector="^ /template/ ContentPresenter#PART_ContentPresenter"> |
||||||
|
<Setter Property="Foreground" |
||||||
|
Value="{DynamicResource ButtonForeground}" /> |
||||||
|
</Style> |
||||||
|
<Setter Property="Content"> |
||||||
|
<Template> |
||||||
|
<TextBlock |
||||||
|
FontWeight="Medium" |
||||||
|
HorizontalAlignment="Center" |
||||||
|
Text="CPU" |
||||||
|
TextAlignment="Center" |
||||||
|
VerticalAlignment="Center" /> |
||||||
|
</Template> |
||||||
|
</Setter> |
||||||
|
</Style> |
||||||
|
</controls:Card.Styles> |
||||||
|
</controls:Card> |
||||||
|
</DataTemplate> |
||||||
|
</ItemsRepeater.ItemTemplate> |
||||||
|
</ItemsRepeater> |
||||||
|
|
||||||
|
<controls1:SymbolIcon Grid.Row="0" |
||||||
|
Grid.RowSpan="4" |
||||||
|
Grid.Column="2" |
||||||
|
HorizontalAlignment="Right" |
||||||
|
VerticalAlignment="Center" |
||||||
|
FontSize="24" |
||||||
|
Symbol="ChevronRight" /> |
||||||
|
</Grid> |
||||||
|
</controls:Card> |
||||||
|
</Button> |
||||||
|
</DataTemplate> |
||||||
|
</controls:UserControlBase.Resources> |
||||||
|
|
||||||
|
<Grid> |
||||||
|
<TabControl TabStripPlacement="Top"> |
||||||
|
<TabControl.Items> |
||||||
|
<TabItem Header="Inference" Margin="8,0,0,0"> |
||||||
|
<ScrollViewer Padding="8"> |
||||||
|
<ItemsRepeater ItemsSource="{Binding InferencePackages}"> |
||||||
|
<ItemsRepeater.Layout> |
||||||
|
<StackLayout Orientation="Vertical" /> |
||||||
|
</ItemsRepeater.Layout> |
||||||
|
<ItemsRepeater.ItemTemplate> |
||||||
|
<StaticResource ResourceKey="PackageTemplate" /> |
||||||
|
</ItemsRepeater.ItemTemplate> |
||||||
|
</ItemsRepeater> |
||||||
|
</ScrollViewer> |
||||||
|
</TabItem> |
||||||
|
<TabItem Header="Training"> |
||||||
|
<ScrollViewer Padding="8"> |
||||||
|
<ItemsRepeater ItemsSource="{Binding TrainingPackages}"> |
||||||
|
<ItemsRepeater.Layout> |
||||||
|
<StackLayout Orientation="Vertical" /> |
||||||
|
</ItemsRepeater.Layout> |
||||||
|
<ItemsRepeater.ItemTemplate> |
||||||
|
<StaticResource ResourceKey="PackageTemplate" /> |
||||||
|
</ItemsRepeater.ItemTemplate> |
||||||
|
</ItemsRepeater> |
||||||
|
</ScrollViewer> |
||||||
|
</TabItem> |
||||||
|
</TabControl.Items> |
||||||
|
</TabControl> |
||||||
|
</Grid> |
||||||
|
</controls:UserControlBase> |
@ -0,0 +1,13 @@ |
|||||||
|
using StabilityMatrix.Avalonia.Controls; |
||||||
|
using StabilityMatrix.Core.Attributes; |
||||||
|
|
||||||
|
namespace StabilityMatrix.Avalonia.Views.Dialogs; |
||||||
|
|
||||||
|
[Singleton] |
||||||
|
public partial class NewInstallerDialog : UserControlBase |
||||||
|
{ |
||||||
|
public NewInstallerDialog() |
||||||
|
{ |
||||||
|
InitializeComponent(); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,49 @@ |
|||||||
|
<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:viewModels="clr-namespace:StabilityMatrix.Avalonia.ViewModels" |
||||||
|
xmlns:controls="clr-namespace:StabilityMatrix.Avalonia.Controls" |
||||||
|
xmlns:designData="clr-namespace:StabilityMatrix.Avalonia.DesignData" |
||||||
|
xmlns:ui="clr-namespace:FluentAvalonia.UI.Controls;assembly=FluentAvalonia.BreadcrumbBar" |
||||||
|
xmlns:controls1="clr-namespace:FluentAvalonia.UI.Controls;assembly=FluentAvalonia" |
||||||
|
xmlns:avalonia="clr-namespace:StabilityMatrix.Avalonia" |
||||||
|
xmlns:base="clr-namespace:StabilityMatrix.Avalonia.ViewModels.Base" |
||||||
|
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450" |
||||||
|
x:DataType="viewModels:NewPackageManagerViewModel" |
||||||
|
x:CompileBindings="True" |
||||||
|
d:DataContext="{x:Static designData:DesignData.NewPackageManagerViewModel}" |
||||||
|
x:Class="StabilityMatrix.Avalonia.Views.NewPackageManagerPage"> |
||||||
|
|
||||||
|
<controls:UserControlBase.Resources> |
||||||
|
<!-- Override styles for BreadcrumbBar --> |
||||||
|
<!-- ReSharper disable Xaml.RedundantResource --> |
||||||
|
<x:Double x:Key="BreadcrumbBarItemThemeFontSize">24</x:Double> |
||||||
|
<x:Double x:Key="BreadcrumbBarChevronFontSize">17</x:Double> |
||||||
|
<Thickness x:Key="BreadcrumbBarChevronPadding">6,3</Thickness> |
||||||
|
<FontWeight x:Key="BreadcrumbBarItemFontWeight">Medium</FontWeight> |
||||||
|
<!-- ReSharper restore Xaml.RedundantResource --> |
||||||
|
</controls:UserControlBase.Resources> |
||||||
|
|
||||||
|
<Grid RowDefinitions="Auto,*"> |
||||||
|
<ui:BreadcrumbBar |
||||||
|
Grid.Row="0" |
||||||
|
Margin="16,8" |
||||||
|
x:Name="BreadcrumbBar" |
||||||
|
ItemsSource="{Binding CurrentPagePath}"> |
||||||
|
<ui:BreadcrumbBar.ItemTemplate> |
||||||
|
<DataTemplate x:DataType="base:PageViewModelBase"> |
||||||
|
<ui:BreadcrumbBarItem Content="{Binding Title}" /> |
||||||
|
</DataTemplate> |
||||||
|
</ui:BreadcrumbBar.ItemTemplate> |
||||||
|
</ui:BreadcrumbBar> |
||||||
|
|
||||||
|
<controls1:Frame |
||||||
|
Grid.Row="1" |
||||||
|
Name="FrameView"> |
||||||
|
<controls1:Frame.NavigationPageFactory> |
||||||
|
<avalonia:ViewLocator/> |
||||||
|
</controls1:Frame.NavigationPageFactory> |
||||||
|
</controls1:Frame> |
||||||
|
</Grid> |
||||||
|
</controls:UserControlBase> |
@ -0,0 +1,99 @@ |
|||||||
|
using System; |
||||||
|
using System.ComponentModel; |
||||||
|
using System.Linq; |
||||||
|
using Avalonia.Interactivity; |
||||||
|
using Avalonia.Threading; |
||||||
|
using FluentAvalonia.UI.Controls; |
||||||
|
using FluentAvalonia.UI.Media.Animation; |
||||||
|
using FluentAvalonia.UI.Navigation; |
||||||
|
using Microsoft.Extensions.DependencyInjection; |
||||||
|
using StabilityMatrix.Avalonia.Animations; |
||||||
|
using StabilityMatrix.Avalonia.Controls; |
||||||
|
using StabilityMatrix.Avalonia.Models; |
||||||
|
using StabilityMatrix.Avalonia.Services; |
||||||
|
using StabilityMatrix.Avalonia.ViewModels; |
||||||
|
using StabilityMatrix.Avalonia.ViewModels.Base; |
||||||
|
using StabilityMatrix.Core.Attributes; |
||||||
|
using StabilityMatrix.Core.Models; |
||||||
|
|
||||||
|
namespace StabilityMatrix.Avalonia.Views; |
||||||
|
|
||||||
|
[Singleton] |
||||||
|
public partial class NewPackageManagerPage : UserControlBase, IHandleNavigation |
||||||
|
{ |
||||||
|
private readonly INavigationService<NewPackageManagerViewModel> packageNavigationService; |
||||||
|
|
||||||
|
private bool hasLoaded; |
||||||
|
|
||||||
|
private NewPackageManagerViewModel ViewModel => (NewPackageManagerViewModel)DataContext!; |
||||||
|
|
||||||
|
[DesignOnly(true)] |
||||||
|
[Obsolete("For XAML use only", true)] |
||||||
|
public NewPackageManagerPage() |
||||||
|
: this(App.Services.GetRequiredService<INavigationService<NewPackageManagerViewModel>>()) { } |
||||||
|
|
||||||
|
public NewPackageManagerPage(INavigationService<NewPackageManagerViewModel> packageNavigationService) |
||||||
|
{ |
||||||
|
this.packageNavigationService = packageNavigationService; |
||||||
|
|
||||||
|
InitializeComponent(); |
||||||
|
|
||||||
|
packageNavigationService.SetFrame(FrameView); |
||||||
|
packageNavigationService.TypedNavigation += NavigationService_OnTypedNavigation; |
||||||
|
FrameView.Navigated += FrameView_Navigated; |
||||||
|
BreadcrumbBar.ItemClicked += BreadcrumbBar_ItemClicked; |
||||||
|
} |
||||||
|
|
||||||
|
/// <inheritdoc /> |
||||||
|
protected override void OnLoaded(RoutedEventArgs e) |
||||||
|
{ |
||||||
|
base.OnLoaded(e); |
||||||
|
|
||||||
|
if (!hasLoaded) |
||||||
|
{ |
||||||
|
// Initial load, navigate to first page |
||||||
|
Dispatcher.UIThread.Post( |
||||||
|
() => |
||||||
|
packageNavigationService.NavigateTo( |
||||||
|
ViewModel.SubPages[0], |
||||||
|
new SuppressNavigationTransitionInfo() |
||||||
|
) |
||||||
|
); |
||||||
|
|
||||||
|
hasLoaded = true; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
private void NavigationService_OnTypedNavigation(object? sender, TypedNavigationEventArgs e) |
||||||
|
{ |
||||||
|
ViewModel.CurrentPage = |
||||||
|
ViewModel.SubPages.FirstOrDefault(x => x.GetType() == e.ViewModelType) |
||||||
|
?? e.ViewModel as PageViewModelBase; |
||||||
|
} |
||||||
|
|
||||||
|
private void FrameView_Navigated(object? sender, NavigationEventArgs args) |
||||||
|
{ |
||||||
|
if (args.Content is not PageViewModelBase vm) |
||||||
|
{ |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
ViewModel.CurrentPage = vm; |
||||||
|
} |
||||||
|
|
||||||
|
private void BreadcrumbBar_ItemClicked(BreadcrumbBar sender, BreadcrumbBarItemClickedEventArgs args) |
||||||
|
{ |
||||||
|
// Skip if already on same page |
||||||
|
if (args.Item is not PageViewModelBase viewModel || viewModel == ViewModel.CurrentPage) |
||||||
|
{ |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
packageNavigationService.NavigateTo(viewModel, BetterSlideNavigationTransition.PageSlideFromLeft); |
||||||
|
} |
||||||
|
|
||||||
|
public bool GoBack() |
||||||
|
{ |
||||||
|
return packageNavigationService.GoBack(); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,195 @@ |
|||||||
|
<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:viewModels="clr-namespace:StabilityMatrix.Avalonia.ViewModels" |
||||||
|
xmlns:controls="clr-namespace:StabilityMatrix.Avalonia.Controls" |
||||||
|
xmlns:designData="clr-namespace:StabilityMatrix.Avalonia.DesignData" |
||||||
|
xmlns:lang="clr-namespace:StabilityMatrix.Avalonia.Languages" |
||||||
|
xmlns:avalonia="clr-namespace:FluentIcons.Avalonia;assembly=FluentIcons.Avalonia" |
||||||
|
xmlns:controls1="clr-namespace:FluentAvalonia.UI.Controls;assembly=FluentAvalonia" |
||||||
|
xmlns:models="clr-namespace:StabilityMatrix.Core.Models;assembly=StabilityMatrix.Core" |
||||||
|
xmlns:database="clr-namespace:StabilityMatrix.Core.Models.Database;assembly=StabilityMatrix.Core" |
||||||
|
xmlns:extensions="clr-namespace:StabilityMatrix.Core.Models.Packages.Extensions;assembly=StabilityMatrix.Core" |
||||||
|
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450" |
||||||
|
x:DataType="viewModels:PackageInstallDetailViewModel" |
||||||
|
x:CompileBindings="True" |
||||||
|
d:DataContext="{x:Static designData:DesignData.PackageInstallDetailViewModel}" |
||||||
|
x:Class="StabilityMatrix.Avalonia.Views.PackageInstallDetailView"> |
||||||
|
|
||||||
|
<Grid ColumnDefinitions="Auto, *" |
||||||
|
RowDefinitions="Auto, *"> |
||||||
|
<controls:BetterAdvancedImage |
||||||
|
MaxHeight="300" |
||||||
|
MaxWidth="300" |
||||||
|
Margin="16,16,8,8" |
||||||
|
CornerRadius="8" |
||||||
|
VerticalAlignment="Top" |
||||||
|
Stretch="UniformToFill" |
||||||
|
Source="{Binding SelectedPackage.PreviewImageUri}" /> |
||||||
|
<StackPanel Grid.Row="0" Grid.Column="1" |
||||||
|
Margin="8" |
||||||
|
Orientation="Vertical"> |
||||||
|
|
||||||
|
<controls:HyperlinkIconButton NavigateUri="{Binding SelectedPackage.LicenseUrl}" |
||||||
|
Content="{Binding SelectedPackage.LicenseType}"/> |
||||||
|
|
||||||
|
<ToggleSwitch OnContent="{x:Static lang:Resources.Label_Releases}" |
||||||
|
OffContent="{x:Static lang:Resources.Label_Branches}" |
||||||
|
IsVisible="{Binding ShowReleaseMode}" |
||||||
|
IsChecked="{Binding IsReleaseMode}" |
||||||
|
Margin="8,0,8,8" /> |
||||||
|
|
||||||
|
<!-- Version Selector --> |
||||||
|
<Label Margin="8,0" |
||||||
|
FontSize="14" |
||||||
|
FontWeight="Light" |
||||||
|
Content="{Binding ReleaseLabelText}" /> |
||||||
|
|
||||||
|
<controls1:FAComboBox |
||||||
|
ItemsSource="{Binding AvailableVersions}" |
||||||
|
MinWidth="250" |
||||||
|
HorizontalAlignment="Stretch" |
||||||
|
VerticalAlignment="Stretch" |
||||||
|
FontSize="16" |
||||||
|
Margin="8,0,8,8" |
||||||
|
SelectedItem="{Binding SelectedVersion}"> |
||||||
|
<controls1:FAComboBox.ItemTemplate> |
||||||
|
<DataTemplate DataType="{x:Type models:PackageVersion}"> |
||||||
|
<TextBlock |
||||||
|
Name="NameTextBlock" |
||||||
|
VerticalAlignment="Center" |
||||||
|
Text="{Binding TagName}" /> |
||||||
|
</DataTemplate> |
||||||
|
</controls1:FAComboBox.ItemTemplate> |
||||||
|
</controls1:FAComboBox> |
||||||
|
|
||||||
|
<Label Margin="8,0" |
||||||
|
FontSize="14" |
||||||
|
FontWeight="Light" |
||||||
|
ToolTip.Tip="This will also be the folder name" |
||||||
|
Content="{x:Static lang:Resources.Label_DisplayName}" /> |
||||||
|
<TextBox MinWidth="250" |
||||||
|
Margin="8,0" |
||||||
|
FontSize="16" |
||||||
|
FontWeight="SemiLight" |
||||||
|
VerticalAlignment="Stretch" |
||||||
|
VerticalContentAlignment="Center" |
||||||
|
ToolTip.Tip="This will also be the folder name" |
||||||
|
Text="{Binding InstallName, Mode=TwoWay}" /> |
||||||
|
<Label Margin="8,0" |
||||||
|
Content="{Binding FullInstallPath}" Foreground="LightGray" /> |
||||||
|
|
||||||
|
<StackPanel Orientation="Horizontal" |
||||||
|
Margin="8,8,8,8" |
||||||
|
IsVisible="{Binding ShowDuplicateWarning}"> |
||||||
|
<avalonia:SymbolIcon |
||||||
|
Foreground="{DynamicResource ThemeRedColor}" |
||||||
|
Margin="0,0,8,0" |
||||||
|
Symbol="Alert" /> |
||||||
|
<TextBlock |
||||||
|
Foreground="{DynamicResource ThemeRedColor}" |
||||||
|
TextAlignment="Left" |
||||||
|
TextWrapping="Wrap"> |
||||||
|
<Run Text="{x:Static lang:Resources.Label_InstallationWithThisNameExists}" /> |
||||||
|
<LineBreak /> |
||||||
|
<Run Text="{x:Static lang:Resources.Label_PleaseChooseDifferentName}" /> |
||||||
|
</TextBlock> |
||||||
|
</StackPanel> |
||||||
|
|
||||||
|
<Expander Header="Extensions" |
||||||
|
FontSize="16" |
||||||
|
HorizontalAlignment="Stretch" |
||||||
|
IsVisible="{Binding ShowExtensions}" |
||||||
|
Margin="8"> |
||||||
|
<ItemsRepeater ItemsSource="{Binding AvailableExtensions}"> |
||||||
|
<ItemsRepeater.Layout> |
||||||
|
<UniformGridLayout MinColumnSpacing="4" MinRowSpacing="4"/> |
||||||
|
</ItemsRepeater.Layout> |
||||||
|
<ItemsRepeater.ItemTemplate> |
||||||
|
<DataTemplate x:DataType="{x:Type viewModels:ExtensionViewModel}"> |
||||||
|
<CheckBox IsChecked="{Binding IsSelected, Mode=TwoWay}" |
||||||
|
Content="{Binding Extension.DisplayName}"/> |
||||||
|
</DataTemplate> |
||||||
|
</ItemsRepeater.ItemTemplate> |
||||||
|
</ItemsRepeater> |
||||||
|
</Expander> |
||||||
|
|
||||||
|
<Expander Header="{x:Static lang:Resources.Label_AdvancedOptions}" |
||||||
|
FontSize="16" |
||||||
|
HorizontalAlignment="Stretch" |
||||||
|
Margin="8"> |
||||||
|
<Grid ColumnDefinitions="*, *, *" |
||||||
|
RowDefinitions="Auto, Auto" |
||||||
|
Margin="8,0"> |
||||||
|
|
||||||
|
<Label Grid.Row="0" Grid.Column="0" |
||||||
|
Content="{x:Static lang:Resources.Label_SharedModelFolderStrategy}" |
||||||
|
Margin="0,0,0,4" /> |
||||||
|
<controls1:FAComboBox Grid.Row="1" Grid.Column="0" |
||||||
|
ItemsSource="{Binding SelectedPackage.AvailableSharedFolderMethods}" |
||||||
|
MinWidth="150" |
||||||
|
MinHeight="38" |
||||||
|
SelectedItem="{Binding SelectedSharedFolderMethod}"> |
||||||
|
<controls1:FAComboBox.ItemTemplate> |
||||||
|
<DataTemplate DataType="{x:Type models:SharedFolderMethod}"> |
||||||
|
<TextBlock |
||||||
|
Margin="8,4,0,4" |
||||||
|
Text="{Binding }" /> |
||||||
|
</DataTemplate> |
||||||
|
</controls1:FAComboBox.ItemTemplate> |
||||||
|
</controls1:FAComboBox> |
||||||
|
|
||||||
|
<Label Grid.Row="0" Grid.Column="1" |
||||||
|
Content="{x:Static lang:Resources.Label_PyTorchVersion}" |
||||||
|
IsVisible="{Binding ShowTorchVersionOptions}" |
||||||
|
Margin="0,0,0,4" /> |
||||||
|
<controls1:FAComboBox Grid.Row="1" Grid.Column="1" |
||||||
|
ItemsSource="{Binding SelectedPackage.AvailableTorchVersions}" |
||||||
|
MinWidth="150" |
||||||
|
MinHeight="38" |
||||||
|
IsVisible="{Binding ShowTorchVersionOptions}" |
||||||
|
SelectedItem="{Binding SelectedTorchVersion}"> |
||||||
|
<controls1:FAComboBox.ItemTemplate> |
||||||
|
<DataTemplate DataType="{x:Type models:TorchVersion}"> |
||||||
|
<TextBlock |
||||||
|
Margin="8,4,0,4" |
||||||
|
Text="{Binding }" /> |
||||||
|
</DataTemplate> |
||||||
|
</controls1:FAComboBox.ItemTemplate> |
||||||
|
</controls1:FAComboBox> |
||||||
|
|
||||||
|
<Label Grid.Row="0" Grid.Column="2" |
||||||
|
Content="{x:Static lang:Resources.Label_Commit}" |
||||||
|
Margin="0,0,0,4" |
||||||
|
IsVisible="{Binding !IsReleaseMode}" /> |
||||||
|
<controls1:FAComboBox Grid.Row="1" Grid.Column="2" |
||||||
|
IsVisible="{Binding !IsReleaseMode}" |
||||||
|
ItemsSource="{Binding AvailableCommits}" |
||||||
|
MinWidth="150" |
||||||
|
MinHeight="38" |
||||||
|
SelectedItem="{Binding SelectedCommit}"> |
||||||
|
<controls1:FAComboBox.ItemTemplate> |
||||||
|
<DataTemplate DataType="{x:Type database:GitCommit}"> |
||||||
|
<TextBlock |
||||||
|
Margin="8,4,0,4" |
||||||
|
Name="NameTextBlock" |
||||||
|
Text="{Binding ShortSha}" /> |
||||||
|
</DataTemplate> |
||||||
|
</controls1:FAComboBox.ItemTemplate> |
||||||
|
</controls1:FAComboBox> |
||||||
|
</Grid> |
||||||
|
</Expander> |
||||||
|
|
||||||
|
<Button Classes="success" |
||||||
|
Margin="8,8,8,8" |
||||||
|
HorizontalAlignment="Stretch" |
||||||
|
VerticalAlignment="Stretch" |
||||||
|
FontSize="16" |
||||||
|
Command="{Binding InstallCommand}" |
||||||
|
Content="{x:Static lang:Resources.Action_Install}" /> |
||||||
|
|
||||||
|
</StackPanel> |
||||||
|
</Grid> |
||||||
|
|
||||||
|
</controls:UserControlBase> |
@ -0,0 +1,13 @@ |
|||||||
|
using StabilityMatrix.Avalonia.Controls; |
||||||
|
using StabilityMatrix.Core.Attributes; |
||||||
|
|
||||||
|
namespace StabilityMatrix.Avalonia.Views; |
||||||
|
|
||||||
|
[Transient] |
||||||
|
public partial class PackageInstallDetailView : UserControlBase |
||||||
|
{ |
||||||
|
public PackageInstallDetailView() |
||||||
|
{ |
||||||
|
InitializeComponent(); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,15 @@ |
|||||||
|
using StabilityMatrix.Core.Models.FileInterfaces; |
||||||
|
using StabilityMatrix.Core.Models.Packages.Extensions; |
||||||
|
using StabilityMatrix.Core.Models.Progress; |
||||||
|
|
||||||
|
namespace StabilityMatrix.Core.Models.PackageModification; |
||||||
|
|
||||||
|
public class InstallExtensionStep(ExtensionBase extension, DirectoryPath extensionsDir) : IPackageStep |
||||||
|
{ |
||||||
|
public Task ExecuteAsync(IProgress<ProgressReport>? progress = null) |
||||||
|
{ |
||||||
|
return extension.InstallExtensionAsync(extensionsDir, extension.MainBranch); |
||||||
|
} |
||||||
|
|
||||||
|
public string ProgressTitle => $"Installing {extension.DisplayName}"; |
||||||
|
} |
@ -0,0 +1,7 @@ |
|||||||
|
namespace StabilityMatrix.Core.Models; |
||||||
|
|
||||||
|
public enum PackageType |
||||||
|
{ |
||||||
|
SdInference, |
||||||
|
SdTraining |
||||||
|
} |
@ -0,0 +1,28 @@ |
|||||||
|
using StabilityMatrix.Core.Helper; |
||||||
|
using StabilityMatrix.Core.Models.FileInterfaces; |
||||||
|
|
||||||
|
namespace StabilityMatrix.Core.Models.Packages.Extensions; |
||||||
|
|
||||||
|
public class ComfyManager(IPrerequisiteHelper prerequisiteHelper) : ExtensionBase |
||||||
|
{ |
||||||
|
public override string RepoName => "ComfyUI-Manager"; |
||||||
|
public override string DisplayName { get; set; } = "ComfyUI Manager"; |
||||||
|
public override string Author => "ltdrdata"; |
||||||
|
|
||||||
|
public override string Blurb => |
||||||
|
"ComfyUI-Manager is an extension designed to enhance the usability of ComfyUI. It offers management functions to install, remove, disable, and enable various custom nodes of ComfyUI."; |
||||||
|
|
||||||
|
public override IEnumerable<string> CompatibleWith => [nameof(ComfyUI)]; |
||||||
|
public override string MainBranch => "main"; |
||||||
|
|
||||||
|
public override Task InstallExtensionAsync( |
||||||
|
DirectoryPath installDirectory, |
||||||
|
string branch, |
||||||
|
CancellationToken cancellationToken = default |
||||||
|
) |
||||||
|
{ |
||||||
|
return Directory.Exists(Path.Combine(installDirectory, RepoName)) |
||||||
|
? Task.CompletedTask |
||||||
|
: prerequisiteHelper.RunGit(new[] { "clone", GithubUrl }, installDirectory); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,24 @@ |
|||||||
|
using StabilityMatrix.Core.Models.FileInterfaces; |
||||||
|
|
||||||
|
namespace StabilityMatrix.Core.Models.Packages.Extensions; |
||||||
|
|
||||||
|
public abstract class ExtensionBase |
||||||
|
{ |
||||||
|
public string ByAuthor => $"By {Author}"; |
||||||
|
|
||||||
|
public abstract string RepoName { get; } |
||||||
|
public abstract string DisplayName { get; set; } |
||||||
|
public abstract string Author { get; } |
||||||
|
|
||||||
|
public abstract string Blurb { get; } |
||||||
|
public abstract IEnumerable<string> CompatibleWith { get; } |
||||||
|
public abstract string MainBranch { get; } |
||||||
|
|
||||||
|
public abstract Task InstallExtensionAsync( |
||||||
|
DirectoryPath installDirectory, |
||||||
|
string branch, |
||||||
|
CancellationToken cancellationToken = default |
||||||
|
); |
||||||
|
|
||||||
|
public string GithubUrl => $"https://github.com/{Author}/{RepoName}"; |
||||||
|
} |
Loading…
Reference in new issue