From 00dc48d8473b5d5293b1db2ddb86dbac019b9653 Mon Sep 17 00:00:00 2001 From: ShadowLemoon <119576779+ShadowLemoon@users.noreply.github.com> Date: Fri, 14 Nov 2025 21:45:26 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E4=B8=BA=E8=BF=87=E6=97=B6=E7=9A=84?= =?UTF-8?q?=E8=84=9A=E6=9C=AC=E4=BB=93=E5=BA=93=E5=BC=B9=E7=AA=97=E6=8F=90?= =?UTF-8?q?=E9=86=92=EF=BC=8C=E6=8F=90=E4=BE=9B=E6=9B=B4=E6=96=B0=E6=8C=89?= =?UTF-8?q?=E9=92=AE=E5=B9=B6=E9=81=BF=E5=85=8D=E7=9B=B4=E6=8E=A5=E6=89=93?= =?UTF-8?q?=E5=BC=80=20(#2460)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../View/Windows/RepoUpdateDialog.xaml | 85 ++++++++++++ .../View/Windows/RepoUpdateDialog.xaml.cs | 125 ++++++++++++++++++ .../View/Windows/ScriptRepoWindow.xaml | 3 +- .../View/Windows/ScriptRepoWindow.xaml.cs | 76 ++++++++++- 4 files changed, 283 insertions(+), 6 deletions(-) create mode 100644 BetterGenshinImpact/View/Windows/RepoUpdateDialog.xaml create mode 100644 BetterGenshinImpact/View/Windows/RepoUpdateDialog.xaml.cs diff --git a/BetterGenshinImpact/View/Windows/RepoUpdateDialog.xaml b/BetterGenshinImpact/View/Windows/RepoUpdateDialog.xaml new file mode 100644 index 00000000..9875aa80 --- /dev/null +++ b/BetterGenshinImpact/View/Windows/RepoUpdateDialog.xaml @@ -0,0 +1,85 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/BetterGenshinImpact/View/Windows/RepoUpdateDialog.xaml.cs b/BetterGenshinImpact/View/Windows/RepoUpdateDialog.xaml.cs new file mode 100644 index 00000000..970fbeaa --- /dev/null +++ b/BetterGenshinImpact/View/Windows/RepoUpdateDialog.xaml.cs @@ -0,0 +1,125 @@ +using System; +using System.Threading.Tasks; +using System.Windows; +using BetterGenshinImpact.Helpers.Ui; +using MessageBoxResult = Wpf.Ui.Controls.MessageBoxResult; + +namespace BetterGenshinImpact.View.Windows; + +/// +/// 仓库更新提示对话框 +/// +public partial class RepoUpdateDialog : Wpf.Ui.Controls.FluentWindow +{ + private System.Windows.Threading.DispatcherTimer? _dialogTimer; + private int _remainingSeconds; + private readonly int _daysSinceUpdate; + private TaskCompletionSource? _taskCompletionSource; + + /// + /// 初始化仓库更新提示对话框 + /// + /// 距上次更新的天数 + public RepoUpdateDialog(int daysSinceUpdate) + { + _daysSinceUpdate = daysSinceUpdate; + + InitializeComponent(); + + // 配置窗口属性 + Title = "仓库更新提示"; + MessageTextBlock.Text = $"脚本仓库已经 {daysSinceUpdate} 天未更新\n\n温馨提示:\n脚本内容跟随仓库版本,旧版仓库会订阅到旧版脚本。\n更新仓库后需要重新订阅脚本,以更新脚本内容。\n\n是否立即更新?"; + Owner = Application.Current.MainWindow; + + // 注册事件 + SourceInitialized += OnSourceInitialized; + Loaded += OnLoaded; + Closed += OnClosed; + } + + private void OnSourceInitialized(object? sender, EventArgs e) + { + WindowHelper.TryApplySystemBackdrop(this); + } + + private void OnLoaded(object sender, RoutedEventArgs e) + { + // 计算倒计时秒数:30 天为 5 秒,超过 30 天每多 2 天增加 1 秒 + _remainingSeconds = 5 + (_daysSinceUpdate - 30) / 2; + SecondaryButton.Content = $"直接打开 ({_remainingSeconds}s)"; + StartDialogTimer(); + } + + private void OnClosed(object? sender, EventArgs e) + { + StopDialogTimer(); + _taskCompletionSource?.TrySetResult(MessageBoxResult.None); + } + + /// + /// 显示对话框并等待结果 + /// + public Task ShowDialogAsync() + { + _taskCompletionSource = new TaskCompletionSource(); + ShowDialog(); + return _taskCompletionSource.Task; + } + + private void PrimaryButton_Click(object sender, RoutedEventArgs e) + { + _taskCompletionSource?.TrySetResult(MessageBoxResult.Primary); + Close(); + } + + private void SecondaryButton_Click(object sender, RoutedEventArgs e) + { + _taskCompletionSource?.TrySetResult(MessageBoxResult.Secondary); + Close(); + } + + /// + /// 启动对话框定时器 + /// + private void StartDialogTimer() + { + // 创建定时器 + _dialogTimer = new System.Windows.Threading.DispatcherTimer + { + Interval = TimeSpan.FromSeconds(1) + }; + + _dialogTimer.Tick += OnTimerTick; + _dialogTimer.Start(); + } + + private void OnTimerTick(object? sender, EventArgs e) + { + _remainingSeconds--; + + if (_remainingSeconds > 0) + { + SecondaryButton.Content = $"直接打开 ({_remainingSeconds}s)"; + } + else + { + // 倒计时结束,启用按钮 + SecondaryButton.Content = "直接打开"; + SecondaryButton.IsEnabled = true; + _dialogTimer?.Stop(); + } + } + + /// + /// 停止对话框定时器 + /// + private void StopDialogTimer() + { + if (_dialogTimer != null) + { + _dialogTimer.Tick -= OnTimerTick; + _dialogTimer.Stop(); + _dialogTimer = null; + } + } +} diff --git a/BetterGenshinImpact/View/Windows/ScriptRepoWindow.xaml b/BetterGenshinImpact/View/Windows/ScriptRepoWindow.xaml index c9928c12..8088a148 100644 --- a/BetterGenshinImpact/View/Windows/ScriptRepoWindow.xaml +++ b/BetterGenshinImpact/View/Windows/ScriptRepoWindow.xaml @@ -315,7 +315,8 @@ Command="{Binding OpenLocalScriptRepoCommand}" Content="打开仓库" Icon="{ui:SymbolIcon BookStar24}" - HorizontalAlignment="Center" /> + HorizontalAlignment="Center" + IsEnabled="{Binding IsUpdating, Converter={StaticResource InverseBooleanConverter}}" /> diff --git a/BetterGenshinImpact/View/Windows/ScriptRepoWindow.xaml.cs b/BetterGenshinImpact/View/Windows/ScriptRepoWindow.xaml.cs index 70a3a5ec..6c09fd51 100644 --- a/BetterGenshinImpact/View/Windows/ScriptRepoWindow.xaml.cs +++ b/BetterGenshinImpact/View/Windows/ScriptRepoWindow.xaml.cs @@ -256,7 +256,7 @@ public partial class ScriptRepoWindow IsUpdating = true; UpdateProgressValue = 0; UpdateProgressText = "准备更新,请耐心等待..."; - + // 执行更新 var (_, updated) = await ScriptRepoUpdater.Instance.UpdateCenterRepoByGit(repoUrl, (path, steps, totalSteps) => @@ -289,11 +289,77 @@ public partial class ScriptRepoWindow } [RelayCommand] - private void OpenLocalScriptRepo() + private async Task OpenLocalScriptRepo() { - TaskContext.Instance().Config.ScriptConfig.ScriptRepoHintDotVisible = false; - ScriptRepoUpdater.Instance.OpenLocalRepoInWebView(); - Close(); + // 检查是否需要提示用户更新仓库 + var shouldContinue = await CheckAndPromptRepoUpdate(); + if (shouldContinue) + { + TaskContext.Instance().Config.ScriptConfig.ScriptRepoHintDotVisible = false; + ScriptRepoUpdater.Instance.OpenLocalRepoInWebView(); + Close(); + } + } + + /// + /// 检查仓库更新时间并提示用户 + /// + /// 是否继续打开仓库(true: 继续打开, false: 取消操作) + private async Task CheckAndPromptRepoUpdate() + { + TimeSpan timeSinceUpdate; + try + { + // 检查仓库文件夹是否存在 + if (!Directory.Exists(ScriptRepoUpdater.CenterRepoPath)) + { + return true; + } + + // 查找 repo.json 文件 + var repoJsonPath = Directory.GetFiles(ScriptRepoUpdater.CenterRepoPath, "repo.json", SearchOption.AllDirectories).FirstOrDefault(); + if (repoJsonPath == null || !File.Exists(repoJsonPath)) + { + return true; + } + + // 获取 repo.json 文件的最后修改时间 + var repoJsonFile = new FileInfo(repoJsonPath); + DateTime lastUpdateTime = repoJsonFile.LastWriteTime; + + // 检查是否超过 30 天 + timeSinceUpdate = DateTime.Now - lastUpdateTime; + if (timeSinceUpdate.TotalDays <= 30) + { + return true; + } + } + catch + { + // 出现异常时,继续打开仓库 + return true; + } + + // 提示用户更新 + var dialog = new RepoUpdateDialog((int)timeSinceUpdate.TotalDays); + var result = await dialog.ShowDialogAsync(); + + if (result == Wpf.Ui.Controls.MessageBoxResult.Primary) + { + // 用户选择"立即更新" + await UpdateRepo(); + return false; + } + else if (result == Wpf.Ui.Controls.MessageBoxResult.Secondary) + { + // 用户选择"直接打开" + return true; + } + else + { + // 用户关闭对话框(点击 X 或按 ESC) + return false; + } } [RelayCommand]