Skip to content

Commit

Permalink
Merge pull request #2521 from Nexus-Mods/healthcheck-emptystate-tweaks
Browse files Browse the repository at this point in the history
Updated Health Check UI empty state\diagnostic details.
  • Loading branch information
Al12rs authored Jan 27, 2025
2 parents 191d729 + 50a9940 commit fadd08b
Show file tree
Hide file tree
Showing 13 changed files with 371 additions and 100 deletions.
15 changes: 15 additions & 0 deletions src/NexusMods.App.UI/Controls/PageHeader/PageHeader.axaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<Styles xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:pageHeader="using:NexusMods.App.UI.Controls.PageHeader"
>

<Design.PreviewWith>
<Border Padding="16">
<pageHeader:PageHeader/>
</Border>
</Design.PreviewWith>

<!-- Control theme is located at src/Themes/NexusMods.Themes.NexusFluentDark/Resources/ControlThemes/PageHeaderControlTheme.axaml
Default style is found here as well as the default template -->

</Styles>
119 changes: 119 additions & 0 deletions src/NexusMods.App.UI/Controls/PageHeader/PageHeader.axaml.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
using Avalonia;
using Avalonia.Controls;
using Avalonia.Controls.Primitives;
using NexusMods.Icons;

namespace NexusMods.App.UI.Controls.PageHeader;

public class PageHeader : ContentControl
{

/// <summary>
/// Defines the Title property of the <see cref="PageHeader"/>.
/// </summary>
public static readonly StyledProperty<string?> TitleProperty = AvaloniaProperty.Register<PageHeader, string?>(nameof(Title), defaultValue: "Default Title");

/// <summary>
/// Defines the Title property of the <see cref="PageHeader"/>.
/// </summary>
public static readonly StyledProperty<string?> DescriptionProperty = AvaloniaProperty.Register<PageHeader, string?>(nameof(Description), defaultValue: "This is the default description of the page.");

/// <summary>
/// Defines the Title property of the <see cref="PageHeader"/>.
/// </summary>
public static readonly StyledProperty<IconValue?> IconProperty = AvaloniaProperty.Register<PageHeader, IconValue?>(nameof(Icon), defaultValue: IconValues.PictogramBox2);

/// <summary>
/// Gets or sets the title text of the <see cref="PageHeader"/>.
/// </summary>
public string? Title
{
get => GetValue(TitleProperty);
set => SetValue(TitleProperty, value);
}
/// <summary>
/// Gets or sets the description text of the <see cref="PageHeader"/>.
/// </summary>
public string? Description
{
get => GetValue(DescriptionProperty);
set => SetValue(DescriptionProperty, value);
}

/// <summary>
/// Gets or sets the icon of the <see cref="PageHeader"/>.
/// </summary>
public IconValue? Icon
{
get => GetValue(IconProperty);
set => SetValue(IconProperty, value);
}

private TextBlock? _titleText;
private TextBlock? _descriptionText;
private UnifiedIcon? _unifiedIcon;

protected override void OnPropertyChanged(AvaloniaPropertyChangedEventArgs change)
{
base.OnPropertyChanged(change);

if (change.Property == TitleProperty)
{
UpdateTitle(change.GetNewValue<string?>());
}
else if (change.Property == DescriptionProperty)
{
UpdateDescription(change.GetNewValue<string?>());
}
else if (change.Property == IconProperty)
{
UpdateIcon(change.GetNewValue<IconValue?>());
}
}

protected override void OnApplyTemplate(TemplateAppliedEventArgs e)
{
_titleText = e.NameScope.Find<TextBlock>("TitleTextBlock");
if (_titleText != null)
UpdateTitle(Title);

_descriptionText = e.NameScope.Find<TextBlock>("DescriptionTextBlock");
if (_descriptionText != null)
UpdateDescription(Description);

_unifiedIcon = e.NameScope.Find<UnifiedIcon>("Icon");
if (_unifiedIcon != null)
UpdateIcon(Icon);
}


/// <summary>
/// Updates the visual title text of the <see cref="PageHeader"/>.
/// </summary>
/// <param name="newTitle">The new title text</param>
private void UpdateTitle(string? newTitle)
{
if (_titleText != null)
_titleText.Text = newTitle;
}

/// <summary>
/// Updates the visual title text of the <see cref="PageHeader"/>.
/// </summary>
/// <param name="newDescription">The new description text</param>
private void UpdateDescription(string? newDescription)
{
if (_descriptionText != null)
_descriptionText.Text = newDescription;
}

/// <summary>
/// Updates the visual icon of the <see cref="PageHeader"/>.
/// </summary>
/// <param name="newIcon">The new icon</param>
private void UpdateIcon(IconValue? newIcon)
{
if (_unifiedIcon != null)
_unifiedIcon.Value = newIcon;
}
}
4 changes: 4 additions & 0 deletions src/NexusMods.App.UI/NexusMods.App.UI.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -744,6 +744,10 @@
<Compile Update="Pages\LoadoutPage\CollectionLoadoutDesignViewModel.cs">
<DependentUpon>ICollectionLoadoutViewModel.cs</DependentUpon>
</Compile>
<Compile Update="Controls\PageHeader\PageHeader.axaml.cs">
<DependentUpon>PageHeader.axaml</DependentUpon>
<SubType>Code</SubType>
</Compile>
</ItemGroup>

<ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,34 +26,40 @@
<DockPanel Margin="24">

<!-- header with pictogram -->
<StackPanel Spacing="8" DockPanel.Dock="Top">

<StackPanel Orientation="Horizontal" Spacing="8">
<Border Width="48" Height="48">
<icons:UnifiedIcon Size="48" Value="{x:Static icons:IconValues.PictogramHealth}" />
</Border>
<TextBlock Text="Health Check:"
Theme="{StaticResource HeadingSMSemiTheme}"
<DockPanel DockPanel.Dock="Top">
<Border Width="60"
Height="60"
Margin="0,0,8,0"
DockPanel.Dock="Left"
VerticalAlignment="Top">
<icons:UnifiedIcon Size="60" x:Name="Icon" Value="{x:Static icons:IconValues.PictogramHealth}" />
</Border>

<StackPanel Orientation="Vertical" VerticalAlignment="Top">
<StackPanel Orientation="Horizontal" Spacing="8">
<TextBlock x:Name="TitleTextBlock"
Text="Health Check:"
Theme="{StaticResource HeadingSMSemiTheme}"
Foreground="{StaticResource NeutralStrongBrush}"
VerticalAlignment="Center"
TextWrapping="Wrap" />
<TextBlock x:Name="SeverityTitleTextBlock"
Theme="{StaticResource HeadingSMSemiTheme}"
VerticalAlignment="Center" />
</StackPanel>
<TextBlock x:Name="DescriptionTextBlock"
Text="Review your Loadout for any issues and learn how to resolve them if needed."
Theme="{StaticResource BodyMDNormalTheme}"
Foreground="{StaticResource NeutralStrongBrush}"
VerticalAlignment="Center" />
<TextBlock x:Name="SeverityTitleTextBlock"
Theme="{StaticResource HeadingSMSemiTheme}"
VerticalAlignment="Center" />
TextWrapping="Wrap" />
</StackPanel>
</DockPanel>

<TextBlock
x:Name="SeverityExplanationTextBlock"
Text="Review your Loadout for any issues and learn how to resolve them if needed."
Theme="{StaticResource BodyMDNormalTheme}"
Foreground="{StaticResource NeutralStrongBrush}"
TextWrapping="Wrap" />
</StackPanel>

<Border DockPanel.Dock="Top" Classes="Toolbar"
Background="Transparent"
<Border DockPanel.Dock="Top" Classes="Toolbar"
Background="Transparent"
BorderThickness="0">
<StackPanel HorizontalAlignment="Left"

<StackPanel HorizontalAlignment="Left"
Margin="0,20,0,0">
<controls:StandardButton x:Name="SwitchView"
Text="Back"
Expand All @@ -62,7 +68,7 @@
Fill="Weak"
ShowIcon="Left"
LeftIcon="{x:Static icons:IconValues.ArrowBack}"
IsEnabled="False"/>
IsEnabled="False" />

<controls:StandardButton x:Name="DeleteButton"
Type="Tertiary"
Expand All @@ -71,22 +77,21 @@
ShowIcon="Left"
ShowLabel="False"
LeftIcon="{x:Static icons:IconValues.Copy}"
IsEnabled="False"/>
IsEnabled="False" />
</StackPanel>
</Border>

<Border
x:Name="MarkdownWrapperBorder"
VerticalAlignment="Top"
Margin="0,12,0,0"
CornerRadius="4"
BorderThickness="2"
Padding="24"
Background="#0D93C5FD"
BorderBrush="#6693C5FD">


<reactiveUi:ViewModelViewHost x:Name="MarkdownRendererViewModelViewHost" />

<reactiveUi:ViewModelViewHost x:Name="MarkdownRendererViewModelViewHost" />
</Border>

</DockPanel>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,20 +40,20 @@ private void InitializeData(IDiagnosticDetailsViewModel vm)
case DiagnosticSeverity.Suggestion:
SeverityTitleTextBlock.Text = Language.DiagnosticDetailsView_SeverityTitle_SUGGESTION;
SeverityTitleTextBlock.Classes.Add("ForegroundInfoStrong");
SeverityExplanationTextBlock.Text = "Suggestions may offer improvements to your experience.";
DescriptionTextBlock.Text = "Suggestions may offer improvements to your experience.";
MarkdownWrapperBorder.Background = SolidColorBrush.Parse("#0D93C5FD");
MarkdownWrapperBorder.BorderBrush = SolidColorBrush.Parse("#6693C5FD");
break;
case DiagnosticSeverity.Warning:
SeverityTitleTextBlock.Text = Language.DiagnosticDetailsView_SeverityTitle_WARNING;
SeverityTitleTextBlock.Classes.Add("ForegroundWarningStrong");
SeverityExplanationTextBlock.Text = "Warnings may negatively impact your experience.";
DescriptionTextBlock.Text = "Warnings may negatively impact your experience.";
MarkdownWrapperBorder.Background = SolidColorBrush.Parse("#0DFEF08A");
MarkdownWrapperBorder.BorderBrush = SolidColorBrush.Parse("#66FEF08A");
break;
case DiagnosticSeverity.Critical:
SeverityTitleTextBlock.Text = Language.DiagnosticDetailsView_SeverityTitle_CRITICAL_ERROR;
SeverityExplanationTextBlock.Text = "Critical errors make the game unplayable.";
DescriptionTextBlock.Text = "Critical errors make the game unplayable.";
SeverityTitleTextBlock.Classes.Add("ForegroundDangerStrong");
MarkdownWrapperBorder.Background = SolidColorBrush.Parse("#0DF87171");
MarkdownWrapperBorder.BorderBrush = SolidColorBrush.Parse("#66F87171");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
xmlns:icons="clr-namespace:NexusMods.Icons;assembly=NexusMods.Icons"
xmlns:resources="clr-namespace:NexusMods.App.UI.Resources"
xmlns:diagnostics="clr-namespace:NexusMods.App.UI.Controls.Diagnostics"
xmlns:pageHeader="clr-namespace:NexusMods.App.UI.Controls.PageHeader"
mc:Ignorable="d" d:DesignWidth="900" d:DesignHeight="500"
x:Class="NexusMods.App.UI.Pages.Diagnostics.DiagnosticListView">

Expand Down Expand Up @@ -47,30 +48,71 @@
<!-- need DockPanel to make the TabControl fill the available space, needed for ScrollViewer to calculate height properly -->
<DockPanel Margin="24">

<!-- header with pictogram -->
<StackPanel Spacing="8" DockPanel.Dock="Top">
<pageHeader:PageHeader DockPanel.Dock="Top"
Title="{x:Static resources:Language.DiagnosticListView_Page_Title}"
Description="{x:Static resources:Language.DiagnosticListView_Page_Description}"
Icon="{x:Static icons:IconValues.PictogramHealth}"/>

<StackPanel Orientation="Horizontal" Spacing="8">
<Border Width="48" Height="48">
<icons:UnifiedIcon Size="48" Value="{x:Static icons:IconValues.PictogramHealth}" />
</Border>
<TextBlock Text="Health Check"
Theme="{StaticResource HeadingSMSemiTheme}"
Foreground="{StaticResource NeutralStrongBrush}"
VerticalAlignment="Center" />
</StackPanel>
<controls:EmptyState x:Name="EmptyState"
Margin="0"
Padding="0"
HorizontalAlignment="Stretch"
VerticalAlignment="Top">

<TextBlock
Text="Review your Loadout for any issues and learn how to resolve them if needed."
Theme="{StaticResource BodyMDNormalTheme}"
Foreground="{StaticResource NeutralStrongBrush}"
TextWrapping="Wrap" />
</StackPanel>
<controls:EmptyState.Styles>
<Style Selector="controls|EmptyState">
<Setter Property="Template">
<ControlTemplate>
<Grid>
<Border x:Name="EmptyStateBorder">
<ContentPresenter x:Name="SubtitleContentPresenter"
Content="{TemplateBinding Subtitle}" />
</Border>
<ContentPresenter Grid.Column="0" Grid.Row="0" x:Name="ContentPresenter"
Content="{TemplateBinding Content}" />
</Grid>
</ControlTemplate>
</Setter>
</Style>

<controls:EmptyState x:Name="EmptyState"
Icon="{x:Static icons:IconValues.CheckCircle}"
Header="{x:Static resources:Language.DiagnosticListView_EmptyState_Header}"
Subtitle="{x:Static resources:Language.DiagnosticListView_EmptyState_Subtitle}">
<Style Selector="Border#EmptyStateBorder">
<Setter Property="HorizontalAlignment" Value="Stretch" />
<Setter Property="Padding" Value="0" />
<Setter Property="Margin" Value="0" />
</Style>
</controls:EmptyState.Styles>

<controls:EmptyState.Subtitle>
<Border
VerticalAlignment="Top"
Margin="0,16,0,0"
CornerRadius="4"
BorderThickness="2"
Padding="24"
Background="#0D86EFAC"
BorderBrush="#6686EFAC">

<StackPanel Orientation="Vertical" Spacing="8">
<DockPanel>
<icons:UnifiedIcon Value="{x:Static icons:IconValues.CheckCircle}"
Size="20"
Foreground="{StaticResource SuccessStrongBrush}"
DockPanel.Dock="Left"
Margin="0,0,6,0" />
<TextBlock
Theme="{StaticResource HeadingXSSemiTheme}"
Foreground="{StaticResource NeutralTranslucentStrongBrush}"
Text="Your loadout passed the health check with no issues"
TextWrapping="Wrap" />
</DockPanel>
<TextBlock
Theme="{StaticResource BodyLGNormalTheme}"
Foreground="{StaticResource NeutralSubduedBrush}"
Text="Ready for gaming"
TextWrapping="Wrap" />
</StackPanel>
</Border>
</controls:EmptyState.Subtitle>

<TabControl x:Name="TabControl"
Margin="0,24,0,0"
Expand Down
Loading

0 comments on commit fadd08b

Please sign in to comment.