Merge branch 'perf/onpush-apps-web' into ci/zoneless-packaged-smoke

# Conflicts:
#	docs/architecture/zoneless-migration.md
This commit is contained in:
4gray committed 2026-10-04 21:52:02 +02:00
commit 10ff2eeaf9
17 files changed
+47 -46

No files matched your search

@@ -101,8 +101,7 @@ import { AppUpdateInstallService } from './services/app-update-install.service';
</section>
}
`,
// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection -- Preserve pre-Angular 22 eager checking during the framework upgrade.
changeDetection: ChangeDetectionStrategy.Eager,
changeDetection: ChangeDetectionStrategy.OnPush,
styles: [
`
.app-update-notification {
+1 -2
View File
@@ -55,8 +55,7 @@ const debugAppComponent = createDevLogger('AppComponent');
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection -- Preserve pre-Angular 22 eager checking during the framework upgrade.
changeDetection: ChangeDetectionStrategy.Eager,
changeDetection: ChangeDetectionStrategy.OnPush,
imports: [
AppStartupStatusComponent,
AppUpdateNotificationPanelComponent,
@@ -178,8 +178,7 @@ function decorateReleaseNotesHtml(html: string): string {
</button>
</mat-dialog-actions>
`,
// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection -- Preserve pre-Angular 22 eager checking during the framework upgrade.
changeDetection: ChangeDetectionStrategy.Eager,
changeDetection: ChangeDetectionStrategy.OnPush,
styles: [
`
.release-notes-dialog {
@@ -32,8 +32,7 @@ import { UpdateChannelOption } from './settings.models';
],
templateUrl: './settings-about-section.component.html',
encapsulation: ViewEncapsulation.None,
// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection -- Preserve pre-Angular 22 eager checking during the framework upgrade.
changeDetection: ChangeDetectionStrategy.Eager,
changeDetection: ChangeDetectionStrategy.OnPush,
styles: [
':host { display: contents; }',
'.version-block .build-commit { opacity: 0.65; font-size: 0.85em; }',
@@ -20,8 +20,7 @@ import { TranslateModule } from '@ngx-translate/core';
],
templateUrl: './settings-backup-section.component.html',
encapsulation: ViewEncapsulation.None,
// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection -- Preserve pre-Angular 22 eager checking during the framework upgrade.
changeDetection: ChangeDetectionStrategy.Eager,
changeDetection: ChangeDetectionStrategy.OnPush,
styles: [':host { display: contents; }'],
})
export class SettingsBackupSectionComponent {
@@ -21,8 +21,7 @@ import { TranslateModule } from '@ngx-translate/core';
],
templateUrl: './settings-dashboard-section.component.html',
encapsulation: ViewEncapsulation.None,
// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection -- Preserve pre-Angular 22 eager checking during the framework upgrade.
changeDetection: ChangeDetectionStrategy.Eager,
changeDetection: ChangeDetectionStrategy.OnPush,
styles: [':host { display: contents; }'],
})
export class SettingsDashboardSectionComponent {
@@ -31,8 +31,7 @@ type SettingsDeleteSummaryItem = {
selector: 'app-settings-delete-all-playlists-dialog',
templateUrl: './settings-delete-all-playlists-dialog.component.html',
styleUrls: ['./settings-delete-all-playlists-dialog.component.scss'],
// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection -- Preserve pre-Angular 22 eager checking during the framework upgrade.
changeDetection: ChangeDetectionStrategy.Eager,
changeDetection: ChangeDetectionStrategy.OnPush,
imports: [
CommonModule,
MatButtonModule,
@@ -34,8 +34,7 @@ import { EpgViewModeOption } from './settings.models';
],
templateUrl: './settings-epg-section.component.html',
encapsulation: ViewEncapsulation.None,
// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection -- Preserve pre-Angular 22 eager checking during the framework upgrade.
changeDetection: ChangeDetectionStrategy.Eager,
changeDetection: ChangeDetectionStrategy.OnPush,
styles: [':host { display: contents; }'],
})
export class SettingsEpgSectionComponent {
@@ -33,8 +33,7 @@ import {
],
templateUrl: './settings-general-section.component.html',
encapsulation: ViewEncapsulation.None,
// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection -- Preserve pre-Angular 22 eager checking during the framework upgrade.
changeDetection: ChangeDetectionStrategy.Eager,
changeDetection: ChangeDetectionStrategy.OnPush,
styles: [':host { display: contents; }'],
})
export class SettingsGeneralSectionComponent {
@@ -36,8 +36,7 @@ import { SettingsPlayerOption } from './settings.models';
],
templateUrl: './settings-playback-section.component.html',
encapsulation: ViewEncapsulation.None,
// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection -- Preserve pre-Angular 22 eager checking during the framework upgrade.
changeDetection: ChangeDetectionStrategy.Eager,
changeDetection: ChangeDetectionStrategy.OnPush,
styles: [':host { display: contents; }'],
})
export class SettingsPlaybackSectionComponent {
@@ -30,8 +30,7 @@ import { QRCodeComponent } from 'angularx-qrcode';
],
templateUrl: './settings-remote-control-section.component.html',
encapsulation: ViewEncapsulation.None,
// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection -- Preserve pre-Angular 22 eager checking during the framework upgrade.
changeDetection: ChangeDetectionStrategy.Eager,
changeDetection: ChangeDetectionStrategy.OnPush,
styles: [':host { display: contents; }'],
})
export class SettingsRemoteControlSectionComponent {
@@ -22,8 +22,7 @@ import { SettingsPlaylistDeleteSummary } from './settings.models';
],
templateUrl: './settings-reset-section.component.html',
encapsulation: ViewEncapsulation.None,
// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection -- Preserve pre-Angular 22 eager checking during the framework upgrade.
changeDetection: ChangeDetectionStrategy.Eager,
changeDetection: ChangeDetectionStrategy.OnPush,
styles: [':host { display: contents; }'],
})
export class SettingsResetSectionComponent {
@@ -33,8 +33,7 @@ type TmdbKeyTestState = 'idle' | 'testing' | 'success' | 'error';
],
templateUrl: './settings-tmdb-section.component.html',
encapsulation: ViewEncapsulation.None,
// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection -- Preserve pre-Angular 22 eager checking during the framework upgrade.
changeDetection: ChangeDetectionStrategy.Eager,
changeDetection: ChangeDetectionStrategy.OnPush,
styles: [
`
app-settings-tmdb-section {
@@ -54,8 +54,7 @@ export interface SettingsUnsavedChangesDialogData {
}
`,
],
// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection -- Preserve pre-Angular 22 eager checking during the framework upgrade.
changeDetection: ChangeDetectionStrategy.Eager,
changeDetection: ChangeDetectionStrategy.OnPush,
template: `
<h2 mat-dialog-title>
{{ 'SETTINGS.UNSAVED_DIALOG_TITLE' | translate }}
@@ -143,6 +143,22 @@ describe('SettingsComponent form', () => {
});
});
// The sections are OnPush and a reset or backup import patches the
// form outside their template events. A value-only patch changes no
// form status signal, so the section must track the value itself.
it('re-renders section selections after a value-only form patch', () => {
const darkTheme = () =>
(fixture.nativeElement as HTMLElement).querySelector(
'[data-test-id="DARK_THEME"]'
);
expect(darkTheme()?.getAttribute('aria-checked')).toBe('false');
component.settingsForm.patchValue({ theme: Theme.DarkTheme });
fixture.detectChanges();
expect(darkTheme()?.getAttribute('aria-checked')).toBe('true');
});
it('hydrates a shared web controls opt-out from the settings store', () => {
settingsStore._setSettings({
webPlayerSharedControls: false,
@@ -102,8 +102,7 @@ export const SETTINGS_DEFAULT_SECTION = 'general';
SettingsSearchResultsComponent,
SettingsTmdbSectionComponent,
],
// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection -- Preserve pre-Angular 22 eager checking during the framework upgrade.
changeDetection: ChangeDetectionStrategy.Eager,
changeDetection: ChangeDetectionStrategy.OnPush,
providers: [
SettingsAppUpdateFacade,
SettingsBackupFacade,
+16 -16
View File
@@ -67,21 +67,21 @@ files that still contain `ChangeDetectionStrategy.Eager`.
### apps/web (15)
- [ ] `apps/web/src/app/app.component.ts` (idle audit root)
- [ ] `apps/web/src/app/app-update-notification-panel.component.ts` (idle audit root)
- [ ] `apps/web/src/app/settings/app-update-release-notes-dialog.component.ts`
- [ ] `apps/web/src/app/settings/settings.component.ts`
- [ ] `apps/web/src/app/settings/settings-about-section.component.ts`
- [ ] `apps/web/src/app/settings/settings-backup-section.component.ts`
- [ ] `apps/web/src/app/settings/settings-dashboard-section.component.ts`
- [ ] `apps/web/src/app/settings/settings-delete-all-playlists-dialog.component.ts`
- [ ] `apps/web/src/app/settings/settings-epg-section.component.ts`
- [ ] `apps/web/src/app/settings/settings-general-section.component.ts`
- [ ] `apps/web/src/app/settings/settings-playback-section.component.ts`
- [ ] `apps/web/src/app/settings/settings-remote-control-section.component.ts`
- [ ] `apps/web/src/app/settings/settings-reset-section.component.ts`
- [ ] `apps/web/src/app/settings/settings-tmdb-section.component.ts`
- [ ] `apps/web/src/app/settings/settings-unsaved-changes-dialog.component.ts`
- [x] `apps/web/src/app/app.component.ts` (idle audit root)
- [x] `apps/web/src/app/app-update-notification-panel.component.ts` (idle audit root)
- [x] `apps/web/src/app/settings/app-update-release-notes-dialog.component.ts`
- [x] `apps/web/src/app/settings/settings.component.ts`
- [x] `apps/web/src/app/settings/settings-about-section.component.ts`
- [x] `apps/web/src/app/settings/settings-backup-section.component.ts`
- [x] `apps/web/src/app/settings/settings-dashboard-section.component.ts`
- [x] `apps/web/src/app/settings/settings-delete-all-playlists-dialog.component.ts`
- [x] `apps/web/src/app/settings/settings-epg-section.component.ts`
- [x] `apps/web/src/app/settings/settings-general-section.component.ts`
- [x] `apps/web/src/app/settings/settings-playback-section.component.ts`
- [x] `apps/web/src/app/settings/settings-remote-control-section.component.ts`
- [x] `apps/web/src/app/settings/settings-reset-section.component.ts`
- [x] `apps/web/src/app/settings/settings-tmdb-section.component.ts`
- [x] `apps/web/src/app/settings/settings-unsaved-changes-dialog.component.ts`
### libs/ui (20 files, 21 components)
@@ -175,7 +175,7 @@ the field a signal (or a `computed`), or writes it through one.
| [x] | `libs/portal/stalker/feature/src/lib/stalker-live-stream-layout/stalker-live-stream-layout.component.ts` (favorites load) | `favorites` Map filled in a `subscribe` without `markForCheck`; the component is OnPush already, so this is a latent bug today | portal |
| [x] | `libs/portal/xtream/feature/src/lib/portal-channels-list/portal-channels-list.component.ts` (favorites load) | same pattern; the neighbouring `favoriteMarks.changes$` handler does call `markForCheck` | portal |
| [x] | same file, programme dialog `afterClosed` | deletes from `epgPrograms`/`currentProgramsProgress` after `await` without marking | portal |
| [ ] | `apps/web/src/app/settings/settings-backup.facade.ts` (backup import) | `change` listener on a detached file input → `hydrateFromStore()`; section templates read `form().value.theme`/`coverSize` | apps/web |
| [x] | `apps/web/src/app/settings/settings-backup.facade.ts` (backup import) | `change` listener on a detached file input → `hydrateFromStore()`; section templates read `form().value.theme`/`coverSize`; no fix needed: a value-only `patchValue` re-renders the OnPush sections (`settings.component.form.spec.ts` guards it) | apps/web |
| [ ] | `libs/ui/remote-control/src/lib/remote-control/remote-control.component.ts` | plain `isLoading`/`error`/`status` written after `await` and from a 2 s `setInterval` | only if `apps/remote-control-web` goes zoneless |
## Explicit zone and change-detector calls