Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 16 additions & 1 deletion LocalLLMServerManager.Shared/Styles/DesignTokens.axaml
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
<SolidColorBrush x:Key="GlassBackgroundBrush" Color="{StaticResource BgDarkColor}" />
<SolidColorBrush x:Key="PrimaryGradientBrush" Color="{StaticResource PrimaryColor}" />

<!-- Vector Icon Geometries for Crisp Tab Navigation -->
<!-- Vector Icon Geometries for Crisp Navigation and Control Rendering -->
<StreamGeometry x:Key="IconModels">M21,16.5C21,16.88 20.79,17.21 20.47,17.38L12.57,21.82C12.41,21.94 12.21,22 12,22C11.79,22 11.59,21.94 11.43,21.82L3.53,17.38C3.21,17.21 3,16.88 3,16.5V7.5C3,7.12 3.21,6.79 3.53,6.62L11.43,2.18C11.59,2.06 11.79,2 12,2C12.21,2 12.41,2.06 12.57,2.18L20.47,6.62C20.79,6.79 21,7.12 21,7.5V16.5M12,4.15L6.04,7.5L12,10.85L17.96,7.5L12,4.15M5,15.91L11,19.29V12.58L5,9.21V15.91M19,15.91V9.21L13,12.58V19.29L19,15.91Z</StreamGeometry>
<StreamGeometry x:Key="IconWorkflows">M13 2L3 14h6l-2 8 10-12h-6l2-8z</StreamGeometry>
<StreamGeometry x:Key="IconCanIRunIt">M6 2v2H4a2 2 0 0 0-2 2v2h2v2H2v2h2v2H2v2a2 2 0 0 0 2 2h2v2h2v-2h2v2h2v-2h2v2h2a2 2 0 0 0 2-2v-2h2v-2h-2v-2h2v-2h-2V6a2 2 0 0 0-2-2h-2V2h-2v2h-2V2h-2v2H8V2H6zm0 4h12v12H6V6zm2 2v8h8V8H8z</StreamGeometry>
Expand All @@ -44,4 +44,19 @@
<StreamGeometry x:Key="IconDownloaded">M19 9h-4V3H9v6H5l7 7 7-7zM5 18v2h14v-2H5z</StreamGeometry>
<StreamGeometry x:Key="IconHub">M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-1 17.93c-3.95-.49-7-3.85-7-7.93 0-.62.08-1.21.21-1.79L9 15v1c0 1.1.9 2 2 2v1.93zm6.9-2.54c-.26-.81-1-1.39-1.9-1.39h-1v-3c0-.55-.45-1-1-1H8v-2h2c.55 0 1-.45 1-1V7h2c1.1 0 2-.9 2-2v-.41c2.93 1.19 5 4.06 5 7.41 0 2.08-.8 3.97-2.1 5.39z</StreamGeometry>
<StreamGeometry x:Key="IconCivitai">M12 2C6.49 2 2 6.49 2 12s4.49 10 10 10a2.5 2.5 0 0 0 2.5-2.5c0-.61-.23-1.2-.64-1.67-.4-.46-.61-1.04-.61-1.63 0-1.38 1.12-2.5 2.5-2.5H17c2.76 0 5-2.24 5-5 0-4.74-4.48-8.7-10-8.7zm-5.5 9a1.5 1.5 0 1 1 0-3 1.5 1.5 0 0 1 0 3zm3-4a1.5 1.5 0 1 1 0-3 1.5 1.5 0 0 1 0 3zm5 0a1.5 1.5 0 1 1 0-3 1.5 1.5 0 0 1 0 3zm3 4a1.5 1.5 0 1 1 0-3 1.5 1.5 0 0 1 0 3z</StreamGeometry>
<StreamGeometry x:Key="IconImages">M21 19V5c0-1.1-.9-2-2-2H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2zM8.5 13.5l2.5 3.01L14.5 12l4.5 6H5l3.5-4.5z</StreamGeometry>
<StreamGeometry x:Key="IconText">M20 2H4c-1.1 0-1.99.9-1.99 2L2 22l4-4h14c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2zm-2 12H6v-2h12v2zm0-3H6V9h12v2zm0-3H6V6h12v2z</StreamGeometry>
<StreamGeometry x:Key="IconVideo">M17 10.5V7c0-.55-.45-1-1-1H4c-.55 0-1 .45-1 1v10c0 .55.45 1 1 1h12c.55 0 1-.45 1-1v-3.5l4 4v-11l-4 4z</StreamGeometry>
<StreamGeometry x:Key="Icon3D">M12 2l-9 4.5v11L12 22l9-4.5v-11L12 2zm0 2.24l6.83 3.41L12 11.07 5.17 7.65 12 4.24zM4.5 9.17l7 3.5v7.65l-7-3.5V9.17zm8.5 11.15v-7.65l7-3.5v7.65l-7 3.5z</StreamGeometry>
<StreamGeometry x:Key="IconAudio">M12 3v10.55c-.59-.34-1.27-.55-2-.55-2.21 0-4 1.79-4 4s1.79 4 4 4 4-1.79 4-4V7h4V3h-6z</StreamGeometry>
<StreamGeometry x:Key="IconSticker">M21.41 11.58l-9-9C12.05 2.22 11.55 2 11 2H4c-1.1 0-2 .9-2 2v7c0 .55.22 1.05.59 1.42l9 9c.36.36.86.58 1.41.58.55 0 1.05-.22 1.41-.59l7-7c.37-.36.59-.86.59-1.41 0-.55-.23-1.06-.59-1.42zM5.5 7C4.67 7 4 6.33 4 5.5S4.67 4 5.5 4 7 4.67 7 5.5 6.33 7 5.5 7z</StreamGeometry>
<StreamGeometry x:Key="IconGpu">M21 6H3c-1.1 0-2 .9-2 2v8c0 1.1.9 2 2 2h18c1.1 0 2-.9 2-2V8c0-1.1-.9-2-2-2zm-10 7H8v3H6v-3H3v-2h3V8h2v3h3v2zm4.5 2c-.83 0-1.5-.67-1.5-1.5s.67-1.5 1.5-1.5 1.5.67 1.5 1.5-.67 1.5-1.5 1.5zm3-3c-.83 0-1.5-.67-1.5-1.5s.67-1.5 1.5-1.5 1.5.67 1.5 1.5-.67 1.5-1.5 1.5z</StreamGeometry>
<StreamGeometry x:Key="IconRefresh">M17.65 6.35C16.2 4.9 14.21 4 12 4c-4.42 0-7.99 3.58-7.99 8s3.57 8 7.99 8c3.73 0 6.84-2.55 7.73-6h-2.08c-.82 2.33-3.04 4-5.65 4-3.31 0-6-2.69-6-6s2.69-6 6-6c1.66 0 3.14.69 4.22 1.78L13 11h7V4l-2.35 2.35z</StreamGeometry>
<StreamGeometry x:Key="IconFolder">M10 4H4c-1.1 0-1.99.9-1.99 2L2 18c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V8c0-1.1-.9-2-2-2h-8l-2-2z</StreamGeometry>
<StreamGeometry x:Key="IconCopy">M16 1H4c-1.1 0-2 .9-2 2v14h2V3h12V1zm3 4H8c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h11c1.1 0 2-.9 2-2V7c0-1.1-.9-2-2-2zm0 16H8V7h11v14z</StreamGeometry>
<StreamGeometry x:Key="IconSave">M17 3H5c-1.11 0-2 .9-2 2v14c0 1.1.89 2 2 2h14c1.1 0 2-.9 2-2V7l-4-4zm-5 16c-1.66 0-3-1.34-3-3s1.34-3 3-3 3 1.34 3 3-1.34 3-3 3zm3-10H5V5h10v4z</StreamGeometry>
<StreamGeometry x:Key="IconChevronLeft">M15.41 7.41L14 6l-6 6 6 6 1.41-1.41L10.83 12z</StreamGeometry>
<StreamGeometry x:Key="IconChevronRight">M10 6L8.59 7.41 13.17 12l-4.58 4.59L10 18l6-6z</StreamGeometry>
<StreamGeometry x:Key="IconRocket">M12 2.5s-4 4-4 9c0 3.04 1.5 5.5 3 6.5V20l1 1 1-1v-2c1.5-1 3-3.46 3-6.5 0-5-4-9-4-9zm-1 8a1 1 0 1 1 2 0 1 1 0 0 1-2 0zM5.5 13C4.67 13 4 13.67 4 14.5c0 1.25.75 3.5 2 4.5.5-1 .5-3-.5-6zm13 0c-1 3-1 5-.5 6 1.25-1 2-3.25 2-4.5 0-.83-.67-1.5-1.5-1.5z</StreamGeometry>
<StreamGeometry x:Key="IconExternal">M19 19H5V5h7V3H5a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14c1.1 0 2-.9 2-2v-7h-2v7zM14 3v2h3.59l-9.83 9.83 1.41 1.41L19 6.41V10h2V3h-7z</StreamGeometry>
</ResourceDictionary>
22 changes: 19 additions & 3 deletions LocalLLMServerManager.Shared/ViewModels/MainViewModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -99,10 +99,15 @@ public HttpClient Http
public StickerStudioViewModel StickerStudio { get; } = new(new StickerGenerationService());

[ObservableProperty]
private bool _isStickerStudioActive = true;
[NotifyPropertyChangedFor(nameof(IsImagesWorkflowActive))]
[NotifyPropertyChangedFor(nameof(IsTextWorkflowActive))]
[NotifyPropertyChangedFor(nameof(IsVideoWorkflowActive))]
[NotifyPropertyChangedFor(nameof(Is3DMeshWorkflowActive))]
[NotifyPropertyChangedFor(nameof(IsAudioWorkflowActive))]
private bool _isStickerStudioActive = false;

[ObservableProperty]
private int _selectedTabIndex = 1;
private int _selectedTabIndex = 0;

partial void OnSelectedTabIndexChanged(int value)
{
Expand Down Expand Up @@ -546,7 +551,18 @@ public void CancelServiceConfirm()

// Studio & Video Studio Observable Properties
[ObservableProperty]
private string _selectedStudioMode = "Video"; // "Images", "Text", "Video", "3D Mesh", "Audio"
[NotifyPropertyChangedFor(nameof(IsImagesWorkflowActive))]
[NotifyPropertyChangedFor(nameof(IsTextWorkflowActive))]
[NotifyPropertyChangedFor(nameof(IsVideoWorkflowActive))]
[NotifyPropertyChangedFor(nameof(Is3DMeshWorkflowActive))]
[NotifyPropertyChangedFor(nameof(IsAudioWorkflowActive))]
private string _selectedStudioMode = "Images"; // "Images", "Text", "Video", "3D Mesh", "Audio"

public bool IsImagesWorkflowActive => !IsStickerStudioActive && SelectedStudioMode == "Images";
public bool IsTextWorkflowActive => !IsStickerStudioActive && SelectedStudioMode == "Text";
public bool IsVideoWorkflowActive => !IsStickerStudioActive && SelectedStudioMode == "Video";
public bool Is3DMeshWorkflowActive => !IsStickerStudioActive && SelectedStudioMode == "3D Mesh";
public bool IsAudioWorkflowActive => !IsStickerStudioActive && SelectedStudioMode == "Audio";

[ObservableProperty]
private string _ollamaPrompt = "Explain how local LLM quantization works in plain language.";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ public partial class NavigationRailViewModel : ObservableObject
[NotifyPropertyChangedFor(nameof(IsModelsSelected))]
[NotifyPropertyChangedFor(nameof(IsHardwareFitSelected))]
[NotifyPropertyChangedFor(nameof(IsSettingsSelected))]
private NavDomain _selectedDomain = NavDomain.Studio;
private NavDomain _selectedDomain = NavDomain.Models;

[ObservableProperty]
private bool _isExpanded = false;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,71 +47,75 @@
<Grid RowDefinitions="Auto, *, Auto">
<!-- Top Primary Domain Buttons -->
<StackPanel Grid.Row="0" Spacing="2">
<!-- ⚡ Studio / Workflows -->
<!-- Studio / Workflows -->
<Button Classes="rail-btn"
Classes.active="{Binding IsStudioSelected}"
Command="{Binding SelectDomainCommand}"
CommandParameter="{x:Static models:NavDomain.Studio}"
ToolTip.Tip="⚡ Studio / Workflows">
ToolTip.Tip="Studio / Workflows">
<Grid ColumnDefinitions="44, *">
<Border Grid.Column="0" Width="3" Height="20" HorizontalAlignment="Left" CornerRadius="1.5"
Background="{StaticResource PrimaryBrush}"
IsVisible="{Binding IsStudioSelected}"/>
<TextBlock Grid.Column="0" Text="⚡" FontSize="16" HorizontalAlignment="Center" VerticalAlignment="Center"/>
<PathIcon Grid.Column="0" Data="{StaticResource IconWorkflows}" Width="16" Height="16"
Foreground="{Binding $parent[Button].Foreground}" HorizontalAlignment="Center" VerticalAlignment="Center"/>
<TextBlock Grid.Column="1" Text="Studio" FontSize="13" FontWeight="SemiBold" VerticalAlignment="Center"
Margin="2,0,4,0"
IsVisible="{Binding IsExpanded, RelativeSource={RelativeSource AncestorType=controls:ActivityRailControl}}"
TextTrimming="CharacterEllipsis"/>
</Grid>
</Button>

<!-- 📦 Models & Hubs -->
<!-- Models & Hubs -->
<Button Classes="rail-btn"
Classes.active="{Binding IsModelsSelected}"
Command="{Binding SelectDomainCommand}"
CommandParameter="{x:Static models:NavDomain.Models}"
ToolTip.Tip="📦 Models &amp; Hubs">
ToolTip.Tip="Models &amp; Hubs">
<Grid ColumnDefinitions="44, *">
<Border Grid.Column="0" Width="3" Height="20" HorizontalAlignment="Left" CornerRadius="1.5"
Background="{StaticResource PrimaryBrush}"
IsVisible="{Binding IsModelsSelected}"/>
<TextBlock Grid.Column="0" Text="📦" FontSize="16" HorizontalAlignment="Center" VerticalAlignment="Center"/>
<PathIcon Grid.Column="0" Data="{StaticResource IconModels}" Width="16" Height="16"
Foreground="{Binding $parent[Button].Foreground}" HorizontalAlignment="Center" VerticalAlignment="Center"/>
<TextBlock Grid.Column="1" Text="Models" FontSize="13" FontWeight="SemiBold" VerticalAlignment="Center"
Margin="2,0,4,0"
IsVisible="{Binding IsExpanded, RelativeSource={RelativeSource AncestorType=controls:ActivityRailControl}}"
TextTrimming="CharacterEllipsis"/>
</Grid>
</Button>

<!-- 💻 Hardware Fit -->
<!-- Hardware Fit -->
<Button Classes="rail-btn"
Classes.active="{Binding IsHardwareFitSelected}"
Command="{Binding SelectDomainCommand}"
CommandParameter="{x:Static models:NavDomain.HardwareFit}"
ToolTip.Tip="💻 Hardware Fit">
ToolTip.Tip="Hardware Fit">
<Grid ColumnDefinitions="44, *">
<Border Grid.Column="0" Width="3" Height="20" HorizontalAlignment="Left" CornerRadius="1.5"
Background="{StaticResource PrimaryBrush}"
IsVisible="{Binding IsHardwareFitSelected}"/>
<TextBlock Grid.Column="0" Text="💻" FontSize="16" HorizontalAlignment="Center" VerticalAlignment="Center"/>
<PathIcon Grid.Column="0" Data="{StaticResource IconCanIRunIt}" Width="16" Height="16"
Foreground="{Binding $parent[Button].Foreground}" HorizontalAlignment="Center" VerticalAlignment="Center"/>
<TextBlock Grid.Column="1" Text="Fit" FontSize="13" FontWeight="SemiBold" VerticalAlignment="Center"
Margin="2,0,4,0"
IsVisible="{Binding IsExpanded, RelativeSource={RelativeSource AncestorType=controls:ActivityRailControl}}"
TextTrimming="CharacterEllipsis"/>
</Grid>
</Button>

<!-- ⚙️ Settings & Daemon -->
<!-- Settings & Daemon -->
<Button Classes="rail-btn"
Classes.active="{Binding IsSettingsSelected}"
Command="{Binding SelectDomainCommand}"
CommandParameter="{x:Static models:NavDomain.Settings}"
ToolTip.Tip="⚙️ Settings &amp; Daemon">
ToolTip.Tip="Settings &amp; Daemon">
<Grid ColumnDefinitions="44, *">
<Border Grid.Column="0" Width="3" Height="20" HorizontalAlignment="Left" CornerRadius="1.5"
Background="{StaticResource PrimaryBrush}"
IsVisible="{Binding IsSettingsSelected}"/>
<TextBlock Grid.Column="0" Text="⚙️" FontSize="16" HorizontalAlignment="Center" VerticalAlignment="Center"/>
<PathIcon Grid.Column="0" Data="{StaticResource IconSettings}" Width="16" Height="16"
Foreground="{Binding $parent[Button].Foreground}" HorizontalAlignment="Center" VerticalAlignment="Center"/>
<TextBlock Grid.Column="1" Text="Settings" FontSize="13" FontWeight="SemiBold" VerticalAlignment="Center"
Margin="2,0,4,0"
IsVisible="{Binding IsExpanded, RelativeSource={RelativeSource AncestorType=controls:ActivityRailControl}}"
Expand All @@ -127,45 +131,49 @@
<!-- Subtle divider line -->
<Rectangle Height="1" Fill="{StaticResource GlassBorderBrush}" Margin="6,4" />

<!-- 📖 Documentation -->
<!-- Documentation -->
<Button x:Name="NavDocumentationBtn"
Classes="rail-btn"
Command="{Binding DocumentationCommand}"
ToolTip.Tip="📖 Documentation">
ToolTip.Tip="Documentation">
<Grid ColumnDefinitions="44, *">
<TextBlock Grid.Column="0" Text="📖" FontSize="15" HorizontalAlignment="Center" VerticalAlignment="Center"/>
<PathIcon Grid.Column="0" Data="{StaticResource IconDocumentation}" Width="15" Height="15"
Foreground="{Binding $parent[Button].Foreground}" HorizontalAlignment="Center" VerticalAlignment="Center"/>
<TextBlock Grid.Column="1" Text="Docs" FontSize="13" FontWeight="SemiBold" VerticalAlignment="Center"
Margin="2,0,4,0"
IsVisible="{Binding IsExpanded, RelativeSource={RelativeSource AncestorType=controls:ActivityRailControl}}"
TextTrimming="CharacterEllipsis"/>
</Grid>
</Button>

<!-- 🤖 AI Assist -->
<!-- AI Assist -->
<Button x:Name="NavAiAssistBtn"
Classes="rail-btn"
Command="{Binding AiAssistCommand}"
ToolTip.Tip="🤖 AI Assistant">
ToolTip.Tip="AI Assistant">
<Grid ColumnDefinitions="44, *">
<TextBlock Grid.Column="0" Text="🤖" FontSize="15" HorizontalAlignment="Center" VerticalAlignment="Center"/>
<PathIcon Grid.Column="0" Data="{StaticResource IconAiAssist}" Width="15" Height="15"
Foreground="{Binding $parent[Button].Foreground}" HorizontalAlignment="Center" VerticalAlignment="Center"/>
<TextBlock Grid.Column="1" Text="AI Assist" FontSize="13" FontWeight="SemiBold" VerticalAlignment="Center"
Margin="2,0,4,0"
IsVisible="{Binding IsExpanded, RelativeSource={RelativeSource AncestorType=controls:ActivityRailControl}}"
TextTrimming="CharacterEllipsis"/>
</Grid>
</Button>

<!-- ◀ / ▶ Expand/Collapse Toggle -->
<!-- Expand/Collapse Toggle -->
<Button x:Name="ToggleRailBtn"
Classes="rail-btn"
Command="{Binding ToggleRailExpandedCommand}"
ToolTip.Tip="Toggle Navigation Rail">
<Grid ColumnDefinitions="44, *">
<Grid Grid.Column="0" HorizontalAlignment="Center" VerticalAlignment="Center">
<TextBlock Text="◀" FontSize="13"
IsVisible="{Binding IsExpanded, RelativeSource={RelativeSource AncestorType=controls:ActivityRailControl}}"/>
<TextBlock Text="▶" FontSize="13"
IsVisible="{Binding !IsExpanded, RelativeSource={RelativeSource AncestorType=controls:ActivityRailControl}}"/>
<PathIcon Data="{StaticResource IconChevronLeft}" Width="14" Height="14"
Foreground="{Binding $parent[Button].Foreground}"
IsVisible="{Binding IsExpanded, RelativeSource={RelativeSource AncestorType=controls:ActivityRailControl}}"/>
<PathIcon Data="{StaticResource IconChevronRight}" Width="14" Height="14"
Foreground="{Binding $parent[Button].Foreground}"
IsVisible="{Binding !IsExpanded, RelativeSource={RelativeSource AncestorType=controls:ActivityRailControl}}"/>
</Grid>
<TextBlock Grid.Column="1" Text="Collapse" FontSize="13" FontWeight="SemiBold" VerticalAlignment="Center"
Margin="2,0,4,0"
Expand Down
Loading
Loading