Skip to content

Commit 78f7ea9

Browse files
refactor(changelog): improve markdown parsing and changelog rendering
1 parent d11b340 commit 78f7ea9

File tree

1 file changed

+26
-16
lines changed
  • apps/desktop/src/components/main/body/changelog

1 file changed

+26
-16
lines changed

apps/desktop/src/components/main/body/changelog/index.tsx

Lines changed: 26 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -51,8 +51,21 @@ function stripImageLine(content: string): string {
5151
return content.replace(/^!\[.*?\]\(.*?\)\s*\n*/m, "");
5252
}
5353

54-
function addSpacingBeforeHeaders(content: string): string {
55-
return content.replace(/\n(#{1,6}\s)/g, "\n\n$1");
54+
function addEmptyParagraphsBeforeHeaders(
55+
json: ReturnType<typeof md2json>,
56+
): ReturnType<typeof md2json> {
57+
if (!json.content) return json;
58+
59+
const newContent: typeof json.content = [];
60+
for (let i = 0; i < json.content.length; i++) {
61+
const node = json.content[i];
62+
if (node.type === "heading" && i > 0) {
63+
newContent.push({ type: "paragraph" });
64+
}
65+
newContent.push(node);
66+
}
67+
68+
return { ...json, content: newContent };
5669
}
5770

5871
export const TabItemChangelog: TabItem<Extract<Tab, { type: "changelog" }>> = ({
@@ -85,7 +98,7 @@ export function TabContentChangelog({
8598
}: {
8699
tab: Extract<Tab, { type: "changelog" }>;
87100
}) {
88-
const { previous, current } = tab.state;
101+
const { current } = tab.state;
89102

90103
const { content, loading } = useChangelogContent(current);
91104
const { scrollRef, atStart, atEnd } = useScrollFade<HTMLDivElement>();
@@ -98,24 +111,21 @@ export function TabContentChangelog({
98111
</div>
99112

100113
<div className="mt-2 px-3 shrink-0">
101-
<h1 className="text-2xl font-semibold text-neutral-900">
102-
v{current}
114+
<h1 className="text-xl font-semibold text-neutral-900">
115+
What's new in {current}?
103116
</h1>
104-
{previous && (
105-
<p className="mt-1 text-sm text-neutral-500">from v{previous}</p>
106-
)}
107117
</div>
108118

109-
<div className="mt-2 px-2 flex-1 min-h-0 relative">
119+
<div className="mt-4 flex-1 min-h-0 relative overflow-hidden">
110120
{!atStart && <ScrollFadeOverlay position="top" />}
111121
{!atEnd && <ScrollFadeOverlay position="bottom" />}
112-
<div ref={scrollRef} className="h-full overflow-y-auto">
122+
<div ref={scrollRef} className="h-full overflow-y-auto px-3">
113123
{loading ? (
114-
<p className="text-neutral-500 px-1">Loading...</p>
124+
<p className="text-neutral-500">Loading...</p>
115125
) : content ? (
116126
<NoteEditor initialContent={content} editable={false} />
117127
) : (
118-
<p className="text-neutral-500 px-1">
128+
<p className="text-neutral-500">
119129
No changelog available for this version.
120130
</p>
121131
)}
@@ -151,7 +161,7 @@ function ChangelogHeader({ version }: { version: string }) {
151161
className="gap-1.5"
152162
onClick={() => openUrl("https://hyprnote.com/changelog")}
153163
>
154-
<ExternalLinkIcon className="size-4" />
164+
<ExternalLinkIcon size={14} className="-mt-0.5" />
155165
<span>See all</span>
156166
</Button>
157167
</div>
@@ -177,9 +187,9 @@ function useChangelogContent(version: string) {
177187
}
178188

179189
changelogFiles[key]().then((raw) => {
180-
const stripped = stripImageLine(stripFrontmatter(raw as string));
181-
const markdown = addSpacingBeforeHeaders(stripped);
182-
setContent(md2json(markdown));
190+
const markdown = stripImageLine(stripFrontmatter(raw as string));
191+
const json = md2json(markdown);
192+
setContent(addEmptyParagraphsBeforeHeaders(json));
183193
setLoading(false);
184194
});
185195
}, [version]);

0 commit comments

Comments
 (0)