}
- @if (supportsManagedExternalPlayers() && form().value.player === 'vlc') {
+ @if (supportsExternalPlayerPathSettings() && form().value.player === 'vlc') {
{{ 'SETTINGS.VLC_PLAYER_PATH_LABEL' | translate }}
diff --git a/apps/web/src/app/settings/settings-playback-section.component.spec.ts b/apps/web/src/app/settings/settings-playback-section.component.spec.ts
index c1f29a349..822a7280c 100644
--- a/apps/web/src/app/settings/settings-playback-section.component.spec.ts
+++ b/apps/web/src/app/settings/settings-playback-section.component.spec.ts
@@ -128,6 +128,28 @@ describe('SettingsPlaybackSectionComponent', () => {
).not.toBeNull();
});
+ it('keeps the double-click option visible when path settings are unavailable', () => {
+ fixture.componentRef.setInput('form', createForm(VideoPlayer.MPV));
+ fixture.componentRef.setInput('isDesktop', true);
+ fixture.componentRef.setInput('supportsManagedExternalPlayers', true);
+ fixture.componentRef.setInput('supportsExternalPlayerPathSettings', false);
+ fixture.detectChanges();
+
+ expect(
+ fixture.nativeElement.querySelector(
+ '[data-test-id="external-player-double-click-setting"]'
+ )
+ ).not.toBeNull();
+ expect(fixture.nativeElement.textContent).not.toContain(
+ MPV_PATH_DESCRIPTION
+ );
+ expect(
+ fixture.nativeElement.querySelector(
+ '[data-test-id="mpv-compatible-player-tip"]'
+ )
+ ).toBeNull();
+ });
+
it('shows the recording folder setting only in desktop builds', () => {
fixture.componentRef.setInput('isDesktop', true);
fixture.detectChanges();
@@ -151,7 +173,7 @@ describe('SettingsPlaybackSectionComponent', () => {
it('shows MPV bundle guidance and the IINA executable tip for desktop MPV playback', () => {
fixture.componentRef.setInput('form', createForm(VideoPlayer.MPV));
fixture.componentRef.setInput('isDesktop', true);
- fixture.componentRef.setInput('supportsManagedExternalPlayers', true);
+ fixture.componentRef.setInput('supportsExternalPlayerPathSettings', true);
fixture.detectChanges();
expect(fixture.nativeElement.textContent).toContain(
@@ -167,10 +189,11 @@ describe('SettingsPlaybackSectionComponent', () => {
);
});
- it('hides MPV path guidance and the IINA executable tip when managed external players are unsupported', () => {
+ it('hides MPV path guidance and the IINA executable tip when path settings are unsupported', () => {
fixture.componentRef.setInput('form', createForm(VideoPlayer.MPV));
fixture.componentRef.setInput('isDesktop', true);
- fixture.componentRef.setInput('supportsManagedExternalPlayers', false);
+ fixture.componentRef.setInput('supportsManagedExternalPlayers', true);
+ fixture.componentRef.setInput('supportsExternalPlayerPathSettings', false);
fixture.detectChanges();
expect(fixture.nativeElement.textContent).not.toContain(
@@ -189,7 +212,7 @@ describe('SettingsPlaybackSectionComponent', () => {
it('shows VLC bundle guidance without the IINA tip for desktop VLC playback', () => {
fixture.componentRef.setInput('form', createForm(VideoPlayer.VLC));
fixture.componentRef.setInput('isDesktop', true);
- fixture.componentRef.setInput('supportsManagedExternalPlayers', true);
+ fixture.componentRef.setInput('supportsExternalPlayerPathSettings', true);
fixture.detectChanges();
expect(fixture.nativeElement.textContent).toContain(
@@ -205,10 +228,11 @@ describe('SettingsPlaybackSectionComponent', () => {
);
});
- it('hides VLC path guidance when managed external players are unsupported', () => {
+ it('hides VLC path guidance when path settings are unsupported', () => {
fixture.componentRef.setInput('form', createForm(VideoPlayer.VLC));
fixture.componentRef.setInput('isDesktop', true);
- fixture.componentRef.setInput('supportsManagedExternalPlayers', false);
+ fixture.componentRef.setInput('supportsManagedExternalPlayers', true);
+ fixture.componentRef.setInput('supportsExternalPlayerPathSettings', false);
fixture.detectChanges();
expect(fixture.nativeElement.textContent).not.toContain(
@@ -223,7 +247,7 @@ describe('SettingsPlaybackSectionComponent', () => {
it('does not show external-player path guidance for embedded players', () => {
fixture.componentRef.setInput('isDesktop', true);
- fixture.componentRef.setInput('supportsManagedExternalPlayers', true);
+ fixture.componentRef.setInput('supportsExternalPlayerPathSettings', true);
fixture.detectChanges();
expect(fixture.nativeElement.textContent).not.toContain(
@@ -242,7 +266,7 @@ describe('SettingsPlaybackSectionComponent', () => {
it('shows MPV command-line arguments only when MPV is selected', () => {
fixture.componentRef.setInput('form', createForm(VideoPlayer.MPV));
fixture.componentRef.setInput('isDesktop', true);
- fixture.componentRef.setInput('supportsManagedExternalPlayers', true);
+ fixture.componentRef.setInput('supportsExternalPlayerPathSettings', true);
fixture.detectChanges();
expect(
@@ -268,7 +292,7 @@ describe('SettingsPlaybackSectionComponent', () => {
it('shows VLC command-line arguments only when VLC is selected', () => {
fixture.componentRef.setInput('form', createForm(VideoPlayer.VLC));
fixture.componentRef.setInput('isDesktop', true);
- fixture.componentRef.setInput('supportsManagedExternalPlayers', true);
+ fixture.componentRef.setInput('supportsExternalPlayerPathSettings', true);
fixture.detectChanges();
expect(
diff --git a/apps/web/src/app/settings/settings-playback-section.component.ts b/apps/web/src/app/settings/settings-playback-section.component.ts
index 08962c16d..a0d6a6531 100644
--- a/apps/web/src/app/settings/settings-playback-section.component.ts
+++ b/apps/web/src/app/settings/settings-playback-section.component.ts
@@ -46,6 +46,7 @@ export class SettingsPlaybackSectionComponent {
readonly streamFormatEnum = input.required();
readonly isDesktop = input(false);
readonly supportsManagedExternalPlayers = input(false);
+ readonly supportsExternalPlayerPathSettings = input(false);
readonly selectRecordingFolder = output();
isExternalPlayerSelected(): boolean {
diff --git a/apps/web/src/app/settings/settings.component.html b/apps/web/src/app/settings/settings.component.html
index f7f435542..440c65a18 100644
--- a/apps/web/src/app/settings/settings.component.html
+++ b/apps/web/src/app/settings/settings.component.html
@@ -48,7 +48,8 @@
[players]="players()"
[streamFormatEnum]="streamFormatEnum"
[isDesktop]="isDesktop"
- [supportsManagedExternalPlayers]="supportsExternalPlayerPathSettings"
+ [supportsManagedExternalPlayers]="supportsManagedExternalPlayers"
+ [supportsExternalPlayerPathSettings]="supportsExternalPlayerPathSettings"
(selectRecordingFolder)="selectRecordingFolder()"
/>
diff --git a/apps/web/src/app/settings/settings.component.ts b/apps/web/src/app/settings/settings.component.ts
index ba7b9b480..ed20802d2 100644
--- a/apps/web/src/app/settings/settings.component.ts
+++ b/apps/web/src/app/settings/settings.component.ts
@@ -139,6 +139,8 @@ export class SettingsComponent implements OnInit, OnDestroy {
readonly isDesktop = this.runtime.isElectron;
readonly supportsDesktopFileSave = this.runtime.supportsDesktopFileSave;
readonly supportsEpg = this.runtime.supportsEpg;
+ readonly supportsManagedExternalPlayers =
+ this.runtime.supportsManagedExternalPlayers;
readonly supportsExternalPlayerPathSettings =
this.runtime.supportsExternalPlayerPathSettings;
readonly supportsRemoteControl = this.runtime.supportsRemoteControl;
diff --git a/libs/portal/shared/data-access/src/lib/collection/unified-favorites-data.service.ts b/libs/portal/shared/data-access/src/lib/collection/unified-favorites-data.service.ts
index 2cd8c0b63..096fdc6a8 100644
--- a/libs/portal/shared/data-access/src/lib/collection/unified-favorites-data.service.ts
+++ b/libs/portal/shared/data-access/src/lib/collection/unified-favorites-data.service.ts
@@ -729,9 +729,10 @@ export class UnifiedFavoritesDataService {
}
private async getSavedOrder(): Promise {
- if (!this.runtime.supportsAppStateStorage) return [];
+ const electron = window.electron;
+ if (!this.runtime.supportsAppStateStorage || !electron) return [];
try {
- const raw = await window.electron?.dbGetAppState(
+ const raw = await electron.dbGetAppState(
GLOBAL_FAVORITES_ORDER_KEY
);
return raw ? (JSON.parse(raw) as string[]) : [];
@@ -741,9 +742,10 @@ export class UnifiedFavoritesDataService {
}
private async saveOrder(uidOrder: string[]): Promise {
- if (!this.runtime.supportsAppStateStorage) return;
+ const electron = window.electron;
+ if (!this.runtime.supportsAppStateStorage || !electron) return;
try {
- await window.electron?.dbSetAppState(
+ await electron.dbSetAppState(
GLOBAL_FAVORITES_ORDER_KEY,
JSON.stringify(uidOrder)
);