From 43da421bea175347e943096491ac382c8bad466d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=94=A1=E5=8F=8A?= <522caiji@gmail.com> Date: Mon, 7 Sep 2026 00:19:20 +0800 Subject: [PATCH 1/2] feat: show compact System version history with plain update copy Let the System page open one recent release at a time, restore the three previous versions, and walk updates as download, update now, then a refresh countdown. --- CHANGELOG.md | 6 + frontend/src/api/system.ts | 8 + frontend/src/components/VersionHistory.tsx | 87 +++++++ frontend/src/i18n/messages.ts | 232 ++++++++++-------- frontend/src/index.css | 5 + frontend/src/lib/versionHistory.ts | 34 +++ frontend/src/pages/SystemPage.tsx | 71 ++++-- internal/update/checker.go | 2 + internal/update/checker_test.go | 3 + internal/update/version.go | 92 +++++++ internal/update/version_test.go | 24 ++ ...t-Dm4Ws2an.js => TrafficChart-BOzMl3v0.js} | 2 +- .../webui/static/assets/index-C6XMRF2t.js | 25 -- ...{index-BzVhVn-Z.css => index-Cjx4mhrj.css} | 2 +- .../webui/static/assets/index-DIkWt7GR.js | 28 +++ internal/webui/static/index.html | 4 +- 16 files changed, 476 insertions(+), 149 deletions(-) create mode 100644 frontend/src/components/VersionHistory.tsx create mode 100644 frontend/src/lib/versionHistory.ts rename internal/webui/static/assets/{TrafficChart-Dm4Ws2an.js => TrafficChart-BOzMl3v0.js} (99%) delete mode 100644 internal/webui/static/assets/index-C6XMRF2t.js rename internal/webui/static/assets/{index-BzVhVn-Z.css => index-Cjx4mhrj.css} (98%) create mode 100644 internal/webui/static/assets/index-DIkWt7GR.js diff --git a/CHANGELOG.md b/CHANGELOG.md index ce8fa42..005d466 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,8 +7,14 @@ Write each change in both `### English` and `### 中文` under `## Unreleased`. ### English +- Show a compact version history on the System page: one release open at a time, with notes and restore for the three previous versions +- Use plain update copy on the System page: download the update, tap Update now, then refresh after a short countdown + ### 中文 +- 系统页用折叠列表展示近期版本:一次只展开一条,可看说明,并可恢复到最近三个旧版本 +- 系统页更新文案改为普通说法:先下载更新,再点立即更新,完成后倒计时刷新页面 + ## 0.3.0 - 2026-09-06 ### English diff --git a/frontend/src/api/system.ts b/frontend/src/api/system.ts index 372f095..90c51dc 100644 --- a/frontend/src/api/system.ts +++ b/frontend/src/api/system.ts @@ -33,6 +33,14 @@ export type SystemUpdateInfo = { rollback_versions?: Array<{ tag_name: string name?: string + body?: string + published_at?: string + html_url?: string + }> + recent_releases?: Array<{ + tag_name: string + name?: string + body?: string published_at?: string html_url?: string }> diff --git a/frontend/src/components/VersionHistory.tsx b/frontend/src/components/VersionHistory.tsx new file mode 100644 index 0000000..1e83363 --- /dev/null +++ b/frontend/src/components/VersionHistory.tsx @@ -0,0 +1,87 @@ +import { Accordion, Button, Chip } from '@heroui/react' +import { ReleaseNotes } from '@/components/ReleaseNotes' +import { extractReleaseNotes } from '@/lib/releaseNotes' +import { useI18n } from '@/hooks/useI18n' +import type { Lang } from '@/i18n/messages' +import type { VersionHistoryRelease } from '@/lib/versionHistory' + +function formatReleaseDate(value: string | undefined, lang: Lang) { + if (!value) return '' + const date = new Date(value) + if (Number.isNaN(date.getTime())) return '' + return date.toLocaleDateString(lang === 'zh' ? 'zh-CN' : 'en-US', { year: 'numeric', month: 'short', day: 'numeric' }) +} + +export function VersionHistory({ + releases, + currentVersion, + nextVersion, + rollbackTags, + canRollback, + submitting, + onRestore, +}: { + releases: VersionHistoryRelease[] + currentVersion: string + nextVersion?: string + rollbackTags: string[] + canRollback: boolean + submitting: boolean + onRestore: (version: string) => void +}) { + const { t, lang } = useI18n() + if (!releases.length) return null + + const featured = nextVersion && nextVersion !== currentVersion ? nextVersion : currentVersion + const defaultExpanded = releases.some((release) => release.tag_name === featured) + ? featured + : releases[0]?.tag_name + const rollbackSet = new Set(rollbackTags) + + return ( +
{t('versionHistory')}
+{t('versionHistoryHint')}
+{t('updateUnavailableHint')}
: null} {info?.agent?.available && !info.agent.staged_update && !busy ?{t('updateLegacyOneShotHint')}
: null} - {canRollback ? ( -{t('rollbackToVersion')}
-{t('rollbackToVersionHint')}
-{updateStateText}{targetVersion ? ` · ${targetVersion}` : ''}{elapsed ? ` · ${t('updateElapsed', { seconds: elapsed })}` : ''}
: null} -{reloadIn != null ? t('updateReloadingHint') : readyToApply ? t('updateReadyTargetHint', { version: targetVersion || info?.next_version || '' }) : applying ? t('updateApplyingHint') : t('updatePreparingImageHint')}
+{statusHint}
{newerThanPrepared ?{t('updateNewerReleaseHint', { latest: info?.next_version || '' })}
: null} {info?.update?.error || info?.agent?.error ?{info?.update?.error || info?.agent?.error}
: null}