Browse Source

Merge pull request #372 from ionite34/checkpoints-username

pull/324/head
Ionite 12 months ago committed by GitHub
parent
commit
a53ac19614
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 3
      CHANGELOG.md
  2. 14
      StabilityMatrix.Avalonia/DesignData/DesignData.cs
  3. 19
      StabilityMatrix.Avalonia/Helpers/IOCommands.cs
  4. 20
      StabilityMatrix.Avalonia/ViewModels/Base/ViewModelBase.cs
  5. 10
      StabilityMatrix.Avalonia/ViewModels/CheckpointBrowserViewModel.cs
  6. 12
      StabilityMatrix.Avalonia/ViewModels/MainWindowViewModel.cs
  7. 43
      StabilityMatrix.Avalonia/Views/CheckpointBrowserPage.axaml
  8. 9
      StabilityMatrix.Core/Models/Api/CivitCreator.cs

3
CHANGELOG.md

@ -11,6 +11,7 @@ and this project adheres to [Semantic Versioning 2.0](https://semver.org/spec/v2
#### Model Browser
- Right clicking anywhere on the model card will open the same menu as the three-dots button
- New model downloads will save trigger words in metadata, if available
- Model author username and avatar display, with clickable link to their profile
#### Checkpoints Page
- Added "Copy Trigger Words" option to the three-dots menu on the Checkpoints page (when data is available)
- Added trigger words on checkpoint card and tooltip
@ -20,6 +21,8 @@ and this project adheres to [Semantic Versioning 2.0](https://semver.org/spec/v2
- Animated zoom effect on hovering over model images
#### Checkpoints Page
- Rearranged top row layout to use CommandBar
### Fixed
- Improved startup time and window load time after exiting dialogs
## v2.7.0-dev.2
### Added

14
StabilityMatrix.Avalonia/DesignData/DesignData.cs

@ -310,7 +310,12 @@ public static class DesignData
Stats = new CivitModelStats { Rating = 3.5, RatingCount = 24 },
ModelVersions = [
new() { Name = "v1.2.2-Inpainting" }
]
],
Creator = new CivitCreator
{
Image = "https://gravatar.com/avatar/fe74084ae8a081dc2283f5bde4736756ad?f=y&d=retro",
Username = "creator-1"
}
};
}),
dialogFactory.Get<CheckpointBrowserCardViewModel>(vm =>
@ -334,7 +339,12 @@ public static class DesignData
}
}
}
]
],
Creator = new CivitCreator
{
Image = "https://gravatar.com/avatar/205e460b479e2e5b48aec07710c08d50?f=y&d=retro",
Username = "creator-2"
}
};
})
};

19
StabilityMatrix.Avalonia/Helpers/IOCommands.cs

@ -0,0 +1,19 @@
using CommunityToolkit.Mvvm.Input;
using StabilityMatrix.Core.Processes;
namespace StabilityMatrix.Avalonia.Helpers;
public static class IOCommands
{
public static RelayCommand<string?> OpenUrlCommand { get; } =
new(
url =>
{
if (string.IsNullOrWhiteSpace(url))
return;
ProcessRunner.OpenUrl(url);
},
url => !string.IsNullOrWhiteSpace(url)
);
}

20
StabilityMatrix.Avalonia/ViewModels/Base/ViewModelBase.cs

@ -1,6 +1,7 @@
using System;
using System.Threading.Tasks;
using AsyncAwaitBestPractices;
using Avalonia.Threading;
using CommunityToolkit.Mvvm.ComponentModel;
using JetBrains.Annotations;
using StabilityMatrix.Avalonia.Models;
@ -39,7 +40,10 @@ public class ViewModelBase : ObservableValidator, IRemovableListItem
if (!ViewModelState.HasFlag(ViewModelState.InitialLoaded))
{
ViewModelState |= ViewModelState.InitialLoaded;
OnInitialLoaded();
Dispatcher.UIThread.InvokeAsync(OnInitialLoadedAsync).SafeFireAndForget();
}
}
@ -54,10 +58,13 @@ public class ViewModelBase : ObservableValidator, IRemovableListItem
/// Runs on the UI thread via Dispatcher.UIThread.InvokeAsync.
/// The view loading will not wait for this to complete.
/// </summary>
public virtual Task OnLoadedAsync()
{
return Task.CompletedTask;
}
public virtual Task OnLoadedAsync() => Task.CompletedTask;
/// <summary>
/// Called the first time the view's LoadedEvent is fired.
/// Sets the <see cref="ViewModelState.InitialLoaded"/> flag.
/// </summary>
protected virtual Task OnInitialLoadedAsync() => Task.CompletedTask;
/// <summary>
/// Called when the view's UnloadedEvent is fired.
@ -69,8 +76,5 @@ public class ViewModelBase : ObservableValidator, IRemovableListItem
/// Runs on the UI thread via Dispatcher.UIThread.InvokeAsync.
/// The view loading will not wait for this to complete.
/// </summary>
public virtual Task OnUnloadedAsync()
{
return Task.CompletedTask;
}
public virtual Task OnUnloadedAsync() => Task.CompletedTask;
}

10
StabilityMatrix.Avalonia/ViewModels/CheckpointBrowserViewModel.cs

@ -470,12 +470,14 @@ public partial class CheckpointBrowserViewModel : PageViewModelBase
}
// See if query is cached
var cachedQuery = await liteDbContext.CivitModelQueryCache
.IncludeAll()
.FindByIdAsync(ObjectHash.GetMd5Guid(modelRequest));
var cachedQueryResult = await notificationService.TryAsync(
liteDbContext.CivitModelQueryCache
.IncludeAll()
.FindByIdAsync(ObjectHash.GetMd5Guid(modelRequest))
);
// If cached, update model cards
if (cachedQuery is not null)
if (cachedQueryResult.Result is { } cachedQuery)
{
var elapsed = timer.Elapsed;
Logger.Debug(

12
StabilityMatrix.Avalonia/ViewModels/MainWindowViewModel.cs

@ -78,7 +78,7 @@ public partial class MainWindowViewModel : ViewModelBase
SelectedCategory ??= Pages.FirstOrDefault();
}
public override async Task OnLoadedAsync()
protected override async Task OnInitialLoadedAsync()
{
await base.OnLoadedAsync();
@ -102,16 +102,20 @@ public partial class MainWindowViewModel : ViewModelBase
// Index checkpoints if we dont have
Task.Run(() => settingsManager.IndexCheckpoints()).SafeFireAndForget();
if (!App.IsHeadlessMode)
// Disable preload for now, might be causing https://github.com/LykosAI/StabilityMatrix/issues/249
/*if (!App.IsHeadlessMode)
{
PreloadPages();
}
}*/
Program.StartupTimer.Stop();
var startupTime = CodeTimer.FormatTime(Program.StartupTimer.Elapsed);
Logger.Info($"App started ({startupTime})");
if (Program.Args.DebugOneClickInstall || !settingsManager.Settings.InstalledPackages.Any())
if (
Program.Args.DebugOneClickInstall
|| settingsManager.Settings.InstalledPackages.Count == 0
)
{
var viewModel = dialogFactory.Get<OneClickInstallViewModel>();
var dialog = new BetterContentDialog

43
StabilityMatrix.Avalonia/Views/CheckpointBrowserPage.axaml

@ -14,6 +14,7 @@
xmlns:vm="clr-namespace:StabilityMatrix.Avalonia.ViewModels.CheckpointManager"
xmlns:converters="clr-namespace:StabilityMatrix.Avalonia.Converters"
xmlns:asyncImageLoader="clr-namespace:AsyncImageLoader;assembly=AsyncImageLoader.Avalonia"
xmlns:helpers="clr-namespace:StabilityMatrix.Avalonia.Helpers"
d:DataContext="{x:Static designData:DesignData.CheckpointBrowserViewModel}"
d:DesignHeight="700"
d:DesignWidth="800"
@ -138,6 +139,48 @@
</Button>
</StackPanel>
<!-- Username pill card -->
<Border
BoxShadow="inset 1.2 0 80 1.8 #66000000"
CornerRadius="16"
Margin="4"
Grid.Row="0"
HorizontalAlignment="Left"
VerticalAlignment="Bottom">
<Border.Resources>
<DropShadowEffect
x:Key="TextDropShadowEffect"
BlurRadius="12"
Color="#FF000000"
Opacity="0.9"/>
<DropShadowEffect
x:Key="ImageDropShadowEffect"
BlurRadius="12"
Color="#FF000000"
Opacity="0.2"/>
</Border.Resources>
<Button
Command="{x:Static helpers:IOCommands.OpenUrlCommand}"
CommandParameter="{Binding CivitModel.Creator.ProfileUrl}"
CornerRadius="16"
Classes="transparent"
Padding="10,4">
<StackPanel Orientation="Horizontal" Spacing="6">
<controls:BetterAdvancedImage
Width="22"
Height="22"
Effect="{StaticResource ImageDropShadowEffect}"
CornerRadius="11"
RenderOptions.BitmapInterpolationMode="HighQuality"
IsVisible="{Binding CivitModel.Creator.Image, Converter={x:Static StringConverters.IsNotNullOrEmpty}}"
Source="{Binding CivitModel.Creator.Image}"/>
<TextBlock
VerticalAlignment="Center"
Effect="{StaticResource TextDropShadowEffect}"
Text="{Binding CivitModel.Creator.Username}"/>
</StackPanel>
</Button>
</Border>
<StackPanel Grid.Row="0" Orientation="Horizontal">
<controls:Card

9
StabilityMatrix.Core/Models/Api/CivitCreator.cs

@ -2,11 +2,14 @@
namespace StabilityMatrix.Core.Models.Api;
public class CivitCreator
public record CivitCreator
{
[JsonPropertyName("username")]
public string Username { get; set; }
public string? Username { get; init; }
[JsonPropertyName("image")]
public string? Image { get; set; }
public string? Image { get; init; }
[JsonIgnore]
public string? ProfileUrl => Username is null ? null : $"https://civitai.com/user/{Username}";
}

Loading…
Cancel
Save