mirror of
https://github.com/DorkSquadRR/DorkNet.git
synced 2026-10-25 23:18:44 -07:00
3039bebc6c
The single HostStatusText/JoinStatusText line gave no sense of where the user was in the flow. Replaced with a step list: - StartupStep model (INotifyPropertyChanged) tracks Title, State (Pending/Active/Done/Failed), Detail, optional Progress 0..1 - ItemsControl + DataTemplate in App.xaml renders each step as a status bullet (empty ring -> filled brand -> green check -> red X), with conditional detail line + restyled mini progress bar - StartupFlow.NewHostFlow / NewJoinFlow build the canonical 5-step host and 2-step join lists; host flow swaps the tunnel step label for LocalNetwork mode - OnHostStart / OnJoinApply advance steps via StartStep/CompleteStep/ FailStep helpers and route progress callbacks to UpdateStepProgress so each download phase has its own bar - Errors mark the active step Failed with the message inline, leaving the rest of the list visible so the user sees where it broke
390 lines
22 KiB
XML
390 lines
22 KiB
XML
<Application x:Class="DorkNet.Launcher.App"
|
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
|
xmlns:backend="clr-namespace:DorkNet.Launcher.Backend"
|
|
StartupUri="MainWindow.xaml">
|
|
|
|
<Application.Resources>
|
|
<!-- ── Palette ─────────────────────────────────────────────────
|
|
Rec Room-adjacent — warm coral + teal on a deep purple-navy.
|
|
Avoids the cold-grey "developer tool" look in favour of the
|
|
friendly game-launcher aesthetic. -->
|
|
<SolidColorBrush x:Key="Bg" Color="#16102A" />
|
|
<SolidColorBrush x:Key="BgDeeper" Color="#0E0A1F" />
|
|
<SolidColorBrush x:Key="BgElev" Color="#221833" />
|
|
<SolidColorBrush x:Key="BgElev2" Color="#2E2245" />
|
|
<SolidColorBrush x:Key="Border" Color="#3A2C56" />
|
|
<SolidColorBrush x:Key="BorderSoft" Color="#2A2042" />
|
|
<SolidColorBrush x:Key="Ink" Color="#F7F3FF" />
|
|
<SolidColorBrush x:Key="InkSoft" Color="#B8AED4" />
|
|
<SolidColorBrush x:Key="InkFaint" Color="#6E608E" />
|
|
|
|
<!-- Brand: warm coral, with teal as the secondary accent. -->
|
|
<SolidColorBrush x:Key="Brand" Color="#FF7B5C" />
|
|
<SolidColorBrush x:Key="BrandHover" Color="#FF9277" />
|
|
<SolidColorBrush x:Key="BrandDeep" Color="#E55F40" />
|
|
<SolidColorBrush x:Key="Teal" Color="#44D6C4" />
|
|
<SolidColorBrush x:Key="TealDeep" Color="#2DB8A6" />
|
|
<SolidColorBrush x:Key="Sunshine" Color="#FFD555" />
|
|
<SolidColorBrush x:Key="Ok" Color="#5BE0A6" />
|
|
<SolidColorBrush x:Key="Danger" Color="#FF6B8A" />
|
|
|
|
<!-- Wordmark gradient: coral → pink → teal across the "DorkNet" letters. -->
|
|
<LinearGradientBrush x:Key="WordmarkBrush" StartPoint="0,0" EndPoint="1,1">
|
|
<GradientStop Color="#FF7B5C" Offset="0" />
|
|
<GradientStop Color="#FF5C95" Offset="0.55" />
|
|
<GradientStop Color="#44D6C4" Offset="1" />
|
|
</LinearGradientBrush>
|
|
|
|
<!-- Subtle card-back gradient — radial illusion via linear top-left
|
|
tint into the base elev colour. -->
|
|
<LinearGradientBrush x:Key="CardBg" StartPoint="0,0" EndPoint="0,1">
|
|
<GradientStop Color="#2A1F40" Offset="0" />
|
|
<GradientStop Color="#221833" Offset="1" />
|
|
</LinearGradientBrush>
|
|
|
|
<LinearGradientBrush x:Key="CardBgHost" StartPoint="0,0" EndPoint="1,1">
|
|
<GradientStop Color="#3A1F35" Offset="0" />
|
|
<GradientStop Color="#221833" Offset="1" />
|
|
</LinearGradientBrush>
|
|
|
|
<LinearGradientBrush x:Key="CardBgJoin" StartPoint="0,0" EndPoint="1,1">
|
|
<GradientStop Color="#1F3540" Offset="0" />
|
|
<GradientStop Color="#221833" Offset="1" />
|
|
</LinearGradientBrush>
|
|
|
|
<!-- Soft drop-shadow effect used on cards / primary buttons. -->
|
|
<DropShadowEffect x:Key="CardShadow" BlurRadius="24" ShadowDepth="0"
|
|
Color="#000000" Opacity="0.45" />
|
|
<DropShadowEffect x:Key="BtnShadow" BlurRadius="16" ShadowDepth="2"
|
|
Color="#FF5C40" Opacity="0.35" />
|
|
|
|
<!-- ── TextBox ─────────────────────────────────────────────────── -->
|
|
<Style TargetType="TextBox">
|
|
<Setter Property="Background" Value="{StaticResource BgElev}" />
|
|
<Setter Property="Foreground" Value="{StaticResource Ink}" />
|
|
<Setter Property="CaretBrush" Value="{StaticResource Ink}" />
|
|
<Setter Property="BorderBrush" Value="{StaticResource Border}" />
|
|
<Setter Property="BorderThickness" Value="1.5" />
|
|
<Setter Property="Padding" Value="12,10" />
|
|
<Setter Property="FontFamily" Value="Segoe UI Variable, Segoe UI" />
|
|
<Setter Property="FontSize" Value="14" />
|
|
<Setter Property="Template">
|
|
<Setter.Value>
|
|
<ControlTemplate TargetType="TextBox">
|
|
<Border Background="{TemplateBinding Background}"
|
|
BorderBrush="{TemplateBinding BorderBrush}"
|
|
BorderThickness="{TemplateBinding BorderThickness}"
|
|
CornerRadius="10">
|
|
<ScrollViewer x:Name="PART_ContentHost"
|
|
Margin="{TemplateBinding Padding}"
|
|
VerticalScrollBarVisibility="Auto" />
|
|
</Border>
|
|
<ControlTemplate.Triggers>
|
|
<Trigger Property="IsFocused" Value="True">
|
|
<Setter Property="BorderBrush" Value="{StaticResource Brand}" />
|
|
</Trigger>
|
|
</ControlTemplate.Triggers>
|
|
</ControlTemplate>
|
|
</Setter.Value>
|
|
</Setter>
|
|
</Style>
|
|
|
|
<!-- ── ComboBox ────────────────────────────────────────────────── -->
|
|
<Style TargetType="ComboBox">
|
|
<Setter Property="Background" Value="{StaticResource BgElev}" />
|
|
<Setter Property="Foreground" Value="{StaticResource Ink}" />
|
|
<Setter Property="BorderBrush" Value="{StaticResource Border}" />
|
|
<Setter Property="BorderThickness" Value="1.5" />
|
|
<Setter Property="Padding" Value="12,10" />
|
|
<Setter Property="FontSize" Value="14" />
|
|
<Setter Property="FontFamily" Value="Segoe UI Variable, Segoe UI" />
|
|
</Style>
|
|
|
|
<Style TargetType="ComboBoxItem">
|
|
<Setter Property="Background" Value="{StaticResource BgElev}" />
|
|
<Setter Property="Foreground" Value="{StaticResource Ink}" />
|
|
<Setter Property="Padding" Value="10,8" />
|
|
</Style>
|
|
|
|
<!-- ── Buttons ─────────────────────────────────────────────────── -->
|
|
<Style x:Key="Btn" TargetType="Button">
|
|
<Setter Property="Background" Value="{StaticResource BgElev2}" />
|
|
<Setter Property="Foreground" Value="{StaticResource Ink}" />
|
|
<Setter Property="BorderBrush" Value="{StaticResource Border}" />
|
|
<Setter Property="BorderThickness" Value="1.5" />
|
|
<Setter Property="Padding" Value="16,10" />
|
|
<Setter Property="FontSize" Value="13" />
|
|
<Setter Property="FontWeight" Value="SemiBold" />
|
|
<Setter Property="FontFamily" Value="Segoe UI Variable, Segoe UI" />
|
|
<Setter Property="Cursor" Value="Hand" />
|
|
<Setter Property="Template">
|
|
<Setter.Value>
|
|
<ControlTemplate TargetType="Button">
|
|
<Border Background="{TemplateBinding Background}"
|
|
BorderBrush="{TemplateBinding BorderBrush}"
|
|
BorderThickness="{TemplateBinding BorderThickness}"
|
|
CornerRadius="10">
|
|
<ContentPresenter HorizontalAlignment="Center"
|
|
VerticalAlignment="Center"
|
|
Margin="{TemplateBinding Padding}" />
|
|
</Border>
|
|
</ControlTemplate>
|
|
</Setter.Value>
|
|
</Setter>
|
|
<Style.Triggers>
|
|
<Trigger Property="IsMouseOver" Value="True">
|
|
<Setter Property="Background" Value="{StaticResource Border}" />
|
|
<Setter Property="BorderBrush" Value="{StaticResource BorderSoft}" />
|
|
</Trigger>
|
|
<Trigger Property="IsEnabled" Value="False">
|
|
<Setter Property="Foreground" Value="{StaticResource InkFaint}" />
|
|
<Setter Property="Background" Value="{StaticResource BgElev}" />
|
|
</Trigger>
|
|
</Style.Triggers>
|
|
</Style>
|
|
|
|
<Style x:Key="PrimaryBtn" TargetType="Button" BasedOn="{StaticResource Btn}">
|
|
<Setter Property="Background" Value="{StaticResource Brand}" />
|
|
<Setter Property="BorderBrush" Value="{StaticResource BrandDeep}" />
|
|
<Setter Property="Foreground" Value="White" />
|
|
<Setter Property="Padding" Value="22,12" />
|
|
<Setter Property="FontSize" Value="14" />
|
|
<Setter Property="Effect" Value="{StaticResource BtnShadow}" />
|
|
<Style.Triggers>
|
|
<Trigger Property="IsMouseOver" Value="True">
|
|
<Setter Property="Background" Value="{StaticResource BrandHover}" />
|
|
<Setter Property="BorderBrush" Value="{StaticResource Brand}" />
|
|
</Trigger>
|
|
<Trigger Property="IsEnabled" Value="False">
|
|
<Setter Property="Background" Value="{StaticResource BgElev2}" />
|
|
<Setter Property="BorderBrush" Value="{StaticResource Border}" />
|
|
<Setter Property="Foreground" Value="{StaticResource InkFaint}" />
|
|
<Setter Property="Effect" Value="{x:Null}" />
|
|
</Trigger>
|
|
</Style.Triggers>
|
|
</Style>
|
|
|
|
<Style x:Key="TealBtn" TargetType="Button" BasedOn="{StaticResource Btn}">
|
|
<Setter Property="Background" Value="{StaticResource Teal}" />
|
|
<Setter Property="BorderBrush" Value="{StaticResource TealDeep}" />
|
|
<Setter Property="Foreground" Value="#0E0A1F" />
|
|
<Setter Property="Padding" Value="22,12" />
|
|
<Setter Property="FontSize" Value="14" />
|
|
<Style.Triggers>
|
|
<Trigger Property="IsMouseOver" Value="True">
|
|
<Setter Property="Background" Value="#5DE8D6" />
|
|
</Trigger>
|
|
</Style.Triggers>
|
|
</Style>
|
|
|
|
<Style x:Key="GhostBtn" TargetType="Button" BasedOn="{StaticResource Btn}">
|
|
<Setter Property="Background" Value="Transparent" />
|
|
</Style>
|
|
|
|
<!-- ── Card buttons for first-run wizard ───────────────────────── -->
|
|
<Style x:Key="ChoiceCardBtn" TargetType="Button">
|
|
<Setter Property="Background" Value="{StaticResource CardBg}" />
|
|
<Setter Property="Foreground" Value="{StaticResource Ink}" />
|
|
<Setter Property="BorderBrush" Value="{StaticResource Border}" />
|
|
<Setter Property="BorderThickness" Value="1.5" />
|
|
<Setter Property="Padding" Value="28" />
|
|
<Setter Property="Cursor" Value="Hand" />
|
|
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
|
|
<Setter Property="VerticalContentAlignment" Value="Stretch" />
|
|
<Setter Property="Effect" Value="{StaticResource CardShadow}" />
|
|
<Setter Property="Template">
|
|
<Setter.Value>
|
|
<ControlTemplate TargetType="Button">
|
|
<Border x:Name="cardBorder"
|
|
Background="{TemplateBinding Background}"
|
|
BorderBrush="{TemplateBinding BorderBrush}"
|
|
BorderThickness="{TemplateBinding BorderThickness}"
|
|
CornerRadius="18">
|
|
<ContentPresenter Margin="{TemplateBinding Padding}" />
|
|
</Border>
|
|
<ControlTemplate.Triggers>
|
|
<Trigger Property="IsMouseOver" Value="True">
|
|
<Setter TargetName="cardBorder" Property="BorderBrush"
|
|
Value="{StaticResource Brand}" />
|
|
</Trigger>
|
|
</ControlTemplate.Triggers>
|
|
</ControlTemplate>
|
|
</Setter.Value>
|
|
</Setter>
|
|
</Style>
|
|
|
|
<!-- ── Section panel — used to group form fields ───────────────── -->
|
|
<Style x:Key="Panel" TargetType="Border">
|
|
<Setter Property="Background" Value="{StaticResource BgElev}" />
|
|
<Setter Property="BorderBrush" Value="{StaticResource BorderSoft}" />
|
|
<Setter Property="BorderThickness" Value="1" />
|
|
<Setter Property="CornerRadius" Value="14" />
|
|
<Setter Property="Padding" Value="20" />
|
|
</Style>
|
|
|
|
<!-- ── Field label text ────────────────────────────────────────── -->
|
|
<Style x:Key="FieldLabel" TargetType="TextBlock">
|
|
<Setter Property="Foreground" Value="{StaticResource InkSoft}" />
|
|
<Setter Property="FontSize" Value="11" />
|
|
<Setter Property="FontWeight" Value="Bold" />
|
|
<Setter Property="Margin" Value="0,0,0,8" />
|
|
<Setter Property="FontFamily" Value="Segoe UI Variable, Segoe UI" />
|
|
</Style>
|
|
|
|
<Style x:Key="SectionTitle" TargetType="TextBlock">
|
|
<Setter Property="Foreground" Value="{StaticResource Ink}" />
|
|
<Setter Property="FontSize" Value="16" />
|
|
<Setter Property="FontWeight" Value="SemiBold" />
|
|
<Setter Property="Margin" Value="0,0,0,12" />
|
|
<Setter Property="FontFamily" Value="Segoe UI Variable, Segoe UI" />
|
|
</Style>
|
|
|
|
<!-- Pill-style "status chip" used in section headers. -->
|
|
<Style x:Key="StatusChip" TargetType="Border">
|
|
<Setter Property="Background" Value="{StaticResource BgElev2}" />
|
|
<Setter Property="CornerRadius" Value="999" />
|
|
<Setter Property="Padding" Value="10,4" />
|
|
</Style>
|
|
|
|
<!-- ── Mini progress bar — restyled WPF ProgressBar to match the
|
|
launcher palette. Used inside the step-row template. ─────── -->
|
|
<Style x:Key="StepProgressBar" TargetType="ProgressBar">
|
|
<Setter Property="Minimum" Value="0" />
|
|
<Setter Property="Maximum" Value="100" />
|
|
<Setter Property="Height" Value="6" />
|
|
<Setter Property="Foreground" Value="{StaticResource Brand}" />
|
|
<Setter Property="Background" Value="{StaticResource BgDeeper}" />
|
|
<Setter Property="BorderThickness" Value="0" />
|
|
<Setter Property="Template">
|
|
<Setter.Value>
|
|
<ControlTemplate TargetType="ProgressBar">
|
|
<Border Background="{TemplateBinding Background}"
|
|
CornerRadius="3" ClipToBounds="True">
|
|
<Grid HorizontalAlignment="Stretch">
|
|
<Rectangle x:Name="PART_Track" />
|
|
<Border x:Name="PART_Indicator"
|
|
Background="{TemplateBinding Foreground}"
|
|
HorizontalAlignment="Left"
|
|
CornerRadius="3" />
|
|
</Grid>
|
|
</Border>
|
|
</ControlTemplate>
|
|
</Setter.Value>
|
|
</Setter>
|
|
</Style>
|
|
|
|
<!-- ── Bool→Visibility converter for HasDetail/HasProgress flags ─ -->
|
|
<BooleanToVisibilityConverter x:Key="BoolToVis" />
|
|
|
|
<!-- ── StartupStep row template ─────────────────────────────────
|
|
A single row in the host/join step list. State drives the
|
|
status icon's colour + glyph; detail/progress are shown only
|
|
when populated (so pending steps render as a clean single
|
|
line). -->
|
|
<DataTemplate x:Key="StepRowTemplate" DataType="{x:Type backend:StartupStep}">
|
|
<Grid Margin="0,0,0,14">
|
|
<Grid.ColumnDefinitions>
|
|
<ColumnDefinition Width="28" />
|
|
<ColumnDefinition Width="*" />
|
|
</Grid.ColumnDefinitions>
|
|
|
|
<!-- Status bullet — circle that recolours and re-glyphs
|
|
based on the bound State. Pending = empty ring,
|
|
Active = filled brand, Done = green checkmark,
|
|
Failed = red X. -->
|
|
<Border Grid.Column="0" Width="22" Height="22" CornerRadius="11"
|
|
VerticalAlignment="Top" Margin="0,1,0,0"
|
|
BorderThickness="2">
|
|
<Border.Style>
|
|
<Style TargetType="Border">
|
|
<Setter Property="Background" Value="Transparent" />
|
|
<Setter Property="BorderBrush" Value="{StaticResource InkFaint}" />
|
|
<Style.Triggers>
|
|
<DataTrigger Binding="{Binding State}" Value="Active">
|
|
<Setter Property="Background" Value="{StaticResource Brand}" />
|
|
<Setter Property="BorderBrush" Value="{StaticResource Brand}" />
|
|
</DataTrigger>
|
|
<DataTrigger Binding="{Binding State}" Value="Done">
|
|
<Setter Property="Background" Value="{StaticResource Ok}" />
|
|
<Setter Property="BorderBrush" Value="{StaticResource Ok}" />
|
|
</DataTrigger>
|
|
<DataTrigger Binding="{Binding State}" Value="Failed">
|
|
<Setter Property="Background" Value="{StaticResource Danger}" />
|
|
<Setter Property="BorderBrush" Value="{StaticResource Danger}" />
|
|
</DataTrigger>
|
|
</Style.Triggers>
|
|
</Style>
|
|
</Border.Style>
|
|
<TextBlock HorizontalAlignment="Center" VerticalAlignment="Center"
|
|
FontSize="13" FontWeight="Bold" Foreground="White">
|
|
<TextBlock.Style>
|
|
<Style TargetType="TextBlock">
|
|
<Setter Property="Text" Value="" />
|
|
<Style.Triggers>
|
|
<DataTrigger Binding="{Binding State}" Value="Active">
|
|
<Setter Property="Text" Value="●" />
|
|
<Setter Property="FontSize" Value="9" />
|
|
</DataTrigger>
|
|
<DataTrigger Binding="{Binding State}" Value="Done">
|
|
<Setter Property="Text" Value="✓" />
|
|
<Setter Property="Foreground" Value="#0E0A1F" />
|
|
</DataTrigger>
|
|
<DataTrigger Binding="{Binding State}" Value="Failed">
|
|
<Setter Property="Text" Value="✕" />
|
|
</DataTrigger>
|
|
</Style.Triggers>
|
|
</Style>
|
|
</TextBlock.Style>
|
|
</TextBlock>
|
|
</Border>
|
|
|
|
<!-- Title + (optional) detail + (optional) progress bar -->
|
|
<StackPanel Grid.Column="1" Margin="12,0,0,0">
|
|
<TextBlock Text="{Binding Title}" FontSize="14">
|
|
<TextBlock.Style>
|
|
<Style TargetType="TextBlock">
|
|
<Setter Property="Foreground" Value="{StaticResource InkSoft}" />
|
|
<Setter Property="FontWeight" Value="Normal" />
|
|
<Style.Triggers>
|
|
<DataTrigger Binding="{Binding State}" Value="Active">
|
|
<Setter Property="Foreground" Value="{StaticResource Ink}" />
|
|
<Setter Property="FontWeight" Value="SemiBold" />
|
|
</DataTrigger>
|
|
<DataTrigger Binding="{Binding State}" Value="Done">
|
|
<Setter Property="Foreground" Value="{StaticResource Ink}" />
|
|
</DataTrigger>
|
|
<DataTrigger Binding="{Binding State}" Value="Failed">
|
|
<Setter Property="Foreground" Value="{StaticResource Danger}" />
|
|
<Setter Property="FontWeight" Value="SemiBold" />
|
|
</DataTrigger>
|
|
</Style.Triggers>
|
|
</Style>
|
|
</TextBlock.Style>
|
|
</TextBlock>
|
|
|
|
<TextBlock Text="{Binding Detail}" TextWrapping="Wrap"
|
|
FontSize="12" Margin="0,4,0,0"
|
|
Visibility="{Binding HasDetail, Converter={StaticResource BoolToVis}}">
|
|
<TextBlock.Style>
|
|
<Style TargetType="TextBlock">
|
|
<Setter Property="Foreground" Value="{StaticResource InkSoft}" />
|
|
<Style.Triggers>
|
|
<DataTrigger Binding="{Binding State}" Value="Failed">
|
|
<Setter Property="Foreground" Value="{StaticResource Danger}" />
|
|
</DataTrigger>
|
|
</Style.Triggers>
|
|
</Style>
|
|
</TextBlock.Style>
|
|
</TextBlock>
|
|
|
|
<ProgressBar Style="{StaticResource StepProgressBar}"
|
|
Value="{Binding ProgressPercent, Mode=OneWay}"
|
|
Margin="0,8,0,0"
|
|
Visibility="{Binding HasProgress, Converter={StaticResource BoolToVis}}" />
|
|
</StackPanel>
|
|
</Grid>
|
|
</DataTemplate>
|
|
</Application.Resources>
|
|
</Application>
|