fix(settings): constrain release note images

This commit is contained in:
4gray committed 2026-06-28 23:19:14 +02:00
1 parent 1296e3e7d7
commit 62ae5307a4
2 files changed
+53 -1

No files matched your search

@@ -70,6 +70,27 @@ describe('AppUpdateReleaseNotesDialogComponent', () => {
).toContain('desktop updater');
});
it('constrains rendered markdown images to the dialog width', async () => {
(
window.electron.getAppUpdateReleaseNotes as jest.Mock
).mockResolvedValueOnce({
...releaseNotes,
bodyMarkdown:
'![Application screenshot](https://example.com/screenshot.png)',
});
fixture.detectChanges();
await fixture.whenStable();
fixture.detectChanges();
const image = fixture.nativeElement.querySelector(
'[data-test-id="release-notes-body"] img'
) as HTMLImageElement;
expect(image).toBeTruthy();
expect(image.classList).toContain('release-notes-dialog__image');
});
it('loads previous notes lazily without closing the dialog', async () => {
fixture.detectChanges();
await fixture.whenStable();
@@ -5,6 +5,7 @@ import {
OnInit,
SecurityContext,
signal,
ViewEncapsulation,
} from '@angular/core';
import { DatePipe } from '@angular/common';
import { MatButtonModule } from '@angular/material/button';
@@ -24,11 +25,28 @@ import {
ElectronBridgeAppUpdateReleaseNotesRequest,
} from '@iptvnator/shared/interfaces';
const RELEASE_NOTES_IMAGE_CLASS = 'release-notes-dialog__image';
export interface AppUpdateReleaseNotesDialogData {
initialVersion?: string;
fallbackToLatest?: boolean;
}
function decorateReleaseNotesHtml(html: string): string {
if (typeof document === 'undefined') {
return html;
}
const template = document.createElement('template');
template.innerHTML = html;
template.content.querySelectorAll('img').forEach((image) => {
image.classList.add(RELEASE_NOTES_IMAGE_CLASS);
});
return template.innerHTML;
}
@Component({
selector: 'app-update-release-notes-dialog',
imports: [
@@ -39,6 +57,7 @@ export interface AppUpdateReleaseNotesDialogData {
DatePipe,
TranslatePipe,
],
encapsulation: ViewEncapsulation.None,
template: `
<h2 mat-dialog-title>
{{ 'SETTINGS.APP_UPDATE_RELEASE_NOTES' | translate }}
@@ -177,6 +196,16 @@ export interface AppUpdateReleaseNotesDialogData {
padding: 1px 4px;
background: var(--app-hover-overlay);
}
.release-notes-dialog__body img,
.release-notes-dialog__image {
display: block;
box-sizing: border-box;
max-width: 100%;
height: auto;
margin: 16px auto;
object-fit: contain;
}
`,
],
})
@@ -195,8 +224,10 @@ export class AppUpdateReleaseNotesDialogComponent implements OnInit {
readonly renderedMarkdown = computed(() => {
const markdown = this.notes()?.bodyMarkdown ?? '';
const html = marked.parse(markdown, { async: false }) as string;
const sanitizedHtml =
this.sanitizer.sanitize(SecurityContext.HTML, html) ?? '';
return this.sanitizer.sanitize(SecurityContext.HTML, html) ?? '';
return decorateReleaseNotesHtml(sanitizedHtml);
});
ngOnInit(): void {