From c3dc4803ad18071065590410aef29dca54201f42 Mon Sep 17 00:00:00 2001 From: Dermot Duffy Date: Tue, 7 Jan 2025 23:28:40 -0700 Subject: [PATCH] fix: Honor the view configured display mode (#1815) - Closes #1812 --- src/card-controller/view/factory.ts | 12 ++- src/config/types.ts | 2 +- tests/card-controller/view/factory.test.ts | 99 ++++++++++++++++------ 3 files changed, 80 insertions(+), 33 deletions(-) diff --git a/src/card-controller/view/factory.ts b/src/card-controller/view/factory.ts index db6c5693..6131bb4c 100644 --- a/src/card-controller/view/factory.ts +++ b/src/card-controller/view/factory.ts @@ -121,11 +121,15 @@ export class ViewFactory { }); } } - + const configuredDisplayMode = this._getDefaultDisplayModeForView(viewName, config); const displayMode = + // Prioritize the configured display mode (if present). + // See: https://github.com/dermotduffy/frigate-hass-card/issues/1812 + (viewName !== options?.baseView?.view ? configuredDisplayMode : null) ?? options?.params?.displayMode ?? options?.baseView?.displayMode ?? - this._getDefaultDisplayModeForView(viewName, config); + configuredDisplayMode ?? + 'single'; const viewParameters: ViewParameters = { ...options?.params, @@ -150,7 +154,7 @@ export class ViewFactory { protected _getDefaultDisplayModeForView( viewName: FrigateCardView, config: FrigateCardConfig, - ): ViewDisplayMode { + ): ViewDisplayMode | null { let mode: ViewDisplayMode | null = null; switch (viewName) { case 'media': @@ -163,6 +167,6 @@ export class ViewFactory { mode = config.live.display?.mode ?? null; break; } - return mode ?? 'single'; + return mode; } } diff --git a/src/config/types.ts b/src/config/types.ts index 6b92cae4..488d9fb6 100644 --- a/src/config/types.ts +++ b/src/config/types.ts @@ -115,7 +115,7 @@ export type ViewDisplayMode = z.infer; const viewDisplaySchema = z .object({ - mode: viewDisplayModeSchema, + mode: viewDisplayModeSchema.optional(), grid_selected_width_factor: z.number().min(0).optional(), grid_max_columns: z.number().min(0).optional(), grid_columns: z.number().min(0).optional(), diff --git a/tests/card-controller/view/factory.test.ts b/tests/card-controller/view/factory.test.ts index c1c770af..df690345 100644 --- a/tests/card-controller/view/factory.test.ts +++ b/tests/card-controller/view/factory.test.ts @@ -320,36 +320,79 @@ describe('getViewByParameters', () => { expect(modifyCallback).toHaveBeenCalledWith(modifiedView); }); - describe('should get correct default display mode', () => { - describe.each([ - ['single' as const, { mode: 'single' as const }], - ['grid' as const, { mode: 'grid' as const }], - ['single' as const, undefined], - ])('%s', (expectedDisplayMode: ViewDisplayMode, displayConfig?: unknown) => { - it.each([ - ['media' as const], - ['clip' as const], - ['recording' as const], - ['snapshot' as const], - ['live' as const], - ])('%s', (viewName: FrigateCardView) => { - const api = createPopulatedAPI({ - media_viewer: { - display: displayConfig, - }, - live: { - display: displayConfig, - }, - }); + describe('should get correct display mode', () => { + it('should use config display mode when changing views', () => { + const api = createPopulatedAPI({ + media_viewer: { + display: { mode: 'single' }, + }, + }); - const factory = new ViewFactory(api); - expect( - factory.getViewByParameters({ - params: { - view: viewName, + const factory = new ViewFactory(api); + expect( + factory.getViewByParameters({ + params: { + view: 'clip', + displayMode: 'grid', + }, + })?.displayMode, + ).toBe('single'); + }); + + it('should ignore config display mode with a view', () => { + const api = createPopulatedAPI({ + media_viewer: { + display: { mode: 'single' }, + }, + }); + + const baseView = createView({ + view: 'live', + }); + + const factory = new ViewFactory(api); + expect( + factory.getViewByParameters({ + baseView: baseView, + params: { + view: 'live', + displayMode: 'grid', + }, + })?.displayMode, + ).toBe('grid'); + }); + + describe('should get correct default display mode', () => { + describe.each([ + ['single' as const, { mode: 'single' as const }], + ['grid' as const, { mode: 'grid' as const }], + ['single' as const, undefined], + ])('%s', (expectedDisplayMode: ViewDisplayMode, displayConfig?: unknown) => { + it.each([ + ['media' as const], + ['clip' as const], + ['recording' as const], + ['snapshot' as const], + ['live' as const], + ])('%s', (viewName: FrigateCardView) => { + const api = createPopulatedAPI({ + media_viewer: { + display: displayConfig, }, - })?.displayMode, - ).toBe(expectedDisplayMode); + live: { + display: displayConfig, + }, + }); + + const factory = new ViewFactory(api); + expect( + factory.getViewByParameters({ + params: { + view: viewName, + }, + })?.displayMode, + ).toBe(expectedDisplayMode); + }); }); }); });