feat: Make cameras optional (#2343)
This commit is contained in:
@@ -0,0 +1,28 @@
|
||||
import { CameraManager } from '../../camera-manager/manager';
|
||||
import { FoldersManager } from '../../card-controller/folders/manager';
|
||||
import {
|
||||
AdvancedCameraCardUserSpecifiedView,
|
||||
AdvancedCameraCardView,
|
||||
} from '../../config/schema/common/const';
|
||||
|
||||
/**
|
||||
* Resolve a view name that may be 'auto'.
|
||||
* @param viewName The view name.
|
||||
* @param cameraManager The camera manager.
|
||||
* @param foldersManager The folders manager.
|
||||
* @returns A concrete view name.
|
||||
*/
|
||||
export const resolveViewName = (
|
||||
viewName: AdvancedCameraCardUserSpecifiedView,
|
||||
cameraManager: CameraManager,
|
||||
foldersManager: FoldersManager,
|
||||
): AdvancedCameraCardView => {
|
||||
if (viewName !== 'auto') {
|
||||
return viewName;
|
||||
}
|
||||
return cameraManager.getStore().getCameraIDs().size
|
||||
? 'live'
|
||||
: foldersManager.hasFolders()
|
||||
? 'folders'
|
||||
: 'image';
|
||||
};
|
||||
+125
-51
@@ -1,64 +1,120 @@
|
||||
import { CameraManager } from '../camera-manager/manager';
|
||||
import { CapabilitySearchOptions } from '../camera-manager/types';
|
||||
import { CapabilitySearchKeys, CapabilitySearchOptions } from '../camera-manager/types';
|
||||
import { FoldersManager } from '../card-controller/folders/manager';
|
||||
import { AdvancedCameraCardView } from '../config/schema/common/const';
|
||||
|
||||
/**
|
||||
* Get cameraIDs that are relevant for a given view name based on camera
|
||||
* capability (if camera specified).
|
||||
*/
|
||||
export const getCameraIDsForViewName = (
|
||||
type ViewSource = 'camera' | 'folder' | 'any';
|
||||
|
||||
interface ViewCapabilityRequirements {
|
||||
src?: ViewSource;
|
||||
mediaCapabilities?: CapabilitySearchKeys;
|
||||
mediaCapabilitiesInclusive?: boolean;
|
||||
}
|
||||
|
||||
const anyMedia: ViewCapabilityRequirements = {
|
||||
src: 'any',
|
||||
mediaCapabilities: {
|
||||
anyCapabilities: ['clips', 'snapshots', 'recordings', 'reviews'],
|
||||
},
|
||||
mediaCapabilitiesInclusive: false,
|
||||
};
|
||||
const anyFolder = { src: 'folder' as const };
|
||||
const noRequirements = {};
|
||||
|
||||
const generateCameraRequirements = (
|
||||
mediaCapabilities: CapabilitySearchKeys,
|
||||
mediaCapabilitiesInclusive = true,
|
||||
): ViewCapabilityRequirements => {
|
||||
return {
|
||||
src: 'camera',
|
||||
mediaCapabilities,
|
||||
mediaCapabilitiesInclusive,
|
||||
};
|
||||
};
|
||||
|
||||
const VIEW_REQUIREMENTS: Record<AdvancedCameraCardView, ViewCapabilityRequirements> = {
|
||||
live: generateCameraRequirements('live', false),
|
||||
|
||||
clip: generateCameraRequirements('clips'),
|
||||
clips: generateCameraRequirements('clips'),
|
||||
snapshot: generateCameraRequirements('snapshots'),
|
||||
snapshots: generateCameraRequirements('snapshots'),
|
||||
recording: generateCameraRequirements('recordings'),
|
||||
recordings: generateCameraRequirements('recordings'),
|
||||
review: generateCameraRequirements('reviews'),
|
||||
reviews: generateCameraRequirements('reviews'),
|
||||
|
||||
gallery: anyMedia,
|
||||
media: anyMedia,
|
||||
timeline: anyMedia,
|
||||
|
||||
folder: anyFolder,
|
||||
folders: anyFolder,
|
||||
|
||||
image: noRequirements,
|
||||
diagnostics: noRequirements,
|
||||
};
|
||||
|
||||
export const isViewAvailable = (
|
||||
view: AdvancedCameraCardView,
|
||||
cameraManager: CameraManager,
|
||||
foldersManager: FoldersManager,
|
||||
): boolean => {
|
||||
const req = VIEW_REQUIREMENTS[view];
|
||||
const hasCameras = cameraManager.getStore().getCameraIDs().size > 0;
|
||||
const hasFolders = foldersManager.hasFolders();
|
||||
|
||||
if (req.src === 'camera') {
|
||||
return hasCameras;
|
||||
}
|
||||
if (req.src === 'folder') {
|
||||
return hasFolders;
|
||||
}
|
||||
if (req.src === 'any') {
|
||||
return hasCameras || hasFolders;
|
||||
}
|
||||
return true;
|
||||
};
|
||||
|
||||
export const doesViewRequireCamera = (view: AdvancedCameraCardView): boolean => {
|
||||
return VIEW_REQUIREMENTS[view].src === 'camera';
|
||||
};
|
||||
|
||||
export const getCameraIDsWithCapabilityForView = (
|
||||
viewName: AdvancedCameraCardView,
|
||||
cameraManager: CameraManager,
|
||||
foldersManager: FoldersManager,
|
||||
cameraID?: string,
|
||||
): Set<string> => {
|
||||
const folder = foldersManager.getFolder();
|
||||
const requirements = VIEW_REQUIREMENTS[viewName];
|
||||
const allCameras = cameraManager.getStore().getCameraIDs();
|
||||
|
||||
switch (viewName) {
|
||||
case 'diagnostics':
|
||||
case 'image':
|
||||
return cameraManager.getStore().getCameraIDs();
|
||||
|
||||
case 'folder':
|
||||
case 'folders':
|
||||
return folder ? cameraManager.getStore().getCameraIDs() : new Set();
|
||||
|
||||
case 'live':
|
||||
case 'clip':
|
||||
case 'clips':
|
||||
case 'snapshot':
|
||||
case 'snapshots':
|
||||
case 'recording':
|
||||
case 'recordings':
|
||||
case 'review':
|
||||
case 'reviews':
|
||||
const options: CapabilitySearchOptions = {
|
||||
inclusive: viewName !== 'live',
|
||||
};
|
||||
const capability =
|
||||
viewName === 'clip'
|
||||
? 'clips'
|
||||
: viewName === 'snapshot'
|
||||
? 'snapshots'
|
||||
: viewName === 'recording'
|
||||
? 'recordings'
|
||||
: viewName === 'review'
|
||||
? 'reviews'
|
||||
: viewName;
|
||||
return cameraID
|
||||
? cameraManager.getStore().getAllDependentCameras(cameraID, capability, options)
|
||||
: cameraManager.getStore().getCameraIDsWithCapability(capability, options);
|
||||
|
||||
case 'gallery':
|
||||
case 'media':
|
||||
case 'timeline':
|
||||
return folder
|
||||
? cameraManager.getStore().getCameraIDs()
|
||||
: cameraManager.getStore().getCameraIDsWithCapability({
|
||||
anyCapabilities: ['clips', 'snapshots', 'recordings', 'reviews'],
|
||||
});
|
||||
if (requirements.src !== 'camera' && requirements.src !== 'any') {
|
||||
if (requirements.src === 'folder' && !foldersManager.hasFolders()) {
|
||||
return new Set();
|
||||
}
|
||||
return allCameras;
|
||||
}
|
||||
|
||||
if (requirements.src === 'any' && foldersManager.hasFolders()) {
|
||||
return allCameras;
|
||||
}
|
||||
|
||||
const options: CapabilitySearchOptions = {
|
||||
inclusive: !!requirements.mediaCapabilitiesInclusive,
|
||||
};
|
||||
const capability = requirements.mediaCapabilities;
|
||||
|
||||
/* istanbul ignore next: this path is currently unreachable given the mapping
|
||||
in VIEW_REQUIREMENTS includes mediaCapabilities for all camera or 'any'
|
||||
related views -- @preserve */
|
||||
if (!capability) {
|
||||
return allCameras;
|
||||
}
|
||||
|
||||
return cameraID
|
||||
? cameraManager.getStore().getAllDependentCameras(cameraID, capability, options)
|
||||
: cameraManager.getStore().getCameraIDsWithCapability(capability, options);
|
||||
};
|
||||
|
||||
export const isViewSupportedByCamera = (
|
||||
@@ -67,5 +123,23 @@ export const isViewSupportedByCamera = (
|
||||
foldersManager: FoldersManager,
|
||||
cameraID: string,
|
||||
): boolean => {
|
||||
return !!getCameraIDsForViewName(view, cameraManager, foldersManager, cameraID)?.size;
|
||||
return !!getCameraIDsWithCapabilityForView(
|
||||
view,
|
||||
cameraManager,
|
||||
foldersManager,
|
||||
cameraID,
|
||||
)?.size;
|
||||
};
|
||||
|
||||
export const isViewSupported = (
|
||||
viewName: AdvancedCameraCardView,
|
||||
cameraManager: CameraManager,
|
||||
foldersManager: FoldersManager,
|
||||
cameraID?: string | null,
|
||||
): boolean => {
|
||||
return (
|
||||
isViewAvailable(viewName, cameraManager, foldersManager) &&
|
||||
(!cameraID ||
|
||||
isViewSupportedByCamera(viewName, cameraManager, foldersManager, cameraID))
|
||||
);
|
||||
};
|
||||
|
||||
+3
-4
@@ -16,7 +16,7 @@ declare module 'view' {
|
||||
|
||||
interface ViewEvolveParameters {
|
||||
view?: AdvancedCameraCardView;
|
||||
camera?: string;
|
||||
camera?: string | null;
|
||||
query?: UnifiedQuery | null;
|
||||
queryResults?: QueryResults | null;
|
||||
context?: ViewContext | null;
|
||||
@@ -25,7 +25,6 @@ interface ViewEvolveParameters {
|
||||
|
||||
export interface ViewParameters extends ViewEvolveParameters {
|
||||
view: AdvancedCameraCardView;
|
||||
camera: string;
|
||||
}
|
||||
|
||||
export const mergeViewContext = (
|
||||
@@ -37,7 +36,7 @@ export const mergeViewContext = (
|
||||
|
||||
export class View {
|
||||
public view: AdvancedCameraCardView;
|
||||
public camera: string;
|
||||
public camera: string | null;
|
||||
public query: UnifiedQuery | null;
|
||||
public queryResults: QueryResults | null;
|
||||
public context: ViewContext | null;
|
||||
@@ -45,7 +44,7 @@ export class View {
|
||||
|
||||
constructor(params: ViewParameters) {
|
||||
this.view = params.view;
|
||||
this.camera = params.camera;
|
||||
this.camera = params.camera ?? null;
|
||||
this.query = params.query ?? null;
|
||||
this.queryResults = params.queryResults ?? null;
|
||||
this.context = params.context ?? null;
|
||||
|
||||
Reference in New Issue
Block a user