From 509a3e17bdb6de9d17f99305cb60b84d62c0918a Mon Sep 17 00:00:00 2001 From: Mohamed Boudra Date: Wed, 9 Sep 2026 15:23:01 +0200 Subject: [PATCH] feat(app): read the changelog in the app instead of the browser (#4576) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit What's new opens an adaptive sheet — bottom sheet on compact, centred card on desktop — that fetches CHANGELOG.md from the repository and renders it with the app's own chrome. The desktop update callout, the sidebar help menu, and a new row in Settings → About all open it; the sheet header links out to paseo.sh/changelog. The parser commits to two facts only: `##` starts a release and `###` starts a section. Section titles are read from the document rather than matched against a list, and everything under a section passes through verbatim to the Markdown renderer, so a future callout, block quote, code fence or image needs no parser change. Fences are tracked because a fenced sample is the one thing that can fool a line scan. The document is fetched rather than bundled because the app has to describe a release that shipped after it was built, which is the update callout's whole purpose. It goes straight to the repository rather than through a host: the notes describe the app, and routing them through a daemon would make them depend on which host happens to be connected. Nothing is fetched or parsed until the sheet opens. The latest release renders as soon as there is one and the rest of the first page follows in a transition, so React slices that work around the opening animation instead of committing hundreds of list items at once. --- docs/release.md | 2 + packages/app/e2e/browser/sidebar-help.spec.ts | 53 ++- packages/app/e2e/support/helpers/changelog.ts | 29 ++ packages/app/src/app/_layout.tsx | 2 + packages/app/src/changelog/changelog-host.tsx | 10 + packages/app/src/changelog/index.ts | 11 + .../changelog/internal/changelog-sheet.tsx | 241 ++++++++++++++ .../changelog/internal/changelog-source.ts | 72 +++++ .../src/changelog/internal/changelog-store.ts | 13 + .../internal/parse-changelog.test.ts | 301 ++++++++++++++++++ .../src/changelog/internal/parse-changelog.ts | 151 +++++++++ .../internal/use-revealed-releases.ts | 42 +++ packages/app/src/changelog/open-changelog.ts | 6 + .../src/components/adaptive-modal-sheet.tsx | 4 + .../components/sidebar/sidebar-help-menu.tsx | 6 +- .../desktop/updates/update-callout-source.tsx | 7 +- packages/app/src/i18n/resources/ar.ts | 11 + packages/app/src/i18n/resources/en.ts | 11 + packages/app/src/i18n/resources/es.ts | 11 + packages/app/src/i18n/resources/fr.ts | 11 + packages/app/src/i18n/resources/ja.ts | 11 + packages/app/src/i18n/resources/ko.ts | 11 + packages/app/src/i18n/resources/pt-BR.ts | 11 + packages/app/src/i18n/resources/ru.ts | 11 + packages/app/src/i18n/resources/zh-CN.ts | 11 + packages/app/src/screens/settings-screen.tsx | 30 ++ 26 files changed, 1063 insertions(+), 16 deletions(-) create mode 100644 packages/app/e2e/support/helpers/changelog.ts create mode 100644 packages/app/src/changelog/changelog-host.tsx create mode 100644 packages/app/src/changelog/index.ts create mode 100644 packages/app/src/changelog/internal/changelog-sheet.tsx create mode 100644 packages/app/src/changelog/internal/changelog-source.ts create mode 100644 packages/app/src/changelog/internal/changelog-store.ts create mode 100644 packages/app/src/changelog/internal/parse-changelog.test.ts create mode 100644 packages/app/src/changelog/internal/parse-changelog.ts create mode 100644 packages/app/src/changelog/internal/use-revealed-releases.ts create mode 100644 packages/app/src/changelog/open-changelog.ts diff --git a/docs/release.md b/docs/release.md index 342fa9eaf9..52b0f17ac2 100644 --- a/docs/release.md +++ b/docs/release.md @@ -486,6 +486,8 @@ Release notes depend on the changelog heading format. The heading **must** be st No prefix (`v`), no extra text. `Release Notes Sync` matches the `## X.Y.Z` (or `## X.Y.Z-beta.N`) line for the pushed tag to extract the version. A malformed heading breaks the release-notes sync for that tag. +`CHANGELOG.md` on `main` is also what the app's **What's new** sheet fetches and renders, so the file is a shipped product surface, not just a release input. `##` starts a release and `###` starts a section; the app reads section titles from the document, so renaming or adding one needs no app change. Everything under a section is rendered as Markdown: prose, lists, links, inline code, fenced code, block quotes, tables, and images. Raw HTML does not render — the shared Markdown parser runs with `html: false`, so a `