mirror of
https://github.com/babalae/better-genshin-impact.git
synced 2026-05-19 09:35:48 +08:00
feat: 为过时的脚本仓库弹窗提醒,提供更新按钮并避免直接打开 (#2460)
This commit is contained in:
85
BetterGenshinImpact/View/Windows/RepoUpdateDialog.xaml
Normal file
85
BetterGenshinImpact/View/Windows/RepoUpdateDialog.xaml
Normal file
@@ -0,0 +1,85 @@
|
||||
<ui:FluentWindow x:Class="BetterGenshinImpact.View.Windows.RepoUpdateDialog"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:ui="http://schemas.lepo.co/wpfui/2022/xaml"
|
||||
Width="520"
|
||||
Height="280"
|
||||
MinWidth="400"
|
||||
MinHeight="240"
|
||||
ui:Design.Background="{DynamicResource ApplicationBackgroundBrush}"
|
||||
ui:Design.Foreground="{DynamicResource TextFillColorPrimaryBrush}"
|
||||
ExtendsContentIntoTitleBar="True"
|
||||
FontFamily="{DynamicResource TextThemeFontFamily}"
|
||||
ResizeMode="NoResize"
|
||||
WindowStartupLocation="CenterOwner"
|
||||
WindowStyle="SingleBorderWindow"
|
||||
mc:Ignorable="d">
|
||||
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="*" />
|
||||
<RowDefinition Height="Auto" />
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<!-- 标题栏 -->
|
||||
<ui:TitleBar Grid.Row="0"
|
||||
Title="{Binding Title, RelativeSource={RelativeSource AncestorType=Window}}"
|
||||
ShowMaximize="False"
|
||||
ShowMinimize="False">
|
||||
<ui:TitleBar.Icon>
|
||||
<ui:ImageIcon Source="pack://application:,,,/Resources/Images/logo.png" />
|
||||
</ui:TitleBar.Icon>
|
||||
</ui:TitleBar>
|
||||
|
||||
<!-- 内容区域 -->
|
||||
<Grid Grid.Row="1" Margin="24,12,24,12">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition Width="*" />
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<!-- 图标 -->
|
||||
<ui:SymbolIcon Grid.Column="0"
|
||||
Symbol="Warning24"
|
||||
FontSize="48"
|
||||
Foreground="{DynamicResource SystemFillColorAttentionBrush}"
|
||||
VerticalAlignment="Center"
|
||||
Margin="0,0,16,0" />
|
||||
|
||||
<!-- 消息内容 -->
|
||||
<ui:TextBlock Grid.Column="1"
|
||||
x:Name="MessageTextBlock"
|
||||
TextAlignment="Left"
|
||||
TextWrapping="Wrap"
|
||||
FontSize="14"
|
||||
VerticalAlignment="Center"
|
||||
Foreground="{DynamicResource TextFillColorPrimaryBrush}" />
|
||||
</Grid>
|
||||
|
||||
<!-- 按钮区域 -->
|
||||
<StackPanel Grid.Row="2"
|
||||
Orientation="Horizontal"
|
||||
HorizontalAlignment="Center"
|
||||
Margin="24,0,24,24">
|
||||
|
||||
<!-- 立即更新按钮 -->
|
||||
<ui:Button x:Name="PrimaryButton"
|
||||
Content="立即更新"
|
||||
Appearance="Primary"
|
||||
MinWidth="100"
|
||||
Margin="0,0,8,0"
|
||||
Click="PrimaryButton_Click" />
|
||||
|
||||
<!-- 直接打开按钮 -->
|
||||
<ui:Button x:Name="SecondaryButton"
|
||||
Content="直接打开"
|
||||
Appearance="Secondary"
|
||||
MinWidth="100"
|
||||
IsEnabled="False"
|
||||
Click="SecondaryButton_Click" />
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
</ui:FluentWindow>
|
||||
125
BetterGenshinImpact/View/Windows/RepoUpdateDialog.xaml.cs
Normal file
125
BetterGenshinImpact/View/Windows/RepoUpdateDialog.xaml.cs
Normal file
@@ -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;
|
||||
|
||||
/// <summary>
|
||||
/// 仓库更新提示对话框
|
||||
/// </summary>
|
||||
public partial class RepoUpdateDialog : Wpf.Ui.Controls.FluentWindow
|
||||
{
|
||||
private System.Windows.Threading.DispatcherTimer? _dialogTimer;
|
||||
private int _remainingSeconds;
|
||||
private readonly int _daysSinceUpdate;
|
||||
private TaskCompletionSource<MessageBoxResult>? _taskCompletionSource;
|
||||
|
||||
/// <summary>
|
||||
/// 初始化仓库更新提示对话框
|
||||
/// </summary>
|
||||
/// <param name="daysSinceUpdate">距上次更新的天数</param>
|
||||
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);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 显示对话框并等待结果
|
||||
/// </summary>
|
||||
public Task<MessageBoxResult> ShowDialogAsync()
|
||||
{
|
||||
_taskCompletionSource = new TaskCompletionSource<MessageBoxResult>();
|
||||
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();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 启动对话框定时器
|
||||
/// </summary>
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 停止对话框定时器
|
||||
/// </summary>
|
||||
private void StopDialogTimer()
|
||||
{
|
||||
if (_dialogTimer != null)
|
||||
{
|
||||
_dialogTimer.Tick -= OnTimerTick;
|
||||
_dialogTimer.Stop();
|
||||
_dialogTimer = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -315,7 +315,8 @@
|
||||
Command="{Binding OpenLocalScriptRepoCommand}"
|
||||
Content="打开仓库"
|
||||
Icon="{ui:SymbolIcon BookStar24}"
|
||||
HorizontalAlignment="Center" />
|
||||
HorizontalAlignment="Center"
|
||||
IsEnabled="{Binding IsUpdating, Converter={StaticResource InverseBooleanConverter}}" />
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Grid>
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 检查仓库更新时间并提示用户
|
||||
/// </summary>
|
||||
/// <returns>是否继续打开仓库(true: 继续打开, false: 取消操作)</returns>
|
||||
private async Task<bool> 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]
|
||||
|
||||
Reference in New Issue
Block a user