Skip to content

Commit 3b8b8cc

Browse files
committed
2 parents 9ac2b91 + e626c47 commit 3b8b8cc

38 files changed

+280
-89
lines changed

CHANGELOG.md

+18
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,24 @@ All notable changes to Stability Matrix will be documented in this file.
55
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
66
and this project adheres to [Semantic Versioning 2.0](https://semver.org/spec/v2.0.0.html).
77

8+
## v2.10.1
9+
### Added
10+
- Added SVD Shared Model & Output Folders for Forge (fixes [#580](https://github.com/LykosAI/StabilityMatrix/issues/580))
11+
### Changed
12+
- Improved error message when logging in with a Lykos account fails due to incorrect email or password
13+
- Model Browser & Workflow Browser now auto-load when first navigating to those pages
14+
- Removed update confirmation dialog, instead showing the new version in the update button tooltip
15+
### Fixed
16+
- Fixed package launch not working when environment variable `SETUPTOOLS_USE_DISTUTILS` is set due to conflict with a default environment variable. User environment variables will now correctly override any default environment variables.
17+
- Fixed "No refresh token found" error when failing to login with Lykos account in some cases
18+
- Fixed blank entries appearing in the Categories dropdown on the Checkpoints page
19+
- Fixed crash when loading invalid connected model info files
20+
- Fixed [#585](https://github.com/LykosAI/StabilityMatrix/issues/585) - Crash when drag & drop source and destination are the same
21+
- Fixed [#584](https://github.com/LykosAI/StabilityMatrix/issues/584) - `--launch-package` argument not working
22+
- Fixed [#581](https://github.com/LykosAI/StabilityMatrix/issues/581) - Inference teaching tip showing more often than it should
23+
- Fixed [#578](https://github.com/LykosAI/StabilityMatrix/issues/578) - "python setup.py egg_info did not run successfully" failure when installing Auto1111 or SDWebUI Forge
24+
- Fixed [#574](https://github.com/LykosAI/StabilityMatrix/issues/574) - local images not showing on macOS or Linux
25+
826
## v2.10.0
927
### Added
1028
- Added Reference-Only mode for Inference ControlNet, used for guiding the sampler with an image without a pretrained model. Part of the latent and attention layers will be connected to the reference image, similar to Image to Image or Inpainting.

StabilityMatrix.Avalonia/Controls/Inference/ImageFolderCard.axaml

+4-1
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
xmlns:scroll="clr-namespace:StabilityMatrix.Avalonia.Controls.Scroll"
1212
xmlns:labs="clr-namespace:Avalonia.Labs.Controls;assembly=Avalonia.Labs.Controls"
1313
xmlns:vendorLabs="clr-namespace:StabilityMatrix.Avalonia.Controls.VendorLabs"
14+
xmlns:converters="clr-namespace:StabilityMatrix.Avalonia.Converters"
1415
x:DataType="vmInference:ImageFolderCardViewModel">
1516

1617
<Design.PreviewWith>
@@ -20,6 +21,8 @@
2021
</Grid>
2122
</Panel>
2223
</Design.PreviewWith>
24+
25+
<converters:FileUriConverter x:Key="FileUriConverter" />
2326

2427
<ControlTheme x:Key="{x:Type controls:ImageFolderCard}" TargetType="controls:ImageFolderCard">
2528
<Setter Property="Background" Value="Transparent" />
@@ -200,7 +203,7 @@
200203
<vendorLabs:BetterAsyncImage
201204
Width="{Binding $parent[ItemsRepeater].((vmInference:ImageFolderCardViewModel)DataContext).ImageSize.Width}"
202205
Height="{Binding $parent[ItemsRepeater].((vmInference:ImageFolderCardViewModel)DataContext).ImageSize.Height}"
203-
Source="{Binding AbsolutePath}"
206+
Source="{Binding AbsolutePath, Converter={StaticResource FileUriConverter}}"
204207
Stretch="UniformToFill" />
205208

206209
<Border

StabilityMatrix.Avalonia/Controls/Inference/PromptCard.axaml

+1-1
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@
7272
<ui:TeachingTip
7373
Target="{Binding #PART_HelpButton}"
7474
Title="{x:Static lang:Resources.TeachingTip_InferencePromptHelpButton}"
75-
IsOpen="{Binding IsHelpButtonTeachingTipOpen}"/>
75+
IsOpen="{Binding IsHelpButtonTeachingTipOpen, Mode=TwoWay}"/>
7676
</Panel>
7777

7878
<Button

StabilityMatrix.Avalonia/Converters/FileUriConverter.cs

+1
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ public class FileUriConverter : IValueConverter
1717

1818
return value switch
1919
{
20+
string str when str.StartsWith("avares://") => new Uri(str),
2021
string str => new Uri("file://" + str),
2122
IFormattable formattable => new Uri("file://" + formattable.ToString(null, culture)),
2223
_ => null

StabilityMatrix.Avalonia/Services/INavigationService.cs

+1
Original file line numberDiff line numberDiff line change
@@ -39,4 +39,5 @@ void NavigateTo(
3939
bool GoBack();
4040

4141
bool CanGoBack { get; }
42+
object? CurrentPageDataContext { get; }
4243
}

StabilityMatrix.Avalonia/Services/NavigationService.cs

+3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
using System;
22
using System.Linq;
3+
using Avalonia.Controls;
34
using FluentAvalonia.UI.Controls;
45
using FluentAvalonia.UI.Media.Animation;
56
using FluentAvalonia.UI.Navigation;
@@ -190,4 +191,6 @@ public bool GoBack()
190191
}
191192

192193
public bool CanGoBack => _frame?.CanGoBack ?? false;
194+
195+
public object? CurrentPageDataContext => (_frame?.Content as Control)?.DataContext;
193196
}

StabilityMatrix.Avalonia/ViewModels/CheckpointBrowser/CivitAiBrowserViewModel.cs

+2
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,8 @@ public override void OnLoaded()
177177
model => model.ShowNsfw,
178178
settings => settings.ModelBrowserNsfwEnabled
179179
);
180+
181+
SearchModelsCommand.ExecuteAsync(false);
180182
}
181183

182184
/// <summary>

StabilityMatrix.Avalonia/ViewModels/CheckpointManager/CheckpointFile.cs

+10-3
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,14 @@
33
using System.Collections.ObjectModel;
44
using System.IO;
55
using System.Linq;
6+
using System.Text.Json;
67
using System.Threading.Tasks;
78
using Avalonia.Data;
89
using CommunityToolkit.Mvvm.ComponentModel;
910
using CommunityToolkit.Mvvm.Input;
1011
using FluentAvalonia.UI.Controls;
1112
using Microsoft.Extensions.DependencyInjection;
1213
using NLog;
13-
using StabilityMatrix.Avalonia.Languages;
1414
using StabilityMatrix.Avalonia.ViewModels.Base;
1515
using StabilityMatrix.Core.Attributes;
1616
using StabilityMatrix.Core.Extensions;
@@ -333,8 +333,15 @@ public static IEnumerable<CheckpointFile> FromDirectoryIndex(
333333
if (File.Exists(jsonPath))
334334
{
335335
var json = File.ReadAllText(jsonPath);
336-
var connectedModelInfo = ConnectedModelInfo.FromJson(json);
337-
checkpointFile.ConnectedModel = connectedModelInfo;
336+
try
337+
{
338+
var connectedModelInfo = ConnectedModelInfo.FromJson(json);
339+
checkpointFile.ConnectedModel = connectedModelInfo;
340+
}
341+
catch (JsonException)
342+
{
343+
checkpointFile.ConnectedModel = null;
344+
}
338345
}
339346

340347
checkpointFile.PreviewImagePath = SupportedImageExtensions

StabilityMatrix.Avalonia/ViewModels/CheckpointManager/CheckpointFolder.cs

+18-1
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,8 @@ public partial class CheckpointFolder : ViewModelBase
9292

9393
public string TitleWithFilesCount =>
9494
CheckpointFiles.Any() || SubFolders.Any(f => f.CheckpointFiles.Any())
95-
? $"{FolderType.GetDescription() ?? FolderType.GetStringValue()} ({CheckpointFiles.Count + SubFolders.Sum(folder => folder.CheckpointFiles.Count)})"
95+
? $"{FolderType.GetDescription() ?? (string.IsNullOrWhiteSpace(FolderType.GetStringValue()) ? Path.GetFileName(DirectoryPath) : FolderType.GetStringValue())} "
96+
+ $"({CheckpointFiles.Count + SubFolders.Sum(folder => folder.CheckpointFiles.Count)})"
9697
: FolderType.GetDescription() ?? FolderType.GetStringValue();
9798

9899
public ProgressViewModel Progress { get; } = new();
@@ -447,6 +448,22 @@ public async Task ImportFilesAsync(IEnumerable<string> files, bool convertToConn
447448
Progress.Value = 0;
448449
var copyPaths = files.ToDictionary(k => k, v => Path.Combine(DirectoryPath, Path.GetFileName(v)));
449450

451+
// remove files that are already in the folder
452+
foreach (var (source, destination) in copyPaths)
453+
{
454+
if (source == destination)
455+
{
456+
copyPaths.Remove(source);
457+
}
458+
}
459+
460+
if (copyPaths.Count == 0)
461+
{
462+
Progress.Text = "Import complete";
463+
Progress.Value = 100;
464+
return;
465+
}
466+
450467
var progress = new Progress<ProgressReport>(report =>
451468
{
452469
Progress.IsIndeterminate = false;

StabilityMatrix.Avalonia/ViewModels/Dialogs/LykosLoginViewModel.cs

+10-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
using System;
22
using System.Collections.Generic;
33
using System.ComponentModel.DataAnnotations;
4+
using System.Net;
45
using System.Threading.Tasks;
56
using CommunityToolkit.Mvvm.ComponentModel;
67
using CommunityToolkit.Mvvm.Input;
@@ -90,7 +91,15 @@ private async Task LoginAsync()
9091
}
9192
catch (ApiException e)
9293
{
93-
LoginError = new AppException("Failed to login", $"{e.StatusCode} - {e.Message}");
94+
LoginError = e.StatusCode switch
95+
{
96+
HttpStatusCode.Unauthorized
97+
=> new AppException(
98+
"Incorrect email or password",
99+
"Please try again or reset your password"
100+
),
101+
_ => new AppException("Failed to login", $"{e.StatusCode} - {e.Message}")
102+
};
94103
}
95104
}
96105

StabilityMatrix.Avalonia/ViewModels/OpenArtBrowserViewModel.cs

+2-3
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@
1212
using FluentAvalonia.UI.Controls;
1313
using Refit;
1414
using StabilityMatrix.Avalonia.Controls;
15-
using StabilityMatrix.Avalonia.Languages;
1615
using StabilityMatrix.Avalonia.Models;
1716
using StabilityMatrix.Avalonia.Services;
1817
using StabilityMatrix.Avalonia.ViewModels.Base;
@@ -36,8 +35,7 @@ public partial class OpenArtBrowserViewModel(
3635
IOpenArtApi openArtApi,
3736
INotificationService notificationService,
3837
ISettingsManager settingsManager,
39-
IPackageFactory packageFactory,
40-
ServiceManager<ViewModelBase> vmFactory
38+
IPackageFactory packageFactory
4139
) : TabViewModelBase, IInfinitelyScroll
4240
{
4341
private const int PageSize = 20;
@@ -90,6 +88,7 @@ protected override void OnInitialLoaded()
9088
{
9189
searchResultsCache.Connect().DeferUntilLoaded().Bind(SearchResults).Subscribe();
9290
SelectedSortMode = AllSortModes.First();
91+
DoSearch().SafeFireAndForget();
9392
}
9493

9594
[RelayCommand]

StabilityMatrix.Avalonia/ViewModels/PackageManager/PackageCardViewModel.cs

+8-15
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,9 @@ RunningPackageService runningPackageService
9595
[ObservableProperty]
9696
private bool showWebUiButton;
9797

98+
[ObservableProperty]
99+
private DownloadPackageVersionOptions? updateVersion;
100+
98101
private void RunningPackagesOnCollectionChanged(object? sender, NotifyCollectionChangedEventArgs e)
99102
{
100103
if (runningPackageService.RunningPackages.Select(x => x.Value) is not { } runningPackages)
@@ -196,6 +199,10 @@ and not UnknownPackage
196199
}
197200

198201
IsUpdateAvailable = await HasUpdate();
202+
if (IsUpdateAvailable)
203+
{
204+
UpdateVersion = await basePackage.GetUpdate(currentPackage);
205+
}
199206

200207
if (
201208
Package != null
@@ -426,21 +433,6 @@ public async Task Update()
426433
versionOptions.CommitHash = latest.Sha;
427434
}
428435

429-
var confirmationDialog = new BetterContentDialog
430-
{
431-
Title = Resources.Label_AreYouSure,
432-
Content =
433-
$"{Package.DisplayName} will be updated to the latest version ({versionOptions.GetReadableVersionString()})",
434-
PrimaryButtonText = Resources.Action_Continue,
435-
SecondaryButtonText = Resources.Action_Cancel,
436-
DefaultButton = ContentDialogButton.Primary,
437-
IsSecondaryButtonEnabled = true,
438-
};
439-
440-
var dialogResult = await confirmationDialog.ShowAsync();
441-
if (dialogResult != ContentDialogResult.Primary)
442-
return;
443-
444436
var updatePackageStep = new UpdatePackageStep(
445437
settingsManager,
446438
Package,
@@ -672,6 +664,7 @@ private async Task<bool> HasUpdate()
672664
try
673665
{
674666
var hasUpdate = await basePackage.CheckForUpdates(Package);
667+
UpdateVersion = await basePackage.GetUpdate(Package);
675668

676669
await using (settingsManager.BeginTransaction())
677670
{

StabilityMatrix.Avalonia/ViewModels/PackageManager/PackageInstallDetailViewModel.cs

+7
Original file line numberDiff line numberDiff line change
@@ -283,6 +283,13 @@ private async Task Install()
283283

284284
if (!runner.Failed)
285285
{
286+
if (ReferenceEquals(this, packageNavigationService.CurrentPageDataContext))
287+
{
288+
packageNavigationService.GoBack();
289+
packageNavigationService.GoBack();
290+
await Task.Delay(100);
291+
}
292+
286293
EventManager.Instance.OnInstalledPackagesChanged();
287294
}
288295
}

StabilityMatrix.Avalonia/ViewModels/PackageManagerViewModel.cs

+40-5
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ public partial class PackageManagerViewModel : PageViewModelBase
4242
private readonly INotificationService notificationService;
4343
private readonly INavigationService<NewPackageManagerViewModel> packageNavigationService;
4444
private readonly ILogger<PackageManagerViewModel> logger;
45+
private readonly RunningPackageService runningPackageService;
4546

4647
public override string Title => Resources.Label_Packages;
4748
public override IconSource IconSource => new SymbolIconSource { Symbol = Symbol.Box, IsFilled = true };
@@ -69,14 +70,16 @@ public PackageManagerViewModel(
6970
ServiceManager<ViewModelBase> dialogFactory,
7071
INotificationService notificationService,
7172
INavigationService<NewPackageManagerViewModel> packageNavigationService,
72-
ILogger<PackageManagerViewModel> logger
73+
ILogger<PackageManagerViewModel> logger,
74+
RunningPackageService runningPackageService
7375
)
7476
{
7577
this.settingsManager = settingsManager;
7678
this.dialogFactory = dialogFactory;
7779
this.notificationService = notificationService;
7880
this.packageNavigationService = packageNavigationService;
7981
this.logger = logger;
82+
this.runningPackageService = runningPackageService;
8083

8184
EventManager.Instance.InstalledPackagesChanged += OnInstalledPackagesChanged;
8285
EventManager.Instance.OneClickInstallFinished += OnOneClickInstallFinished;
@@ -118,15 +121,39 @@ public void SetUnknownPackages(IEnumerable<InstalledPackage> packages)
118121
unknownInstalledPackages.Edit(s => s.Load(packages));
119122
}
120123

124+
protected override async Task OnInitialLoadedAsync()
125+
{
126+
if (string.IsNullOrWhiteSpace(Program.Args.LaunchPackageName))
127+
{
128+
await base.OnInitialLoadedAsync();
129+
return;
130+
}
131+
132+
await LoadPackages();
133+
134+
var package = Packages.FirstOrDefault(x => x.DisplayName == Program.Args.LaunchPackageName);
135+
if (package is not null)
136+
{
137+
await runningPackageService.StartPackage(package);
138+
return;
139+
}
140+
141+
package = Packages.FirstOrDefault(x => x.Id.ToString() == Program.Args.LaunchPackageName);
142+
if (package is null)
143+
{
144+
await base.OnInitialLoadedAsync();
145+
return;
146+
}
147+
148+
await runningPackageService.StartPackage(package);
149+
}
150+
121151
public override async Task OnLoadedAsync()
122152
{
123153
if (Design.IsDesignMode || !settingsManager.IsLibraryDirSet)
124154
return;
125155

126-
installedPackages.EditDiff(settingsManager.Settings.InstalledPackages, InstalledPackage.Comparer);
127-
128-
var currentUnknown = await Task.Run(IndexUnknownPackages);
129-
unknownInstalledPackages.Edit(s => s.Load(currentUnknown));
156+
await LoadPackages();
130157

131158
timer.Start();
132159
}
@@ -142,6 +169,14 @@ public void ShowInstallDialog(BasePackage? selectedPackage = null)
142169
NavigateToSubPage(typeof(PackageInstallBrowserViewModel));
143170
}
144171

172+
private async Task LoadPackages()
173+
{
174+
installedPackages.EditDiff(settingsManager.Settings.InstalledPackages, InstalledPackage.Comparer);
175+
176+
var currentUnknown = await Task.Run(IndexUnknownPackages);
177+
unknownInstalledPackages.Edit(s => s.Load(currentUnknown));
178+
}
179+
145180
private async Task CheckPackagesForUpdates()
146181
{
147182
foreach (var package in PackageCards)

StabilityMatrix.Avalonia/Views/CheckpointsPage.axaml

+3-2
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
x:Key="TextDropShadowEffect" />
3232

3333
<converters:EnumStringConverter x:Key="EnumStringConverter" />
34+
<converters:FileUriConverter x:Key="FileUriConverter"/>
3435

3536
<!-- Template for a single badge -->
3637
<DataTemplate DataType="{x:Type system:String}" x:Key="BadgeTemplate">
@@ -143,7 +144,7 @@
143144
<vendorLabs:BetterAsyncImage
144145
Margin="0,0,0,4"
145146
CornerRadius="4"
146-
Source="{Binding PreviewImagePath}"
147+
Source="{Binding PreviewImagePath, Converter={StaticResource FileUriConverter}}"
147148
Stretch="Uniform"
148149
IsVisible="{Binding IsConnectedModel}" />
149150
<TextBlock
@@ -182,7 +183,7 @@
182183
Grid.ColumnSpan="2"
183184
Margin="0, 4,0,4"
184185
CornerRadius="8"
185-
Source="{Binding PreviewImagePath}"
186+
Source="{Binding PreviewImagePath, Converter={StaticResource FileUriConverter}}"
186187
ClipToBounds="True"
187188
Stretch="UniformToFill"
188189
Height="300"

StabilityMatrix.Avalonia/Views/Dialogs/LykosLoginDialog.axaml

+1
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
xmlns:mdxaml="https://github.com/whistyun/Markdown.Avalonia.Tight"
1515
xmlns:ctxt="clr-namespace:ColorTextBlock.Avalonia;assembly=ColorTextBlock.Avalonia"
1616
Focusable="True"
17+
MaxWidth="400"
1718
d:DataContext="{x:Static mocks:DesignData.LykosLoginViewModel}"
1819
d:DesignHeight="350"
1920
d:DesignWidth="400"

0 commit comments

Comments
 (0)