Skip to content

Commit 1825be9

Browse files
authored
Merge pull request #685 from ionite34/2.11.1
2.11.1
2 parents 69585e4 + f515fcf commit 1825be9

35 files changed

+887
-278
lines changed

.github/workflows/stale.yml

+39
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
name: 'Close stale issues'
2+
3+
permissions:
4+
issues: write
5+
pull-requests: write
6+
7+
on:
8+
workflow_dispatch:
9+
schedule:
10+
- cron: '30 1 * * *'
11+
12+
jobs:
13+
stale:
14+
runs-on: ubuntu-latest
15+
steps:
16+
- uses: actions/stale@v9
17+
with:
18+
stale-issue-message: 'This issue is pending because it has been awaiting a response for 14 days with no activity. Remove the pending label or comment, else this will be closed in 5 days.'
19+
close-issue-message: 'This issue was closed because it has been pending for 5 days with no activity.'
20+
only-labels: 'awaiting-feedback'
21+
stale-issue-label: 'pending'
22+
exempt-issue-labels: 'planned,milestone,work-in-progress'
23+
days-before-issue-stale: 14
24+
days-before-issue-close: 5
25+
days-before-pr-close: -1
26+
days-before-pr-stale: -1
27+
operations-per-run: 45
28+
29+
- uses: actions/stale@v9
30+
with:
31+
stale-issue-message: 'This issue is stale because it has been open 30 days with no activity. Remove the stale label or comment, else this will be closed in 5 days.'
32+
close-issue-message: 'This issue was closed because it has been stale for 5 days with no activity.'
33+
stale-issue-label: 'stale'
34+
exempt-issue-labels: 'planned,milestone,work-in-progress'
35+
days-before-issue-stale: 30
36+
days-before-issue-close: 5
37+
days-before-pr-close: -1
38+
days-before-pr-stale: -1
39+
operations-per-run: 45

CHANGELOG.md

+17
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,23 @@ 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.11.1
9+
### Added
10+
- Added Rename option back to the Checkpoints page
11+
### Changed
12+
- Unobserved Task Exceptions across the app will now show a toast notification to aid in debugging
13+
- Updated SD.Next Package details and thumbnail - [#697](https://github.com/LykosAI/StabilityMatrix/pull/697)
14+
### Fixed
15+
- Fixed [#689](https://github.com/LykosAI/StabilityMatrix/issues/689) - New ComfyUI installs encountering launch error due to torch 2.0.0 update, added pinned `numpy==1.26.4` to install and update.
16+
- Fixed Inference image mask editor's 'Load Mask' not able to load image files
17+
- Fixed Fooocus ControlNet default config shared folder mode not taking effect
18+
- Fixed tkinter python libraries not working on macOS with 'Can't find a usable init.tcl' error
19+
### Supporters
20+
#### Visionaries
21+
- Shoutout to our Visionary-tier supporters on Patreon, **Scopp Mcdee** and **Waterclouds**! Your generous support is appreciated and helps us continue to make Stability Matrix better for everyone!
22+
#### Pioneers
23+
- A big thank you to our Pioneer-tier supporters on Patreon, **tankfox** and **tanangular**! Your support helps us continue to improve Stability Matrix!
24+
825
## v2.11.0
926
### Added
1027
#### Packages

StabilityMatrix.Avalonia/App.axaml.cs

+31
Original file line numberDiff line numberDiff line change
@@ -294,6 +294,7 @@ private void ShowMainWindow()
294294
DesktopLifetime.ShutdownRequested += OnShutdownRequested;
295295

296296
AppDomain.CurrentDomain.ProcessExit += OnExit;
297+
TaskScheduler.UnobservedTaskException += TaskScheduler_UnobservedTaskException;
297298

298299
// Since we're manually shutting down NLog in OnExit
299300
LogManager.AutoShutdown = false;
@@ -883,6 +884,36 @@ private void OnExit(object? sender, EventArgs _)
883884
}
884885
}
885886

887+
private static void TaskScheduler_UnobservedTaskException(
888+
object? sender,
889+
UnobservedTaskExceptionEventArgs e
890+
)
891+
{
892+
if (e.Exception is not Exception unobservedEx)
893+
return;
894+
895+
try
896+
{
897+
var notificationService = Services.GetRequiredService<INotificationService>();
898+
899+
Dispatcher.UIThread.Invoke(() =>
900+
{
901+
var originException = unobservedEx.InnerException ?? unobservedEx;
902+
notificationService.ShowPersistent(
903+
$"Unobserved Task Exception - {originException.GetType().Name}",
904+
originException.Message
905+
);
906+
});
907+
908+
// Consider the exception observed if we were able to show a notification
909+
e.SetObserved();
910+
}
911+
catch (Exception ex)
912+
{
913+
Logger.Error(ex, "Failed to show Unobserved Task Exception notification");
914+
}
915+
}
916+
886917
private static LoggingConfiguration ConfigureLogging()
887918
{
888919
var setupBuilder = LogManager.Setup();

StabilityMatrix.Avalonia/DesignData/DesignData.cs

+2
Original file line numberDiff line numberDiff line change
@@ -327,6 +327,7 @@ public static void Initialize()
327327
new MockModelIndexService(),
328328
notificationService,
329329
dialogFactory,
330+
null,
330331
new LocalModelFile
331332
{
332333
SharedFolderType = SharedFolderType.StableDiffusion,
@@ -356,6 +357,7 @@ public static void Initialize()
356357
new MockModelIndexService(),
357358
notificationService,
358359
dialogFactory,
360+
null,
359361
new LocalModelFile
360362
{
361363
RelativePath = "~/Models/Lora/model.safetensors",

StabilityMatrix.Avalonia/Program.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -349,7 +349,7 @@ UnobservedTaskExceptionEventArgs e
349349
{
350350
if (e.Exception is Exception ex)
351351
{
352-
Logger.Error(ex, "Unobserved task exception");
352+
Logger.Error(ex, "Unobserved Task Exception");
353353
}
354354
}
355355

StabilityMatrix.Avalonia/StabilityMatrix.Avalonia.csproj

+1-1
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
<ApplicationManifest>app.manifest</ApplicationManifest>
1818
<AvaloniaUseCompiledBindingsByDefault>true</AvaloniaUseCompiledBindingsByDefault>
1919
<ApplicationIcon>./Assets/Icon.ico</ApplicationIcon>
20-
<Version>2.11.0-dev.999</Version>
20+
<Version>2.12.0-dev.999</Version>
2121
<InformationalVersion>$(Version)</InformationalVersion>
2222
<EnableWindowsTargeting>true</EnableWindowsTargeting>
2323
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>

StabilityMatrix.Avalonia/ViewModels/CheckpointManager/CheckpointFileViewModel.cs

+73
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,14 @@
11
using System;
22
using System.Collections.Immutable;
33
using System.ComponentModel;
4+
using System.IO;
45
using System.Threading.Tasks;
56
using Avalonia.Controls.Notifications;
7+
using Avalonia.Data;
68
using CommunityToolkit.Mvvm.ComponentModel;
79
using CommunityToolkit.Mvvm.Input;
810
using FluentAvalonia.UI.Controls;
11+
using Microsoft.Extensions.Logging;
912
using StabilityMatrix.Avalonia.Services;
1013
using StabilityMatrix.Avalonia.ViewModels.Base;
1114
using StabilityMatrix.Avalonia.ViewModels.Dialogs;
@@ -36,6 +39,7 @@ public partial class CheckpointFileViewModel : SelectableViewModelBase
3639
private readonly IModelIndexService modelIndexService;
3740
private readonly INotificationService notificationService;
3841
private readonly ServiceManager<ViewModelBase> vmFactory;
42+
private readonly ILogger logger;
3943

4044
public bool CanShowTriggerWords => CheckpointFile.ConnectedModelInfo?.TrainedWords?.Length > 0;
4145
public string BaseModelName => CheckpointFile.ConnectedModelInfo?.BaseModel ?? string.Empty;
@@ -47,13 +51,15 @@ public CheckpointFileViewModel(
4751
IModelIndexService modelIndexService,
4852
INotificationService notificationService,
4953
ServiceManager<ViewModelBase> vmFactory,
54+
ILogger logger,
5055
LocalModelFile checkpointFile
5156
)
5257
{
5358
this.settingsManager = settingsManager;
5459
this.modelIndexService = modelIndexService;
5560
this.notificationService = notificationService;
5661
this.vmFactory = vmFactory;
62+
this.logger = logger;
5763
CheckpointFile = checkpointFile;
5864
ThumbnailUri = settingsManager.IsLibraryDirSet
5965
? CheckpointFile.GetPreviewImageFullPath(settingsManager.ModelsDirectory)
@@ -186,4 +192,71 @@ private async Task DeleteAsync(bool showConfirmation = true)
186192

187193
await modelIndexService.RemoveModelAsync(CheckpointFile);
188194
}
195+
196+
[RelayCommand]
197+
private async Task RenameAsync()
198+
{
199+
// Parent folder path
200+
var parentPath =
201+
Path.GetDirectoryName((string?)CheckpointFile.GetFullPath(settingsManager.ModelsDirectory)) ?? "";
202+
203+
var textFields = new TextBoxField[]
204+
{
205+
new()
206+
{
207+
Label = "File name",
208+
Validator = text =>
209+
{
210+
if (string.IsNullOrWhiteSpace(text))
211+
throw new DataValidationException("File name is required");
212+
213+
if (File.Exists(Path.Combine(parentPath, text)))
214+
throw new DataValidationException("File name already exists");
215+
},
216+
Text = CheckpointFile.FileName
217+
}
218+
};
219+
220+
var dialog = DialogHelper.CreateTextEntryDialog("Rename Model", "", textFields);
221+
222+
if (await dialog.ShowAsync() == ContentDialogResult.Primary)
223+
{
224+
var name = textFields[0].Text;
225+
var nameNoExt = Path.GetFileNameWithoutExtension(name);
226+
var originalNameNoExt = Path.GetFileNameWithoutExtension(CheckpointFile.FileName);
227+
// Rename file in OS
228+
try
229+
{
230+
var newFilePath = Path.Combine(parentPath, name);
231+
File.Move(CheckpointFile.GetFullPath(settingsManager.ModelsDirectory), newFilePath);
232+
233+
// If preview image exists, rename it too
234+
var previewPath = CheckpointFile.GetPreviewImageFullPath(settingsManager.ModelsDirectory);
235+
if (previewPath != null && File.Exists(previewPath))
236+
{
237+
var newPreviewImagePath = Path.Combine(
238+
parentPath,
239+
$"{nameNoExt}.preview{Path.GetExtension(previewPath)}"
240+
);
241+
File.Move(previewPath, newPreviewImagePath);
242+
}
243+
244+
// If connected model info exists, rename it too (<name>.cm-info.json)
245+
if (CheckpointFile.HasConnectedModel)
246+
{
247+
var cmInfoPath = Path.Combine(parentPath, $"{originalNameNoExt}.cm-info.json");
248+
if (File.Exists(cmInfoPath))
249+
{
250+
File.Move(cmInfoPath, Path.Combine(parentPath, $"{nameNoExt}.cm-info.json"));
251+
}
252+
}
253+
254+
await modelIndexService.RefreshIndex();
255+
}
256+
catch (Exception e)
257+
{
258+
logger.LogError(e, "Failed to rename checkpoint file");
259+
}
260+
}
261+
}
189262
}

StabilityMatrix.Avalonia/ViewModels/CheckpointsPageViewModel.cs

+1
Original file line numberDiff line numberDiff line change
@@ -274,6 +274,7 @@ or nameof(SortConnectedModelsFirst)
274274
modelIndexService,
275275
notificationService,
276276
dialogFactory,
277+
logger,
277278
x
278279
)
279280
)

StabilityMatrix.Avalonia/ViewModels/Controls/PaintCanvasViewModel.cs

+4-6
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
using System;
22
using System.Collections.Concurrent;
3-
using System.Collections.Generic;
43
using System.Collections.Immutable;
54
using System.ComponentModel;
65
using System.Linq;
@@ -77,6 +76,9 @@ public partial class PaintCanvasViewModel(ILogger<PaintCanvasViewModel> logger)
7776
[JsonIgnore]
7877
private SKLayer BrushLayer => Layers["Brush"];
7978

79+
[JsonIgnore]
80+
private SKLayer ImagesLayer => Layers["Images"];
81+
8082
[JsonIgnore]
8183
private SKLayer BackgroundLayer => Layers["Background"];
8284

@@ -99,9 +101,6 @@ public SKBitmap? BackgroundImage
99101
}
100102
}
101103

102-
[JsonIgnore]
103-
public List<SKBitmap> LayerImages { get; } = [];
104-
105104
/// <summary>
106105
/// Set by <see cref="PaintCanvas"/> to allow the view model to
107106
/// refresh the canvas view after updating points or bitmap layers.
@@ -117,8 +116,7 @@ public void SetSourceCanvas(SKCanvas canvas)
117116

118117
public void LoadCanvasFromBitmap(SKBitmap bitmap)
119118
{
120-
LayerImages.Clear();
121-
LayerImages.Add(bitmap);
119+
ImagesLayer.Bitmaps = [bitmap];
122120

123121
RefreshCanvas?.Invoke();
124122
}

StabilityMatrix.Avalonia/Views/CheckpointsPage.axaml

+2-2
Original file line numberDiff line numberDiff line change
@@ -367,8 +367,8 @@
367367
IsVisible="{Binding CheckpointFile.HasConnectedModel}" />
368368

369369
<ui:MenuFlyoutSeparator />
370-
<!-- <ui:MenuFlyoutItem Command="{Binding RenameCommand}" -->
371-
<!-- Text="{x:Static lang:Resources.Action_Rename}" IconSource="Rename" /> -->
370+
<ui:MenuFlyoutItem Command="{Binding RenameCommand}"
371+
Text="{x:Static lang:Resources.Action_Rename}" IconSource="Rename" />
372372
<ui:MenuFlyoutItem Command="{Binding DeleteCommand}"
373373
CommandParameter="{StaticResource True}"
374374
Text="{x:Static lang:Resources.Action_Delete}"

0 commit comments

Comments
 (0)