Browse Source

use AsyncImage where possible (some weird stacklayout bug means we still use BetterAdvancedImage in some places). also updated nugets including avalonia to 11.0.10. also updated readme.

pull/629/head
JT 8 months ago
parent
commit
f40f0b6cc0
  1. 2
      Avalonia.Gif/Avalonia.Gif.csproj
  2. 3
      CHANGELOG.md
  3. 51
      README.md
  4. 6
      StabilityMatrix.Avalonia.Diagnostics/StabilityMatrix.Avalonia.Diagnostics.csproj
  5. 7
      StabilityMatrix.Avalonia/App.axaml
  6. 6
      StabilityMatrix.Avalonia/Controls/Inference/ImageFolderCard.axaml
  7. 8
      StabilityMatrix.Avalonia/Controls/Inference/ImageGalleryCard.axaml
  8. 2
      StabilityMatrix.Avalonia/Models/ImageSource.cs
  9. 38
      StabilityMatrix.Avalonia/StabilityMatrix.Avalonia.csproj
  10. 29
      StabilityMatrix.Avalonia/Styles/ControlThemes/BetterComboBoxStyles.axaml
  11. 13
      StabilityMatrix.Avalonia/ViewModels/OutputsPageViewModel.cs
  12. 6
      StabilityMatrix.Avalonia/ViewModels/PackageManager/PackageCardViewModel.cs
  13. 26
      StabilityMatrix.Avalonia/Views/CheckpointsPage.axaml
  14. 19
      StabilityMatrix.Avalonia/Views/CivitAiBrowserPage.axaml
  15. 3
      StabilityMatrix.Avalonia/Views/Dialogs/OpenArtWorkflowDialog.axaml
  16. 2
      StabilityMatrix.Avalonia/Views/InstalledWorkflowsPage.axaml
  17. 11
      StabilityMatrix.Avalonia/Views/OpenArtBrowserPage.axaml
  18. 4
      StabilityMatrix.Avalonia/Views/PackageManager/PackageInstallBrowserView.axaml
  19. 9
      StabilityMatrix.Avalonia/Views/PackageManager/PackageInstallBrowserView.axaml.cs
  20. 19
      StabilityMatrix.Avalonia/Views/PackageManager/PackageInstallDetailView.axaml
  21. 5
      StabilityMatrix.Avalonia/Views/PackageManagerPage.axaml
  22. 12
      StabilityMatrix.Core/StabilityMatrix.Core.csproj
  23. 8
      StabilityMatrix.Tests/StabilityMatrix.Tests.csproj
  24. 8
      StabilityMatrix.UITests/StabilityMatrix.UITests.csproj

2
Avalonia.Gif/Avalonia.Gif.csproj

@ -10,7 +10,7 @@
<EnableWindowsTargeting>true</EnableWindowsTargeting> <EnableWindowsTargeting>true</EnableWindowsTargeting>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Avalonia" Version="11.0.9" /> <PackageReference Include="Avalonia" Version="11.0.10" />
<PackageReference Include="SkiaSharp" Version="2.88.7" /> <PackageReference Include="SkiaSharp" Version="2.88.7" />
<PackageReference Include="DotNet.Bundle" Version="0.9.13" /> <PackageReference Include="DotNet.Bundle" Version="0.9.13" />
</ItemGroup> </ItemGroup>

3
CHANGELOG.md

@ -9,6 +9,9 @@ and this project adheres to [Semantic Versioning 2.0](https://semver.org/spec/v2
## v2.10.0-preview.1 ## v2.10.0-preview.1
### Added ### Added
- Added OpenArt.AI workflow browser for ComfyUI workflows - Added OpenArt.AI workflow browser for ComfyUI workflows
### Changed
- Updated to Avalonia 11.0.10
- Changed to a new image control for pages with many images
## v2.10.0-dev.3 ## v2.10.0-dev.3
### Added ### Added

51
README.md

@ -2,6 +2,7 @@
[![Build](https://github.com/LykosAI/StabilityMatrix/actions/workflows/build.yml/badge.svg)](https://github.com/LykosAI/StabilityMatrix/actions/workflows/build.yml) [![Build](https://github.com/LykosAI/StabilityMatrix/actions/workflows/build.yml/badge.svg)](https://github.com/LykosAI/StabilityMatrix/actions/workflows/build.yml)
[![Discord Server](https://img.shields.io/discord/1115555685476868168?logo=discord&logoColor=white&label=Discord%20Server)](https://discord.com/invite/TUrgfECxHz) [![Discord Server](https://img.shields.io/discord/1115555685476868168?logo=discord&logoColor=white&label=Discord%20Server)](https://discord.com/invite/TUrgfECxHz)
[![Release](https://img.shields.io/github/v/release/LykosAI/StabilityMatrix?label=Latest%20Release&link=https%3A%2F%2Fgithub.com%2FLykosAI%2FStabilityMatrix%2Freleases%2Flatest)][release]
[release]: https://github.com/LykosAI/StabilityMatrix/releases/latest [release]: https://github.com/LykosAI/StabilityMatrix/releases/latest
[download-win-x64]: https://github.com/LykosAI/StabilityMatrix/releases/latest/download/StabilityMatrix-win-x64.zip [download-win-x64]: https://github.com/LykosAI/StabilityMatrix/releases/latest/download/StabilityMatrix-win-x64.zip
@ -9,7 +10,7 @@
[download-macos-arm64]: https://github.com/LykosAI/StabilityMatrix/releases/latest/download/StabilityMatrix-macos-arm64.dmg [download-macos-arm64]: https://github.com/LykosAI/StabilityMatrix/releases/latest/download/StabilityMatrix-macos-arm64.dmg
[auto1111]: https://github.com/AUTOMATIC1111/stable-diffusion-webui [auto1111]: https://github.com/AUTOMATIC1111/stable-diffusion-webui
[auto1111-directml]: https://github.com/lshqqytiger/stable-diffusion-webui-directml [sdwebui-directml]: https://github.com/lshqqytiger/stable-diffusion-webui-directml
[webui-ux]: https://github.com/anapnoe/stable-diffusion-webui-ux [webui-ux]: https://github.com/anapnoe/stable-diffusion-webui-ux
[comfy]: https://github.com/comfyanonymous/ComfyUI [comfy]: https://github.com/comfyanonymous/ComfyUI
[sdnext]: https://github.com/vladmandic/automatic [sdnext]: https://github.com/vladmandic/automatic
@ -25,44 +26,29 @@
[civitai]: https://civitai.com/ [civitai]: https://civitai.com/
[huggingface]: https://huggingface.co/ [huggingface]: https://huggingface.co/
Multi-Platform Package Manager and Inference UI for Stable Diffusion ![Header image for Stability Matrix, Multi-Platform Package Manager and Inference UI for Stable Diffusion](https://cdn.lykos.ai/static/sm-banner-rounded.webp)
### ✨ New in 2.5 - [Inference](#inference-A-reimagined-built-in-Stable-Diffusion-experience), a built-in interface for Stable Diffusion powered by ComfyUI [![Windows](https://img.shields.io/badge/Windows%2010,%2011-%230079d5.svg?style=for-the-badge&logo=Windows%2011&logoColor=white)][download-win-x64]
[![Linux](https://img.shields.io/badge/Linux-FCC624?style=for-the-badge&logo=linux&logoColor=black)][download-linux-x64]
[![macOS](https://img.shields.io/badge/mac%20os%20%28apple%20silicon%29-000000?style=for-the-badge&logo=macos&logoColor=F0F0F0)][download-macos-arm64]
Multi-Platform Package Manager and Inference UI for Stable Diffusion
### 🖱 One click install and update for Stable Diffusion Web UI Packages ### 🖱 One click install and update for Stable Diffusion Web UI Packages
- Supports: - Supports:
- [Automatic 1111][auto1111], [Automatic 1111 DirectML][auto1111-directml], [SD Web UI-UX][webui-ux], [SD.Next][sdnext] - [Automatic1111][auto1111], [Stable Diffusion WebUI DirectML][sdwebui-directml], [SD Web UI-UX][webui-ux], [SD.Next][sdnext]
- [Fooocus][fooocus], [Fooocus MRE][fooocus-mre], [Fooocus ControlNet SDXL][fooocus-controlnet], [Ruined Fooocus][ruined-fooocus] - [Fooocus][fooocus], [Fooocus ControlNet SDXL][fooocus-controlnet], [Ruined Fooocus][ruined-fooocus]
- [ComfyUI][comfy] - [ComfyUI][comfy]
- [VoltaML][voltaml] - [VoltaML][voltaml]
- [InvokeAI][invokeai] - [InvokeAI][invokeai]
- [Kohya's GUI][kohya-ss] - [Kohya's GUI][kohya-ss]
- [OneTrainer][onetrainer] - [OneTrainer][onetrainer]
- Manage plugins / extensions for supported packages ([Automatic 1111][auto1111], [Comfy UI][comfy]) - Manage plugins / extensions for supported packages ([Automatic1111][auto1111], [Comfy UI][comfy], [SD Web UI-UX][webui-ux], and [SD.Next][sdnext])
- Easily install or update Python dependencies for each package - Easily install or update Python dependencies for each package
- Embedded Git and Python dependencies, with no need for either to be globally installed - Embedded Git and Python dependencies, with no need for either to be globally installed
- Fully portable - move Stability Matrix's Data Directory to a new drive or computer at any time - Fully portable - move Stability Matrix's Data Directory to a new drive or computer at any time
### 🚀 Launcher with syntax highlighted terminal emulator, routed GUI input prompts ### ✨ Inference - A Reimagined Stable Diffusion Interface, Built-In to Stability Matrix
- Launch arguments editor with predefined or custom options for each Package install
- Configurable Environment Variables
### 🗃 Checkpoint Manager, configured to be shared by all Package installs
- Option to find CivitAI metadata and preview thumbnails for new local imports
### ☁ Model Browser to import from [CivitAI][civitai] and [HuggingFace][huggingface]
- Automatically imports to the associated model folder depending on the model type
- Downloads relevant metadata files and preview image
![header](https://cdn.lykos.ai/static/sm-banner-rounded.webp)
[![Release](https://img.shields.io/github/v/release/LykosAI/StabilityMatrix?label=Latest%20Release&link=https%3A%2F%2Fgithub.com%2FLykosAI%2FStabilityMatrix%2Freleases%2Flatest)][release]
[![Windows](https://img.shields.io/badge/Windows%2010,%2011-%230079d5.svg?style=for-the-badge&logo=Windows%2011&logoColor=white)][download-win-x64]
[![Linux](https://img.shields.io/badge/Linux-FCC624?style=for-the-badge&logo=linux&logoColor=black)][download-linux-x64]
[![macOS](https://img.shields.io/badge/mac%20os%20%28apple%20silicon%29-000000?style=for-the-badge&logo=macos&logoColor=F0F0F0)][download-macos-arm64]
### Inference - A reimagined built-in Stable Diffusion experience
- Powerful auto-completion and syntax highlighting using a formal language grammar - Powerful auto-completion and syntax highlighting using a formal language grammar
- Workspaces open in tabs that save and load from `.smproj` project files - Workspaces open in tabs that save and load from `.smproj` project files
@ -76,13 +62,20 @@ Multi-Platform Package Manager and Inference UI for Stable Diffusion
<img style="width: 80%; height: 80%" src="https://github.com/LykosAI/StabilityMatrix/assets/13956642/4341cc34-a584-4e9c-bb3b-276009bdae80" alt=""/> <img style="width: 80%; height: 80%" src="https://github.com/LykosAI/StabilityMatrix/assets/13956642/4341cc34-a584-4e9c-bb3b-276009bdae80" alt=""/>
</p> </p>
### Searchable launch options ### 🚀 Launcher with syntax highlighted terminal emulator, routed GUI input prompts
- Launch arguments editor with predefined or custom options for each Package install
- Configurable Environment Variables
<p align="center"> <p align="center">
<img style="width: 80%; height: 80%" src="https://github.com/LykosAI/StabilityMatrix/assets/13956642/75456866-9d95-47c6-8c0a-fdc19443ee02" alt=""/> <img style="width: 80%; height: 80%" src="https://github.com/LykosAI/StabilityMatrix/assets/13956642/75456866-9d95-47c6-8c0a-fdc19443ee02" alt=""/>
</p> </p>
### Model browser powered by [Civit AI][civitai] ### 🗃 Checkpoint Manager, configured to be shared by all Package installs
- Downloads new models, automatically uses the appropriate shared model directory - Option to find CivitAI metadata and preview thumbnails for new local imports
### ☁ Model Browser to import from [CivitAI][civitai] and [HuggingFace][huggingface]
- Automatically imports to the associated model folder depending on the model type
- Downloads relevant metadata files and preview image
- Pause and resume downloads, even after closing the app - Pause and resume downloads, even after closing the app
<p align="center"> <p align="center">

6
StabilityMatrix.Avalonia.Diagnostics/StabilityMatrix.Avalonia.Diagnostics.csproj

@ -19,12 +19,12 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Avalonia" Version="11.0.9" /> <PackageReference Include="Avalonia" Version="11.0.10" />
<PackageReference Include="Avalonia.Controls.DataGrid" Version="11.0.9" /> <PackageReference Include="Avalonia.Controls.DataGrid" Version="11.0.10" />
<PackageReference Include="DotNet.Bundle" Version="0.9.13" /> <PackageReference Include="DotNet.Bundle" Version="0.9.13" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="8.0.0" /> <PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="8.0.0" />
<PackageReference Include="Microsoft.Extensions.Hosting" Version="8.0.0" /> <PackageReference Include="Microsoft.Extensions.Hosting" Version="8.0.0" />
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="8.0.0" /> <PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="8.0.1" />
<PackageReference Include="NLog" Version="5.2.8" /> <PackageReference Include="NLog" Version="5.2.8" />
</ItemGroup> </ItemGroup>

7
StabilityMatrix.Avalonia/App.axaml

@ -4,7 +4,7 @@
xmlns:local="using:StabilityMatrix.Avalonia" xmlns:local="using:StabilityMatrix.Avalonia"
xmlns:idcr="using:Dock.Avalonia.Controls.Recycling" xmlns:idcr="using:Dock.Avalonia.Controls.Recycling"
xmlns:styling="clr-namespace:FluentAvalonia.Styling;assembly=FluentAvalonia" xmlns:styling="clr-namespace:FluentAvalonia.Styling;assembly=FluentAvalonia"
xmlns:controls="clr-namespace:Avalonia.Labs.Controls;assembly=Avalonia.Labs.Controls" xmlns:labs="clr-namespace:Avalonia.Labs.Controls;assembly=Avalonia.Labs.Controls"
Name="Stability Matrix" Name="Stability Matrix"
RequestedThemeVariant="Dark"> RequestedThemeVariant="Dark">
<!-- "Default" ThemeVariant follows system theme variant. "Dark" or "Light" are other available options. --> <!-- "Default" ThemeVariant follows system theme variant. "Dark" or "Light" are other available options. -->
@ -81,10 +81,13 @@
<StyleInclude Source="Controls/Inference/FreeUCard.axaml"/> <StyleInclude Source="Controls/Inference/FreeUCard.axaml"/>
<StyleInclude Source="Controls/Inference/ControlNetCard.axaml"/> <StyleInclude Source="Controls/Inference/ControlNetCard.axaml"/>
<StyleInclude Source="Controls/Inference/PromptExpansionCard.axaml"/> <StyleInclude Source="Controls/Inference/PromptExpansionCard.axaml"/>
<controls:ControlThemes/> <labs:ControlThemes/>
<Style Selector="DockControl"> <Style Selector="DockControl">
<Setter Property="(DockProperties.ControlRecycling)" Value="{StaticResource ControlRecyclingKey}" /> <Setter Property="(DockProperties.ControlRecycling)" Value="{StaticResource ControlRecyclingKey}" />
</Style> </Style>
<Style Selector="labs|AsyncImage Border">
<Setter Property="ClipToBounds" Value="True"/>
</Style>
</Application.Styles> </Application.Styles>
</Application> </Application>

6
StabilityMatrix.Avalonia/Controls/Inference/ImageFolderCard.axaml

@ -9,6 +9,7 @@
xmlns:ui="using:FluentAvalonia.UI.Controls" xmlns:ui="using:FluentAvalonia.UI.Controls"
xmlns:vmInference="clr-namespace:StabilityMatrix.Avalonia.ViewModels.Inference" xmlns:vmInference="clr-namespace:StabilityMatrix.Avalonia.ViewModels.Inference"
xmlns:scroll="clr-namespace:StabilityMatrix.Avalonia.Controls.Scroll" xmlns:scroll="clr-namespace:StabilityMatrix.Avalonia.Controls.Scroll"
xmlns:labs="clr-namespace:Avalonia.Labs.Controls;assembly=Avalonia.Labs.Controls"
x:DataType="vmInference:ImageFolderCardViewModel"> x:DataType="vmInference:ImageFolderCardViewModel">
<Design.PreviewWith> <Design.PreviewWith>
@ -195,12 +196,11 @@
<Border ClipToBounds="True" CornerRadius="8"> <Border ClipToBounds="True" CornerRadius="8">
<Grid RowDefinitions="*,Auto"> <Grid RowDefinitions="*,Auto">
<controls:BetterAdvancedImage <labs:AsyncImage
Width="{Binding $parent[ItemsRepeater].((vmInference:ImageFolderCardViewModel)DataContext).ImageSize.Width}" Width="{Binding $parent[ItemsRepeater].((vmInference:ImageFolderCardViewModel)DataContext).ImageSize.Width}"
Height="{Binding $parent[ItemsRepeater].((vmInference:ImageFolderCardViewModel)DataContext).ImageSize.Height}" Height="{Binding $parent[ItemsRepeater].((vmInference:ImageFolderCardViewModel)DataContext).ImageSize.Height}"
Source="{Binding AbsolutePath}" Source="{Binding AbsolutePath}"
Stretch="UniformToFill" Stretch="UniformToFill" />
StretchDirection="Both" />
<Border <Border
Grid.Row="1" Grid.Row="1"

8
StabilityMatrix.Avalonia/Controls/Inference/ImageGalleryCard.axaml

@ -5,6 +5,7 @@
xmlns:mocks="clr-namespace:StabilityMatrix.Avalonia.DesignData" xmlns:mocks="clr-namespace:StabilityMatrix.Avalonia.DesignData"
xmlns:models="clr-namespace:StabilityMatrix.Avalonia.Models" xmlns:models="clr-namespace:StabilityMatrix.Avalonia.Models"
xmlns:vmInference="clr-namespace:StabilityMatrix.Avalonia.ViewModels.Inference" xmlns:vmInference="clr-namespace:StabilityMatrix.Avalonia.ViewModels.Inference"
xmlns:labs="clr-namespace:Avalonia.Labs.Controls;assembly=Avalonia.Labs.Controls"
x:DataType="vmInference:ImageGalleryCardViewModel"> x:DataType="vmInference:ImageGalleryCardViewModel">
<Design.PreviewWith> <Design.PreviewWith>
@ -115,12 +116,11 @@
</ListBox.Styles> </ListBox.Styles>
<ListBox.ItemTemplate> <ListBox.ItemTemplate>
<DataTemplate DataType="{x:Type models:ImageSource}"> <DataTemplate DataType="{x:Type models:ImageSource}">
<controls:BetterAdvancedImage <labs:AsyncImage
MaxHeight="65" MaxHeight="65"
CornerRadius="4" CornerRadius="4"
Source="{Binding}" Source="{Binding Uri}"
Stretch="Uniform" Stretch="Uniform" />
StretchDirection="Both" />
</DataTemplate> </DataTemplate>
</ListBox.ItemTemplate> </ListBox.ItemTemplate>
</ListBox> </ListBox>

2
StabilityMatrix.Avalonia/Models/ImageSource.cs

@ -58,6 +58,8 @@ public record ImageSource : IDisposable, ITemplateKey<ImageSourceTemplateType>
Bitmap = bitmap; Bitmap = bitmap;
} }
public Uri? Uri => LocalFile?.FullPath != null ? new Uri(LocalFile.FullPath) : RemoteUrl;
/// <inheritdoc /> /// <inheritdoc />
public ImageSourceTemplateType TemplateKey { get; private set; } public ImageSourceTemplateType TemplateKey { get; private set; }

38
StabilityMatrix.Avalonia/StabilityMatrix.Avalonia.csproj

@ -39,17 +39,17 @@
<PackageReference Include="AsyncImageLoader.Avalonia" Version="3.2.1" /> <PackageReference Include="AsyncImageLoader.Avalonia" Version="3.2.1" />
<PackageReference Include="AutoComplete.Net" Version="1.2211.2014.42"/> <PackageReference Include="AutoComplete.Net" Version="1.2211.2014.42"/>
<PackageReference Include="Avalonia.AvaloniaEdit" Version="11.0.6" /> <PackageReference Include="Avalonia.AvaloniaEdit" Version="11.0.6" />
<PackageReference Include="Avalonia.Controls.DataGrid" Version="11.0.9" /> <PackageReference Include="Avalonia.Controls.DataGrid" Version="11.0.10" />
<PackageReference Include="Avalonia.Controls.ItemsRepeater" Version="11.0.9" /> <PackageReference Include="Avalonia.Controls.ItemsRepeater" Version="11.0.10" />
<PackageReference Include="Avalonia.Controls.PanAndZoom" Version="11.0.0.2" /> <PackageReference Include="Avalonia.Controls.PanAndZoom" Version="11.0.0.3" />
<PackageReference Include="Avalonia" Version="11.0.9" /> <PackageReference Include="Avalonia" Version="11.0.10" />
<PackageReference Include="Avalonia.Desktop" Version="11.0.9" /> <PackageReference Include="Avalonia.Desktop" Version="11.0.10" />
<PackageReference Include="Avalonia.Fonts.Inter" Version="11.0.9" /> <PackageReference Include="Avalonia.Fonts.Inter" Version="11.0.10" />
<!--Condition below is needed to remove Avalonia.Diagnostics package from build output in Release configuration.--> <!--Condition below is needed to remove Avalonia.Diagnostics package from build output in Release configuration.-->
<PackageReference Condition="'$(Configuration)' == 'Debug'" Include="Avalonia.Diagnostics" Version="11.0.9" /> <PackageReference Condition="'$(Configuration)' == 'Debug'" Include="Avalonia.Diagnostics" Version="11.0.10" />
<PackageReference Include="Avalonia.HtmlRenderer" Version="11.0.0" /> <PackageReference Include="Avalonia.HtmlRenderer" Version="11.0.0" />
<PackageReference Include="Avalonia.Labs.Controls" Version="11.0.3" /> <PackageReference Include="Avalonia.Labs.Controls" Version="11.0.10.1" />
<PackageReference Include="Avalonia.Xaml.Behaviors" Version="11.0.6" /> <PackageReference Include="Avalonia.Xaml.Behaviors" Version="11.0.10.1" />
<PackageReference Include="AvaloniaEdit.TextMate" Version="11.0.6" /> <PackageReference Include="AvaloniaEdit.TextMate" Version="11.0.6" />
<PackageReference Include="bodong.Avalonia.PropertyGrid" Version="11.0.6.3" /> <PackageReference Include="bodong.Avalonia.PropertyGrid" Version="11.0.6.3" />
<PackageReference Include="bodong.PropertyModels" Version="11.0.6.2" /> <PackageReference Include="bodong.PropertyModels" Version="11.0.6.2" />
@ -58,10 +58,10 @@
<PackageReference Include="DesktopNotifications" Version="1.3.1" /> <PackageReference Include="DesktopNotifications" Version="1.3.1" />
<PackageReference Include="DesktopNotifications.Avalonia" Version="1.3.1" /> <PackageReference Include="DesktopNotifications.Avalonia" Version="1.3.1" />
<PackageReference Include="DiscordRichPresence" Version="1.2.1.24" /> <PackageReference Include="DiscordRichPresence" Version="1.2.1.24" />
<PackageReference Include="Dock.Avalonia" Version="11.0.0.5" /> <PackageReference Include="Dock.Avalonia" Version="11.0.0.7" />
<PackageReference Include="Dock.Model.Avalonia" Version="11.0.0.5" /> <PackageReference Include="Dock.Model.Avalonia" Version="11.0.0.7" />
<PackageReference Include="Dock.Serializer" Version="11.0.0.5" /> <PackageReference Include="Dock.Serializer" Version="11.0.0.7" />
<PackageReference Include="DynamicData" Version="8.3.27" /> <PackageReference Include="DynamicData" Version="8.4.1" />
<PackageReference Include="DotNet.Bundle" Version="0.9.13" /> <PackageReference Include="DotNet.Bundle" Version="0.9.13" />
<PackageReference Include="Exceptionless.DateTimeExtensions" Version="3.4.3" /> <PackageReference Include="Exceptionless.DateTimeExtensions" Version="3.4.3" />
<PackageReference Include="FluentAvalonia.BreadcrumbBar" Version="2.0.2" /> <PackageReference Include="FluentAvalonia.BreadcrumbBar" Version="2.0.2" />
@ -78,25 +78,25 @@
<PackageReference Include="Microsoft.Extensions.Configuration.FileExtensions" Version="8.0.0" /> <PackageReference Include="Microsoft.Extensions.Configuration.FileExtensions" Version="8.0.0" />
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="8.0.0" /> <PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="8.0.0" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="8.0.0" /> <PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="8.0.0" />
<PackageReference Include="Microsoft.Extensions.Http.Polly" Version="8.0.2" /> <PackageReference Include="Microsoft.Extensions.Http.Polly" Version="8.0.3" />
<PackageReference Include="Microsoft.Extensions.Options.ConfigurationExtensions" Version="8.0.0" /> <PackageReference Include="Microsoft.Extensions.Options.ConfigurationExtensions" Version="8.0.0" />
<PackageReference Include="Nito.AsyncEx" Version="5.1.2" /> <PackageReference Include="Nito.AsyncEx" Version="5.1.2" />
<PackageReference Include="NLog" Version="5.2.8" /> <PackageReference Include="NLog" Version="5.2.8" />
<PackageReference Include="NLog.Extensions.Logging" Version="5.3.8" /> <PackageReference Include="NLog.Extensions.Logging" Version="5.3.8" />
<PackageReference Include="NSubstitute" Version="5.1.0" /> <PackageReference Include="NSubstitute" Version="5.1.0" />
<PackageReference Include="OneOf" Version="3.0.263" /> <PackageReference Include="OneOf" Version="3.0.263" />
<PackageReference Include="Polly" Version="8.3.0" /> <PackageReference Include="Polly" Version="8.3.1" />
<PackageReference Include="Polly.Contrib.WaitAndRetry" Version="1.1.1" /> <PackageReference Include="Polly.Contrib.WaitAndRetry" Version="1.1.1" />
<PackageReference Include="Polly.Extensions.Http" Version="3.0.0" /> <PackageReference Include="Polly.Extensions.Http" Version="3.0.0" />
<PackageReference Include="Projektanker.Icons.Avalonia.FontAwesome" Version="9.1.1" /> <PackageReference Include="Projektanker.Icons.Avalonia.FontAwesome" Version="9.1.2" />
<PackageReference Include="RockLib.Reflection.Optimized" Version="3.0.0" /> <PackageReference Include="RockLib.Reflection.Optimized" Version="3.0.0" />
<PackageReference Include="Sentry" Version="4.1.2" /> <PackageReference Include="Sentry" Version="4.2.1" />
<PackageReference Include="Sentry.NLog" Version="4.1.2" /> <PackageReference Include="Sentry.NLog" Version="4.2.1" />
<PackageReference Include="SpacedGrid-Avalonia" Version="11.0.0" /> <PackageReference Include="SpacedGrid-Avalonia" Version="11.0.0" />
<PackageReference Include="Sylvan.Common" Version="0.4.3" /> <PackageReference Include="Sylvan.Common" Version="0.4.3" />
<PackageReference Include="Sylvan.Data" Version="0.2.13" /> <PackageReference Include="Sylvan.Data" Version="0.2.13" />
<PackageReference Include="Sylvan.Data.Csv" Version="1.3.7" /> <PackageReference Include="Sylvan.Data.Csv" Version="1.3.7" />
<PackageReference Include="System.Drawing.Common" Version="8.0.2" /> <PackageReference Include="System.Drawing.Common" Version="8.0.3" />
<PackageReference Include="System.IO.Hashing" Version="8.0.0" /> <PackageReference Include="System.IO.Hashing" Version="8.0.0" />
<PackageReference Include="TextMateSharp.Grammars" Version="1.0.56" /> <PackageReference Include="TextMateSharp.Grammars" Version="1.0.56" />
<PackageReference Include="URISchemeTools" Version="1.0.2" /> <PackageReference Include="URISchemeTools" Version="1.0.2" />

29
StabilityMatrix.Avalonia/Styles/ControlThemes/BetterComboBoxStyles.axaml

@ -6,7 +6,8 @@
xmlns:mocks="using:StabilityMatrix.Avalonia.DesignData" xmlns:mocks="using:StabilityMatrix.Avalonia.DesignData"
xmlns:models="clr-namespace:StabilityMatrix.Core.Models;assembly=StabilityMatrix.Core" xmlns:models="clr-namespace:StabilityMatrix.Core.Models;assembly=StabilityMatrix.Core"
xmlns:sg="clr-namespace:SpacedGridControl.Avalonia;assembly=SpacedGridControl.Avalonia" xmlns:sg="clr-namespace:SpacedGridControl.Avalonia;assembly=SpacedGridControl.Avalonia"
xmlns:ui="clr-namespace:FluentAvalonia.UI.Controls;assembly=FluentAvalonia"> xmlns:ui="clr-namespace:FluentAvalonia.UI.Controls;assembly=FluentAvalonia"
xmlns:labs="clr-namespace:Avalonia.Labs.Controls;assembly=Avalonia.Labs.Controls">
<Design.PreviewWith> <Design.PreviewWith>
<Panel Width="450" Height="600"> <Panel Width="450" Height="600">
@ -42,15 +43,14 @@
ColumnSpacing="6" ColumnSpacing="6"
RowSpacing="0"> RowSpacing="0">
<!-- Image --> <!-- Image -->
<controls:BetterAdvancedImage <labs:AsyncImage
Width="64" Width="64"
Height="96" Height="96"
CornerRadius="6" CornerRadius="6"
IsVisible="{Binding Local.PreviewImageFullPathGlobal, Converter={x:Static StringConverters.IsNotNullOrEmpty}, FallbackValue=''}" IsVisible="{Binding Local.PreviewImageFullPathGlobal, Converter={x:Static StringConverters.IsNotNullOrEmpty}, FallbackValue=''}"
RenderOptions.BitmapInterpolationMode="HighQuality" RenderOptions.BitmapInterpolationMode="HighQuality"
Source="{Binding Local.PreviewImageFullPathGlobal, FallbackValue=''}" Source="{Binding Local.PreviewImageFullPathGlobal, FallbackValue=''}"
Stretch="UniformToFill" Stretch="UniformToFill"/>
StretchDirection="Both" />
<StackPanel <StackPanel
Grid.Column="1" Grid.Column="1"
MaxWidth="300" MaxWidth="300"
@ -125,18 +125,14 @@
ColumnSpacing="8" ColumnSpacing="8"
TextBlock.TextTrimming="CharacterEllipsis" TextBlock.TextTrimming="CharacterEllipsis"
TextBlock.TextWrapping="NoWrap"> TextBlock.TextWrapping="NoWrap">
<controls:BetterAdvancedImage <labs:AsyncImage
Grid.RowSpan="2" Grid.RowSpan="2"
Width="42" Width="42"
Height="42" Height="42"
RenderOptions.BitmapInterpolationMode="HighQuality" RenderOptions.BitmapInterpolationMode="HighQuality"
CornerRadius="40"
Source="{Binding Local.PreviewImageFullPathGlobal}" Source="{Binding Local.PreviewImageFullPathGlobal}"
Stretch="UniformToFill" Stretch="UniformToFill"/>
StretchDirection="Both">
<controls:BetterAdvancedImage.Clip>
<EllipseGeometry Rect="0,0,42,42" />
</controls:BetterAdvancedImage.Clip>
</controls:BetterAdvancedImage>
<!-- Text --> <!-- Text -->
<sg:SpacedGrid <sg:SpacedGrid
@ -217,18 +213,15 @@
ColumnSpacing="8" ColumnSpacing="8"
TextBlock.TextTrimming="CharacterEllipsis" TextBlock.TextTrimming="CharacterEllipsis"
TextBlock.TextWrapping="NoWrap"> TextBlock.TextWrapping="NoWrap">
<controls:BetterAdvancedImage <labs:AsyncImage
Grid.RowSpan="2" Grid.RowSpan="2"
Width="36" Width="36"
Height="36" Height="36"
CornerRadius="60"
RenderOptions.BitmapInterpolationMode="HighQuality" RenderOptions.BitmapInterpolationMode="HighQuality"
Source="{Binding Local.PreviewImageFullPathGlobal}" Source="{Binding Local.PreviewImageFullPathGlobal}"
Stretch="UniformToFill" Stretch="UniformToFill">
StretchDirection="Both"> </labs:AsyncImage>
<controls:BetterAdvancedImage.Clip>
<EllipseGeometry Rect="0,0,36,36" />
</controls:BetterAdvancedImage.Clip>
</controls:BetterAdvancedImage>
<!-- Text --> <!-- Text -->
<sg:SpacedGrid <sg:SpacedGrid

13
StabilityMatrix.Avalonia/ViewModels/OutputsPageViewModel.cs

@ -145,6 +145,7 @@ public partial class OutputsPageViewModel : PageViewModelBase
.Subscribe(_ => .Subscribe(_ =>
{ {
NumItemsSelected = Outputs.Count(o => o.IsSelected); NumItemsSelected = Outputs.Count(o => o.IsSelected);
Console.WriteLine($"Subscribe called");
}); });
categoriesCache.Connect().DeferUntilLoaded().Bind(Categories).Subscribe(); categoriesCache.Connect().DeferUntilLoaded().Bind(Categories).Subscribe();
@ -395,12 +396,13 @@ public partial class OutputsPageViewModel : PageViewModelBase
var selected = Outputs.Where(o => o.IsSelected).ToList(); var selected = Outputs.Where(o => o.IsSelected).ToList();
Debug.Assert(selected.Count == NumItemsSelected); Debug.Assert(selected.Count == NumItemsSelected);
var imagesToRemove = new List<LocalImageFile>();
foreach (var output in selected) foreach (var output in selected)
{ {
// Delete the file // Delete the file
var imageFile = new FilePath(output.ImageFile.AbsolutePath); var imageFile = new FilePath(output.ImageFile.AbsolutePath);
var result = await notificationService.TryAsync(imageFile.DeleteAsync()); var result = await notificationService.TryAsync(imageFile.DeleteAsync());
if (!result.IsSuccessful) if (!result.IsSuccessful)
{ {
continue; continue;
@ -413,15 +415,10 @@ public partial class OutputsPageViewModel : PageViewModelBase
await notificationService.TryAsync(sideCar.DeleteAsync()); await notificationService.TryAsync(sideCar.DeleteAsync());
} }
OutputsCache.Remove(output.ImageFile); imagesToRemove.Add(output.ImageFile);
// Invalidate cache
if (ImageLoader.AsyncImageLoader is FallbackRamCachedWebImageLoader loader)
{
loader.RemoveAllNamesFromCache(imageFile.Name);
}
} }
OutputsCache.Remove(imagesToRemove);
NumItemsSelected = 0; NumItemsSelected = 0;
ClearSelection(); ClearSelection();
} }

6
StabilityMatrix.Avalonia/ViewModels/PackageManager/PackageCardViewModel.cs

@ -54,7 +54,7 @@ public partial class PackageCardViewModel(
private InstalledPackage? package; private InstalledPackage? package;
[ObservableProperty] [ObservableProperty]
private string? cardImageSource; private Uri? cardImageSource;
[ObservableProperty] [ObservableProperty]
private bool isUpdateAvailable; private bool isUpdateAvailable;
@ -127,7 +127,7 @@ public partial class PackageCardViewModel(
) )
{ {
IsUnknownPackage = true; IsUnknownPackage = true;
CardImageSource = ""; CardImageSource = null;
InstalledVersion = "Unknown"; InstalledVersion = "Unknown";
} }
else else
@ -135,7 +135,7 @@ public partial class PackageCardViewModel(
IsUnknownPackage = false; IsUnknownPackage = false;
var basePackage = packageFactory[value.PackageName]; var basePackage = packageFactory[value.PackageName];
CardImageSource = basePackage?.PreviewImageUri.ToString() ?? Assets.NoImage.ToString(); CardImageSource = basePackage?.PreviewImageUri ?? Assets.NoImage;
InstalledVersion = value.Version?.DisplayVersion ?? "Unknown"; InstalledVersion = value.Version?.DisplayVersion ?? "Unknown";
CanUseConfigMethod = CanUseConfigMethod =
basePackage?.AvailableSharedFolderMethods.Contains(SharedFolderMethod.Configuration) ?? false; basePackage?.AvailableSharedFolderMethods.Contains(SharedFolderMethod.Configuration) ?? false;

26
StabilityMatrix.Avalonia/Views/CheckpointsPage.axaml

@ -13,6 +13,7 @@
xmlns:api="clr-namespace:StabilityMatrix.Core.Models.Api;assembly=StabilityMatrix.Core" xmlns:api="clr-namespace:StabilityMatrix.Core.Models.Api;assembly=StabilityMatrix.Core"
xmlns:generic="clr-namespace:System.Collections.Generic;assembly=System.Collections" xmlns:generic="clr-namespace:System.Collections.Generic;assembly=System.Collections"
xmlns:converters="clr-namespace:StabilityMatrix.Avalonia.Converters" xmlns:converters="clr-namespace:StabilityMatrix.Avalonia.Converters"
xmlns:labs="clr-namespace:Avalonia.Labs.Controls;assembly=Avalonia.Labs.Controls"
d:DataContext="{x:Static mocks:DesignData.CheckpointsPageViewModel}" d:DataContext="{x:Static mocks:DesignData.CheckpointsPageViewModel}"
x:CompileBindings="True" x:CompileBindings="True"
x:DataType="vm:CheckpointsPageViewModel" x:DataType="vm:CheckpointsPageViewModel"
@ -138,7 +139,7 @@
TextWrapping="WrapWithOverflow" TextWrapping="WrapWithOverflow"
IsVisible="{Binding IsConnectedModel}" /> IsVisible="{Binding IsConnectedModel}" />
<!-- Image --> <!-- Image -->
<controls:BetterAdvancedImage <labs:AsyncImage
Margin="0,0,0,4" Margin="0,0,0,4"
CornerRadius="4" CornerRadius="4"
Source="{Binding PreviewImagePath}" Source="{Binding PreviewImagePath}"
@ -175,18 +176,19 @@
IsVisible="{Binding IsConnectedModel}" /> IsVisible="{Binding IsConnectedModel}" />
</StackPanel> </StackPanel>
<controls:BetterAdvancedImage Grid.Row="1" <labs:AsyncImage Grid.Row="1"
Grid.Column="0" Grid.Column="0"
Grid.ColumnSpan="2" Grid.ColumnSpan="2"
Margin="0, 4,0,4" Margin="0, 4,0,4"
CornerRadius="8" CornerRadius="8"
Source="{Binding PreviewImagePath}" Source="{Binding PreviewImagePath}"
Stretch="UniformToFill" ClipToBounds="True"
Height="300" Stretch="UniformToFill"
Width="300" Height="300"
IsVisible="{Binding $parent[ItemsControl].((vm:CheckpointsPageViewModel)DataContext).ShowConnectedModelImages}" /> Width="300"
IsVisible="{Binding $parent[ItemsControl].((vm:CheckpointsPageViewModel)DataContext).ShowConnectedModelImages}"/>
<StackPanel Orientation="Horizontal" <StackPanel Orientation="Horizontal"
Grid.Column="1" Grid.Column="1"
Grid.Row="0" Grid.Row="0"
HorizontalAlignment="Right"> HorizontalAlignment="Right">
<controls:Card <controls:Card

19
StabilityMatrix.Avalonia/Views/CivitAiBrowserPage.axaml

@ -15,7 +15,7 @@
xmlns:converters="clr-namespace:StabilityMatrix.Avalonia.Converters" xmlns:converters="clr-namespace:StabilityMatrix.Avalonia.Converters"
xmlns:asyncImageLoader="clr-namespace:AsyncImageLoader;assembly=AsyncImageLoader.Avalonia" xmlns:asyncImageLoader="clr-namespace:AsyncImageLoader;assembly=AsyncImageLoader.Avalonia"
xmlns:helpers="clr-namespace:StabilityMatrix.Avalonia.Helpers" xmlns:helpers="clr-namespace:StabilityMatrix.Avalonia.Helpers"
xmlns:controls1="clr-namespace:Avalonia.Labs.Controls;assembly=Avalonia.Labs.Controls" xmlns:labs="clr-namespace:Avalonia.Labs.Controls;assembly=Avalonia.Labs.Controls"
xmlns:system="clr-namespace:System;assembly=System.Runtime" xmlns:system="clr-namespace:System;assembly=System.Runtime"
d:DataContext="{x:Static designData:DesignData.CivitAiBrowserViewModel}" d:DataContext="{x:Static designData:DesignData.CivitAiBrowserViewModel}"
d:DesignHeight="700" d:DesignHeight="700"
@ -32,7 +32,7 @@
</Transitions> </Transitions>
</Setter> </Setter>
<Style Selector="^ asyncImageLoader|AdvancedImage"> <Style Selector="^ labs|AsyncImage">
<Setter Property="Transitions"> <Setter Property="Transitions">
<Transitions> <Transitions>
<TransformOperationsTransition Property="RenderTransform" <TransformOperationsTransition Property="RenderTransform"
@ -48,7 +48,7 @@
<Style Selector="^:pointerover"> <Style Selector="^:pointerover">
<Setter Property="BoxShadow" Value="0 0 40 0 #60000000"/> <Setter Property="BoxShadow" Value="0 0 40 0 #60000000"/>
<Setter Property="Cursor" Value="Hand" /> <Setter Property="Cursor" Value="Hand" />
<Style Selector="^ asyncImageLoader|AdvancedImage"> <Style Selector="^ labs|AsyncImage">
<Setter Property="CornerRadius" Value="12"/> <Setter Property="CornerRadius" Value="12"/>
<Setter Property="RenderTransform" Value="scale(1.03, 1.03)"/> <Setter Property="RenderTransform" Value="scale(1.03, 1.03)"/>
</Style> </Style>
@ -60,7 +60,7 @@
<Style Selector="^:not(:pointerover)"> <Style Selector="^:not(:pointerover)">
<Setter Property="BoxShadow" Value="0 0 20 0 #60000000"/> <Setter Property="BoxShadow" Value="0 0 20 0 #60000000"/>
<Setter Property="Cursor" Value="Arrow" /> <Setter Property="Cursor" Value="Arrow" />
<Style Selector="^ asyncImageLoader|AdvancedImage"> <Style Selector="^ labs|AsyncImage">
<Setter Property="CornerRadius" Value="8"/> <Setter Property="CornerRadius" Value="8"/>
<Setter Property="RenderTransform" Value="scale(1, 1)"/> <Setter Property="RenderTransform" Value="scale(1, 1)"/>
</Style> </Style>
@ -103,7 +103,7 @@
CommandParameter="{Binding CivitModel}" CommandParameter="{Binding CivitModel}"
IsEnabled="{Binding !IsImporting}"> IsEnabled="{Binding !IsImporting}">
<Grid RowDefinitions="*, Auto"> <Grid RowDefinitions="*, Auto">
<controls1:AsyncImage Grid.Row="0" <labs:AsyncImage Grid.Row="0"
CornerRadius="8" CornerRadius="8"
VerticalAlignment="Top" VerticalAlignment="Top"
HorizontalAlignment="Center" HorizontalAlignment="Center"
@ -115,8 +115,8 @@
<!-- <controls:BetterAdvancedImage.RenderTransform> --> <!-- <controls:BetterAdvancedImage.RenderTransform> -->
<!-- <RotateTransform Angle="315"></RotateTransform> --> <!-- <RotateTransform Angle="315"></RotateTransform> -->
<!-- </controls:BetterAdvancedImage.RenderTransform> --> <!-- </controls:BetterAdvancedImage.RenderTransform> -->
</controls1:AsyncImage> </labs:AsyncImage>
<controls1:AsyncImage <labs:AsyncImage
Grid.Row="0" Grid.Row="0"
Grid.RowSpan="2" Grid.RowSpan="2"
CornerRadius="8" CornerRadius="8"
@ -182,14 +182,15 @@
Classes="transparent" Classes="transparent"
Padding="10,4"> Padding="10,4">
<StackPanel Orientation="Horizontal" Spacing="6"> <StackPanel Orientation="Horizontal" Spacing="6">
<controls1:AsyncImage <labs:AsyncImage
Width="22" Width="22"
Height="22" Height="22"
Effect="{StaticResource ImageDropShadowEffect}" Effect="{StaticResource ImageDropShadowEffect}"
CornerRadius="11" CornerRadius="11"
RenderOptions.BitmapInterpolationMode="HighQuality" RenderOptions.BitmapInterpolationMode="HighQuality"
IsVisible="{Binding CivitModel.Creator.Image, Converter={x:Static StringConverters.IsNotNullOrEmpty}}" IsVisible="{Binding CivitModel.Creator.Image, Converter={x:Static StringConverters.IsNotNullOrEmpty}}"
Source="{Binding CivitModel.Creator.Image}"/> Source="{Binding CivitModel.Creator.Image}">
</labs:AsyncImage>
<TextBlock <TextBlock
VerticalAlignment="Center" VerticalAlignment="Center"
Effect="{StaticResource TextDropShadowEffect}" Effect="{StaticResource TextDropShadowEffect}"

3
StabilityMatrix.Avalonia/Views/Dialogs/OpenArtWorkflowDialog.axaml

@ -12,6 +12,7 @@
xmlns:models="clr-namespace:StabilityMatrix.Avalonia.Models" xmlns:models="clr-namespace:StabilityMatrix.Avalonia.Models"
xmlns:system="clr-namespace:System;assembly=System.Runtime" xmlns:system="clr-namespace:System;assembly=System.Runtime"
xmlns:ui="clr-namespace:FluentAvalonia.UI.Controls;assembly=FluentAvalonia" xmlns:ui="clr-namespace:FluentAvalonia.UI.Controls;assembly=FluentAvalonia"
xmlns:labs="clr-namespace:Avalonia.Labs.Controls;assembly=Avalonia.Labs.Controls"
d:DataContext="{x:Static designData:DesignData.OpenArtWorkflowViewModel}" d:DataContext="{x:Static designData:DesignData.OpenArtWorkflowViewModel}"
d:DesignHeight="650" d:DesignHeight="650"
d:DesignWidth="600" d:DesignWidth="600"
@ -35,7 +36,7 @@
<Run Text="{Binding Workflow.Creator.Name}" /> <Run Text="{Binding Workflow.Creator.Name}" />
</TextBlock> </TextBlock>
<controls:BetterAdvancedImage <labs:AsyncImage
Grid.Row="2" Grid.Row="2"
Grid.Column="0" Grid.Column="0"
Height="300" Height="300"

2
StabilityMatrix.Avalonia/Views/InstalledWorkflowsPage.axaml

@ -210,7 +210,7 @@
Classes="transparent" Classes="transparent"
Padding="10,4"> Padding="10,4">
<StackPanel Orientation="Horizontal" Spacing="6"> <StackPanel Orientation="Horizontal" Spacing="6">
<controls:BetterAdvancedImage <labs:AsyncImage
Width="22" Width="22"
Height="22" Height="22"
Effect="{StaticResource ImageDropShadowEffect}" Effect="{StaticResource ImageDropShadowEffect}"

11
StabilityMatrix.Avalonia/Views/OpenArtBrowserPage.axaml

@ -40,7 +40,7 @@
<Style Selector="^:pointerover"> <Style Selector="^:pointerover">
<Setter Property="BoxShadow" Value="0 0 40 0 #60000000" /> <Setter Property="BoxShadow" Value="0 0 40 0 #60000000" />
<Setter Property="Cursor" Value="Hand" /> <Setter Property="Cursor" Value="Hand" />
<Style Selector="^ asyncImageLoader|AdvancedImage"> <Style Selector="^ labs|AsyncImage">
<Setter Property="CornerRadius" Value="12" /> <Setter Property="CornerRadius" Value="12" />
<Setter Property="RenderTransform" Value="scale(1.03, 1.03)" /> <Setter Property="RenderTransform" Value="scale(1.03, 1.03)" />
</Style> </Style>
@ -52,7 +52,7 @@
<Style Selector="^:not(:pointerover)"> <Style Selector="^:not(:pointerover)">
<Setter Property="BoxShadow" Value="0 0 20 0 #60000000" /> <Setter Property="BoxShadow" Value="0 0 20 0 #60000000" />
<Setter Property="Cursor" Value="Arrow" /> <Setter Property="Cursor" Value="Arrow" />
<Style Selector="^ asyncImageLoader|AdvancedImage"> <Style Selector="^ labs|AsyncImage">
<Setter Property="CornerRadius" Value="8" /> <Setter Property="CornerRadius" Value="8" />
<Setter Property="RenderTransform" Value="scale(1, 1)" /> <Setter Property="RenderTransform" Value="scale(1, 1)" />
</Style> </Style>
@ -121,6 +121,7 @@
CornerRadius="16" CornerRadius="16"
Margin="4" Margin="4"
Grid.Row="0" Grid.Row="0"
ClipToBounds="True"
HorizontalAlignment="Left" HorizontalAlignment="Left"
VerticalAlignment="Bottom"> VerticalAlignment="Bottom">
<Border.Resources> <Border.Resources>
@ -142,14 +143,16 @@
Classes="transparent" Classes="transparent"
Padding="10,4"> Padding="10,4">
<StackPanel Orientation="Horizontal" Spacing="6"> <StackPanel Orientation="Horizontal" Spacing="6">
<controls:BetterAdvancedImage <labs:AsyncImage
Width="22" Width="22"
Height="22" Height="22"
ClipToBounds="True"
Effect="{StaticResource ImageDropShadowEffect}" Effect="{StaticResource ImageDropShadowEffect}"
CornerRadius="11" CornerRadius="11"
RenderOptions.BitmapInterpolationMode="HighQuality" RenderOptions.BitmapInterpolationMode="HighQuality"
IsVisible="{Binding Creator.Avatar, Converter={x:Static StringConverters.IsNotNullOrEmpty}}" IsVisible="{Binding Creator.Avatar, Converter={x:Static StringConverters.IsNotNullOrEmpty}}"
Source="{Binding Creator.Avatar}" /> Source="{Binding Creator.Avatar}">
</labs:AsyncImage>
<TextBlock <TextBlock
VerticalAlignment="Center" VerticalAlignment="Center"
Foreground="{DynamicResource TextControlForeground}" Foreground="{DynamicResource TextControlForeground}"

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

@ -34,8 +34,8 @@
<Grid ColumnDefinitions="Auto, *, Auto"> <Grid ColumnDefinitions="Auto, *, Auto">
<controls:BetterAdvancedImage <controls:BetterAdvancedImage
Grid.Column="0" Grid.Column="0"
MaxHeight="128" Height="128"
MaxWidth="128" Width="128"
Stretch="UniformToFill" Stretch="UniformToFill"
CornerRadius="4" CornerRadius="4"
Source="{Binding PreviewImageUri}" /> Source="{Binding PreviewImageUri}" />

9
StabilityMatrix.Avalonia/Views/PackageManager/PackageInstallBrowserView.axaml.cs

@ -1,4 +1,6 @@
using Avalonia.Input; using System.Diagnostics;
using Avalonia.Input;
using Avalonia.Labs.Controls;
using StabilityMatrix.Avalonia.Controls; using StabilityMatrix.Avalonia.Controls;
using StabilityMatrix.Avalonia.ViewModels.PackageManager; using StabilityMatrix.Avalonia.ViewModels.PackageManager;
using StabilityMatrix.Core.Attributes; using StabilityMatrix.Core.Attributes;
@ -20,4 +22,9 @@ public partial class PackageInstallBrowserView : UserControlBase
vm.ClearSearchQuery(); vm.ClearSearchQuery();
} }
} }
private void AsyncImage_OnFailed(object? sender, AsyncImage.AsyncImageFailedEventArgs e)
{
Debug.WriteLine($"Failed to load image: {e.ErrorException?.Message}");
}
} }

19
StabilityMatrix.Avalonia/Views/PackageManager/PackageInstallDetailView.axaml

@ -2,7 +2,6 @@
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:viewModels="clr-namespace:StabilityMatrix.Avalonia.ViewModels"
xmlns:controls="clr-namespace:StabilityMatrix.Avalonia.Controls" xmlns:controls="clr-namespace:StabilityMatrix.Avalonia.Controls"
xmlns:designData="clr-namespace:StabilityMatrix.Avalonia.DesignData" xmlns:designData="clr-namespace:StabilityMatrix.Avalonia.DesignData"
xmlns:lang="clr-namespace:StabilityMatrix.Avalonia.Languages" xmlns:lang="clr-namespace:StabilityMatrix.Avalonia.Languages"
@ -10,24 +9,26 @@
xmlns:controls1="clr-namespace:FluentAvalonia.UI.Controls;assembly=FluentAvalonia" xmlns:controls1="clr-namespace:FluentAvalonia.UI.Controls;assembly=FluentAvalonia"
xmlns:models="clr-namespace:StabilityMatrix.Core.Models;assembly=StabilityMatrix.Core" xmlns:models="clr-namespace:StabilityMatrix.Core.Models;assembly=StabilityMatrix.Core"
xmlns:database="clr-namespace:StabilityMatrix.Core.Models.Database;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"
xmlns:packageManager="clr-namespace:StabilityMatrix.Avalonia.ViewModels.PackageManager" xmlns:packageManager="clr-namespace:StabilityMatrix.Avalonia.ViewModels.PackageManager"
xmlns:labs="clr-namespace:Avalonia.Labs.Controls;assembly=Avalonia.Labs.Controls"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450" mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
x:DataType="packageManager:PackageInstallDetailViewModel" x:DataType="packageManager:PackageInstallDetailViewModel"
x:CompileBindings="True" x:CompileBindings="True"
d:DataContext="{x:Static designData:DesignData.PackageInstallDetailViewModel}" d:DataContext="{x:Static designData:DesignData.PackageInstallDetailViewModel}"
x:Class="StabilityMatrix.Avalonia.Views.PackageManager.PackageInstallDetailView"> x:Class="StabilityMatrix.Avalonia.Views.PackageManager.PackageInstallDetailView">
<Grid ColumnDefinitions="Auto, *" <Grid ColumnDefinitions="Auto, *"
RowDefinitions="Auto, *"> RowDefinitions="Auto, *">
<controls:BetterAdvancedImage <labs:AsyncImage
MaxHeight="300" Height="300"
MaxWidth="300" Width="300"
Margin="16,16,8,8"
CornerRadius="8"
VerticalAlignment="Top" VerticalAlignment="Top"
Stretch="UniformToFill" Stretch="UniformToFill"
Source="{Binding SelectedPackage.PreviewImageUri}" /> Margin="16, 16, 8, 8"
CornerRadius="8"
Source="{Binding SelectedPackage.PreviewImageUri}">
</labs:AsyncImage>
<StackPanel Grid.Row="0" Grid.Column="1" <StackPanel Grid.Row="0" Grid.Column="1"
Margin="8" Margin="8"
Orientation="Vertical"> Orientation="Vertical">

5
StabilityMatrix.Avalonia/Views/PackageManagerPage.axaml

@ -13,6 +13,7 @@
xmlns:converters="clr-namespace:StabilityMatrix.Avalonia.Converters" xmlns:converters="clr-namespace:StabilityMatrix.Avalonia.Converters"
xmlns:avalonia="clr-namespace:SpacedGridControl.Avalonia;assembly=SpacedGridControl.Avalonia" xmlns:avalonia="clr-namespace:SpacedGridControl.Avalonia;assembly=SpacedGridControl.Avalonia"
xmlns:markupExtensions="clr-namespace:StabilityMatrix.Avalonia.MarkupExtensions" xmlns:markupExtensions="clr-namespace:StabilityMatrix.Avalonia.MarkupExtensions"
xmlns:labs="clr-namespace:Avalonia.Labs.Controls;assembly=Avalonia.Labs.Controls"
mc:Ignorable="d" d:DesignWidth="1000" d:DesignHeight="450" mc:Ignorable="d" d:DesignWidth="1000" d:DesignHeight="450"
x:DataType="viewModels:PackageManagerViewModel" x:DataType="viewModels:PackageManagerViewModel"
x:CompileBindings="True" x:CompileBindings="True"
@ -44,15 +45,13 @@
</MultiBinding> </MultiBinding>
</controls:Card.Background> </controls:Card.Background>
<Grid ColumnDefinitions="Auto, *"> <Grid ColumnDefinitions="Auto, *">
<controls:BetterAdvancedImage <labs:AsyncImage
Grid.Column="0" Grid.Column="0"
Height="150" Height="150"
Width="150" Width="150"
Margin="4, 8" Margin="4, 8"
CornerRadius="8" CornerRadius="8"
HorizontalAlignment="Center" HorizontalAlignment="Center"
VerticalContentAlignment="Top"
HorizontalContentAlignment="Center"
Source="{Binding CardImageSource}" Source="{Binding CardImageSource}"
IsVisible="{Binding !IsUnknownPackage}" IsVisible="{Binding !IsUnknownPackage}"
Stretch="UniformToFill" /> Stretch="UniformToFill" />

12
StabilityMatrix.Core/StabilityMatrix.Core.csproj

@ -17,8 +17,8 @@
<ItemGroup> <ItemGroup>
<PackageReference Include="AsyncAwaitBestPractices" Version="7.0.0" /> <PackageReference Include="AsyncAwaitBestPractices" Version="7.0.0" />
<PackageReference Include="AutoCtor" Version="2.1.1" /> <PackageReference Include="AutoCtor" Version="2.2.0" />
<PackageReference Include="Blake3" Version="1.0.0" /> <PackageReference Include="Blake3" Version="1.1.0" />
<PackageReference Include="Crc32.NET" Version="1.2.0" /> <PackageReference Include="Crc32.NET" Version="1.2.0" />
<PackageReference Include="CSharpDiscriminatedUnion" Version="2.0.1" /> <PackageReference Include="CSharpDiscriminatedUnion" Version="2.0.1" />
<PackageReference Include="DeviceId" Version="6.6.0" /> <PackageReference Include="DeviceId" Version="6.6.0" />
@ -27,10 +27,10 @@
<PackageReference Include="DeviceId.Windows" Version="6.6.0" /> <PackageReference Include="DeviceId.Windows" Version="6.6.0" />
<PackageReference Include="DeviceId.Windows.Wmi" Version="6.6.0" /> <PackageReference Include="DeviceId.Windows.Wmi" Version="6.6.0" />
<PackageReference Include="DotNet.Bundle" Version="0.9.13" /> <PackageReference Include="DotNet.Bundle" Version="0.9.13" />
<PackageReference Include="DynamicData" Version="8.3.27" /> <PackageReference Include="DynamicData" Version="8.4.1" />
<PackageReference Include="ExifLibNet" Version="2.1.4" /> <PackageReference Include="ExifLibNet" Version="2.1.4" />
<PackageReference Include="FreneticLLC.FreneticUtilities" Version="1.0.24" /> <PackageReference Include="FreneticLLC.FreneticUtilities" Version="1.0.24" />
<PackageReference Include="Hardware.Info" Version="100.0.1.1" /> <PackageReference Include="Hardware.Info" Version="100.1.0" />
<PackageReference Include="JetBrains.Annotations" Version="2023.3.0" /> <PackageReference Include="JetBrains.Annotations" Version="2023.3.0" />
<PackageReference Include="KGySoft.Drawing.Core" Version="8.1.0" /> <PackageReference Include="KGySoft.Drawing.Core" Version="8.1.0" />
<PackageReference Include="KGySoft.Drawing.SkiaSharp" Version="8.1.0" /> <PackageReference Include="KGySoft.Drawing.SkiaSharp" Version="8.1.0" />
@ -45,7 +45,7 @@
<PackageReference Include="Octokit" Version="10.0.0" /> <PackageReference Include="Octokit" Version="10.0.0" />
<PackageReference Include="OneOf" Version="3.0.263" /> <PackageReference Include="OneOf" Version="3.0.263" />
<PackageReference Include="OneOf.SourceGenerator" Version="3.0.263" /> <PackageReference Include="OneOf.SourceGenerator" Version="3.0.263" />
<PackageReference Include="Polly" Version="8.3.0" /> <PackageReference Include="Polly" Version="8.3.1" />
<PackageReference Include="Polly.Contrib.WaitAndRetry" Version="1.1.1" /> <PackageReference Include="Polly.Contrib.WaitAndRetry" Version="1.1.1" />
<PackageReference Include="pythonnet" Version="3.0.3" /> <PackageReference Include="pythonnet" Version="3.0.3" />
<PackageReference Include="Refit" Version="7.0.0" /> <PackageReference Include="Refit" Version="7.0.0" />
@ -53,7 +53,7 @@
<PackageReference Include="RockLib.Reflection.Optimized" Version="3.0.0" /> <PackageReference Include="RockLib.Reflection.Optimized" Version="3.0.0" />
<PackageReference Include="Salaros.ConfigParser" Version="0.3.8" /> <PackageReference Include="Salaros.ConfigParser" Version="0.3.8" />
<PackageReference Include="Semver" Version="3.0.0-beta.1" /> <PackageReference Include="Semver" Version="3.0.0-beta.1" />
<PackageReference Include="Sentry.NLog" Version="4.1.2" /> <PackageReference Include="Sentry.NLog" Version="4.2.1" />
<PackageReference Include="SharpCompress" Version="0.36.0" /> <PackageReference Include="SharpCompress" Version="0.36.0" />
<PackageReference Include="SkiaSharp" Version="2.88.7" /> <PackageReference Include="SkiaSharp" Version="2.88.7" />
<PackageReference Include="Websocket.Client" Version="5.1.1" /> <PackageReference Include="Websocket.Client" Version="5.1.1" />

8
StabilityMatrix.Tests/StabilityMatrix.Tests.csproj

@ -17,18 +17,18 @@
<ItemGroup> <ItemGroup>
<PackageReference Include="DotNet.Bundle" Version="0.9.13" /> <PackageReference Include="DotNet.Bundle" Version="0.9.13" />
<PackageReference Include="DotNext" Version="5.1.0" /> <PackageReference Include="DotNext" Version="5.3.1" />
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="8.0.0" /> <PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="8.0.0" />
<PackageReference Include="Microsoft.Extensions.Http.Polly" Version="8.0.2" /> <PackageReference Include="Microsoft.Extensions.Http.Polly" Version="8.0.3" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.9.0" /> <PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.9.0" />
<PackageReference Include="MSTest.TestAdapter" Version="3.2.2" /> <PackageReference Include="MSTest.TestAdapter" Version="3.2.2" />
<PackageReference Include="MSTest.TestFramework" Version="3.2.2" /> <PackageReference Include="MSTest.TestFramework" Version="3.2.2" />
<PackageReference Include="coverlet.collector" Version="6.0.1"> <PackageReference Include="coverlet.collector" Version="6.0.2">
<PrivateAssets>all</PrivateAssets> <PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference> </PackageReference>
<PackageReference Include="NSubstitute" Version="5.1.0" /> <PackageReference Include="NSubstitute" Version="5.1.0" />
<PackageReference Include="Polly" Version="8.3.0" /> <PackageReference Include="Polly" Version="8.3.1" />
<PackageReference Include="Polly.Contrib.WaitAndRetry" Version="1.1.1" /> <PackageReference Include="Polly.Contrib.WaitAndRetry" Version="1.1.1" />
</ItemGroup> </ItemGroup>

8
StabilityMatrix.UITests/StabilityMatrix.UITests.csproj

@ -15,16 +15,16 @@
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Avalonia.Headless.XUnit" Version="11.0.9" /> <PackageReference Include="Avalonia.Headless.XUnit" Version="11.0.10" />
<PackageReference Include="DotNet.Bundle" Version="0.9.13" /> <PackageReference Include="DotNet.Bundle" Version="0.9.13" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.9.0" /> <PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.9.0" />
<PackageReference Include="NSubstitute" Version="5.1.0" /> <PackageReference Include="NSubstitute" Version="5.1.0" />
<PackageReference Include="System.Drawing.Common" Version="8.0.2" /> <PackageReference Include="System.Drawing.Common" Version="8.0.3" />
<PackageReference Include="Verify" Version="23.2.2" /> <PackageReference Include="Verify" Version="23.5.2" />
<PackageReference Include="Verify.CommunityToolkit.Mvvm" Version="0.1.0" /> <PackageReference Include="Verify.CommunityToolkit.Mvvm" Version="0.1.0" />
<PackageReference Include="Verify.Avalonia" Version="1.0.1" /> <PackageReference Include="Verify.Avalonia" Version="1.0.1" />
<PackageReference Include="Verify.Phash" Version="3.1.0" /> <PackageReference Include="Verify.Phash" Version="3.1.0" />
<PackageReference Include="Verify.Xunit" Version="23.2.2" /> <PackageReference Include="Verify.Xunit" Version="23.5.2" />
<PackageReference Include="xunit" Version="2.7.0" /> <PackageReference Include="xunit" Version="2.7.0" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.5.7"> <PackageReference Include="xunit.runner.visualstudio" Version="2.5.7">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>

Loading…
Cancel
Save