diff --git a/client/src/components/Admin/GitHubPanel.tsx b/client/src/components/Admin/GitHubPanel.tsx
index 2657f5d34..dda191525 100644
--- a/client/src/components/Admin/GitHubPanel.tsx
+++ b/client/src/components/Admin/GitHubPanel.tsx
@@ -102,6 +102,13 @@ export default function GitHubPanel({ isPrerelease = false }: { isPrerelease?: b
);
}
+ if (block.kind === 'h5') {
+ return (
+
+ {block.text}
+
+ );
+ }
if (block.kind === 'h4') {
return (
diff --git a/client/src/mobile/screens/admin/MAdminGitHubPanel.tsx b/client/src/mobile/screens/admin/MAdminGitHubPanel.tsx
index dab18b102..a545bac42 100644
--- a/client/src/mobile/screens/admin/MAdminGitHubPanel.tsx
+++ b/client/src/mobile/screens/admin/MAdminGitHubPanel.tsx
@@ -83,6 +83,13 @@ export default function MAdminGitHubPanel({ isPrerelease = false }: { isPrerelea
)
}
+ if (block.kind === 'h5') {
+ return (
+
+ {block.text}
+
+ );
+ }
if (block.kind === 'h4') {
return (
diff --git a/client/src/utils/releaseNotes.test.ts b/client/src/utils/releaseNotes.test.ts
index 4a5d99c9a..aba447092 100644
--- a/client/src/utils/releaseNotes.test.ts
+++ b/client/src/utils/releaseNotes.test.ts
@@ -22,11 +22,11 @@ describe('parseReleaseNotes', () => {
]);
});
- it('FE-UTIL-RELNOTES-003: lines are trimmed and markers need their space', () => {
+ it('FE-UTIL-RELNOTES-003: lines are trimmed, markers need their space and #### heads a feature', () => {
expect(parseReleaseNotes(' ## Spaced \n-no space\n#### deep\n\n\n')).toEqual([
{ kind: 'h3', text: 'Spaced' },
{ kind: 'p', text: '-no space' },
- { kind: 'p', text: '#### deep' },
+ { kind: 'h5', text: 'deep' },
]);
});
diff --git a/client/src/utils/releaseNotes.ts b/client/src/utils/releaseNotes.ts
index c9f5de0a8..57ee4cb2a 100644
--- a/client/src/utils/releaseNotes.ts
+++ b/client/src/utils/releaseNotes.ts
@@ -1,5 +1,5 @@
/** One block of a release body: a heading, a paragraph, or a run of list items. */
-export type ReleaseNoteBlock = { kind: 'h3' | 'h4' | 'p'; text: string } | { kind: 'ul'; items: string[] };
+export type ReleaseNoteBlock = { kind: 'h3' | 'h4' | 'h5' | 'p'; text: string } | { kind: 'ul'; items: string[] };
/** Escapes the characters that would let release text break out of the HTML it is placed in. */
export function escapeReleaseHtml(str: string): string {
@@ -7,8 +7,8 @@ export function escapeReleaseHtml(str: string): string {
}
/**
- * Splits a GitHub release body into the blocks both admin shells render: `### ` and `## `
- * headings, `- ` or `* ` list items gathered into one list until anything else breaks the
+ * Splits a GitHub release body into the blocks both admin shells render: `## `, `### ` and
+ * `#### ` headings (the version, a section such as Added, a feature inside it), `- ` or `* ` list items gathered into one list until anything else breaks the
* run, and every other non-empty line as a paragraph. Blank lines only end a list. The
* text stays raw; each shell formats it inline itself.
*/
@@ -30,7 +30,10 @@ export function parseReleaseNotes(body: string): ReleaseNoteBlock[] {
continue;
}
- if (trimmed.startsWith('### ')) {
+ if (trimmed.startsWith('#### ')) {
+ flushList();
+ blocks.push({ kind: 'h5', text: trimmed.slice(5) });
+ } else if (trimmed.startsWith('### ')) {
flushList();
blocks.push({ kind: 'h4', text: trimmed.slice(4) });
} else if (trimmed.startsWith('## ')) {