feat: emphasize update changelog sections

Render release-note headings, categories, items, and body lines as safe structured text with larger typography for section labels and compact spacing for details.
This commit is contained in:
Sucukdeluxe
2026-08-21 00:40:08 +02:00
parent aea0b22a4f
commit 6539db5d52
4 changed files with 68 additions and 24 deletions
+33 -21
View File
@@ -7445,26 +7445,40 @@ function setupListeners() {
}
// --- Update UI ---
function _formatUpdateReleaseNotes(value) {
const output = [];
let pendingBlank = false;
function _cleanUpdateReleaseText(value) {
return String(value || '')
.replace(/\*\*([^*]+)\*\*/g, '$1')
.replace(/`([^`]+)`/g, '$1')
.replace(/\[([^\]]+)\]\([^)]+\)/g, '$1');
}
function _renderUpdateReleaseNotes(container, value) {
const fragment = document.createDocumentFragment();
let consumed = 0;
for (const rawLine of String(value || '').replace(/\r\n?/g, '\n').split('\n')) {
let line = rawLine.trim();
if (!line) {
if (output.length > 0) pendingBlank = true;
continue;
}
line = line
.replace(/^#{1,6}\s+/, '')
.replace(/^[-*+]\s+/, '• ')
.replace(/\*\*([^*]+)\*\*/g, '$1')
.replace(/`([^`]+)`/g, '$1')
.replace(/\[([^\]]+)\]\([^)]+\)/g, '$1');
if (pendingBlank && output.at(-1) !== '') output.push('');
output.push(line);
pendingBlank = false;
const line = rawLine.trim();
if (!line) continue;
const heading = line.match(/^(#{1,6})\s+(.+)$/);
const bullet = line.match(/^[-*+]\s+(.+)$/);
const className = heading
? (heading[1].length <= 2 ? 'update-release-heading' : 'update-release-category')
: bullet
? 'update-release-item'
: 'update-release-line';
const source = heading ? heading[2] : bullet ? `${bullet[1]}` : line;
const cleaned = _cleanUpdateReleaseText(source);
const available = 2400 - consumed;
if (available <= 0) break;
const text = cleaned.length > available ? `${cleaned.slice(0, Math.max(0, available - 1))}` : cleaned;
const element = document.createElement('div');
element.className = className;
element.textContent = text;
fragment.appendChild(element);
consumed += text.length;
if (text.endsWith('…')) break;
}
return output.join('\n');
container.replaceChildren(fragment);
return container.childElementCount > 0;
}
function showUpdateBanner(info) {
@@ -7488,9 +7502,7 @@ function showUpdateBanner(info) {
message.hidden = false;
}
if (notes && notesBody) {
const releaseNotes = _formatUpdateReleaseNotes(info.releaseNotes);
notesBody.textContent = releaseNotes.length > 2400 ? `${releaseNotes.slice(0, 2399)}` : releaseNotes;
notes.hidden = !releaseNotes;
notes.hidden = !_renderUpdateReleaseNotes(notesBody, info.releaseNotes);
}
if (installButton) {
installButton.disabled = false;
+31 -1
View File
@@ -2491,7 +2491,37 @@ select.hs-input { max-width: none; width: auto; min-width: 140px; }
}
.update-release-notes-body {
white-space: pre-wrap;
white-space: normal;
}
.update-release-heading {
margin: 2px 0 11px;
color: var(--text);
font-size: 14px;
font-weight: 750;
line-height: 1.3;
}
.update-release-category {
margin: 15px 0 7px;
color: var(--text);
font-size: 13px;
font-weight: 700;
line-height: 1.35;
}
.update-release-heading + .update-release-category {
margin-top: 0;
}
.update-release-item,
.update-release-line {
margin: 4px 0;
}
.update-release-item {
padding-left: 11px;
text-indent: -9px;
}
.update-progress-track {