Browse Source

redesigned packages page & made it the first tab & removed old launch page from tabs

pull/629/head
JT 9 months ago
parent
commit
2303759eec
  1. 3
      StabilityMatrix.Avalonia/App.axaml.cs
  2. 73
      StabilityMatrix.Avalonia/Styles/ButtonStyles.axaml
  3. 12
      StabilityMatrix.Avalonia/ViewModels/CheckpointManager/CheckpointFolder.cs
  4. 73
      StabilityMatrix.Avalonia/ViewModels/PackageManager/PackageCardViewModel.cs
  5. 11
      StabilityMatrix.Avalonia/ViewModels/RunningPackageViewModel.cs
  6. 8
      StabilityMatrix.Avalonia/Views/ConsoleOutputPage.axaml
  7. 249
      StabilityMatrix.Avalonia/Views/PackageManagerPage.axaml
  8. 3
      StabilityMatrix.Core/Models/DownloadPackageVersionOptions.cs

3
StabilityMatrix.Avalonia/App.axaml.cs

@ -328,9 +328,8 @@ public sealed class App : Application
{ {
Pages = Pages =
{ {
provider.GetRequiredService<LaunchPageViewModel>(),
provider.GetRequiredService<InferenceViewModel>(),
provider.GetRequiredService<NewPackageManagerViewModel>(), provider.GetRequiredService<NewPackageManagerViewModel>(),
provider.GetRequiredService<InferenceViewModel>(),
provider.GetRequiredService<CheckpointsPageViewModel>(), provider.GetRequiredService<CheckpointsPageViewModel>(),
provider.GetRequiredService<CheckpointBrowserViewModel>(), provider.GetRequiredService<CheckpointBrowserViewModel>(),
provider.GetRequiredService<OutputsPageViewModel>() provider.GetRequiredService<OutputsPageViewModel>()

73
StabilityMatrix.Avalonia/Styles/ButtonStyles.axaml

@ -99,6 +99,43 @@
</Style> </Style>
</Style> </Style>
<!-- Danger -->
<Style Selector="Button.borderless-danger">
<Style Selector="^ /template/ ui|FABorder#Root">
<Setter Property="Background" Value="{DynamicResource ThemeRedColor}" />
</Style>
<Style Selector="^ /template/ ContentPresenter#PART_ContentPresenter">
<Setter Property="Foreground" Value="{DynamicResource ButtonForeground}" />
</Style>
<Style Selector="^:pointerover">
<Style Selector="^ /template/ ui|FABorder#Root">
<Setter Property="Background" Value="{DynamicResource ThemeDarkRedColor}"/>
</Style>
<Style Selector="^ /template/ ContentPresenter#PART_ContentPresenter">
<Setter Property="Foreground" Value="{DynamicResource ButtonForegroundPointerOver}" />
</Style>
</Style>
<Style Selector="^:pressed">
<Style Selector="^ /template/ ui|FABorder#Root">
<Setter Property="Background" Value="{DynamicResource ThemeDarkDarkRedColor}" />
</Style>
<Style Selector="^ /template/ ContentPresenter#PART_ContentPresenter">
<Setter Property="Foreground" Value="{DynamicResource ButtonForegroundPressed}" />
</Style>
</Style>
<Style Selector="^:disabled">
<Style Selector="^ /template/ ui|FABorder#Root">
<Setter Property="Background" Value="{DynamicResource ButtonBackgroundDisabled}" />
</Style>
<Style Selector="^ /template/ ContentPresenter#PART_ContentPresenter">
<Setter Property="Foreground" Value="{DynamicResource ButtonForegroundDisabled}" />
</Style>
</Style>
</Style>
<!-- Info --> <!-- Info -->
<Style Selector="Button.info"> <Style Selector="Button.info">
<Style Selector="^ /template/ ui|FABorder#Root"> <Style Selector="^ /template/ ui|FABorder#Root">
@ -140,6 +177,42 @@
</Style> </Style>
</Style> </Style>
<Style Selector="Button.borderless-info">
<Style Selector="^ /template/ ui|FABorder#Root">
<Setter Property="Background" Value="{DynamicResource ThemeLightBlueColor}" />
</Style>
<Style Selector="^ /template/ ContentPresenter#PART_ContentPresenter">
<Setter Property="Foreground" Value="{DynamicResource ButtonForeground}" />
</Style>
<Style Selector="^:pointerover">
<Style Selector="^ /template/ ui|FABorder#Root">
<Setter Property="Background" Value="{DynamicResource ThemeBlueColor}"/>
</Style>
<Style Selector="^ /template/ ContentPresenter#PART_ContentPresenter">
<Setter Property="Foreground" Value="{DynamicResource ButtonForegroundPointerOver}" />
</Style>
</Style>
<Style Selector="^:pressed">
<Style Selector="^ /template/ ui|FABorder#Root">
<Setter Property="Background" Value="{DynamicResource ThemeDarkBlueColor}" />
</Style>
<Style Selector="^ /template/ ContentPresenter#PART_ContentPresenter">
<Setter Property="Foreground" Value="{DynamicResource ButtonForegroundPressed}" />
</Style>
</Style>
<Style Selector="^:disabled">
<Style Selector="^ /template/ ui|FABorder#Root">
<Setter Property="Background" Value="{DynamicResource ButtonBackgroundDisabled}" />
</Style>
<Style Selector="^ /template/ ContentPresenter#PART_ContentPresenter">
<Setter Property="Foreground" Value="{DynamicResource ButtonForegroundDisabled}" />
</Style>
</Style>
</Style>
<!--Accent Button--> <!--Accent Button-->
<Style Selector="Button.accent"> <Style Selector="Button.accent">
<Style Selector="^ /template/ ui|FABorder#Root"> <Style Selector="^ /template/ ui|FABorder#Root">

12
StabilityMatrix.Avalonia/ViewModels/CheckpointManager/CheckpointFolder.cs

@ -111,6 +111,10 @@ public partial class CheckpointFolder : ViewModelBase
public IObservableCollection<string> BaseModelOptions { get; } = public IObservableCollection<string> BaseModelOptions { get; } =
new ObservableCollectionExtended<string>(); new ObservableCollectionExtended<string>();
private IEnumerable<string> allModelOptions = Enum.GetValues<CivitBaseModelType>()
.Where(x => x != CivitBaseModelType.All)
.Select(x => x.GetStringValue());
public CheckpointFolder( public CheckpointFolder(
ISettingsManager settingsManager, ISettingsManager settingsManager,
IDownloadService downloadService, IDownloadService downloadService,
@ -175,11 +179,7 @@ public partial class CheckpointFolder : ViewModelBase
SubFoldersCache.Refresh(); SubFoldersCache.Refresh();
}); });
BaseModelOptionsCache.AddOrUpdate( BaseModelOptionsCache.AddOrUpdate(allModelOptions);
Enum.GetValues<CivitBaseModelType>()
.Where(x => x != CivitBaseModelType.All)
.Select(x => x.GetStringValue())
);
CheckpointFiles.CollectionChanged += OnCheckpointFilesChanged; CheckpointFiles.CollectionChanged += OnCheckpointFilesChanged;
// DisplayedCheckpointFiles = CheckpointFiles; // DisplayedCheckpointFiles = CheckpointFiles;
@ -187,7 +187,7 @@ public partial class CheckpointFolder : ViewModelBase
private bool BaseModelFilter(CheckpointFile file) private bool BaseModelFilter(CheckpointFile file)
{ {
return file.IsConnectedModel return file.IsConnectedModel && allModelOptions.Contains(file.ConnectedModel!.BaseModel)
? BaseModelOptions.Contains(file.ConnectedModel!.BaseModel) ? BaseModelOptions.Contains(file.ConnectedModel!.BaseModel)
: BaseModelOptions.Contains("Other"); : BaseModelOptions.Contains("Other");
} }

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

@ -1,5 +1,6 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Collections.Immutable;
using System.Collections.Specialized; using System.Collections.Specialized;
using System.Linq; using System.Linq;
using System.Threading; using System.Threading;
@ -96,13 +97,10 @@ public partial class PackageCardViewModel(
private void RunningPackagesOnCollectionChanged(object? sender, NotifyCollectionChangedEventArgs e) private void RunningPackagesOnCollectionChanged(object? sender, NotifyCollectionChangedEventArgs e)
{ {
if ( if (runningPackageService.RunningPackages.Select(x => x.Value) is not { } runningPackages)
e.NewItems?.OfType<KeyValuePair<Guid, RunningPackageViewModel>>().Select(x => x.Value)
is not { } newItems
)
return; return;
var runningViewModel = newItems.FirstOrDefault( var runningViewModel = runningPackages.FirstOrDefault(
x => x.RunningPackage.InstalledPackage.Id == Package?.Id x => x.RunningPackage.InstalledPackage.Id == Package?.Id
); );
if (runningViewModel is not null) if (runningViewModel is not null)
@ -114,6 +112,7 @@ public partial class PackageCardViewModel(
else if (runningViewModel is null && IsRunning) else if (runningViewModel is null && IsRunning)
{ {
IsRunning = false; IsRunning = false;
ShowWebUiButton = false;
} }
} }
@ -165,6 +164,7 @@ public partial class PackageCardViewModel(
if (Design.IsDesignMode && Package?.DisplayName == "Running Comfy") if (Design.IsDesignMode && Package?.DisplayName == "Running Comfy")
{ {
IsRunning = true; IsRunning = true;
IsUpdateAvailable = true;
ShowWebUiButton = true; ShowWebUiButton = true;
} }
@ -422,6 +422,21 @@ public partial class PackageCardViewModel(
versionOptions.CommitHash = latest.Sha; versionOptions.CommitHash = latest.Sha;
} }
var confirmationDialog = new BetterContentDialog
{
Title = Resources.Label_AreYouSure,
Content =
$"{Package.DisplayName} will be updated to the latest version ({versionOptions.GetReadableVersionString()})",
PrimaryButtonText = Resources.Action_Continue,
SecondaryButtonText = Resources.Action_Cancel,
DefaultButton = ContentDialogButton.Primary,
IsSecondaryButtonEnabled = true,
};
var dialogResult = await confirmationDialog.ShowAsync();
if (dialogResult != ContentDialogResult.Primary)
return;
var updatePackageStep = new UpdatePackageStep( var updatePackageStep = new UpdatePackageStep(
settingsManager, settingsManager,
Package, Package,
@ -583,6 +598,54 @@ public partial class PackageCardViewModel(
await runningPackageService.StopPackage(Package.Id); await runningPackageService.StopPackage(Package.Id);
IsRunning = false; IsRunning = false;
ShowWebUiButton = false;
}
[RelayCommand]
private async Task Restart()
{
await Stop();
await Launch();
}
[RelayCommand]
private async Task ShowLaunchOptions()
{
var basePackage = packageFactory.FindPackageByName(Package?.PackageName);
if (basePackage == null)
{
logger.LogWarning("Package {Name} not found", Package?.PackageName);
return;
}
var viewModel = vmFactory.Get<LaunchOptionsViewModel>();
viewModel.Cards = LaunchOptionCard
.FromDefinitions(basePackage.LaunchOptions, Package?.LaunchArgs ?? [])
.ToImmutableArray();
logger.LogDebug("Launching config dialog with cards: {CardsCount}", viewModel.Cards.Count);
var dialog = new BetterContentDialog
{
ContentVerticalScrollBarVisibility = ScrollBarVisibility.Disabled,
IsPrimaryButtonEnabled = true,
PrimaryButtonText = Resources.Action_Save,
CloseButtonText = Resources.Action_Cancel,
FullSizeDesired = true,
DefaultButton = ContentDialogButton.Primary,
ContentMargin = new Thickness(32, 16),
Padding = new Thickness(0, 16),
Content = new LaunchOptionsDialog { DataContext = viewModel, }
};
var result = await dialog.ShowAsync();
if (result == ContentDialogResult.Primary && Package != null)
{
// Save config
var args = viewModel.AsLaunchArgs();
settingsManager.SaveLaunchArgs(Package.Id, args);
}
} }
private async Task<bool> HasUpdate() private async Task<bool> HasUpdate()

11
StabilityMatrix.Avalonia/ViewModels/RunningPackageViewModel.cs

@ -39,6 +39,9 @@ public partial class RunningPackageViewModel : PageViewModelBase, IDisposable, I
[ObservableProperty] [ObservableProperty]
private bool isRunning = true; private bool isRunning = true;
[ObservableProperty]
private string consoleInput = string.Empty;
/// <inheritdoc/> /// <inheritdoc/>
public RunningPackageViewModel( public RunningPackageViewModel(
ISettingsManager settingsManager, ISettingsManager settingsManager,
@ -118,18 +121,20 @@ public partial class RunningPackageViewModel : PageViewModelBase, IDisposable, I
} }
[RelayCommand] [RelayCommand]
private async Task SendToConsole(string input) private async Task SendToConsole()
{ {
Console.PostLine(input); Console.PostLine(ConsoleInput);
if (RunningPackage?.BasePackage is BaseGitPackage gitPackage) if (RunningPackage?.BasePackage is BaseGitPackage gitPackage)
{ {
var venv = gitPackage.VenvRunner; var venv = gitPackage.VenvRunner;
var process = venv?.Process; var process = venv?.Process;
if (process is not null) if (process is not null)
{ {
await process.StandardInput.WriteLineAsync(input); await process.StandardInput.WriteLineAsync(ConsoleInput);
} }
} }
ConsoleInput = string.Empty;
} }
public void Dispose() public void Dispose()

8
StabilityMatrix.Avalonia/Views/ConsoleOutputPage.axaml

@ -73,14 +73,14 @@
WordWrap="True" /> WordWrap="True" />
<Grid Grid.Row="2" ColumnDefinitions="*, Auto" <Grid Grid.Row="2" ColumnDefinitions="*, Auto"
Margin="8,4,8,8"> Margin="16,4,16,16">
<TextBox Grid.Column="0" Name="ManualInputBox" <TextBox Grid.Column="0" Text="{Binding ConsoleInput, Mode=TwoWay}"
Margin="0,0,8,0"/> Margin="0,0,8,0"/>
<Button Grid.Column="1" <Button Grid.Column="1"
Classes="accent" Classes="accent"
IsDefault="True"
Content="{x:Static lang:Resources.Action_Send}" Content="{x:Static lang:Resources.Action_Send}"
Command="{Binding SendToConsoleCommand}" Command="{Binding SendToConsoleCommand}"/>
CommandParameter="{Binding #ManualInputBox.Text}"/>
</Grid> </Grid>
</Grid> </Grid>
</controls:UserControlBase> </controls:UserControlBase>

249
StabilityMatrix.Avalonia/Views/PackageManagerPage.axaml

@ -12,7 +12,8 @@
xmlns:system="clr-namespace:System;assembly=System.Runtime" xmlns:system="clr-namespace:System;assembly=System.Runtime"
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"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450" xmlns:markupExtensions="clr-namespace:StabilityMatrix.Avalonia.MarkupExtensions"
mc:Ignorable="d" d:DesignWidth="1000" d:DesignHeight="450"
x:DataType="viewModels:PackageManagerViewModel" x:DataType="viewModels:PackageManagerViewModel"
x:CompileBindings="True" x:CompileBindings="True"
d:DataContext="{x:Static designData:DesignData.PackageManagerViewModel}" d:DataContext="{x:Static designData:DesignData.PackageManagerViewModel}"
@ -32,6 +33,7 @@
<ItemsRepeater.ItemTemplate> <ItemsRepeater.ItemTemplate>
<DataTemplate DataType="{x:Type packageManager:PackageCardViewModel}"> <DataTemplate DataType="{x:Type packageManager:PackageCardViewModel}">
<controls:Card Padding="8" <controls:Card Padding="8"
MinWidth="400"
CornerRadius="8"> CornerRadius="8">
<controls:Card.Background> <controls:Card.Background>
<MultiBinding Converter="{StaticResource BoolChoiceMultiConverter}"> <MultiBinding Converter="{StaticResource BoolChoiceMultiConverter}">
@ -40,15 +42,55 @@
<DynamicResource ResourceKey="ButtonBackground" /> <DynamicResource ResourceKey="ButtonBackground" />
</MultiBinding> </MultiBinding>
</controls:Card.Background> </controls:Card.Background>
<Grid RowDefinitions="Auto, Auto, Auto, Auto" <Grid ColumnDefinitions="Auto, *">
ColumnDefinitions="*,Auto"> <controls:BetterAdvancedImage
Grid.Column="0"
<TextBlock Grid.Row="0" Height="150"
Width="150"
Margin="4, 8"
CornerRadius="8"
HorizontalAlignment="Center"
VerticalContentAlignment="Top"
HorizontalContentAlignment="Center"
Source="{Binding CardImageSource}"
IsVisible="{Binding !IsUnknownPackage}"
Stretch="UniformToFill" />
<Border
Grid.Column="0" Grid.Column="0"
ToolTip.Tip="{Binding Package.DisplayName, FallbackValue=''}" Height="150"
Text="{Binding Package.DisplayName, FallbackValue=''}" Width="150"
TextTrimming="WordEllipsis" Margin="4, 8"
TextAlignment="Left" /> CornerRadius="8"
HorizontalAlignment="Center"
IsVisible="{Binding IsUnknownPackage}"
Background="#202020">
<TextBlock
TextAlignment="Center"
VerticalAlignment="Center"
FontSize="18"
TextWrapping="Wrap"
Text="{x:Static lang:Resources.Label_UnknownPackage}" />
</Border>
<Grid Grid.Column="1" RowDefinitions="Auto, Auto, Auto, *"
ColumnDefinitions="Auto, *">
<TextBlock Grid.Column="0"
Grid.Row="0"
Text="{Binding Package.DisplayName}"
Margin="8,0,8,0"
FontWeight="SemiBold"
MaxWidth="200"
TextWrapping="NoWrap"
TextTrimming="CharacterEllipsis"
ToolTip.Tip="{Binding Package.DisplayName}"
FontSize="16" />
<TextBlock Grid.Column="0"
Grid.Row="1"
FontSize="13"
Foreground="{DynamicResource TextControlPlaceholderForeground}"
Margin="8,0,8,0"
VerticalAlignment="Center"
Text="{Binding InstalledVersion}" />
<Button <Button
Grid.Row="0" Grid.Row="0"
Grid.Column="1" Grid.Column="1"
@ -56,7 +98,7 @@
HorizontalAlignment="Right" HorizontalAlignment="Right"
VerticalContentAlignment="Top" VerticalContentAlignment="Top"
VerticalAlignment="Top" VerticalAlignment="Top"
Padding="4,1" Padding="4"
Margin="4,0,0,0" Margin="4,0,0,0"
Classes="transparent" Classes="transparent"
Width="24" Width="24"
@ -111,7 +153,8 @@
<Separator IsVisible="{Binding CanUseSharedOutput}" /> <Separator IsVisible="{Binding CanUseSharedOutput}" />
<MenuItem Header="{x:Static lang:Resources.Label_SharedModelStrategyShort}" <MenuItem
Header="{x:Static lang:Resources.Label_SharedModelStrategyShort}"
IsVisible="{Binding !IsUnknownPackage}"> IsVisible="{Binding !IsUnknownPackage}">
<MenuItem.Icon> <MenuItem.Icon>
<ui:SymbolIcon Symbol="FolderLink" /> <ui:SymbolIcon Symbol="FolderLink" />
@ -186,82 +229,68 @@
</Button.Flyout> </Button.Flyout>
</Button> </Button>
<TextBlock Grid.Row="1" <StackPanel Grid.Row="2"
Grid.Column="0"
Grid.ColumnSpan="2"
Margin="2,0,0,0"
VerticalAlignment="Center"
Text="{Binding InstalledVersion}" />
<Border Grid.Row="2"
Grid.Column="0" Grid.Column="0"
Grid.ColumnSpan="2" Margin="0,4,0,0"
Margin="0,8" Orientation="Horizontal">
Background="#AA000000" <Button Classes="transparent-full"
IsVisible="{Binding IsRunning}" Margin="4,4,0,0"
CornerRadius="4" Padding="4"
ZIndex="1"> ToolTip.Tip="{x:Static lang:Resources.Action_CheckForUpdates}"
<Button Classes="danger" Command="{Binding OnLoadedAsync}"
FontSize="16" >
MinWidth="100" <Button.IsVisible>
MinHeight="40" <MultiBinding Converter="{x:Static BoolConverters.And}">
Command="{Binding StopCommand}" <Binding Path="!IsUnknownPackage" />
HorizontalAlignment="Center" <Binding Path="!IsUpdateAvailable" />
HorizontalContentAlignment="Center"> </MultiBinding>
<StackPanel Orientation="Horizontal"> </Button.IsVisible>
<icons:Icon Value="fa-solid fa-stop" <ui:SymbolIcon Symbol="Refresh"
FontSize="20" FontSize="20"/>
Margin="0,0,8,0"/>
<TextBlock Text="{x:Static lang:Resources.Action_Stop}"/>
</StackPanel>
</Button> </Button>
</Border>
<!-- Normal packages shows image --> <Button Classes="transparent-full"
<controls:BetterAdvancedImage Margin="4,4,0,0"
Grid.Row="2" Padding="4"
Grid.Column="0" IsEnabled="{Binding !IsRunning}"
Grid.ColumnSpan="2" ToolTip.Tip="{x:Static lang:Resources.Label_UpdateAvailable}"
Margin="0,8,0,8" markupExtensions:ShowDisabledTooltipExtension.ShowOnDisabled="True"
Height="180" Command="{Binding Update}">
Width="225" <Button.IsVisible>
CornerRadius="4" <MultiBinding Converter="{x:Static BoolConverters.And}">
HorizontalAlignment="Center" <Binding Path="!IsUnknownPackage" />
VerticalContentAlignment="Top" <Binding Path="IsUpdateAvailable" />
HorizontalContentAlignment="Center" </MultiBinding>
Source="{Binding CardImageSource}" </Button.IsVisible>
<ui:SymbolIcon Symbol="CloudDownload"
IsEnabled="{Binding !IsRunning}"
FontSize="24">
<ui:SymbolIcon.Styles>
<Style Selector="ui|SymbolIcon">
<Setter Property="Foreground" Value="Lime" />
</Style>
<Style Selector="ui|SymbolIcon:disabled">
<Setter Property="Foreground" Value="Gray" />
</Style>
</ui:SymbolIcon.Styles>
</ui:SymbolIcon>
</Button>
<Button Classes="transparent-full"
Margin="4,4,0,0"
Padding="4"
ToolTip.Tip="Launch Options"
IsVisible="{Binding !IsUnknownPackage}" IsVisible="{Binding !IsUnknownPackage}"
Stretch="UniformToFill" /> Command="{Binding ShowLaunchOptionsCommand}">
<ui:SymbolIcon Symbol="SettingsFilled"
<!-- Unknown packages panel --> FontSize="20"/>
<Border </Button>
Grid.Row="2" </StackPanel>
Grid.Column="0" <UniformGrid Grid.Column="0"
Grid.ColumnSpan="2" Grid.ColumnSpan="2"
Margin="0,8,0,8"
Height="180"
Width="225"
CornerRadius="4"
HorizontalAlignment="Center"
IsVisible="{Binding IsUnknownPackage}"
Background="#202020">
<TextBlock
TextAlignment="Center"
VerticalAlignment="Center"
FontSize="18"
TextWrapping="Wrap"
Text="{x:Static lang:Resources.Label_UnknownPackage}" />
</Border>
<Grid
Grid.Row="3" Grid.Row="3"
Grid.Column="0" VerticalAlignment="Bottom"
Grid.ColumnSpan="2" Margin="8,8,8,0">
IsVisible="{Binding !IsUnknownPackage}" <Button Classes="accent"
ColumnDefinitions="*,Auto">
<!-- Launch and update buttons -->
<Button Grid.Column="0" Classes="accent"
VerticalAlignment="Bottom" VerticalAlignment="Bottom"
HorizontalAlignment="Stretch" HorizontalAlignment="Stretch"
Command="{Binding Launch}"> Command="{Binding Launch}">
@ -278,25 +307,34 @@
<TextBlock Text="{x:Static lang:Resources.Action_Launch}" /> <TextBlock Text="{x:Static lang:Resources.Action_Launch}" />
</StackPanel> </StackPanel>
</Button> </Button>
<Button Grid.Column="1" Classes="accent" <Button Classes="borderless-danger"
VerticalAlignment="Bottom" VerticalAlignment="Bottom"
HorizontalAlignment="Stretch" HorizontalAlignment="Stretch"
Command="{Binding Update}"> IsVisible="{Binding IsRunning}"
<Button.IsVisible> Command="{Binding StopCommand}">
<MultiBinding Converter="{x:Static BoolConverters.And}">
<Binding Path="IsUpdateAvailable" />
<Binding Path="!IsRunning" />
</MultiBinding>
</Button.IsVisible>
<StackPanel Orientation="Horizontal" <StackPanel Orientation="Horizontal"
Margin="10,2"> Margin="0,2">
<icons:Icon Value="fa-solid fa-download" <icons:Icon Value="fa-solid fa-stop"
Margin="0,0,8,0" Margin="0,0,8,0"
FontSize="14" /> FontSize="14" />
<TextBlock Text="{x:Static lang:Resources.Action_Update}" /> <TextBlock Text="{x:Static lang:Resources.Action_Stop}" />
</StackPanel> </StackPanel>
</Button> </Button>
<Button Grid.Column="0" Classes="accent" <Button Classes="borderless-info"
BorderBrush="Transparent"
VerticalAlignment="Bottom"
HorizontalAlignment="Stretch"
IsVisible="{Binding IsRunning}"
Command="{Binding RestartCommand}">
<StackPanel Orientation="Horizontal"
Margin="0,2">
<icons:Icon Value="fa-solid fa-arrow-rotate-left"
Margin="0,0,8,0"
FontSize="14" />
<TextBlock Text="{x:Static lang:Resources.Action_Restart}" />
</StackPanel>
</Button>
<Button Classes="accent"
VerticalAlignment="Bottom" VerticalAlignment="Bottom"
HorizontalAlignment="Stretch" HorizontalAlignment="Stretch"
IsVisible="{Binding IsRunning}" IsVisible="{Binding IsRunning}"
@ -309,7 +347,7 @@
<TextBlock Text="Console" /> <TextBlock Text="Console" />
</StackPanel> </StackPanel>
</Button> </Button>
<Button Grid.Column="1" Classes="accent" <Button Classes="accent"
VerticalAlignment="Bottom" VerticalAlignment="Bottom"
HorizontalAlignment="Stretch" HorizontalAlignment="Stretch"
IsVisible="{Binding ShowWebUiButton}" IsVisible="{Binding ShowWebUiButton}"
@ -321,11 +359,7 @@
<TextBlock Text="Web UI" /> <TextBlock Text="Web UI" />
</StackPanel> </StackPanel>
</Button> </Button>
</Grid> <Button Classes="transparent-info"
<!-- Import button (for unknown) -->
<Button Grid.Row="3" Grid.Column="0" Classes="transparent-info"
Grid.ColumnSpan="2"
VerticalAlignment="Bottom" VerticalAlignment="Bottom"
HorizontalAlignment="Stretch" HorizontalAlignment="Stretch"
Command="{Binding Import}" Command="{Binding Import}"
@ -337,29 +371,28 @@
<TextBlock Text="{x:Static lang:Resources.Action_Import}" /> <TextBlock Text="{x:Static lang:Resources.Action_Import}" />
</StackPanel> </StackPanel>
</Button> </Button>
</UniformGrid>
</Grid>
<!-- Update overlay --> <!-- Update overlay -->
<Border <Border
Grid.Row="0" Grid.RowSpan="4"
Grid.Column="0" Grid.Column="0"
Grid.ColumnSpan="2" Grid.ColumnSpan="2"
Background="#DD000000" Background="#DD000000"
CornerRadius="4" CornerRadius="8"
HorizontalAlignment="Stretch" HorizontalAlignment="Stretch"
VerticalAlignment="Stretch" VerticalAlignment="Stretch"
IsVisible="{Binding IsProgressVisible}"/> IsVisible="{Binding IsProgressVisible}"/>
<Grid Grid.Row="0" Grid.RowSpan="4" <Grid Grid.Column="0"
Grid.Column="0"
Grid.ColumnSpan="2" Grid.ColumnSpan="2"
HorizontalAlignment="Center" HorizontalAlignment="Center"
VerticalAlignment="Center" VerticalAlignment="Center"
RowDefinitions="Auto, *" IsVisible="{Binding IsProgressVisible}"
IsVisible="{Binding IsProgressVisible}"> RowDefinitions="Auto, *">
<controls:ProgressRing <controls:ProgressRing
HorizontalAlignment="Center" HorizontalAlignment="Center"
IsIndeterminate="{Binding IsIndeterminate}" IsIndeterminate="{Binding IsIndeterminate}"
Width="150" Width="120"
Height="150" Height="120"
StartAngle="90" StartAngle="90"
EndAngle="450" EndAngle="450"
Value="{Binding Value}" Value="{Binding Value}"

3
StabilityMatrix.Core/Models/DownloadPackageVersionOptions.cs

@ -7,4 +7,7 @@ public class DownloadPackageVersionOptions
public string? VersionTag { get; set; } public string? VersionTag { get; set; }
public bool IsLatest { get; set; } public bool IsLatest { get; set; }
public bool IsPrerelease { get; set; } public bool IsPrerelease { get; set; }
public string GetReadableVersionString() =>
!string.IsNullOrWhiteSpace(VersionTag) ? VersionTag : $"{BranchName}@{CommitHash?[..7]}";
} }

Loading…
Cancel
Save