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]