完善音乐下载、下载管理和开发工具
This commit is contained in:
@@ -19,6 +19,7 @@ public sealed class DevEnvironmentConfigToolPage : ToolPageBase
|
||||
private readonly Action? _goBack;
|
||||
private readonly IDevEnvironmentDetectionService _detection = AppServices.GetRequiredService<IDevEnvironmentDetectionService>();
|
||||
private readonly IDevEnvironmentCatalogService _catalog = AppServices.GetRequiredService<IDevEnvironmentCatalogService>();
|
||||
private readonly IDevTerminalSetupService _terminalSetup = AppServices.GetRequiredService<IDevTerminalSetupService>();
|
||||
private readonly IDownloadManagerService _downloads = AppServices.GetRequiredService<IDownloadManagerService>();
|
||||
private readonly StackPanel _environmentList = new() { Spacing = 12 };
|
||||
private readonly TextBlock _statusText = ModernUi.Text(AppLocalizer.T("准备检测开发环境。", "Ready to detect development environments."), 14, foreground: ModernUi.TextSecondary);
|
||||
@@ -26,6 +27,12 @@ public sealed class DevEnvironmentConfigToolPage : ToolPageBase
|
||||
private readonly Dictionary<string, ComboBox> _sourceBoxes = new(StringComparer.OrdinalIgnoreCase);
|
||||
private readonly Dictionary<string, Button> _quickButtons = new(StringComparer.OrdinalIgnoreCase);
|
||||
private readonly Dictionary<string, Button> _sourceButtons = new(StringComparer.OrdinalIgnoreCase);
|
||||
private readonly TextBlock _terminalStatus = ModernUi.Text(AppLocalizer.T("正在检测终端环境...", "Checking terminal environment..."), 14, FontWeights.SemiBold);
|
||||
private readonly TextBlock _terminalDetail = ModernUi.Text(string.Empty, 12, foreground: ModernUi.TextSecondary, maxLines: 3);
|
||||
private readonly ProgressBar _terminalProgress = new() { Minimum = 0, Maximum = 100, Visibility = Visibility.Collapsed };
|
||||
private Button? _terminalInstallButton;
|
||||
private Button? _terminalOpenButton;
|
||||
private DevTerminalSnapshot? _terminalSnapshot;
|
||||
private IReadOnlyDictionary<string, DetectedDevEnvironment> _detected = new Dictionary<string, DetectedDevEnvironment>();
|
||||
private IReadOnlyDictionary<string, IReadOnlyList<DevEnvironmentVersion>> _versions = new Dictionary<string, IReadOnlyList<DevEnvironmentVersion>>();
|
||||
|
||||
@@ -58,6 +65,7 @@ public sealed class DevEnvironmentConfigToolPage : ToolPageBase
|
||||
back: _goBack,
|
||||
backTooltip: AppLocalizer.T("返回上一级", "Back"),
|
||||
meta: _statusText));
|
||||
root.Children.Add(BuildTerminalSetupCard());
|
||||
root.Children.Add(_environmentList);
|
||||
|
||||
return new ScrollViewer
|
||||
@@ -68,6 +76,63 @@ public sealed class DevEnvironmentConfigToolPage : ToolPageBase
|
||||
};
|
||||
}
|
||||
|
||||
private Border BuildTerminalSetupCard()
|
||||
{
|
||||
_terminalInstallButton = ModernUi.PillButton(
|
||||
AppLocalizer.T("安装 / 修复", "Install / repair"),
|
||||
"\uE896",
|
||||
async () => await InstallTerminalAsync(),
|
||||
primary: true);
|
||||
_terminalOpenButton = ModernUi.PillButton(
|
||||
AppLocalizer.T("打开终端", "Open terminal"),
|
||||
"\uE756",
|
||||
async () => await OpenTerminalAsync());
|
||||
var refresh = ModernUi.IconButton("\uE72C", AppLocalizer.T("重新检测终端", "Check terminal again"), async () => await RefreshTerminalAsync());
|
||||
var actions = new StackPanel
|
||||
{
|
||||
Orientation = Orientation.Horizontal,
|
||||
Spacing = 8,
|
||||
Children = { _terminalInstallButton, _terminalOpenButton, refresh }
|
||||
};
|
||||
|
||||
var top = new Grid { ColumnSpacing = 14 };
|
||||
top.ColumnDefinitions.Add(new ColumnDefinition { Width = GridLength.Auto });
|
||||
top.ColumnDefinitions.Add(new ColumnDefinition());
|
||||
top.ColumnDefinitions.Add(new ColumnDefinition { Width = GridLength.Auto });
|
||||
top.Children.Add(ModernUi.IconTile("\uE756", 44, ModernUi.AccentSoft, ModernUi.Accent, 19));
|
||||
var copy = new StackPanel
|
||||
{
|
||||
Spacing = 3,
|
||||
Children =
|
||||
{
|
||||
ModernUi.Text(AppLocalizer.T("Windows 终端环境", "Windows terminal environment"), 18, FontWeights.SemiBold),
|
||||
_terminalStatus,
|
||||
_terminalDetail
|
||||
}
|
||||
};
|
||||
Grid.SetColumn(copy, 1);
|
||||
top.Children.Add(copy);
|
||||
Grid.SetColumn(actions, 2);
|
||||
top.Children.Add(actions);
|
||||
|
||||
return ModernUi.Card(new StackPanel
|
||||
{
|
||||
Spacing = 12,
|
||||
Children =
|
||||
{
|
||||
top,
|
||||
_terminalProgress,
|
||||
ModernUi.Text(
|
||||
AppLocalizer.T(
|
||||
"安装 Windows Terminal 与 PowerShell 7;系统支持时自动设置默认终端和默认 PowerShell 配置。",
|
||||
"Install Windows Terminal and PowerShell 7, then configure supported default terminal settings."),
|
||||
12,
|
||||
foreground: ModernUi.TextSecondary,
|
||||
maxLines: 2)
|
||||
}
|
||||
}, new Thickness(16), radius: 8);
|
||||
}
|
||||
|
||||
private async Task ReloadAsync()
|
||||
{
|
||||
_statusText.Text = AppLocalizer.T("正在检测本机环境并读取官方版本信息...", "Detecting local environments and reading official version metadata...");
|
||||
@@ -76,7 +141,9 @@ public sealed class DevEnvironmentConfigToolPage : ToolPageBase
|
||||
|
||||
try
|
||||
{
|
||||
var detected = await _detection.DetectAsync();
|
||||
var terminalTask = _terminalSetup.DetectAsync();
|
||||
var detectedTask = _detection.DetectAsync();
|
||||
var detected = await detectedTask;
|
||||
_detected = detected.ToDictionary(item => item.Id, StringComparer.OrdinalIgnoreCase);
|
||||
|
||||
var versionPairs = await Task.WhenAll(_catalog.Definitions.Select(async definition =>
|
||||
@@ -85,6 +152,7 @@ public sealed class DevEnvironmentConfigToolPage : ToolPageBase
|
||||
return (definition.Id, Versions: versions);
|
||||
}));
|
||||
_versions = versionPairs.ToDictionary(item => item.Id, item => item.Versions, StringComparer.OrdinalIgnoreCase);
|
||||
ApplyTerminalSnapshot(await terminalTask);
|
||||
|
||||
Render();
|
||||
}
|
||||
@@ -99,6 +167,146 @@ public sealed class DevEnvironmentConfigToolPage : ToolPageBase
|
||||
}
|
||||
}
|
||||
|
||||
private async Task RefreshTerminalAsync()
|
||||
{
|
||||
SetTerminalBusy(true, AppLocalizer.T("正在检测终端环境...", "Checking terminal environment..."));
|
||||
try
|
||||
{
|
||||
ApplyTerminalSnapshot(await _terminalSetup.DetectAsync());
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
_terminalStatus.Text = AppLocalizer.T("终端检测失败", "Terminal check failed");
|
||||
_terminalDetail.Text = AppLocalizer.SanitizeSensitiveText(exception.Message, 180);
|
||||
}
|
||||
finally
|
||||
{
|
||||
SetTerminalBusy(false);
|
||||
}
|
||||
}
|
||||
|
||||
private async Task InstallTerminalAsync()
|
||||
{
|
||||
if (XamlRoot is null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var dialog = new ContentDialog
|
||||
{
|
||||
XamlRoot = XamlRoot,
|
||||
Title = AppLocalizer.T("安装终端套件?", "Install terminal suite?"),
|
||||
Content = ModernUi.Text(
|
||||
AppLocalizer.T(
|
||||
"将安装或升级 Windows Terminal 与 PowerShell 7,并在系统支持时更新当前用户的 PATH 和默认终端设置。安装包仅从微软官方来源获取。",
|
||||
"Windows Terminal and PowerShell 7 will be installed or upgraded from official Microsoft sources. Supported PATH and default-terminal settings will be updated for the current user."),
|
||||
13,
|
||||
foreground: ModernUi.TextSecondary,
|
||||
maxLines: 5),
|
||||
PrimaryButtonText = AppLocalizer.T("继续", "Continue"),
|
||||
CloseButtonText = AppLocalizer.T("取消", "Cancel"),
|
||||
DefaultButton = ContentDialogButton.Primary
|
||||
};
|
||||
if (await dialog.ShowAsync() != ContentDialogResult.Primary)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
SetTerminalBusy(true, AppLocalizer.T("正在准备终端安装...", "Preparing terminal setup..."));
|
||||
try
|
||||
{
|
||||
var progress = new Progress<DevTerminalInstallProgress>(item =>
|
||||
{
|
||||
_terminalProgress.Value = item.Percent;
|
||||
_terminalStatus.Text = AppLocalizer.T(item.Message switch
|
||||
{
|
||||
"Checking the current terminal environment..." => "正在检查当前终端环境...",
|
||||
"Installing or upgrading Windows Terminal..." => "正在安装或升级 Windows Terminal...",
|
||||
"Installing or upgrading PowerShell 7..." => "正在安装或升级 PowerShell 7...",
|
||||
"Refreshing PATH and verifying terminal commands..." => "正在刷新 PATH 并验证终端命令...",
|
||||
"Configuring Windows Terminal defaults..." => "正在配置默认终端...",
|
||||
"Terminal setup completed." => "终端配置已完成。",
|
||||
_ => item.Message
|
||||
}, item.Message);
|
||||
});
|
||||
var result = await _terminalSetup.InstallOrRepairAsync(progress);
|
||||
ApplyTerminalSnapshot(result.Snapshot);
|
||||
if (result.Succeeded)
|
||||
{
|
||||
ToastService.Show(AppLocalizer.T("终端套件已配置。", "Terminal suite configured."), ToastKind.Success);
|
||||
}
|
||||
else
|
||||
{
|
||||
_terminalDetail.Text = string.Join(" ", result.Messages.Append(AppLocalizer.T("请查看状态后重试失败的组件。", "Review the status and retry the failed component.")));
|
||||
ToastService.Show(AppLocalizer.T("终端套件仅完成了部分配置。", "Terminal setup completed partially."), ToastKind.Warning);
|
||||
}
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
_terminalStatus.Text = AppLocalizer.T("终端安装失败", "Terminal setup failed");
|
||||
_terminalDetail.Text = AppLocalizer.SanitizeSensitiveText(exception.Message, 200);
|
||||
ToastService.Show(AppLocalizer.T("终端安装失败,请查看详细状态。", "Terminal setup failed. Review the status details."), ToastKind.Warning);
|
||||
}
|
||||
finally
|
||||
{
|
||||
SetTerminalBusy(false);
|
||||
}
|
||||
}
|
||||
|
||||
private async Task OpenTerminalAsync()
|
||||
{
|
||||
if (!await _terminalSetup.OpenTerminalAsync())
|
||||
{
|
||||
ToastService.Show(AppLocalizer.T("无法启动终端。", "Could not start a terminal."), ToastKind.Warning);
|
||||
}
|
||||
}
|
||||
|
||||
private void ApplyTerminalSnapshot(DevTerminalSnapshot snapshot)
|
||||
{
|
||||
_terminalSnapshot = snapshot;
|
||||
var terminal = snapshot.WindowsTerminalInstalled
|
||||
? $"Windows Terminal {ValueOrDash(snapshot.WindowsTerminalVersion)}"
|
||||
: AppLocalizer.T("Windows Terminal 未安装", "Windows Terminal not installed");
|
||||
var powershell = snapshot.PowerShellInstalled
|
||||
? $"PowerShell {ValueOrDash(snapshot.PowerShellVersion)}"
|
||||
: AppLocalizer.T("PowerShell 7 未安装", "PowerShell 7 not installed");
|
||||
_terminalStatus.Text = $"{terminal} · {powershell}";
|
||||
|
||||
var defaultState = !snapshot.SupportsDefaultTerminal
|
||||
? AppLocalizer.T($"Windows {snapshot.WindowsBuild} 不支持系统默认终端切换", $"Windows {snapshot.WindowsBuild} does not support changing the system default terminal")
|
||||
: snapshot.IsWindowsTerminalDefault
|
||||
? AppLocalizer.T("Windows Terminal 已设为默认", "Windows Terminal is the default")
|
||||
: AppLocalizer.T("尚未设为默认终端", "Not yet the default terminal");
|
||||
var profileState = snapshot.IsPowerShellDefaultProfile
|
||||
? AppLocalizer.T("PowerShell 7 默认配置已启用", "PowerShell 7 default profile enabled")
|
||||
: AppLocalizer.T("PowerShell 7 默认配置待设置", "PowerShell 7 default profile pending");
|
||||
_terminalDetail.Text = $"{defaultState} · {profileState} · {snapshot.Architecture}";
|
||||
if (_terminalOpenButton is not null)
|
||||
{
|
||||
_terminalOpenButton.IsEnabled = snapshot.PowerShellInstalled || snapshot.WindowsTerminalInstalled;
|
||||
}
|
||||
}
|
||||
|
||||
private void SetTerminalBusy(bool busy, string? message = null)
|
||||
{
|
||||
if (_terminalInstallButton is not null)
|
||||
{
|
||||
_terminalInstallButton.IsEnabled = !busy;
|
||||
}
|
||||
if (_terminalOpenButton is not null)
|
||||
{
|
||||
_terminalOpenButton.IsEnabled = !busy && (_terminalSnapshot?.IsReady == true || _terminalSnapshot?.PowerShellInstalled == true);
|
||||
}
|
||||
_terminalProgress.Visibility = busy ? Visibility.Visible : Visibility.Collapsed;
|
||||
_terminalProgress.IsIndeterminate = busy && _terminalProgress.Value <= 0;
|
||||
if (!string.IsNullOrWhiteSpace(message))
|
||||
{
|
||||
_terminalStatus.Text = message;
|
||||
}
|
||||
}
|
||||
|
||||
private static string ValueOrDash(string value) => string.IsNullOrWhiteSpace(value) ? "--" : value;
|
||||
|
||||
private void Render()
|
||||
{
|
||||
_versionBoxes.Clear();
|
||||
@@ -229,6 +437,14 @@ public sealed class DevEnvironmentConfigToolPage : ToolPageBase
|
||||
return;
|
||||
}
|
||||
|
||||
if (string.Equals(candidate.Source.SourceKind, "Manual", StringComparison.OrdinalIgnoreCase) ||
|
||||
string.Equals(Path.GetExtension(candidate.Source.FileName), ".url", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
await Launcher.LaunchUriAsync(uri);
|
||||
ToastService.Show(AppLocalizer.T("已打开官方下载安装页面。", "Opened the official download page."), ToastKind.Success);
|
||||
return;
|
||||
}
|
||||
|
||||
var plan = _catalog.CreateInstallPlan(definition.Id, version, candidate);
|
||||
var item = await _downloads.EnqueueAsync(
|
||||
candidate.Source,
|
||||
@@ -236,7 +452,8 @@ public sealed class DevEnvironmentConfigToolPage : ToolPageBase
|
||||
InstallCommand: mode == DevEnvironmentInstallMode.QuickInstall ? "installer" : null,
|
||||
InstallArguments: plan.InstallArguments,
|
||||
IsInstaller: mode == DevEnvironmentInstallMode.QuickInstall,
|
||||
DeleteAfterInstall: mode == DevEnvironmentInstallMode.QuickInstall));
|
||||
DeleteAfterInstall: mode == DevEnvironmentInstallMode.QuickInstall,
|
||||
OpenKind: mode == DevEnvironmentInstallMode.QuickInstall ? DownloadOpenKind.Installer : DownloadOpenKind.File));
|
||||
|
||||
ToastService.Show(AppLocalizer.T("已加入下载管理。", "Added to Download Manager."), ToastKind.Success);
|
||||
if (mode == DevEnvironmentInstallMode.SourceBuild)
|
||||
|
||||
Reference in New Issue
Block a user