Restyle the Avalonia server host and add a single-file publish workflow (#18)
Give the host a cohesive vault-terminal look: header wordmark with a live status pill that glows green while running, sectioned configuration card with per-field labels, a terminal-style server log, richer player rows (id, name, address, packet counts), and a bold Start/Stop control bar. All existing bindings are unchanged. Add publish-host.yml to build self-contained, single-file win-x64 and linux-x64 binaries on the self-hosted runner and upload them as artifacts, and document the untrimmed publish commands in the host README.
This commit is contained in:
+177
-73
@@ -3,102 +3,206 @@
|
||||
xmlns:vm="clr-namespace:CommonwealthOnline.Host.ViewModels"
|
||||
x:Class="CommonwealthOnline.Host.Views.MainWindow"
|
||||
x:DataType="vm:MainWindowViewModel"
|
||||
Width="960" Height="700"
|
||||
MinWidth="820" MinHeight="600"
|
||||
Width="1040" Height="740"
|
||||
MinWidth="900" MinHeight="640"
|
||||
Title="Commonwealth Online — Server Host"
|
||||
Background="{StaticResource CoBackgroundBrush}">
|
||||
Background="{StaticResource CoWindowBrush}">
|
||||
|
||||
<Grid RowDefinitions="Auto,*,Auto" Margin="18">
|
||||
<Grid RowDefinitions="Auto,*,Auto">
|
||||
|
||||
<Image Grid.Row="0" Source="/Assets/logo.png" Height="84"
|
||||
HorizontalAlignment="Left" Margin="0,0,0,14" />
|
||||
<!-- ============ Header ============ -->
|
||||
<Border Grid.Row="0" Background="{StaticResource CoBarBrush}"
|
||||
BorderBrush="{StaticResource CoBorderBrush}" BorderThickness="0,0,0,1"
|
||||
Padding="20,12">
|
||||
<Grid ColumnDefinitions="Auto,*,Auto" VerticalAlignment="Center">
|
||||
|
||||
<Grid Grid.Row="1" ColumnDefinitions="330,*">
|
||||
<StackPanel Grid.Column="0" Orientation="Horizontal" Spacing="14" VerticalAlignment="Center">
|
||||
<Image Source="/Assets/logo.png" Height="42" VerticalAlignment="Center" />
|
||||
<StackPanel VerticalAlignment="Center" Spacing="1">
|
||||
<TextBlock Text="COMMONWEALTH ONLINE" Foreground="{StaticResource CoAccentBrush}"
|
||||
FontWeight="Bold" FontSize="16" LetterSpacing="3" />
|
||||
<TextBlock Text="DEDICATED SERVER HOST" Foreground="{StaticResource CoMutedBrush}"
|
||||
FontSize="10" LetterSpacing="4" />
|
||||
</StackPanel>
|
||||
</StackPanel>
|
||||
|
||||
<StackPanel Grid.Column="0" Spacing="9" Margin="0,0,18,0">
|
||||
<TextBlock Text="SERVER" Foreground="{StaticResource CoAccentBrush}"
|
||||
FontWeight="Bold" FontSize="13" />
|
||||
<TextBox Watermark="Server name" Text="{Binding ServerName}" />
|
||||
<Grid ColumnDefinitions="*,*">
|
||||
<TextBox Grid.Column="0" Watermark="Host" Text="{Binding Host}" Margin="0,0,4,0" />
|
||||
<TextBox Grid.Column="1" Watermark="Port" Text="{Binding Port}" Margin="4,0,0,0" />
|
||||
</Grid>
|
||||
<Grid ColumnDefinitions="*,*">
|
||||
<TextBox Grid.Column="0" Watermark="Max players" Text="{Binding MaxPlayers}" Margin="0,0,4,0" />
|
||||
<TextBox Grid.Column="1" Watermark="Admin port" Text="{Binding AdminPort}" Margin="4,0,0,0" />
|
||||
</Grid>
|
||||
<TextBlock Text="LOG VERBOSITY" Foreground="{StaticResource CoAccentBrush}"
|
||||
FontWeight="Bold" FontSize="12" Margin="0,4,0,0" />
|
||||
<ComboBox HorizontalAlignment="Stretch"
|
||||
ItemsSource="{Binding VerbosityOptions}"
|
||||
SelectedItem="{Binding LogVerbosity}" />
|
||||
<CheckBox Content="Enable GNS transport" IsChecked="{Binding EnableGnsTransport}"
|
||||
Foreground="{StaticResource CoTextBrush}" />
|
||||
<Button Content="Save config" Command="{Binding SaveCommand}"
|
||||
HorizontalAlignment="Stretch" />
|
||||
</StackPanel>
|
||||
<!-- Live status pill -->
|
||||
<Border Grid.Column="2" Classes="pill" Classes.on="{Binding IsRunning}"
|
||||
Background="{StaticResource CoSurface2Brush}"
|
||||
BorderThickness="1"
|
||||
CornerRadius="14" Padding="14,7" VerticalAlignment="Center">
|
||||
<StackPanel Orientation="Horizontal" Spacing="9" VerticalAlignment="Center">
|
||||
<Ellipse Classes="dot" Classes.on="{Binding IsRunning}"
|
||||
Width="10" Height="10" VerticalAlignment="Center" />
|
||||
<TextBlock Text="{Binding StatusText}" Foreground="{StaticResource CoTextBrush}"
|
||||
FontWeight="SemiBold" FontSize="13" LetterSpacing="1"
|
||||
VerticalAlignment="Center" />
|
||||
</StackPanel>
|
||||
</Border>
|
||||
</Grid>
|
||||
</Border>
|
||||
|
||||
<!-- ============ Body ============ -->
|
||||
<Grid Grid.Row="1" ColumnDefinitions="352,*" Margin="20,18,20,14">
|
||||
|
||||
<!-- Config card -->
|
||||
<Border Grid.Column="0" Classes="card" Background="{StaticResource CoSurfaceBrush}"
|
||||
BorderBrush="{StaticResource CoBorderBrush}" BorderThickness="1"
|
||||
CornerRadius="8" Padding="18" Margin="0,0,18,0">
|
||||
<StackPanel Spacing="12">
|
||||
<TextBlock Classes="section" Text="CONFIGURATION" />
|
||||
|
||||
<StackPanel Spacing="4">
|
||||
<TextBlock Classes="fieldlabel" Text="SERVER NAME" />
|
||||
<TextBox Watermark="My Commonwealth server" Text="{Binding ServerName}" />
|
||||
</StackPanel>
|
||||
|
||||
<Grid ColumnDefinitions="*,Auto">
|
||||
<StackPanel Grid.Column="0" Spacing="4" Margin="0,0,8,0">
|
||||
<TextBlock Classes="fieldlabel" Text="HOST ADDRESS" />
|
||||
<TextBox Watermark="0.0.0.0" Text="{Binding Host}" />
|
||||
</StackPanel>
|
||||
<StackPanel Grid.Column="1" Spacing="4" Width="96">
|
||||
<TextBlock Classes="fieldlabel" Text="PORT" />
|
||||
<TextBox Watermark="7777" Text="{Binding Port}" />
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
|
||||
<Grid ColumnDefinitions="*,Auto">
|
||||
<StackPanel Grid.Column="0" Spacing="4" Margin="0,0,8,0">
|
||||
<TextBlock Classes="fieldlabel" Text="MAX PLAYERS" />
|
||||
<TextBox Watermark="16" Text="{Binding MaxPlayers}" />
|
||||
</StackPanel>
|
||||
<StackPanel Grid.Column="1" Spacing="4" Width="96">
|
||||
<TextBlock Classes="fieldlabel" Text="ADMIN PORT" />
|
||||
<TextBox Watermark="7779" Text="{Binding AdminPort}" />
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
|
||||
<StackPanel Spacing="4">
|
||||
<TextBlock Classes="fieldlabel" Text="LOG VERBOSITY" />
|
||||
<ComboBox HorizontalAlignment="Stretch"
|
||||
ItemsSource="{Binding VerbosityOptions}"
|
||||
SelectedItem="{Binding LogVerbosity}" />
|
||||
</StackPanel>
|
||||
|
||||
<Border Background="{StaticResource CoSurface2Brush}"
|
||||
BorderBrush="{StaticResource CoBorderBrush}" BorderThickness="1"
|
||||
CornerRadius="5" Padding="10,8" Margin="0,2,0,0">
|
||||
<CheckBox Content="Enable GNS transport (UDP)"
|
||||
IsChecked="{Binding EnableGnsTransport}" />
|
||||
</Border>
|
||||
|
||||
<Button Classes="ghost" Content="Save configuration"
|
||||
Command="{Binding SaveCommand}"
|
||||
HorizontalAlignment="Stretch" Margin="0,4,0,0" />
|
||||
</StackPanel>
|
||||
</Border>
|
||||
|
||||
<!-- Right column: log + players -->
|
||||
<Grid Grid.Column="1" RowDefinitions="*,Auto">
|
||||
|
||||
<Border Grid.Row="0" Background="{StaticResource CoSurfaceBrush}"
|
||||
CornerRadius="4" Padding="10">
|
||||
<ScrollViewer>
|
||||
<ItemsControl ItemsSource="{Binding Log}">
|
||||
<ItemsControl.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<TextBlock Text="{Binding}" Foreground="{StaticResource CoTextBrush}"
|
||||
FontFamily="Cascadia Mono,Consolas,monospace" FontSize="12"
|
||||
TextWrapping="Wrap" />
|
||||
</DataTemplate>
|
||||
</ItemsControl.ItemTemplate>
|
||||
</ItemsControl>
|
||||
</ScrollViewer>
|
||||
<!-- Server log -->
|
||||
<Border Grid.Row="0" Classes="card" Background="{StaticResource CoSurfaceBrush}"
|
||||
BorderBrush="{StaticResource CoBorderBrush}" BorderThickness="1"
|
||||
CornerRadius="8" Padding="0">
|
||||
<Grid RowDefinitions="Auto,*">
|
||||
<Border Grid.Row="0" Background="{StaticResource CoSurface2Brush}"
|
||||
BorderBrush="{StaticResource CoBorderBrush}" BorderThickness="0,0,0,1"
|
||||
CornerRadius="8,8,0,0" Padding="14,9">
|
||||
<StackPanel Orientation="Horizontal" Spacing="9">
|
||||
<Ellipse Classes="dot" Classes.on="{Binding IsRunning}"
|
||||
Width="9" Height="9" VerticalAlignment="Center" />
|
||||
<TextBlock Classes="section" Text="SERVER LOG" VerticalAlignment="Center" />
|
||||
</StackPanel>
|
||||
</Border>
|
||||
<ScrollViewer Grid.Row="1" Padding="14,10" x:Name="LogScroll">
|
||||
<ItemsControl ItemsSource="{Binding Log}">
|
||||
<ItemsControl.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<TextBlock Text="{Binding}" Foreground="{StaticResource CoTextBrush}"
|
||||
FontFamily="Cascadia Mono,Consolas,Menlo,monospace" FontSize="12"
|
||||
TextWrapping="Wrap" Margin="0,0,0,1" />
|
||||
</DataTemplate>
|
||||
</ItemsControl.ItemTemplate>
|
||||
</ItemsControl>
|
||||
</ScrollViewer>
|
||||
</Grid>
|
||||
</Border>
|
||||
|
||||
<Border Grid.Row="1" Background="{StaticResource CoSurfaceBrush}"
|
||||
CornerRadius="4" Padding="10" Margin="0,10,0,0" Height="188">
|
||||
<!-- Players -->
|
||||
<Border Grid.Row="1" Classes="card" Background="{StaticResource CoSurfaceBrush}"
|
||||
BorderBrush="{StaticResource CoBorderBrush}" BorderThickness="1"
|
||||
CornerRadius="8" Padding="0" Margin="0,14,0,0" Height="210">
|
||||
<Grid RowDefinitions="Auto,*,Auto">
|
||||
<DockPanel Grid.Row="0" Margin="0,0,0,6">
|
||||
<TextBlock DockPanel.Dock="Left" Text="PLAYERS"
|
||||
Foreground="{StaticResource CoAccentBrush}" FontWeight="Bold" FontSize="12" />
|
||||
<TextBlock DockPanel.Dock="Right" Text="{Binding StatsText}"
|
||||
Foreground="{StaticResource CoTextBrush}" FontSize="11"
|
||||
HorizontalAlignment="Right" />
|
||||
</DockPanel>
|
||||
<ListBox Grid.Row="1" Background="Transparent"
|
||||
<Border Grid.Row="0" Background="{StaticResource CoSurface2Brush}"
|
||||
BorderBrush="{StaticResource CoBorderBrush}" BorderThickness="0,0,0,1"
|
||||
CornerRadius="8,8,0,0" Padding="14,9">
|
||||
<DockPanel>
|
||||
<TextBlock DockPanel.Dock="Left" Classes="section" Text="PLAYERS"
|
||||
VerticalAlignment="Center" />
|
||||
<TextBlock DockPanel.Dock="Right" Text="{Binding StatsText}"
|
||||
Foreground="{StaticResource CoMutedBrush}" FontSize="11"
|
||||
FontFamily="Cascadia Mono,Consolas,monospace"
|
||||
HorizontalAlignment="Right" VerticalAlignment="Center" />
|
||||
</DockPanel>
|
||||
</Border>
|
||||
|
||||
<ListBox Grid.Row="1" Margin="6,4"
|
||||
ItemsSource="{Binding Players}" SelectedItem="{Binding SelectedPlayer}">
|
||||
<ListBox.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<TextBlock Text="{Binding Display}" Foreground="{StaticResource CoTextBrush}"
|
||||
FontFamily="Cascadia Mono,Consolas,monospace" FontSize="12" />
|
||||
<DataTemplate x:DataType="vm:PlayerRow">
|
||||
<Grid ColumnDefinitions="52,*,Auto" >
|
||||
<TextBlock Grid.Column="0" Text="{Binding PlayerId, StringFormat='#{0}'}"
|
||||
Foreground="{StaticResource CoAccentBrush}" FontWeight="Bold"
|
||||
FontFamily="Cascadia Mono,Consolas,monospace" FontSize="12"
|
||||
VerticalAlignment="Center" />
|
||||
<StackPanel Grid.Column="1" VerticalAlignment="Center" Spacing="0">
|
||||
<TextBlock Text="{Binding Label}" Foreground="{StaticResource CoTextBrush}"
|
||||
FontSize="13" />
|
||||
<TextBlock Text="{Binding Address}" Foreground="{StaticResource CoMutedBrush}"
|
||||
FontFamily="Cascadia Mono,Consolas,monospace" FontSize="10" />
|
||||
</StackPanel>
|
||||
<TextBlock Grid.Column="2"
|
||||
Text="{Binding PacketsReceived, StringFormat='↓{0}'}"
|
||||
Foreground="{StaticResource CoMutedBrush}"
|
||||
FontFamily="Cascadia Mono,Consolas,monospace" FontSize="11"
|
||||
VerticalAlignment="Center" />
|
||||
</Grid>
|
||||
</DataTemplate>
|
||||
</ListBox.ItemTemplate>
|
||||
</ListBox>
|
||||
<StackPanel Grid.Row="2" Orientation="Horizontal" Spacing="8" Margin="0,6,0,0">
|
||||
<Button Content="Kick" Command="{Binding KickCommand}" Padding="18,4" />
|
||||
<Button Content="Ban" Command="{Binding BanCommand}" Padding="18,4"
|
||||
Background="{StaticResource CoDangerBrush}" Foreground="White" />
|
||||
|
||||
<StackPanel Grid.Row="2" Orientation="Horizontal" Spacing="8"
|
||||
HorizontalAlignment="Right" Margin="10,0,10,10">
|
||||
<Button Content="Kick" Command="{Binding KickCommand}" Padding="22,5" />
|
||||
<Button Classes="danger" Content="Ban" Command="{Binding BanCommand}" Padding="22,5" />
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
</Border>
|
||||
|
||||
</Grid>
|
||||
|
||||
</Grid>
|
||||
|
||||
<Grid Grid.Row="2" ColumnDefinitions="Auto,*,Auto,Auto" Margin="0,14,0,0">
|
||||
<TextBlock Grid.Column="0" Text="Status:" Foreground="{StaticResource CoTextBrush}"
|
||||
VerticalAlignment="Center" Margin="0,0,6,0" />
|
||||
<TextBlock Grid.Column="1" Text="{Binding StatusText}"
|
||||
Foreground="{StaticResource CoAccentBrush}" FontWeight="Bold"
|
||||
VerticalAlignment="Center" />
|
||||
<Button Grid.Column="2" Content="Start" Command="{Binding StartCommand}"
|
||||
Margin="0,0,8,0" Padding="26,7"
|
||||
Background="{StaticResource CoAccentBrush}" Foreground="#0E120B" FontWeight="Bold" />
|
||||
<Button Grid.Column="3" Content="Stop" Command="{Binding StopCommand}"
|
||||
Padding="26,7"
|
||||
Background="{StaticResource CoDangerBrush}" Foreground="White" FontWeight="Bold" />
|
||||
</Grid>
|
||||
<!-- ============ Control bar ============ -->
|
||||
<Border Grid.Row="2" Background="{StaticResource CoBarBrush}"
|
||||
BorderBrush="{StaticResource CoBorderBrush}" BorderThickness="0,1,0,0"
|
||||
Padding="20,14">
|
||||
<Grid ColumnDefinitions="*,Auto,Auto">
|
||||
<StackPanel Grid.Column="0" Orientation="Horizontal" Spacing="8" VerticalAlignment="Center">
|
||||
<TextBlock Text="●" Foreground="{StaticResource CoMutedBrush}" FontSize="10"
|
||||
VerticalAlignment="Center" />
|
||||
<TextBlock Text="Local admin channel · 127.0.0.1"
|
||||
Foreground="{StaticResource CoMutedBrush}" FontSize="11"
|
||||
FontFamily="Cascadia Mono,Consolas,monospace" VerticalAlignment="Center" />
|
||||
</StackPanel>
|
||||
<Button Grid.Column="1" Classes="accent" Content="▶ START SERVER"
|
||||
Command="{Binding StartCommand}" Margin="0,0,10,0" Padding="26,9"
|
||||
FontSize="14" />
|
||||
<Button Grid.Column="2" Classes="danger" Content="■ STOP"
|
||||
Command="{Binding StopCommand}" Padding="26,9" FontSize="14" />
|
||||
</Grid>
|
||||
</Border>
|
||||
|
||||
</Grid>
|
||||
</Window>
|
||||
|
||||
Reference in New Issue
Block a user