fix: Fix issue with media view incorrectly rejecting cameras (#2061)

For issue: #1748
This commit is contained in:
Dermot Duffy
2025-05-23 20:02:13 -07:00
committed by GitHub
parent 14cf80c7b4
commit b97e1358d0
7 changed files with 21 additions and 24 deletions
+3
View File
@@ -41,6 +41,9 @@ export class FoldersManager {
} }
} }
public hasFolders(): boolean {
return this._folders.size > 0;
}
public getFolderCount(): number { public getFolderCount(): number {
return this._folders.size; return this._folders.size;
} }
+6 -5
View File
@@ -34,16 +34,17 @@ export class ViewFactory {
const cameraIDs = [ const cameraIDs = [
...getCameraIDsForViewName(this._api.getCameraManager(), viewName), ...getCameraIDsForViewName(this._api.getCameraManager(), viewName),
]; ];
if (!cameraIDs.length) {
return null;
}
if (options?.baseView?.camera && config.view.default_cycle_camera) { if (
cameraIDs.length &&
options?.baseView?.camera &&
config.view.default_cycle_camera
) {
const currentIndex = cameraIDs.indexOf(options.baseView.camera); const currentIndex = cameraIDs.indexOf(options.baseView.camera);
const targetIndex = currentIndex + 1 >= cameraIDs.length ? 0 : currentIndex + 1; const targetIndex = currentIndex + 1 >= cameraIDs.length ? 0 : currentIndex + 1;
cameraID = cameraIDs[targetIndex]; cameraID = cameraIDs[targetIndex];
} else { } else {
cameraID = cameraIDs[0]; cameraID = cameraIDs[0] ?? null;
} }
} }
+1 -7
View File
@@ -19,6 +19,7 @@ export const getCameraIDsForViewName = (
case 'diagnostics': case 'diagnostics':
case 'image': case 'image':
case 'folder': case 'folder':
case 'media':
return cameraManager.getStore().getCameraIDs(); return cameraManager.getStore().getCameraIDs();
case 'live': case 'live':
@@ -44,12 +45,5 @@ export const getCameraIDsForViewName = (
return cameraManager return cameraManager
.getStore() .getStore()
.getCameraIDsWithCapability(capabilityMatchAnyMedia); .getCameraIDsWithCapability(capabilityMatchAnyMedia);
case 'media':
return cameraID
? cameraManager
.getStore()
.getAllDependentCameras(cameraID, capabilityMatchAnyMedia)
: cameraManager.getStore().getCameraIDsWithCapability(capabilityMatchAnyMedia);
} }
}; };
@@ -19,6 +19,7 @@ describe('FoldersManager', () => {
const api = createCardAPI(); const api = createCardAPI();
const manager = new FoldersManager(api); const manager = new FoldersManager(api);
expect(manager.getFolderCount()).toBe(0); expect(manager.getFolderCount()).toBe(0);
expect(manager.hasFolders()).toBe(false);
}); });
describe('should add folders', () => { describe('should add folders', () => {
@@ -32,6 +33,7 @@ describe('FoldersManager', () => {
...folder, ...folder,
title: 'Folder 0', title: 'Folder 0',
}); });
expect(manager.hasFolders()).toBe(true);
}); });
it('should add a folder correctly with a title', () => { it('should add a folder correctly with a title', () => {
@@ -128,7 +130,7 @@ describe('FoldersManager', () => {
const folder: FolderConfig = createFolder(); const folder: FolderConfig = createFolder();
const query: FolderQuery = { const query: FolderQuery = {
folder, folder,
path: ['media-source://'], path: [{ id: 'media-source://' }],
}; };
const executor = mock<FoldersExecutor>(); const executor = mock<FoldersExecutor>();
@@ -144,7 +146,7 @@ describe('FoldersManager', () => {
const folder: FolderConfig = createFolder(); const folder: FolderConfig = createFolder();
const query: FolderQuery = { const query: FolderQuery = {
folder, folder,
path: ['media-source://'], path: [{ id: 'media-source://' }],
}; };
const executor = mock<FoldersExecutor>(); const executor = mock<FoldersExecutor>();
@@ -160,7 +162,7 @@ describe('FoldersManager', () => {
const folder: FolderConfig = createFolder(); const folder: FolderConfig = createFolder();
const query: FolderQuery = { const query: FolderQuery = {
folder, folder,
path: ['media-source://'], path: [{ id: 'media-source://' }],
}; };
const executor = mock<FoldersExecutor>(); const executor = mock<FoldersExecutor>();
@@ -188,7 +190,7 @@ describe('FoldersManager', () => {
const engineOptions = {}; const engineOptions = {};
const query: FolderQuery = { const query: FolderQuery = {
folder, folder,
path: ['media-source://'], path: [{ id: 'media-source://' }],
}; };
expect(await manager.expandFolder(query, engineOptions)).toEqual([media]); expect(await manager.expandFolder(query, engineOptions)).toEqual([media]);
@@ -203,7 +205,7 @@ describe('FoldersManager', () => {
const folder = createFolder({ id: 'folder-1' }); const folder = createFolder({ id: 'folder-1' });
expect( expect(
await manager.expandFolder({ folder, path: ['media-source://'] }), await manager.expandFolder({ folder, path: [{ id: 'media-source://' }] }),
).toBeNull(); ).toBeNull();
expect(executor.expandFolder).not.toBeCalled(); expect(executor.expandFolder).not.toBeCalled();
+2 -2
View File
@@ -20,7 +20,7 @@ describe('getViewDefault', () => {
expect(factory.getViewDefault()).toBeNull(); expect(factory.getViewDefault()).toBeNull();
}); });
it('should return null if no cameras support view', () => { it('should throw if no cameras support view', () => {
const api = createCardAPI(); const api = createCardAPI();
vi.mocked(api.getConfigManager().getConfig).mockReturnValue(createConfig()); vi.mocked(api.getConfigManager().getConfig).mockReturnValue(createConfig());
vi.mocked(api.getCameraManager).mockReturnValue(createCameraManager()); vi.mocked(api.getCameraManager).mockReturnValue(createCameraManager());
@@ -44,7 +44,7 @@ describe('getViewDefault', () => {
); );
const factory = new ViewFactory(api); const factory = new ViewFactory(api);
expect(factory.getViewDefault()).toBeNull(); expect(() => factory.getViewDefault()).toThrowError(/No cameras support this view/);
}); });
it('should create view', () => { it('should create view', () => {
@@ -313,7 +313,7 @@ describe('isViewSupportedByCamera', () => {
['recording' as const, false], ['recording' as const, false],
['recordings' as const, false], ['recordings' as const, false],
['timeline' as const, false], ['timeline' as const, false],
['media' as const, false], ['media' as const, true],
])('%s', (viewName: AdvancedCameraCardView, expected: boolean) => { ])('%s', (viewName: AdvancedCameraCardView, expected: boolean) => {
const api = createInitializedCardAPI(); const api = createInitializedCardAPI();
vi.mocked(api.getCameraManager).mockReturnValue(createCameraManager()); vi.mocked(api.getCameraManager).mockReturnValue(createCameraManager());
+1 -4
View File
@@ -11,7 +11,7 @@ import {
describe('getCameraIDsForViewName', () => { describe('getCameraIDsForViewName', () => {
describe('views that are always supported', () => { describe('views that are always supported', () => {
it.each([['image' as const], ['diagnostics' as const]])( it.each([['diagnostics' as const], ['image' as const], ['media' as const]])(
'%s', '%s',
(viewName: AdvancedCameraCardView) => { (viewName: AdvancedCameraCardView) => {
const cameraManager = createCameraManager(); const cameraManager = createCameraManager();
@@ -47,9 +47,6 @@ describe('getCameraIDsForViewName', () => {
['snapshots' as const, 'snapshots' as const], ['snapshots' as const, 'snapshots' as const],
['recording' as const, 'recordings' as const], ['recording' as const, 'recordings' as const],
['recordings' as const, 'recordings' as const], ['recordings' as const, 'recordings' as const],
['media' as const, 'clips' as const],
['media' as const, 'snapshots' as const],
['media' as const, 'recordings' as const],
['timeline' as const, 'clips' as const], ['timeline' as const, 'clips' as const],
['timeline' as const, 'snapshots' as const], ['timeline' as const, 'snapshots' as const],
['timeline' as const, 'recordings' as const], ['timeline' as const, 'recordings' as const],