Skip to content

refactor(desktop): rebuild the About page as labeled settings groups - #4571

Merged
Astro-Han merged 7 commits into
mainfrom
feat/about-page-hierarchy
Sep 2, 2026
Merged

refactor(desktop): rebuild the About page as labeled settings groups#4571
Astro-Han merged 7 commits into
mainfrom
feat/about-page-hierarchy

Conversation

@Astro-Han

@Astro-Han Astro-Han commented Sep 2, 2026

Copy link
Copy Markdown
Contributor

Summary

The About page was the only settings page built outside SettingsSection: a bespoke hero with two Badges, three hand-written Dividers, two-column Grids, and a primary button on a support action. The release channel — the first thing a nightly user needs to know — was a pill label, and a dev build's "does not check for updates" sentence rendered twice.

This rebuilds the page as the settings-sidebar template's anatomy — a lead group plus labeled row groups — and makes the channel the lead:

  • Lead group: product name with a channel Token (nightly orange, dev gray, release unmarked), version and build as supporting text, and one sentence on what the channel means. Astryx's Badge guidance excludes versions and dates; Token carries categorical state.
  • Update status sits in the same group, one line with a secondary check button: nightly's steady state is "downloaded, restart from the sidebar", not "up to date". Runtime, OS and workspace path are not repeated here; the diagnostics report and the Data page already carry them.
  • Support: three quiet row actions (ghost copy + shortcut, issue link, shortcuts link). No primary button remains on the page.
  • Privacy: consolidate five bullets into three and relabel the group, preserving the existing privacy commitments.

The diagnostics report gains a Channel: line, read from the packaged manifest through a helper that degrades to unknown rather than throwing, so the report still copies when the manifest itself is broken. PageHeader in @maka/ui lost its last caller and is removed with its styles, and the page's own stylesheet goes with the icon plate it styled; nothing on the page is styled outside Astryx now.

Before (main) vs. after (this branch), dev build, same viewport:

Before and after, dev build

The two packaged channels are new Storybook variants with no main counterpart; nightly (left) vs. release (right):

After, nightly and release

Verification

  • npm run format, npm run lint at the root: clean.
  • apps/desktop: npm run typecheck (preload, main, renderer, storybook), npm run test:dist (1971 pass, 0 fail), npx playwright test about-page.spec.ts (1 passed).
  • node apps/desktop/scripts/check-renderer-architecture.mjs: passed, ledger unchanged.
  • Storybook: product-settings-pages--about, --about-nightly, --about-release, light and dark, 1280 wide (screenshots above).

AI use

Select exactly one:

  • No generative tool made a substantive contribution
  • Generative tooling made a substantive contribution

Tool(s) and scope: Claude Code drafted the page, stories, tests, and this description under review.

Checklist

  • Tests cover the change and fail without it
  • Lint, format, typecheck and the affected suites pass locally

Does this PR entail a change in behavior?

  • Yes — described under Summary above
  • No

… mode

The About page mapped `buildMode === 'packaged'` to 正式版, so a packaged
nightly install (version `0.2.0-dev.<run>.<date>`) wore a release badge that
contradicted its own version string. Build mode and release channel answer
different questions - how the binary was produced vs which feed it follows -
and the page only ever saw the former.

`app:info` now carries `updateChannel`, resolved from the packaged manifest by
the same `desktopUpdateChannelFromManifest` parse that drives the updater, so
the pill and the update feed share one authority. The pill logic moves into a
pure `aboutChannelBadge` helper: nightly → Nightly (orange), release → 正式版
(blue), dev → 本地开发版 · commit (neutral, a checkout is not a release
artifact either).

Generated-by: Maka
…late anatomy

The old page had no focus: five privacy bullets opened it, the actions a user
actually needs were scattered (update check mid-page, diagnostics + shortcut +
issue link crammed into one bottom row), and the page promised 运行环境 without
showing any. A dev build also printed the same 本地开发版不检查 GitHub 发布
更新 sentence twice - once as row detail, once as help text.

The page now follows the vendored Astryx pages/settings template anatomy:
two-column Grid sections (Heading 3 + supporting lede left, content right) with
a bare Divider between sections, and no row hairlines - the kit makes dividers
opt-in everywhere. Facts (channel / runtime / workspace) render as a
MetadataList, the same label-to-value construction the MCP detail panel uses.
Order follows the page's real jobs: identity facts, software updates, support
and diagnostics (merged from the old 参考 + 版本信息 sections), privacy last,
compressed from five bullets to three. Support stays outside the info
conditional so diagnostics remain copyable when app.info fails - the state the
existing SSR test locks in.

The channel pill's helper moves into about-update-status.ts instead of a new
module: the architecture ledger forbids growing the legacy AppShell closure,
and this was that module's seam already. The ledger shrinks by the two
dependencies the page no longer imports.

Generated-by: Maka
The diagnostics report printed `Build: packaged @ <sha>`, which cannot tell a nightly install from a release one — the two channels update from different feeds and reproduce different bugs. Read the channel from the packaged manifest through a total helper that degrades to `unknown` instead of throwing, because the report must still copy when the manifest itself is what broke.
The About page was the only settings page that bypassed `SettingsSection`: a bespoke hero with two Badges, three hand-written Dividers, two-column Grids, and a primary button on a support action. The release channel — the one fact a nightly user needs first — was a pill label.

Make the channel the page's lead: a Token next to the product name (nightly orange, dev gray, release unmarked), the version and build as supporting text, and one sentence on what the channel means. Every group below is a `SettingsSection`: update status as a single row, version facts as a bare MetadataList with the workspace path collapsed to `~`, support as three quiet row actions, and the privacy list. No Badge, Grid, Divider, or primary button remains; Astryx's Badge guidance excludes versions and dates, and Token carries categorical state.

`PageHeader` in `@maka/ui` lost its last caller and is removed with its styles. Stories gain packaged nightly and release variants so both channels render in Storybook; the About e2e and channel tests follow the new structure.
@github-actions github-actions Bot added the effort/L Under 1000 readable lines label Sep 2, 2026
The rebuilt About page had five groups, and three of them restated
something the reader already had.

The 版本信息 readout repeated the lead verbatim — channel, version and
build are the two lines directly above it — while its remaining two rows
are answered better elsewhere: the runtime triple and the workspace path
are both in the diagnostic report the 支持 group copies, and the
workspace path is the 数据 page's own subject. A five-row MetadataList
that duplicates its own header and defers on the rest is not a group.

软件更新 was a titled group around a single status sentence. Its title
named what the sentence already said, and its lede promised background
checks the sidebar prompt delivers. The status line and its 检查更新
button move into the lead, where they read as one more fact about this
install rather than a section of their own.

隐私 keeps its title and its three commitments; the lede under it only
counted them.

That leaves the lead (unlabeled — the page title says 关于), 支持 and
本地优先 · 隐私默认: two anchor hairlines instead of four, and no group
whose content is available one click away. The copy keys the removed
rows owned go with them, along with the release channel's name string —
a release install wears no token, so nothing renders it. 复制诊断信息's
helper line drops its inventory of report fields for the two facts that
govern the decision: it is redacted, and it only reaches the clipboard.
The lead's 48px Sparkles plate was the page's last hand-written CSS, and
it decorated a heading that already reads as the product's name. Its
whole file goes with it: about.css held nothing else after the hero,
heading row and tagline rules were retired, so the stylesheet and its
@import in settings.css are gone too. About now renders with zero
`.settings*` selectors of its own.

The generated ledgers follow the two deletions: the renderer
architecture entry loses `@maka/ui/icons`, and the Astryx surface
inventory drops page-header.tsx (removed with the About rebuild) and
about.css. Both were regenerated, not hand-edited.
@Astro-Han
Astro-Han marked this pull request as ready for review September 2, 2026 15:27

@Sun-GLiang Sun-GLiang left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review notes focused on the public UI contract, failure-path coverage, and PR/spec consistency.

Comment thread packages/ui/src/index.ts
Comment thread apps/desktop/src/main/app-update-attestation.ts
Comment thread apps/desktop/src/renderer/locales/settings-preferences-copy.ts
…row controls

Three findings from the adversarial review and the ablation, plus their
consequences.

A dev checkout said the same thing twice in a row: the channel sentence
("本地开发构建,不检查更新。") and, immediately under it, the updater's own
"本地开发版不检查 GitHub 发布更新。请使用正式安装包。" beside a permanently
disabled button. The update row now renders only where it can act, so the
channel sentence carries the fact alone. With no caller left,
`aboutUpdateStatusDetail` loses its `isDevBuild` short-circuit and
`updateDevBuildHelp` is gone.

The three row-end controls were named "复制" / "打开" / "查看" — verbs that
mean nothing without the row label a screen reader reads separately.
Each now carries an aria-label naming what it acts on.

`desktopDiagnosticUpdateChannel` shipped with no test at all. It has one
now, over a real manifest in a temp directory: both packaged feeds, the
unpackaged checkout, and the three ways a manifest can fail to name a
channel. Replacing the body with `return 'unknown'` fails it.

The ablation's removals: `wrap="wrap"` on the lead row (its content is
129px against a 380px floor — it can never wrap), `align="start"` on the
status row (pixel-identical at every width), the e2e's `正式版` count-0
assertion (that string no longer exists in any copy), and the story
fixture's `homePath` (About shows no path since the version readout went;
its only consumer is the 工作区 page, whose story does not need it).

Also: `about-settings-page.test.ts` matched the row label rather than the
button, so deleting the button kept it green; `copyHelp` gets the
workspace-path clause back, because the report does carry a `Workspace:`
line and the user decides before clicking; and `packages/ui/README.md`
stopped importing the deleted `PageHeader` in its barrel example.

@jackwener jackwener left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I reviewed this at b942c6f00c50da68640384cfc3d85d598292e9f9. No P0 or P1. One P2, already inlined by Sun-GLiang and still present.

About was the one settings page built outside SettingsSection. Rebuilding it as a lead group plus labeled rows, putting the release channel in that lead, dropping the restated version table and the duplicate dev "does not update" sentence, and deleting PageHeader with its last caller is the smaller cut. Support stays reachable when app.info fails. Row-end controls are named by the row, not by the verb on their face.

Sun-GLiang's other two P2s are closed on this head: packages/ui/README.md no longer imports PageHeader, and desktopDiagnosticUpdateChannel is tested for missing, malformed, and invalid-channel manifests returning unknown without throwing.

Still present: Privacy is not an unchanged list. main has five bullets; this head consolidates them into three. The facts are the same (local data and credentials, no telemetry, explicit permission plus local retention). The E2E test even says "three commitments, not the old wall of five bullets." Describe that consolidation in the summary, or put the five bullets back.

Refactor. Hosted test is green. MERGEABLE. I am not merging it.

简体中文

我审的是 b942c6f00c50da68640384cfc3d85d598292e9f9。没有 P0/P1。一条 P2,Sun-GLiang 已行内,本 head 仍在。

关于页收回 SettingsSection、频道放到 lead、删掉重复的版本表和开发版「不检查更新」第二句、PageHeader 随最后调用方一起删,切法对。Support 不依赖 app.info

另外两条 P2 在本 head 已关上:README 不再 import PageHeader;诊断频道 fallback 有测试。

仍在:隐私不是「未改清单」。main 五条,这里收成三条,事实还在,摘要写错了。E2E 自己也写了「不是旧的五条」。改摘要,或改回五条。

这是重构。hosted test 绿。我不合入。


Automated review notice: This comment was posted by an automated review agent operated by WAWQAQ. It is not an independent human review and does not replace one.

Comment thread apps/desktop/e2e/about-page.spec.ts

@hqhq1025 hqhq1025 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed exact head b942c6f00c50da68640384cfc3d85d598292e9f9. No P0/P1 blockers and no new code findings.

The current head correctly distinguishes packaged release/nightly channels through the same manifest authority used by the updater, keeps diagnostics copyable through an unknown fallback, and keeps support actions reachable when app.info fails. The prior README and fallback-test comments are fixed on this head. The existing inline P2 about the PR summary saying Privacy: unchanged list while the implementation consolidates five bullets into three remains an editorial mismatch; I did not duplicate it.

Validation covered a clean install, build:test, full typecheck, 38 focused tests, changed-file Biome, renderer architecture, Astryx inventory, ASF headers, git diff --check, the About Electron E2E under Xvfb, and a clean synthetic merge onto current main. Hosted test is green. I did not validate the visual result in a real signed nightly/release installation.


Review notice: This review was prepared by an automated review agent operated by hqhq1025 and is published at the direction of AstroHan, who has read these findings and is the human accountable for them.

@Astro-Han
Astro-Han merged commit c86da40 into main Sep 2, 2026
1 of 2 checks passed
@Astro-Han
Astro-Han deleted the feat/about-page-hierarchy branch September 2, 2026 17:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

effort/L Under 1000 readable lines

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants