feat(updater): 优化更新体验与 UI

- ui: UpdateBadge 使用 Tailwind 内置过渡,支持点击打开设置,保留图标动画

- updater: 新增 UpdateContext 首启延迟检查,忽略版本键名命名空间化(含旧键迁移),并发保护

- settings: 去除版本硬编码回退;检测到更新时复用 updateHandle 下载并安装,并新增常显“更新日志”入口

- a11y: 更新徽标支持键盘触达(Enter/Space)

- refactor: 移除未使用的 runUpdateFlow 导出

- chore: 类型检查通过,整体行为与权限边界未改变
This commit is contained in:
Jason
2025-09-10 19:46:38 +08:00
parent bf7e13d4e9
commit af8b9289fe
8 changed files with 321 additions and 68 deletions

View File

@@ -0,0 +1,59 @@
import { X, Sparkles } from "lucide-react";
import { useUpdate } from "../contexts/UpdateContext";
interface UpdateBadgeProps {
className?: string;
onClick?: () => void; // 点击徽标的回调(例如打开设置)
}
export function UpdateBadge({ className = "", onClick }: UpdateBadgeProps) {
const { hasUpdate, updateInfo, isDismissed, dismissUpdate } = useUpdate();
// 如果没有更新或已关闭,不显示
if (!hasUpdate || isDismissed || !updateInfo) {
return null;
}
return (
<div
className={`
flex items-center gap-2 px-3 py-1.5
bg-gradient-to-r from-blue-500/20 to-purple-500/20
border border-blue-500/30
rounded-full text-xs
transition-all duration-200
${onClick ? "cursor-pointer hover:border-blue-400/50" : ""}
${className}
`}
role={onClick ? "button" : undefined}
tabIndex={onClick ? 0 : -1}
onClick={onClick}
onKeyDown={(e) => {
if (!onClick) return;
if (e.key === "Enter" || e.key === " ") {
e.preventDefault();
onClick();
}
}}
>
<Sparkles className="w-3 h-3 text-blue-400 animate-pulse" />
<span className="text-gray-200 font-medium">
{updateInfo.availableVersion}
</span>
<button
onClick={(e) => {
e.stopPropagation();
dismissUpdate();
}}
className="
-mr-1 p-0.5 rounded-full
hover:bg-white/10 transition-colors
focus:outline-none focus:ring-2 focus:ring-blue-500/50
"
aria-label="关闭更新提醒"
>
<X className="w-3 h-3 text-gray-400 hover:text-gray-200" />
</button>
</div>
);
}