From 2246840f71d9f10fef9a4b7c83e0ea53d60e19b4 Mon Sep 17 00:00:00 2001 From: 4gray Date: Fri, 17 Jul 2026 07:28:29 +0200 Subject: [PATCH] feat(settings): persist shared web controls preference --- .../src/lib/settings-store.service.spec.ts | 46 +++++++++++++++++++ .../src/lib/settings-store.service.ts | 5 ++ .../interfaces/src/lib/settings.interface.ts | 5 ++ 3 files changed, 56 insertions(+) diff --git a/libs/services/src/lib/settings-store.service.spec.ts b/libs/services/src/lib/settings-store.service.spec.ts index 9f9ae531a..c37daa0d8 100644 --- a/libs/services/src/lib/settings-store.service.spec.ts +++ b/libs/services/src/lib/settings-store.service.spec.ts @@ -64,6 +64,52 @@ describe('SettingsStore dashboard rail settings', () => { ); }); + it('defaults shared web controls to false when the stored field is missing', async () => { + storedSettings = {}; + const store = injector.get(SettingsStore); + + await store.loadSettings(); + + expect(store.getSettings().webPlayerSharedControls).toBe(false); + }); + + it('restores a persisted true shared web controls preference', async () => { + storedSettings = { + webPlayerSharedControls: true, + }; + const store = injector.get(SettingsStore); + + await store.loadSettings(); + + expect(store.getSettings().webPlayerSharedControls).toBe(true); + }); + + it('normalizes a persisted string "true" shared web controls preference to false', async () => { + storedSettings = { + webPlayerSharedControls: 'true' as unknown as boolean, + }; + const store = injector.get(SettingsStore); + + await store.loadSettings(); + + expect(store.getSettings().webPlayerSharedControls).toBe(false); + }); + + it('persists an updated true shared web controls preference', async () => { + const store = injector.get(SettingsStore); + + await store.updateSettings({ + webPlayerSharedControls: true, + }); + + expect(storage.set).toHaveBeenCalledWith( + STORE_KEY.Settings, + expect.objectContaining({ + webPlayerSharedControls: true, + }) + ); + }); + it('deep-merges partial stored dashboard rail settings with enabled defaults', async () => { storedSettings = { player: VideoPlayer.VideoJs, diff --git a/libs/services/src/lib/settings-store.service.ts b/libs/services/src/lib/settings-store.service.ts index ced7df83d..5944370f0 100644 --- a/libs/services/src/lib/settings-store.service.ts +++ b/libs/services/src/lib/settings-store.service.ts @@ -26,6 +26,7 @@ import { const DEFAULT_SETTINGS: Settings = { player: VideoPlayer.VideoJs, + webPlayerSharedControls: false, streamFormat: StreamFormat.AutoStreamFormat, openStreamOnDoubleClick: false, language: Language.ENGLISH, @@ -118,6 +119,8 @@ export const SettingsStore = signalStore( patchState(store, { ...DEFAULT_SETTINGS, ...storedSettings, + webPlayerSharedControls: + storedSettings.webPlayerSharedControls === true, dashboardRails: normalizeDashboardRailsSettings( storedSettings.dashboardRails ), @@ -164,6 +167,8 @@ export const SettingsStore = signalStore( getSettings() { return { player: store.player(), + webPlayerSharedControls: + store.webPlayerSharedControls?.() === true, streamFormat: store.streamFormat(), openStreamOnDoubleClick: store.openStreamOnDoubleClick(), language: store.language(), diff --git a/libs/shared/interfaces/src/lib/settings.interface.ts b/libs/shared/interfaces/src/lib/settings.interface.ts index 582adfb84..758d2bd2a 100644 --- a/libs/shared/interfaces/src/lib/settings.interface.ts +++ b/libs/shared/interfaces/src/lib/settings.interface.ts @@ -78,6 +78,11 @@ export function normalizeDashboardRailsSettings( */ export interface Settings { player: VideoPlayer; + /** + * Use IPTVnator's shared controls in HTML5, Video.js, and ArtPlayer. + * Missing values remain off for compatibility with older saved settings. + */ + webPlayerSharedControls?: boolean; epgUrl: string[]; streamFormat: StreamFormat; openStreamOnDoubleClick: boolean;