Files
iptvnator/apps/web/src/app/settings/settings-embedded-mpv.facade.ts
T
4gray f9ea3070ee refactor(settings): split the settings page into per-section facades (#1274)
settings.component.ts had grown to 819 lines — past the CLAUDE.md target (<300)
and hard maximum, passing lint only because it sat in the max-lines baseline.

The behaviour moves into facades the template binds to directly, following the
precedent already in this folder: new app-update (218), form (197), epg (123),
embedded-mpv (74) and remote-control (37) facades, with playlist-reset extended
to 143 and settings-options to 200. The component is now a 259-line coordinator
holding capability flags, section nav, players() and the cross-facade flows.
settings.component.ts is removed from the max-lines baseline.

No behaviour change. One ordering detail: applyChangedSettings now applies
language/theme before kicking off the EPG re-fetch; changeTheme only touches DOM
theme sync and translate.use does not touch the form, so the two are
independent.
2026-07-26 22:57:16 +02:00

75 lines
2.3 KiB
TypeScript

import { computed, inject, Injectable, signal } from '@angular/core';
import { RuntimeCapabilitiesService } from '@iptvnator/services';
import { EmbeddedMpvSupport } from '@iptvnator/shared/interfaces';
/**
* Probes the desktop backend for embedded MPV support so the playback
* section can hide options the current build cannot deliver.
*/
@Injectable()
export class SettingsEmbeddedMpvFacade {
private readonly runtime = inject(RuntimeCapabilitiesService);
readonly support = signal<EmbeddedMpvSupport | null>(null);
readonly supported = computed(
() => this.runtime.isElectron && !!this.support()?.supported
);
readonly frameCopyAvailable = computed(
() => this.runtime.isElectron && !!this.support()?.frameCopyAvailable
);
readonly frameCopyActive = computed(
() => this.support()?.engine === 'frame-copy'
);
async load(): Promise<void> {
if (!this.runtime.isElectron) {
this.support.set({
supported: false,
platform: 'web',
reason: 'Embedded MPV requires the Electron desktop build.',
});
return;
}
if (!window.electron?.getEmbeddedMpvSupport) {
this.support.set({
supported: false,
platform: window.electron.platform,
reason: 'Embedded MPV support is not available in this build.',
});
return;
}
try {
this.support.set(await window.electron.getEmbeddedMpvSupport());
} catch (error) {
this.support.set({
supported: false,
platform: window.electron.platform,
reason: error instanceof Error ? error.message : String(error),
});
}
}
/**
* Opens the native folder picker for MPV recordings.
* @returns the selected folder, or null when the user cancelled or the
* desktop bridge cannot show the dialog
*/
async selectRecordingFolder(): Promise<string | null> {
if (
!this.runtime.isElectron ||
!window.electron?.selectEmbeddedMpvRecordingFolder
) {
return null;
}
return (
(await window.electron.selectEmbeddedMpvRecordingFolder()) ?? null
);
}
}