Skip to content

Commit

Permalink
Merge pull request #1099 from LykosAI/main
Browse files Browse the repository at this point in the history
v2.13.1
  • Loading branch information
mohnjiles authored Jan 9, 2025
2 parents 18c1db5 + 44e9cd6 commit a353386
Show file tree
Hide file tree
Showing 22 changed files with 499 additions and 341 deletions.
10 changes: 7 additions & 3 deletions Avalonia.Gif/WebpInstance.cs
Original file line number Diff line number Diff line change
Expand Up @@ -54,14 +54,18 @@ public WebpInstance(Stream currentStream)

var pixSize = new PixelSize(_codec.Info.Width, _codec.Info.Height);

_targetBitmap = new WriteableBitmap(pixSize, new Vector(96, 96), PixelFormat.Bgra8888, AlphaFormat.Opaque);
_targetBitmap = new WriteableBitmap(
pixSize,
new Vector(96, 96),
PixelFormat.Bgra8888,
AlphaFormat.Opaque
);
GifPixelSize = pixSize;

_totalTime = TimeSpan.Zero;

_frameTimes = _codec
.FrameInfo
.Select(frame =>
.FrameInfo.Select(frame =>
{
_totalTime = _totalTime.Add(TimeSpan.FromMilliseconds(frame.Duration));
return _totalTime;
Expand Down
19 changes: 19 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,25 @@ All notable changes to Stability Matrix will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
and this project adheres to [Semantic Versioning 2.0](https://semver.org/spec/v2.0.0.html).

## v2.13.1
### Changed
- Redesigned the Checkpoint Manager Filter flyout to include more options and improve the layout
- "Clear All" button will now remain at the top of the Downloads list regardless of scroll position - thanks to @Genteure!
- Improved image metadata parsing - thanks to @Genteure!
### Fixed
- Fixed [#1078](https://github.com/LykosAI/StabilityMatrix/issues/1078) - "Call from invalid thread" error after one-click install finishes
- Fixed [#1080](https://github.com/LykosAI/StabilityMatrix/issues/1080) - Some models not displayed in Checkpoint Manager
- Fixed Inference image selector card buttons taking up the whole height of the card
- Fixed Inference mask editor failing to paint to the right-most edge on large images
- Fixed Inference mask editor not showing the entire image in certain circumstances
- Fixed crash when dragging & dropping images in Inference (hopefully)
- Fixed an issue where certain sampler/scheduler combos would not get saved in image metadata - thanks to @yansigit!
### Supporters
#### Visionaries
- A heartfelt thank you to our exceptional Visionary-tier Patreon backers, **Waterclouds** and **TheTekknician**! We truly appreciate your steadfast support!
#### Pioneers
- We are also very grateful to our wonderful Pioneer-tier Patreon supporters, **tankfox**, **Mr Unknown**, **Szir777**, **Tigon**, and **NowFallenAngel**! Your support means a lot to us!

## v2.13.0
### Added
- Added new package - [ComfyUI-Zluda](https://github.com/patientx/ComfyUI-Zluda) - for AMD GPU users on Windows
Expand Down
42 changes: 24 additions & 18 deletions StabilityMatrix.Avalonia/Controls/Inference/SelectImageCard.axaml
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@
Source="{Binding ImageSource}"
Stretch="Uniform"
StretchDirection="Both" />

<!-- Overlay Image -->
<Panel>
<Panel.IsVisible>
Expand All @@ -57,13 +57,13 @@
<CompiledBinding Path="IsMaskOverlayEnabled" />
</MultiBinding>
</Panel.IsVisible>
<controls:BetterImage
<controls:BetterImage
VerticalAlignment="Stretch"
Stretch="Uniform"
StretchDirection="Both"
RenderOptions.BitmapInterpolationMode="HighQuality"
DataContext="{Binding MaskEditorViewModel}"
Source="{Binding CachedOrNewMaskRenderImage.Bitmap}"/>
RenderOptions.BitmapInterpolationMode="HighQuality"
Source="{Binding CachedOrNewMaskRenderImage.Bitmap}"
Stretch="Uniform"
StretchDirection="Both" />
</Panel>

<!-- Missing image -->
Expand Down Expand Up @@ -102,16 +102,18 @@
<!-- Active Selection Prompt -->
<StackPanel
Margin="4"
Spacing="4"
Orientation="Horizontal"
HorizontalAlignment="Right"
VerticalAlignment="Top"
IsVisible="{Binding !IsSelectionAvailable}">
<!-- Mask Overlay Toggle -->
IsVisible="{Binding !IsSelectionAvailable}"
Orientation="Horizontal"
Spacing="4">
<!-- Mask Overlay Toggle -->
<Border
IsVisible="{Binding IsMaskEditorEnabled}"
Width="40"
Height="40"
BoxShadow="inset 1.2 0 80 1.8 #66000000"
CornerRadius="10">
CornerRadius="10"
IsVisible="{Binding IsMaskEditorEnabled}">
<Border.Resources>
<DropShadowEffect
x:Key="TextDropShadowEffect"
Expand All @@ -126,9 +128,9 @@
</Border.Resources>
<ToggleButton
Padding="2"
IsChecked="{Binding IsMaskOverlayEnabled}"
CornerRadius="10"
FontSize="{TemplateBinding FontSize}">
FontSize="{TemplateBinding FontSize}"
IsChecked="{Binding IsMaskOverlayEnabled}">
<ToolTip.Tip>
<MultiBinding StringFormat="{}{0} - {1}">
<CompiledBinding Source="{x:Static lang:Resources.Label_ClippingMask}" />
Expand All @@ -142,11 +144,13 @@
Symbol="Eye" />
</ToggleButton>
</Border>
<!-- Mask Editor -->
<!-- Mask Editor -->
<Border
IsVisible="{Binding IsMaskEditorEnabled}"
Width="40"
Height="40"
BoxShadow="inset 1.2 0 80 1.8 #66000000"
CornerRadius="10">
CornerRadius="10"
IsVisible="{Binding IsMaskEditorEnabled}">
<Border.Resources>
<DropShadowEffect
x:Key="TextDropShadowEffect"
Expand Down Expand Up @@ -178,8 +182,10 @@
Symbol="Layer" />
</Button>
</Border>
<!-- Replace Contents -->
<!-- Replace Contents -->
<Border
Width="40"
Height="40"
BoxShadow="inset 1.2 0 80 1.8 #66000000"
CornerRadius="10">
<Border.Resources>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -260,7 +260,7 @@ private void HandlePointerMoved(PointerEventArgs e)
// penPath.Path.LineTo(cursorPosition.ToSKPoint());

// Get bounds for discarding invalid points
var canvasBounds = MainCanvas?.Bounds ?? new Rect();
var canvasBounds = new Rect(0, 0, MainCanvas?.Bounds.Width ?? 0, MainCanvas?.Bounds.Height ?? 0);

// Add points
foreach (var point in points)
Expand Down
2 changes: 1 addition & 1 deletion StabilityMatrix.Avalonia/Models/ImageSource.cs
Original file line number Diff line number Diff line change
Expand Up @@ -277,7 +277,7 @@ protected virtual void Dispose(bool disposing)
if (!disposing)
return;

Bitmap?.Dispose();
Bitmap = null;
}

/// <inheritdoc />
Expand Down
92 changes: 92 additions & 0 deletions StabilityMatrix.Avalonia/Services/CivitBaseModelTypeService.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
using System.Text.Json.Nodes;
using Injectio.Attributes;
using Microsoft.Extensions.Logging;
using StabilityMatrix.Core.Api;
using StabilityMatrix.Core.Database;
using StabilityMatrix.Core.Models.Api;
using StabilityMatrix.Core.Models.Database;

namespace StabilityMatrix.Avalonia.Services;

[RegisterSingleton<ICivitBaseModelTypeService, CivitBaseModelTypeService>]
public class CivitBaseModelTypeService(
ILogger<CivitBaseModelTypeService> logger,
ICivitApi civitApi,
ILiteDbContext dbContext
) : ICivitBaseModelTypeService
{
private const string CacheId = "BaseModelTypes";
private static readonly TimeSpan CacheExpiration = TimeSpan.FromHours(24);

/// <summary>
/// Gets the list of base model types, using cache if available and not expired
/// </summary>
public async Task<List<string>> GetBaseModelTypes(bool forceRefresh = false, bool includeAllOption = true)
{
List<string> civitBaseModels = [];

if (!forceRefresh)
{
var cached = await dbContext.GetCivitBaseModelTypeCacheEntry(CacheId);
if (cached != null && DateTimeOffset.UtcNow.Subtract(cached.CreatedAt) < CacheExpiration)
{
civitBaseModels = cached.ModelTypes;
}
}

try
{
if (civitBaseModels.Count <= 0)
{
var baseModelsResponse = await civitApi.GetBaseModelList();
var jsonContent = await baseModelsResponse.Content.ReadAsStringAsync();
var baseModels = JsonNode.Parse(jsonContent);

var jArray =
baseModels?["error"]?["issues"]?[0]?["unionErrors"]?[0]?["issues"]?[0]?["options"]
as JsonArray;

civitBaseModels = jArray?.GetValues<string>().ToList() ?? [];

// Cache the results
var cacheEntry = new CivitBaseModelTypeCacheEntry
{
Id = CacheId,
ModelTypes = civitBaseModels,
CreatedAt = DateTimeOffset.UtcNow
};

await dbContext.UpsertCivitBaseModelTypeCacheEntry(cacheEntry);
}

if (includeAllOption)
{
civitBaseModels.Insert(0, CivitBaseModelType.All.ToString());
}

// Filter and sort results
var filteredResults = civitBaseModels
.Where(s => !s.Equals("odor", StringComparison.OrdinalIgnoreCase))
.OrderBy(s => s)
.ToList();

return filteredResults;
}
catch (Exception e)
{
logger.LogError(e, "Failed to get base model list");

// Return cached results if available, even if expired
var expiredCache = await dbContext.GetCivitBaseModelTypeCacheEntry(CacheId);
return expiredCache?.ModelTypes ?? [];
}
}

/// <summary>
/// Clears the cached base model types
/// </summary>
public void ClearCache()
{
dbContext.CivitBaseModelTypeCache.DeleteAllAsync();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
namespace StabilityMatrix.Avalonia.Services;

public interface ICivitBaseModelTypeService
{
Task<List<string>> GetBaseModelTypes(bool forceRefresh = false, bool includeAllOption = true);
void ClearCache();
}
Original file line number Diff line number Diff line change
Expand Up @@ -421,7 +421,7 @@ await notificationService.ShowAsync(

// Clear progress
OutputProgress.ClearProgress();
ImageGalleryCardViewModel.PreviewImage?.Dispose();
// ImageGalleryCardViewModel.PreviewImage?.Dispose();
ImageGalleryCardViewModel.PreviewImage = null;
ImageGalleryCardViewModel.IsPreviewOverlayEnabled = false;

Expand Down
4 changes: 2 additions & 2 deletions StabilityMatrix.Avalonia/ViewModels/Base/PageViewModelBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ namespace StabilityMatrix.Avalonia.ViewModels.Base;
/// <summary>
/// An abstract class for enabling page navigation.
/// </summary>
public abstract class PageViewModelBase : ViewModelBase
public abstract class PageViewModelBase : DisposableViewModelBase
{
/// <summary>
/// Gets if the user can navigate to the next page
Expand All @@ -16,7 +16,7 @@ public abstract class PageViewModelBase : ViewModelBase
/// Gets if the user can navigate to the previous page
/// </summary>
public virtual bool CanNavigatePrevious { get; protected set; }

public abstract string Title { get; }
public abstract IconSource IconSource { get; }
}
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ public sealed partial class CivitAiBrowserViewModel : TabViewModelBase, IInfinit
private readonly ISettingsManager settingsManager;
private readonly ILiteDbContext liteDbContext;
private readonly INotificationService notificationService;
private readonly ICivitBaseModelTypeService baseModelTypeService;
private bool dontSearch = false;

private readonly SourceCache<OrderedValue<CivitModel>, int> modelCache = new(static ov => ov.Value.Id);
Expand Down Expand Up @@ -126,13 +127,15 @@ public CivitAiBrowserViewModel(
ISettingsManager settingsManager,
ServiceManager<ViewModelBase> dialogFactory,
ILiteDbContext liteDbContext,
INotificationService notificationService
INotificationService notificationService,
ICivitBaseModelTypeService baseModelTypeService
)
{
this.civitApi = civitApi;
this.settingsManager = settingsManager;
this.liteDbContext = liteDbContext;
this.notificationService = notificationService;
this.baseModelTypeService = baseModelTypeService;

EventManager.Instance.NavigateAndFindCivitModelRequested += OnNavigateAndFindCivitModelRequested;

Expand Down Expand Up @@ -727,31 +730,7 @@ private void UpdateResultsText()
[Localizable(false)]
private async Task<List<string>> GetBaseModelList()
{
try
{
var baseModelsResponse = await civitApi.GetBaseModelList();
var jsonContent = await baseModelsResponse.Content.ReadAsStringAsync();
var baseModels = JsonNode.Parse(jsonContent);

var jArray =
baseModels?["error"]?["issues"]?[0]?["unionErrors"]?[0]?["issues"]?[0]?["options"]
as JsonArray;
var civitBaseModels = jArray?.GetValues<string>().ToList() ?? [];

civitBaseModels.Insert(0, CivitBaseModelType.All.ToString());

var filteredResults = civitBaseModels
.Where(s => s.Equals("odor", StringComparison.OrdinalIgnoreCase) == false)
.OrderBy(s => s)
.ToList();

return filteredResults;
}
catch (Exception e)
{
Logger.Error(e, "Failed to get base model list");
return [];
}
return await baseModelTypeService.GetBaseModelTypes();
}

public override string Header => Resources.Label_CivitAi;
Expand Down
Loading

0 comments on commit a353386

Please sign in to comment.