🐛 fix(about): 移除重复更新日志入口 (#834) (#843)

## 关联 Issue

Fixes #834

## 问题根因

V2
设置中心的“关于”页面已经在版本信息区域提供“查看更新日志”链接,但底部复用了旧版关于弹窗的操作集合,额外再次渲染了同名按钮,造成入口重复并增加页面纵向占用。

## 修复方案

为关于页底部操作集合区分页面形态:V2
设置中心隐藏重复的底部更新日志按钮,保留版本信息区域的入口;旧版独立关于弹窗继续保留原有更新日志按钮。新增回归测试覆盖两种页面形态的入口策略。

## 验证结果

| 验证项 | 命令或步骤 | 结果 |
| --- | --- | --- |
| 回归测试(修复前) | `npm --prefix frontend test --
src/utils/aboutUpdateActions.test.ts` | 按预期失败:设置中心仍返回显示更新日志入口 |
| 相关前端测试 | `npm --prefix frontend test --
src/utils/aboutUpdateActions.test.ts
src/hooks/useAppUpdateManager.test.tsx
src/components/UpdateReleaseNotesModal.test.tsx
src/App.tool-center.test.ts` | 通过,32 tests |
| 前端构建 | `npm --prefix frontend run build` | 通过,TypeScript 与 Vite 构建成功 |
| 完整前端测试 | `npm --prefix frontend test` | 通过,445 test files / 3748 tests
|
| Web Server 健康检查 | 隔离临时数据根目录启动 `go run . web-server --addr
127.0.0.1:34117`,请求 `GET /__gonavi/healthz` | 通过,HTTP 200 / `ok` |
| 桌面视口 UI 验证 | Web Server 登录后进入 Settings → About,视口 `1280×720` |
通过:`View release notes` 按钮数量为 1;页面
`scrollWidth=clientWidth=1280`、`scrollHeight=clientHeight=720`;截图确认底部仅保留检查和下载操作
|
| 窄屏视口 UI 验证 | 同一路径,视口 `390×844` | 通过入口验收:按钮数量为 1;页面
`scrollWidth=clientWidth=390`、`scrollHeight=clientHeight=844`。同时观察到设置中心既有双栏内容在窄屏下挤压,该布局不在本次
diff 范围内,未混入本 PR |

## 风险与兼容性

仅调整 V2 设置中心底部操作按钮的显示条件,不改变更新检查、更新日志弹窗、下载或旧版关于弹窗行为;不涉及数据、配置、公共 API
或依赖。窄屏双栏布局的既有显示问题仍需单独评估。

## 回滚方式

回滚提交 `a0f84fd6e364daa4db50eac2291861ffa9da80c0` 即可恢复原有入口显示逻辑,不影响数据或配置。
This commit is contained in:
Syngnat
2026-08-05 14:33:33 +08:00
committed by GitHub
3 changed files with 26 additions and 3 deletions

View File

@@ -22,6 +22,10 @@ import {
isReleaseNotesRead,
markReleaseNotesRead,
} from './utils/updateReleaseNotesReadState';
import {
shouldShowFooterReleaseNotesAction,
type AboutUpdateActionsSurface,
} from './utils/aboutUpdateActions';
import { type DataSyncEntryMode } from './components/dataSyncEntryMode';
import DriverManagerModal from './components/DriverManagerModal';
import LinuxCJKFontBanner from './components/LinuxCJKFontBanner';
@@ -5408,14 +5412,17 @@ function App() {
) : null
);
const renderAboutUpdateActions = (closeAction?: React.ReactNode) => [
const renderAboutUpdateActions = (
surface: AboutUpdateActionsSurface,
closeAction?: React.ReactNode,
) => [
isBackgroundProgressForLatestUpdate && !isLatestUpdateDownloaded ? (
<Button key="progress" icon={<DownloadOutlined />} onClick={showUpdateDownloadProgress}>{t('app.about.action.download_progress')}</Button>
) : null,
lastUpdateInfo?.hasUpdate && !isLatestUpdateDownloaded && !isBackgroundProgressForLatestUpdate ? (
<Button key="mute" onClick={muteLatestUpdate}>{t('app.about.action.mute_this_version')}</Button>
) : null,
renderReleaseNotesActionButton(),
shouldShowFooterReleaseNotesAction(surface) ? renderReleaseNotesActionButton() : null,
<Button
key="check"
icon={<CloudDownloadOutlined />}
@@ -5812,7 +5819,7 @@ function App() {
</span>
</div>
<div style={{ display: 'flex', justifyContent: 'flex-end', alignItems: 'center', gap: 12, flexWrap: 'wrap' }}>
{renderAboutUpdateActions()}
{renderAboutUpdateActions('settings-center')}
</div>
</>
);
@@ -9202,6 +9209,7 @@ function App() {
onCancel={() => setIsAboutOpen(false)}
styles={{ content: utilityModalShellStyle, header: { background: 'transparent', borderBottom: 'none', paddingBottom: 8 }, body: { paddingTop: 8 }, footer: { background: 'transparent', borderTop: 'none', paddingTop: 10, display: 'flex', flexWrap: 'wrap', gap: 10, justifyContent: 'flex-end' } }}
footer={renderAboutUpdateActions(
'legacy-modal',
<Button key="close" onClick={() => setIsAboutOpen(false)}>{t('common.close')}</Button>,
)}
>

View File

@@ -0,0 +1,10 @@
import { describe, expect, it } from 'vitest';
import { shouldShowFooterReleaseNotesAction } from './aboutUpdateActions';
describe('aboutUpdateActions', () => {
it('keeps release notes in the legacy modal footer only', () => {
expect(shouldShowFooterReleaseNotesAction('legacy-modal')).toBe(true);
expect(shouldShowFooterReleaseNotesAction('settings-center')).toBe(false);
});
});

View File

@@ -0,0 +1,5 @@
export type AboutUpdateActionsSurface = 'settings-center' | 'legacy-modal';
export const shouldShowFooterReleaseNotesAction = (
surface: AboutUpdateActionsSurface,
): boolean => surface === 'legacy-modal';