diff --git a/src/view/view.ts b/src/view/view.ts index 89d5c69b..0f417081 100644 --- a/src/view/view.ts +++ b/src/view/view.ts @@ -79,6 +79,11 @@ export class View { // changes camera to the *current* camera (via the menu) it will cause a // new view to issue without a query and just the 'media' view, which // means the viewer cannot know what kind of media to fetch. + // + // * Case #3: Staying within the live view in order to preserve substreams + // turned on. See: + // https://github.com/dermotduffy/frigate-hass-card/issues/1122 + // let currentQueriesView: ClipsOrSnapshots | 'recordings' | null = null; if (MediaQueriesClassifier.areEventQueries(curr.query)) { @@ -114,6 +119,17 @@ export class View { : 'recording'; } } + + if ( + curr.is('live') && + next.is('live') && + curr.context?.live?.overrides && + !next.context?.live?.overrides + ) { + const nextLiveContext = next.context?.live ?? {}; + nextLiveContext.overrides = curr.context.live.overrides; + next.mergeInContext({ live: nextLiveContext }); + } } /** diff --git a/tests/view/view.test.ts b/tests/view/view.test.ts index dcc6c87a..bb4cb261 100644 --- a/tests/view/view.test.ts +++ b/tests/view/view.test.ts @@ -367,6 +367,60 @@ describe('View.adoptFromViewIfAppropriate', () => { View.adoptFromViewIfAppropriate(next, current); expect(next.view).toBe('clip'); }); + + it('should adopt live context overrides for substreams', () => { + const current = createView({ + view: 'live', + context: { + live: { + overrides: new Map([['camera', 'camera2']]), + }, + }, + }); + const next = createView({ + view: 'live', + }); + View.adoptFromViewIfAppropriate(next, current); + expect(next.context?.live).toEqual(current.context?.live); + }); + + it('should not adopt live context overrides if there are new overrides', () => { + const current = createView({ + view: 'live', + context: { + live: { + overrides: new Map([['camera', 'camera2']]), + }, + }, + }); + const next = createView({ + view: 'live', + context: { + live: { + overrides: new Map([['camera', 'camera3']]), + }, + }, + }); + View.adoptFromViewIfAppropriate(next, current); + expect(next.context?.live?.overrides).toEqual(new Map([['camera', 'camera3']])); + }); + + it('should adopt live context overrides even if there is new context', () => { + const current = createView({ + view: 'live', + context: { + live: { + overrides: new Map([['camera', 'camera2']]), + }, + }, + }); + const next = createView({ + view: 'live', + context: {}, + }); + View.adoptFromViewIfAppropriate(next, current); + expect(next.context?.live).toEqual(current.context?.live); + }); }); // @vitest-environment jsdom