Files
LanMountainDesktop/LanMountainDesktop/Views/SettingsPages/GeneralSettingsPage.axaml
lincube 33591a0a63 Add startup visual modes and attempt registry
Implement startup visual behavior, de-duplicate startup attempts, and improve failure UX.

Key changes:
- Add spec and docs for startup visuals and timing contract (.trae/specs and docs/LAUNCHER_STARTUP_VISUALS.md).
- Introduce StartupVisualPreferences contract and resolver; create SplashWindow via resolved mode.
- Add StartupAttemptRecord model and a file-backed StartupAttemptRegistry to persist and coordinate in-progress startup attempts (attach/adopt, soft/hard timeouts, IPC/connect state, lifecycle updates).
- Update LauncherFlowCoordinator to: adopt/attach to existing attempts, track IPC connection and soft/hard timeouts (30s/120s), show delayed UI state, attempt foreground recovery via public IPC, compose detailed launch result metadata, and mark registry states (soft timeout, detached waiting, succeeded, failed).
- Add TryActivateExistingInstanceAsync to attempt activating an existing desktop via IPC.
- Change failure flow: ShowFailureWindowAsync now returns user choice; ErrorWindow updated to present Activate/Wait/Open Logs/Exit semantics and new layouts/styles; improved button wiring and debug/dev mode handling.
- Add UI and resource tweaks (ErrorWindow and SplashWindow changes), project asset link for nightly logo, and unit tests for StartupVisualPreferences.

These changes prevent duplicate desktop processes during slow startups, provide clearer UX for delayed startups, and persist startup attempt state across Launcher invocations for safer recovery/attach behavior.
2026-04-23 09:03:35 +08:00

143 lines
7.2 KiB
XML

<UserControl xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:vm="using:LanMountainDesktop.ViewModels"
xmlns:controls="using:LanMountainDesktop.Controls"
xmlns:ui="using:FluentAvalonia.UI.Controls"
xmlns:fi="using:FluentIcons.Avalonia.Fluent"
x:Class="LanMountainDesktop.Views.SettingsPages.GeneralSettingsPage"
x:DataType="vm:GeneralSettingsPageViewModel">
<ScrollViewer VerticalScrollBarVisibility="Auto">
<StackPanel Classes="settings-page-container settings-page-animated">
<controls:IconText Icon="Globe"
Text="{Binding BasicHeader}"
Margin="0,0,0,4" />
<ui:SettingsExpander Header="{Binding LanguageHeader}">
<ui:SettingsExpander.IconSource>
<fi:SymbolIconSource Symbol="Settings" />
</ui:SettingsExpander.IconSource>
<ui:SettingsExpander.Footer>
<ComboBox Width="220"
ItemsSource="{Binding Languages}"
SelectedItem="{Binding SelectedLanguage}">
<ComboBox.ItemTemplate>
<DataTemplate x:DataType="vm:SelectionOption">
<TextBlock Text="{Binding Label}" />
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
</ui:SettingsExpander.Footer>
</ui:SettingsExpander>
<ui:SettingsExpander Header="{Binding TimeZoneHeader}"
Description="{Binding TimeZoneDescription}">
<ui:SettingsExpander.IconSource>
<fi:SymbolIconSource Symbol="Clock" />
</ui:SettingsExpander.IconSource>
<ui:SettingsExpander.Footer>
<ComboBox Width="240"
ItemsSource="{Binding TimeZones}"
SelectedItem="{Binding SelectedTimeZone}">
<ComboBox.ItemTemplate>
<DataTemplate x:DataType="vm:TimeZoneOption">
<TextBlock Text="{Binding Label}" />
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
</ui:SettingsExpander.Footer>
</ui:SettingsExpander>
<ui:SettingsExpander Header="{Binding PreviewHeader}">
<ui:SettingsExpander.IconSource>
<fi:SymbolIconSource Symbol="Calendar" />
</ui:SettingsExpander.IconSource>
<ui:SettingsExpanderItem>
<Grid ColumnDefinitions="Auto,*"
ColumnSpacing="16"
RowDefinitions="Auto,Auto"
RowSpacing="12">
<TextBlock FontWeight="SemiBold"
Text="{Binding PreviewTimeLabel}" />
<TextBlock Grid.Column="1"
Opacity="0.82"
Text="{Binding PreviewTimeText}" />
<TextBlock Grid.Row="1"
FontWeight="SemiBold"
Text="{Binding PreviewDateLabel}" />
<TextBlock Grid.Row="1"
Grid.Column="1"
Opacity="0.82"
Text="{Binding PreviewDateText}" />
</Grid>
</ui:SettingsExpanderItem>
</ui:SettingsExpander>
<Separator Classes="settings-separator" />
<controls:IconText Icon="DeveloperBoard"
Text="{Binding RuntimeHeader}"
Margin="0,0,0,4" />
<ui:SettingsExpander Header="{Binding RenderModeHeader}"
Description="{Binding RuntimeDescription}"
IsExpanded="True">
<ui:SettingsExpander.IconSource>
<fi:SymbolIconSource Symbol="DeveloperBoard" />
</ui:SettingsExpander.IconSource>
<ui:SettingsExpander.Footer>
<ComboBox Width="220"
ItemsSource="{Binding RenderModes}"
SelectedItem="{Binding SelectedRenderMode}">
<ComboBox.ItemTemplate>
<DataTemplate x:DataType="vm:SelectionOption">
<TextBlock Text="{Binding Label}" />
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
</ui:SettingsExpander.Footer>
<ui:SettingsExpanderItem>
<TextBlock Text="{Binding RenderModeRestartMessage}"
Opacity="0.7"
FontSize="12"
TextWrapping="Wrap" />
</ui:SettingsExpanderItem>
</ui:SettingsExpander>
<ui:SettingsExpander Header="淡入淡出效果"
Description="{Binding FadeTransitionDescription}"
IsVisible="{Binding IsSlideTransitionAvailable}">
<ui:SettingsExpander.IconSource>
<fi:SymbolIconSource Symbol="ArrowUpload" />
</ui:SettingsExpander.IconSource>
<ui:SettingsExpander.Footer>
<ToggleSwitch IsChecked="{Binding EnableFadeTransition}"
IsEnabled="{Binding IsFadeTransitionToggleEnabled}" />
</ui:SettingsExpander.Footer>
</ui:SettingsExpander>
<ui:SettingsExpander Header="启动滑入滑出效果"
Description="启用后,启动和恢复时从屏幕右侧边缘滑入或滑出,仅 Windows 可用。"
IsVisible="{Binding IsSlideTransitionAvailable}">
<ui:SettingsExpander.IconSource>
<fi:SymbolIconSource Symbol="ArrowRight" />
</ui:SettingsExpander.IconSource>
<ui:SettingsExpander.Footer>
<ToggleSwitch IsChecked="{Binding EnableSlideTransition}" />
</ui:SettingsExpander.Footer>
</ui:SettingsExpander>
<ui:SettingsExpander Header="桌面主窗口在任务栏显示图标"
Description="仅控制桌面主窗口在系统任务栏中的图标显示,不影响设置窗口。">
<ui:SettingsExpander.IconSource>
<fi:SymbolIconSource Symbol="Window" />
</ui:SettingsExpander.IconSource>
<ui:SettingsExpander.Footer>
<ToggleSwitch IsChecked="{Binding ShowInTaskbar}" />
</ui:SettingsExpander.Footer>
</ui:SettingsExpander>
</StackPanel>
</ScrollViewer>
</UserControl>