Files
LanMountainDesktop/LanDesktopPLONDS.installer/Views/MainWindow.axaml
2026-06-09 22:18:27 +08:00

536 lines
25 KiB
XML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<Window xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:vm="using:LanDesktopPLONDS.Installer.ViewModels"
x:Class="LanDesktopPLONDS.Installer.Views.MainWindow"
x:DataType="vm:MainWindowViewModel"
Width="1040"
Height="680"
MinWidth="900"
MinHeight="620"
CanResize="True"
x:Name="Root"
Title="{Binding WindowTitle}"
Background="Transparent"
TransparencyLevelHint="Mica, AcrylicBlur, None"
ExtendClientAreaToDecorationsHint="True"
ExtendClientAreaTitleBarHeightHint="48"
WindowDecorations="None">
<Window.Styles>
<Style Selector="Grid.step-page">
<Setter Property="IsVisible" Value="False" />
</Style>
<Style Selector="TextBlock.muted">
<Setter Property="Foreground" Value="{DynamicResource InstallerTextSecondaryBrush}" />
<Setter Property="TextWrapping" Value="Wrap" />
<Setter Property="LineHeight" Value="20" />
</Style>
<Style Selector="Button.step-nav-item">
<Setter Property="Template">
<ControlTemplate>
<Border Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
CornerRadius="{TemplateBinding CornerRadius}">
<ContentPresenter Content="{TemplateBinding Content}"
ContentTemplate="{TemplateBinding ContentTemplate}"
HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}" />
</Border>
</ControlTemplate>
</Setter>
<Setter Property="Background" Value="Transparent" />
<Setter Property="BorderThickness" Value="0" />
<Setter Property="CornerRadius" Value="{DynamicResource DesignCornerRadiusMd}" />
<Setter Property="HorizontalAlignment" Value="Stretch" />
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
<Setter Property="VerticalContentAlignment" Value="Stretch" />
<Setter Property="Margin" Value="0,0,0,3" />
<Setter Property="Padding" Value="0" />
<Setter Property="MinHeight" Value="40" />
</Style>
<Style Selector="Button.step-nav-item:pointerover">
<Setter Property="Background" Value="{DynamicResource InstallerSubtleFillHoverBrush}" />
</Style>
<Style Selector="Button.step-nav-item:pressed">
<Setter Property="Background" Value="{DynamicResource InstallerSubtleFillPressedBrush}" />
</Style>
<Style Selector="Button.step-nav-item:disabled">
<Setter Property="Background" Value="Transparent" />
<Setter Property="Opacity" Value="1" />
</Style>
<Style Selector="Button.step-nav-item:disabled TextBlock.step-title">
<Setter Property="Foreground" Value="{DynamicResource InstallerDisabledTextBrush}" />
</Style>
<Style Selector="Button.step-nav-item:disabled TextBlock.installer-icon">
<Setter Property="Foreground" Value="{DynamicResource InstallerDisabledTextBrush}" />
</Style>
<Style Selector="Border.step-nav-selected-fill">
<Setter Property="Background" Value="{DynamicResource InstallerSubtleFillBrush}" />
<Setter Property="CornerRadius" Value="{DynamicResource DesignCornerRadiusMd}" />
</Style>
<Style Selector="TextBlock.step-title">
<Setter Property="FontSize" Value="13" />
<Setter Property="FontWeight" Value="SemiBold" />
<Setter Property="Foreground" Value="{DynamicResource InstallerTextSecondaryBrush}" />
</Style>
<Style Selector="Border.info-panel">
<Setter Property="Background" Value="{DynamicResource InstallerSurfaceAltBrush}" />
<Setter Property="BorderBrush" Value="{DynamicResource InstallerBorderBrush}" />
<Setter Property="BorderThickness" Value="1" />
<Setter Property="CornerRadius" Value="{DynamicResource DesignCornerRadiusMd}" />
<Setter Property="Padding" Value="12" />
</Style>
<Style Selector="Border.content-card">
<Setter Property="Background" Value="{DynamicResource InstallerSurfaceBrush}" />
<Setter Property="BorderBrush" Value="{DynamicResource InstallerBorderBrush}" />
<Setter Property="BorderThickness" Value="1" />
<Setter Property="CornerRadius" Value="{DynamicResource DesignCornerRadiusLg}" />
<Setter Property="Padding" Value="20" />
</Style>
<Style Selector="Border.error-bar">
<Setter Property="Background" Value="{DynamicResource InstallerErrorBackgroundBrush}" />
<Setter Property="BorderBrush" Value="{DynamicResource InstallerErrorBorderBrush}" />
<Setter Property="BorderThickness" Value="1" />
<Setter Property="CornerRadius" Value="{DynamicResource DesignCornerRadiusMd}" />
<Setter Property="Padding" Value="12" />
</Style>
<Style Selector="TextBlock.meta-label">
<Setter Property="FontSize" Value="12" />
<Setter Property="Foreground" Value="{DynamicResource InstallerTextTertiaryBrush}" />
</Style>
<Style Selector="TextBlock.meta-value">
<Setter Property="FontSize" Value="13" />
<Setter Property="FontWeight" Value="SemiBold" />
<Setter Property="Foreground" Value="{DynamicResource InstallerTextPrimaryBrush}" />
<Setter Property="TextWrapping" Value="Wrap" />
</Style>
<Style Selector="Border.separator">
<Setter Property="Height" Value="1" />
<Setter Property="Background" Value="{DynamicResource InstallerBorderBrush}" />
</Style>
</Window.Styles>
<Border Background="{DynamicResource InstallerWindowBackgroundBrush}"
CornerRadius="{DynamicResource DesignCornerRadiusXl}"
ClipToBounds="True">
<Grid x:Name="RootGrid"
RowDefinitions="48,*"
Background="Transparent">
<Border Grid.Row="0"
Background="{DynamicResource InstallerWindowBackgroundBrush}"
PointerPressed="OnTitleBarPointerPressed">
<Grid ColumnDefinitions="Auto,*,Auto">
<StackPanel Orientation="Horizontal"
Margin="16,0,0,0"
Spacing="10"
VerticalAlignment="Center">
<Border Width="28"
Height="28"
Background="{DynamicResource InstallerAccentBrush}"
CornerRadius="{DynamicResource DesignCornerRadiusSm}">
<TextBlock Classes="installer-icon"
Text="&#xE896;"
Foreground="{DynamicResource InstallerOnAccentBrush}"
FontSize="16" />
</Border>
<TextBlock Text="{Binding WindowTitle}"
FontSize="13"
FontWeight="SemiBold"
VerticalAlignment="Center" />
</StackPanel>
<StackPanel Grid.Column="2"
Orientation="Horizontal"
Spacing="2"
Margin="0,0,8,0"
VerticalAlignment="Center">
<Button Classes="titlebar-icon-button"
ToolTip.Tip="最小化"
Click="OnMinimizeClick">
<TextBlock Classes="installer-icon"
Text="&#xE921;"
FontSize="14" />
</Button>
<Button Classes="titlebar-icon-button"
ToolTip.Tip="关闭"
Click="OnCloseClick">
<TextBlock Classes="installer-icon"
Text="&#xE711;"
FontSize="14" />
</Button>
</StackPanel>
</Grid>
</Border>
<Grid Grid.Row="1"
ColumnDefinitions="260,10,*"
Margin="10,0,10,10">
<Border Grid.Column="0"
Background="{DynamicResource InstallerPaneBackgroundBrush}"
CornerRadius="{DynamicResource DesignCornerRadiusLg}"
Padding="22,24">
<Grid RowDefinitions="Auto,*,Auto">
<StackPanel Spacing="8">
<TextBlock Text="阑山桌面"
FontSize="22"
FontWeight="SemiBold" />
<TextBlock Text="在线安装程序"
Classes="caption-text" />
</StackPanel>
<ItemsControl Grid.Row="1"
Margin="0,28,0,0"
ItemsSource="{Binding Steps}">
<ItemsControl.ItemTemplate>
<DataTemplate x:DataType="vm:InstallerStepViewModel">
<Button Classes="step-nav-item"
Command="{Binding #Root.DataContext.SelectStepCommand}"
CommandParameter="{Binding}"
IsEnabled="{Binding IsUnlocked}">
<Grid MinHeight="40">
<Border Classes="step-nav-selected-fill"
IsVisible="{Binding IsSelected}" />
<Grid ColumnDefinitions="Auto,*"
ColumnSpacing="10"
Margin="10,0">
<Grid Width="18"
VerticalAlignment="Center">
<TextBlock Classes="installer-icon"
Text="{Binding IconGlyph}"
Foreground="{DynamicResource InstallerTextSecondaryBrush}"
FontSize="17"
IsVisible="{Binding !IsSelected}" />
<TextBlock Classes="installer-icon"
Text="{Binding IconGlyph}"
Foreground="{DynamicResource InstallerTextPrimaryBrush}"
FontSize="17"
IsVisible="{Binding IsSelected}" />
</Grid>
<Grid Grid.Column="1"
VerticalAlignment="Center">
<TextBlock Classes="step-title"
Text="{Binding Title}"
IsVisible="{Binding !IsSelected}" />
<TextBlock Classes="step-title"
Text="{Binding Title}"
Foreground="{DynamicResource InstallerTextPrimaryBrush}"
IsVisible="{Binding IsSelected}" />
</Grid>
</Grid>
</Grid>
</Button>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
<TextBlock Grid.Row="2"
Classes="caption-text"
Text="安装期间请保持网络连接。下载失败时可返回上一步重新检查。" />
</Grid>
</Border>
<Border Grid.Column="2"
Background="{DynamicResource InstallerContentBackgroundBrush}"
CornerRadius="{DynamicResource DesignCornerRadiusLg}"
ClipToBounds="True">
<Grid RowDefinitions="*,Auto"
Background="Transparent">
<ScrollViewer Grid.Row="0"
Padding="36,34,42,24"
VerticalScrollBarVisibility="Auto">
<Grid>
<Grid Classes="step-page"
IsVisible="{Binding IsWelcomeStep}">
<StackPanel Classes="installer-page-container">
<StackPanel Spacing="8">
<TextBlock Classes="page-title-text"
Text="安装阑山桌面" />
<TextBlock Classes="page-description-text"
Text="在线安装程序会获取最新完整包,并把应用部署到本机版本目录。" />
</StackPanel>
<Border Classes="content-card">
<Grid ColumnDefinitions="Auto,*"
ColumnSpacing="14">
<Border Width="40"
Height="40"
Background="{DynamicResource InstallerSubtleFillBrush}"
CornerRadius="{DynamicResource DesignCornerRadiusMd}">
<TextBlock Classes="installer-icon"
Text="&#xE896;"
FontSize="20" />
</Border>
<StackPanel Grid.Column="1"
Spacing="6">
<TextBlock Text="准备开始"
FontSize="16"
FontWeight="SemiBold" />
<TextBlock Text="安装器会检查最新版本、下载完整包、校验文件并激活部署。"
Classes="muted" />
</StackPanel>
</Grid>
</Border>
</StackPanel>
</Grid>
<Grid Classes="step-page"
IsVisible="{Binding IsLocationStep}">
<StackPanel Classes="installer-page-container">
<StackPanel Spacing="8">
<TextBlock Classes="page-title-text"
Text="选择安装位置" />
<TextBlock Classes="page-description-text"
Text="请选择一个专用文件夹。默认位置需要管理员权限,和现有安装方式保持一致。" />
</StackPanel>
<Border Classes="content-card">
<StackPanel Spacing="16">
<StackPanel Spacing="6">
<TextBlock Text="安装目录"
FontSize="16"
FontWeight="SemiBold" />
<TextBlock Text="安装根目录下会创建 .Launcher 和 app-{version}-0。"
Classes="muted" />
</StackPanel>
<Grid ColumnDefinitions="*,Auto"
ColumnSpacing="10">
<TextBox Text="{Binding InstallPath, Mode=TwoWay}"
PlaceholderText="安装路径" />
<Button Grid.Column="1"
Classes="secondary-command"
Command="{Binding BrowseCommand}">
<StackPanel Orientation="Horizontal"
Spacing="6">
<TextBlock Classes="installer-icon"
Text="&#xE838;" />
<TextBlock Text="浏览" />
</StackPanel>
</Button>
</Grid>
<CheckBox IsChecked="{Binding CreateDesktopShortcut}"
Content="创建桌面快捷方式" />
<CheckBox IsChecked="{Binding CreateStartupShortcut}"
Content="开机时自动启动阑山桌面" />
</StackPanel>
</Border>
</StackPanel>
</Grid>
<Grid Classes="step-page"
IsVisible="{Binding IsPrivacyStep}">
<StackPanel Classes="installer-page-container">
<StackPanel Spacing="8">
<TextBlock Classes="page-title-text"
Text="确认数据使用" />
<TextBlock Classes="page-description-text"
Text="安装阶段需要使用匿名设备码和基础请求信息,用于安装、风控和用户量统计。" />
</StackPanel>
<Border Classes="content-card">
<StackPanel Spacing="16">
<StackPanel Spacing="6">
<TextBlock Text="匿名设备码"
FontSize="16"
FontWeight="SemiBold" />
<TextBlock Text="{Binding DeviceIdPreview}"
TextWrapping="Wrap"
FontFamily="Consolas"
Foreground="{DynamicResource InstallerTextSecondaryBrush}" />
</StackPanel>
<Border Classes="info-panel">
<Grid ColumnDefinitions="Auto,*"
ColumnSpacing="10">
<TextBlock Classes="installer-icon"
Text="&#xEA18;"
Foreground="{DynamicResource InstallerAccentBrush}"
FontSize="18" />
<TextBlock Grid.Column="1"
Text="安装器会发送匿名设备码、系统与架构信息、目标版本和请求 IP不会上传用户名、机器名或安装目录。"
Classes="muted" />
</Grid>
</Border>
<CheckBox IsChecked="{Binding PrivacyConfirmed}"
Content="我确认上述匿名数据可用于安装、风控和用户量统计。" />
</StackPanel>
</Border>
</StackPanel>
</Grid>
<Grid Classes="step-page"
IsVisible="{Binding IsDeployStep}">
<StackPanel Classes="installer-page-container">
<StackPanel Spacing="8">
<TextBlock Classes="page-title-text"
Text="开始部署" />
<TextBlock Classes="page-description-text"
Text="安装时会下载完整包,并写入当前版本目录。" />
</StackPanel>
<Border Classes="content-card">
<StackPanel Spacing="18">
<Grid ColumnDefinitions="Auto,*"
RowDefinitions="Auto,Auto,Auto"
ColumnSpacing="18"
RowSpacing="10">
<TextBlock Classes="meta-label"
Text="版本" />
<TextBlock Grid.Column="1"
Classes="meta-value"
Text="{Binding TargetVersion}" />
<Border Grid.Row="1"
Grid.ColumnSpan="2"
Classes="separator" />
<TextBlock Grid.Row="2"
Classes="meta-label"
Text="来源" />
<TextBlock Grid.Row="2"
Grid.Column="1"
Classes="meta-value"
Text="{Binding SourceId}" />
</Grid>
<StackPanel Spacing="8">
<TextBlock Text="{Binding StatusText}"
FontWeight="SemiBold" />
<ProgressBar Minimum="0"
Maximum="1"
Value="{Binding DownloadProgress}" />
<TextBlock Classes="caption-text"
Text="{Binding DownloadBytesText}" />
</StackPanel>
<StackPanel Spacing="8">
<TextBlock Text="安装进度"
FontWeight="SemiBold" />
<ProgressBar Minimum="0"
Maximum="1"
Value="{Binding InstallProgress}" />
<TextBlock Classes="caption-text"
Text="{Binding CurrentFile}" />
</StackPanel>
<StackPanel Orientation="Horizontal"
Spacing="8">
<Button Classes="primary-command"
Command="{Binding StartInstallCommand}">
<StackPanel Orientation="Horizontal"
Spacing="6">
<TextBlock Classes="installer-icon"
Text="&#xE896;" />
<TextBlock Text="开始安装" />
</StackPanel>
</Button>
<Button Classes="secondary-command"
Command="{Binding CancelInstallCommand}"
IsEnabled="{Binding IsInstalling}">
<StackPanel Orientation="Horizontal"
Spacing="6">
<TextBlock Classes="installer-icon"
Text="&#xE711;" />
<TextBlock Text="取消" />
</StackPanel>
</Button>
</StackPanel>
</StackPanel>
</Border>
</StackPanel>
</Grid>
<Grid Classes="step-page"
IsVisible="{Binding IsCompleteStep}">
<StackPanel Classes="installer-page-container">
<StackPanel Spacing="8">
<TextBlock Classes="page-title-text"
Text="完成安装" />
<TextBlock Classes="page-description-text"
Text="阑山桌面已经部署完成。" />
</StackPanel>
<Border Classes="content-card">
<Grid ColumnDefinitions="Auto,*"
ColumnSpacing="14">
<Border Width="40"
Height="40"
Background="{DynamicResource InstallerSubtleFillBrush}"
CornerRadius="{DynamicResource DesignCornerRadiusMd}">
<TextBlock Classes="installer-icon"
Text="&#xE73E;"
Foreground="{DynamicResource InstallerSuccessBrush}"
FontSize="22" />
</Border>
<StackPanel Grid.Column="1"
Spacing="12">
<StackPanel Spacing="5">
<TextBlock Text="可以启动应用"
FontSize="16"
FontWeight="SemiBold" />
<TextBlock Text="使用 Launcher 进入首次启动流程。"
Classes="muted" />
</StackPanel>
<Button Classes="primary-command"
HorizontalAlignment="Left"
Command="{Binding LaunchCommand}">
<StackPanel Orientation="Horizontal"
Spacing="6">
<TextBlock Classes="installer-icon"
Text="&#xE768;" />
<TextBlock Text="打开阑山桌面" />
</StackPanel>
</Button>
</StackPanel>
</Grid>
</Border>
</StackPanel>
</Grid>
</Grid>
</ScrollViewer>
<Border Grid.Row="1"
Background="Transparent"
Padding="36,16,42,18">
<Grid ColumnDefinitions="*,Auto,Auto"
ColumnSpacing="8">
<Border Classes="error-bar"
IsVisible="{Binding HasError}">
<Grid ColumnDefinitions="Auto,*"
ColumnSpacing="10">
<TextBlock Classes="installer-icon"
Text="&#xE783;"
Foreground="{DynamicResource InstallerErrorBrush}"
FontSize="18" />
<TextBlock Grid.Column="1"
Text="{Binding ErrorMessage}"
Foreground="{DynamicResource InstallerErrorBrush}"
TextWrapping="Wrap"
VerticalAlignment="Center" />
</Grid>
</Border>
<Button Grid.Column="1"
Classes="secondary-command"
Command="{Binding BackCommand}">
<StackPanel Orientation="Horizontal"
Spacing="6">
<TextBlock Classes="installer-icon"
Text="&#xE72B;" />
<TextBlock Text="上一步" />
</StackPanel>
</Button>
<Button Grid.Column="2"
Classes="primary-command"
Command="{Binding NextCommand}">
<StackPanel Orientation="Horizontal"
Spacing="6">
<TextBlock Text="下一步" />
<TextBlock Classes="installer-icon"
Text="&#xE72A;" />
</StackPanel>
</Button>
</Grid>
</Border>
</Grid>
</Border>
</Grid>
</Grid>
</Border>
</Window>