Conversation
Add single-instance window activation signaling (cherry picked from commit 1ad05fe1f14aee62cafd09df9c9946ef1bfbf9f3) # Conflicts: # CHANGELOG.md
(cherry picked from commit 4711b23035d22f690c9a5355213b339b1a7b8c1e) # Conflicts: # CHANGELOG.md
Updated version number and changelog entries for version 2.15.7. Removed outdated sections and added new features and fixes.
…rive-warning Add OneDrive folder warning and fix download issues (cherry picked from commit e7eb0100a91fc0fa27cf23ef3ed7bf707d865506)
[dev to main] backport: Add OneDrive folder warning and fix download issues (1219)
…into downmerg-stuff
Downmerg stuff
…wing-inopportunely Refactor Teaching Tip logic in MainPackageManagerView. (cherry picked from commit 770671ec72fd69978f0727c0d753b1c64736f125) # Conflicts: # CHANGELOG.md # StabilityMatrix.Core/Processes/ProcessRunner.cs
…forge Fix setuptools version to avoid runtime issues with CLIP imports (cherry picked from commit 373b890f7ff11e4e6e9762fbcbd6e44c4f1f04f1) # Conflicts: # CHANGELOG.md # StabilityMatrix.Core/Processes/ProcessRunner.cs
[dev to main] backport: Refactor Teaching Tip logic in MainPackageManagerView. (1224)
…into downmerg-again
[dev to main] backport: Fix setuptools version to avoid runtime issues with CLIP imports (1226)
Downmerg again
shoutout chagenlog and download json length fix (cherry picked from commit ce8c057db3df1f95134e1bfd0b55d2e19308e788) # Conflicts: # CHANGELOG.md
[dev to main] backport: shoutout chagenlog and download json length fix (1230)
…ccounts Update account UI for Lykos membership migration (cherry picked from commit eca1fd20e5320240ccd3be1f7e00cf95f7ad8736) # Conflicts: # StabilityMatrix.Avalonia/Views/Dialogs/LayeredMaskEditorDialog.axaml # StabilityMatrix.Avalonia/Views/Settings/AccountSettingsPage.axaml
Updated CHANGELOG with new features, changes, and fixes.
Updated the list of supporters in the CHANGELOG.md, adding new Visionaries and Pioneers.
Revise supporter acknowledgments in CHANGELOG.md
(cherry picked from commit 44eaca38fc392ccdb99bf765912230ae88fcd1f4)
There was a problem hiding this comment.
Code Review
This pull request introduces a comprehensive notification system with localizable banners and markdown dialogs, transitions the membership model from Patreon to direct Lykos accounts, and implements single-instance window activation. It also includes critical fixes for Python environment variable poisoning, download failures related to redirects and auth headers, and font rendering issues in markdown dialogs. Feedback highlights several improvement opportunities: a logic error in the notification dialog button routing where the secondary button is never assigned, potential data corruption when starting fresh downloads without truncating existing files, and the need for better caching of font instances. Additionally, it is recommended to use culture-aware date formatting for localized strings and to utilize the Uri class for more robust parsing of local file paths.
| AppNotificationButton? secondaryButton = null; | ||
| AppNotificationButton? closeButton = null; | ||
|
|
||
| if (dialogData.Buttons is { Count: > 0 } buttons) | ||
| { | ||
| // Route each button to its ContentDialog slot based on Style | ||
| foreach (var btn in buttons) | ||
| { | ||
| switch (btn.Style) | ||
| { | ||
| case AppNotificationButtonStyle.Primary: | ||
| case AppNotificationButtonStyle.Accent: | ||
| if (primaryButton is null) | ||
| { | ||
| primaryButton = btn; | ||
| dialog.PrimaryButtonText = | ||
| appNotificationService.ResolveLocalizedString(btn.Label) ?? ""; | ||
| dialog.IsPrimaryButtonEnabled = true; | ||
| } | ||
| break; | ||
|
|
||
| case AppNotificationButtonStyle.Close: | ||
| case AppNotificationButtonStyle.Secondary | ||
| when closeButton is null && primaryButton is not null: | ||
| // Use as close slot if we already have a primary, or it's explicitly Close style | ||
| if (btn.Style == AppNotificationButtonStyle.Close || closeButton is null) | ||
| { | ||
| closeButton = btn; | ||
| dialog.CloseButtonText = | ||
| appNotificationService.ResolveLocalizedString(btn.Label) ?? ""; | ||
| } | ||
| break; | ||
|
|
||
| case AppNotificationButtonStyle.Secondary: | ||
| // First Secondary with no Primary yet → treat as Primary | ||
| if (primaryButton is null) | ||
| { | ||
| primaryButton = btn; | ||
| dialog.PrimaryButtonText = | ||
| appNotificationService.ResolveLocalizedString(btn.Label) ?? ""; | ||
| dialog.IsPrimaryButtonEnabled = true; | ||
| } | ||
| else if (closeButton is null) | ||
| { | ||
| closeButton = btn; | ||
| dialog.CloseButtonText = | ||
| appNotificationService.ResolveLocalizedString(btn.Label) ?? ""; | ||
| } | ||
| break; | ||
| } | ||
| } | ||
| } | ||
| else | ||
| { | ||
| dialog.CloseButtonText = Resources.Action_Close; | ||
| } | ||
|
|
||
| var result = await dialog.ShowAsync(); | ||
|
|
||
| // Resolve which button was clicked from the ContentDialog result | ||
| var clickedButton = result switch | ||
| { | ||
| ContentDialogResult.Primary => primaryButton, | ||
| ContentDialogResult.Secondary => secondaryButton, |
There was a problem hiding this comment.
The secondaryButton variable is declared but never assigned a value within the button routing loop (lines 128-172). As a result, the SecondaryButtonText of the dialog is never set, and the result mapping on line 185 will always return null for ContentDialogResult.Secondary. This prevents any secondary action from being displayed or executed.
| FileMode.OpenOrCreate, | ||
| FileAccess.Write, | ||
| FileShare.None | ||
| ); | ||
| file.Seek(existingFileSize, SeekOrigin.Begin); |
There was a problem hiding this comment.
When starting a fresh download (where existingFileSize is 0), using FileMode.OpenOrCreate without truncating the file can lead to data corruption if a file already exists at the destination. If the new download is smaller than the existing file, trailing data from the previous file will remain. Consider calling file.SetLength(0) when existingFileSize is 0 to ensure a clean start.
| { | ||
| var fontFamily = | ||
| Cultures.Current?.Name == "ja-JP" ? app.GetPlatformDefaultFontFamily() | ||
| : Compat.IsWindows ? new FontFamily("Segoe UI") |
| PatreonGracePeriodText = ShowPatreonMigrationPrompt | ||
| ? string.Format( | ||
| Resources.InfoBar_PatreonGracePeriod, | ||
| new DateTimeOffset(2026, 4, 25, 0, 0, 0, TimeSpan.Zero).ToString("MMMM d, yyyy") |
There was a problem hiding this comment.
The date format string "MMMM d, yyyy" is hardcoded, which fixes the order of date components regardless of the user's locale. Given that this release adds support for multiple languages (Japanese, Korean, German, French), consider using a localized resource string or a standard culture-aware format pattern to ensure the date is displayed in a format familiar to the user.
| if (Compat.IsWindows && filePath.StartsWith('\\')) | ||
| filePath = filePath[1..]; | ||
|
|
There was a problem hiding this comment.
Manual parsing of file:// URIs using string slicing and character replacement is brittle and may fail for various URI formats (e.g., UNC paths or relative paths). Using the Uri class to extract the LocalPath is more robust and cross-platform.
var uri = new Uri(NotificationsUrl);
var filePath = uri.LocalPath;
v2.15.7
Added
Changed
Fixed
Align Your Stepsscheduler and Unet Loader workflows ignored Regional Prompting (and other addon) conditioning modifiers.CBoldandCItalicinline styles to the markdown style sheetPYTHONHOME,PYTHONPATH,VIRTUAL_ENV, and Conda environment variablesSocketException: Address already in useon Linux startup by cleaning stale interprocess socket files and reactivating the existing windowSupporters
🌟 Visionaries
Lifting up our legendary Visionaries: Waterclouds, JungleDragon, bluepopsicle, Bob S, and whudunit. Through every release, every milestone, and every twist of this wild journey, your support has been our north star. A huge welcome to our newest Visionaries Droolguy and snotty (leveling up from the Pioneer crew!), a warm welcome back to longtime Visionary Ibixat, and an equally huge welcome to LG and MrMxyzptlk12836, making their Stability Matrix debut straight at the Visionary tier - so glad to have you all on board! We cannot thank you enough for standing behind Stability Matrix!
🚀 Pioneers
And to our mighty Pioneer crew - the folks who keep the engine humming - thank you for everything! Massive shoutout to: Szir777, Noah M, [USA]TechDude, Thom, SeraphOfSalem, Desert Viber, Adam, ACTUALLY_the_Real_Willem_Dafoe, takyamtom, robek, Ghislain G, Phil R, Tundra Everquill, Andrew B, SinthCore, and Ahmed S. And a very warm welcome to our newest Pioneers Commissar Lord Death, Firelight, and jweg, plus a heartfelt shoutout to one more new Pioneer who joined us quietly through the Stripe migration - you know who you are, and we're so glad to have you!
And one more heartfelt thank you to everyone now supporting us directly through our new platform - this next chapter wouldn't be possible without your trust, and we're so grateful you've come along for the ride!