fix: Expose gallery and media views as media type agnostic (#2335)
This commit is contained in:
@@ -91,8 +91,10 @@ export class ActionFactory {
|
||||
case 'clips':
|
||||
case 'folder':
|
||||
case 'folders':
|
||||
case 'gallery':
|
||||
case 'image':
|
||||
case 'live':
|
||||
case 'media':
|
||||
case 'recording':
|
||||
case 'recordings':
|
||||
case 'review':
|
||||
|
||||
@@ -131,10 +131,16 @@ export class QueryStringManager {
|
||||
case 'clip':
|
||||
case 'clips':
|
||||
case 'diagnostics':
|
||||
case 'folder':
|
||||
case 'folders':
|
||||
case 'gallery':
|
||||
case 'image':
|
||||
case 'live':
|
||||
case 'media':
|
||||
case 'recording':
|
||||
case 'recordings':
|
||||
case 'review':
|
||||
case 'reviews':
|
||||
case 'snapshot':
|
||||
case 'snapshots':
|
||||
case 'timeline':
|
||||
@@ -159,10 +165,16 @@ export class QueryStringManager {
|
||||
case 'clip':
|
||||
case 'clips':
|
||||
case 'diagnostics':
|
||||
case 'folder':
|
||||
case 'folders':
|
||||
case 'gallery':
|
||||
case 'image':
|
||||
case 'live':
|
||||
case 'media':
|
||||
case 'recording':
|
||||
case 'recordings':
|
||||
case 'review':
|
||||
case 'reviews':
|
||||
case 'snapshot':
|
||||
case 'snapshots':
|
||||
case 'timeline':
|
||||
|
||||
@@ -105,23 +105,30 @@ export class ViewQueryExecutor {
|
||||
|
||||
const cameraForQuery = view.isGrid() ? undefined : view.camera;
|
||||
|
||||
const getDefaultQueryModifiers = async () => {
|
||||
const query = builder.buildDefaultCameraQuery(cameraForQuery, {
|
||||
limit: this._getLimit(),
|
||||
});
|
||||
return await executeQuery(query);
|
||||
};
|
||||
|
||||
switch (view.view) {
|
||||
case 'live':
|
||||
if (config.live.controls.thumbnails.mode !== 'none') {
|
||||
const defaultQuery = builder.buildDefaultCameraQuery(cameraForQuery);
|
||||
if (defaultQuery) {
|
||||
viewModifiers.push(...(await executeQuery(defaultQuery)));
|
||||
}
|
||||
viewModifiers.push(...(await getDefaultQueryModifiers()));
|
||||
}
|
||||
break;
|
||||
case 'timeline':
|
||||
// Timeline view always queries all cameras with media capabilities.
|
||||
viewModifiers.push(...(await executeQuery(builder.buildDefaultCameraQuery())));
|
||||
break;
|
||||
case 'gallery':
|
||||
case 'media':
|
||||
// If the user is looking at media in the `media` view and then
|
||||
// changes camera (via the menu) it should default to showing clips
|
||||
// for the new camera.
|
||||
// If the user is looking at media in the `media` view and then changes
|
||||
// camera (via the menu) it should default to the default camera media
|
||||
// type.
|
||||
viewModifiers.push(...(await getDefaultQueryModifiers()));
|
||||
break;
|
||||
case 'clip':
|
||||
case 'clips':
|
||||
viewModifiers.push(
|
||||
|
||||
@@ -9,7 +9,6 @@ import {
|
||||
AdvancedCameraCardView,
|
||||
VIEWS_USER_SPECIFIED,
|
||||
} from '../config/schema/common/const';
|
||||
import { MenuItemBase } from '../config/schema/elements/custom/menu/base';
|
||||
import { MenuItem } from '../config/schema/elements/custom/menu/types';
|
||||
import { AdvancedCameraCardConfig } from '../config/schema/types';
|
||||
import { getEntityTitle } from '../ha/get-entity-title';
|
||||
@@ -82,6 +81,7 @@ export class MenuButtonController {
|
||||
this._getSnapshotsButton(config, cameraManager, foldersManager, options?.view),
|
||||
this._getRecordingsButton(config, cameraManager, foldersManager, options?.view),
|
||||
this._getReviewsButton(config, cameraManager, foldersManager, options?.view),
|
||||
this._getGalleryButton(config, cameraManager, foldersManager, options?.view),
|
||||
this._getImageButton(config, cameraManager, foldersManager, options?.view),
|
||||
this._getTimelineButton(config, cameraManager, foldersManager, options?.view),
|
||||
this._getDownloadButton(config, cameraManager, options?.view),
|
||||
@@ -252,45 +252,17 @@ export class MenuButtonController {
|
||||
: null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if a media button (clips/snapshots) should be shown. These are
|
||||
* hidden by default if reviews are supported.
|
||||
*/
|
||||
protected _shouldShowEventMediaButton(
|
||||
viewName: 'clips' | 'snapshots',
|
||||
buttonConfig: MenuItemBase,
|
||||
cameraManager: CameraManager,
|
||||
foldersManager: FoldersManager,
|
||||
view?: View | null,
|
||||
): boolean {
|
||||
const supportsEventView =
|
||||
view &&
|
||||
isViewSupportedByCamera(viewName, cameraManager, foldersManager, view.camera);
|
||||
const supportsReviewsView =
|
||||
view &&
|
||||
isViewSupportedByCamera('reviews', cameraManager, foldersManager, view.camera);
|
||||
|
||||
// Show if: explicitly enabled OR (supports view AND reviews not supported)
|
||||
return !!supportsEventView && (buttonConfig.enabled || !supportsReviewsView);
|
||||
}
|
||||
|
||||
protected _getClipsButton(
|
||||
config: AdvancedCameraCardConfig,
|
||||
cameraManager: CameraManager,
|
||||
foldersManager: FoldersManager,
|
||||
view?: View | null,
|
||||
): MenuItem | null {
|
||||
return this._shouldShowEventMediaButton(
|
||||
'clips',
|
||||
config.menu.buttons.clips,
|
||||
cameraManager,
|
||||
foldersManager,
|
||||
view,
|
||||
)
|
||||
return view &&
|
||||
isViewSupportedByCamera('clips', cameraManager, foldersManager, view.camera)
|
||||
? {
|
||||
icon: 'mdi:filmstrip',
|
||||
...config.menu.buttons.clips,
|
||||
enabled: true,
|
||||
type: 'custom:advanced-camera-card-menu-icon',
|
||||
title: localize('config.view.views.clips'),
|
||||
style: view?.is('clips') ? this._getEmphasizedStyle() : {},
|
||||
@@ -306,17 +278,11 @@ export class MenuButtonController {
|
||||
foldersManager: FoldersManager,
|
||||
view?: View | null,
|
||||
): MenuItem | null {
|
||||
return this._shouldShowEventMediaButton(
|
||||
'snapshots',
|
||||
config.menu.buttons.snapshots,
|
||||
cameraManager,
|
||||
foldersManager,
|
||||
view,
|
||||
)
|
||||
return view &&
|
||||
isViewSupportedByCamera('snapshots', cameraManager, foldersManager, view.camera)
|
||||
? {
|
||||
icon: 'mdi:camera',
|
||||
...config.menu.buttons.snapshots,
|
||||
enabled: true,
|
||||
type: 'custom:advanced-camera-card-menu-icon',
|
||||
title: localize('config.view.views.snapshots'),
|
||||
style: view?.is('snapshots') ? this._getEmphasizedStyle() : {},
|
||||
@@ -355,7 +321,7 @@ export class MenuButtonController {
|
||||
return view &&
|
||||
isViewSupportedByCamera('reviews', cameraManager, foldersManager, view.camera)
|
||||
? {
|
||||
icon: 'mdi:play-box-multiple',
|
||||
icon: 'mdi:play-box-edit-outline',
|
||||
...config.menu.buttons.reviews,
|
||||
type: 'custom:advanced-camera-card-menu-icon',
|
||||
title: localize('config.view.views.reviews'),
|
||||
@@ -366,6 +332,26 @@ export class MenuButtonController {
|
||||
: null;
|
||||
}
|
||||
|
||||
protected _getGalleryButton(
|
||||
config: AdvancedCameraCardConfig,
|
||||
cameraManager: CameraManager,
|
||||
foldersManager: FoldersManager,
|
||||
view?: View | null,
|
||||
): MenuItem | null {
|
||||
return view &&
|
||||
isViewSupportedByCamera('gallery', cameraManager, foldersManager, view.camera)
|
||||
? {
|
||||
icon: 'mdi:play-box-multiple',
|
||||
...config.menu.buttons.gallery,
|
||||
type: 'custom:advanced-camera-card-menu-icon',
|
||||
title: localize('config.menu.buttons.gallery'),
|
||||
style: view.is('gallery') ? this._getEmphasizedStyle() : {},
|
||||
tap_action: createViewAction('gallery'),
|
||||
hold_action: createViewAction('media'),
|
||||
}
|
||||
: null;
|
||||
}
|
||||
|
||||
protected _getImageButton(
|
||||
config: AdvancedCameraCardConfig,
|
||||
cameraManager: CameraManager,
|
||||
|
||||
@@ -18,6 +18,8 @@ export const VIEWS_USER_SPECIFIED = [
|
||||
'clips',
|
||||
'folder',
|
||||
'folders',
|
||||
'gallery',
|
||||
'media',
|
||||
'snapshot',
|
||||
'snapshots',
|
||||
'recording',
|
||||
@@ -28,7 +30,4 @@ export const VIEWS_USER_SPECIFIED = [
|
||||
'timeline',
|
||||
] as const;
|
||||
export type AdvancedCameraCardUserSpecifiedView = (typeof VIEWS_USER_SPECIFIED)[number];
|
||||
export type AdvancedCameraCardView =
|
||||
| AdvancedCameraCardUserSpecifiedView
|
||||
| 'media'
|
||||
| 'diagnostics';
|
||||
export type AdvancedCameraCardView = AdvancedCameraCardUserSpecifiedView | 'diagnostics';
|
||||
|
||||
@@ -39,6 +39,7 @@ export const menuConfigDefault = {
|
||||
fullscreen: visibleButtonDefault,
|
||||
image: hiddenButtonDefault,
|
||||
info: visibleButtonDefault,
|
||||
gallery: visibleButtonDefault,
|
||||
live: visibleButtonDefault,
|
||||
media_player: visibleButtonDefault,
|
||||
microphone: {
|
||||
@@ -49,7 +50,7 @@ export const menuConfigDefault = {
|
||||
play: hiddenButtonDefault,
|
||||
ptz_controls: hiddenButtonDefault,
|
||||
recordings: hiddenButtonDefault,
|
||||
reviews: visibleButtonDefault,
|
||||
reviews: hiddenButtonDefault,
|
||||
set_review: visibleButtonDefault,
|
||||
screenshot: hiddenButtonDefault,
|
||||
snapshots: hiddenButtonDefault,
|
||||
@@ -91,6 +92,7 @@ export const menuConfigSchema = z
|
||||
fullscreen: visibleButtonSchema.default(menuConfigDefault.buttons.fullscreen),
|
||||
image: hiddenButtonSchema.default(menuConfigDefault.buttons.image),
|
||||
info: visibleButtonSchema.default(menuConfigDefault.buttons.info),
|
||||
gallery: visibleButtonSchema.default(menuConfigDefault.buttons.gallery),
|
||||
live: visibleButtonSchema.default(menuConfigDefault.buttons.live),
|
||||
media_player: visibleButtonSchema.default(
|
||||
menuConfigDefault.buttons.media_player,
|
||||
@@ -106,7 +108,7 @@ export const menuConfigSchema = z
|
||||
play: hiddenButtonSchema.default(menuConfigDefault.buttons.play),
|
||||
ptz_controls: hiddenButtonSchema.default(menuConfigDefault.buttons.ptz_controls),
|
||||
recordings: hiddenButtonSchema.default(menuConfigDefault.buttons.recordings),
|
||||
reviews: visibleButtonSchema.default(menuConfigDefault.buttons.reviews),
|
||||
reviews: hiddenButtonSchema.default(menuConfigDefault.buttons.reviews),
|
||||
set_review: visibleButtonSchema.default(menuConfigDefault.buttons.set_review),
|
||||
screenshot: hiddenButtonSchema.default(menuConfigDefault.buttons.screenshot),
|
||||
snapshots: hiddenButtonSchema.default(menuConfigDefault.buttons.snapshots),
|
||||
|
||||
+4
-1
@@ -368,7 +368,7 @@ const options: EditorOptions = {
|
||||
secondary: localize('editor.folders'),
|
||||
},
|
||||
media_gallery: {
|
||||
icon: 'grid',
|
||||
icon: 'play-box-multiple',
|
||||
name: localize('editor.media_gallery'),
|
||||
secondary: localize('editor.media_gallery_secondary'),
|
||||
},
|
||||
@@ -432,8 +432,10 @@ export class AdvancedCameraCardEditor extends LitElement implements LovelaceCard
|
||||
{ value: 'clips', label: localize('config.view.views.clips') },
|
||||
{ value: 'folder', label: localize('config.view.views.folder') },
|
||||
{ value: 'folders', label: localize('config.view.views.folders') },
|
||||
{ value: 'gallery', label: localize('config.view.views.gallery') },
|
||||
{ value: 'image', label: localize('config.view.views.image') },
|
||||
{ value: 'live', label: localize('config.view.views.live') },
|
||||
{ value: 'media', label: localize('config.view.views.media') },
|
||||
{ value: 'recording', label: localize('config.view.views.recording') },
|
||||
{ value: 'recordings', label: localize('config.view.views.recordings') },
|
||||
{ value: 'review', label: localize('config.view.views.review') },
|
||||
@@ -2927,6 +2929,7 @@ export class AdvancedCameraCardEditor extends LitElement implements LovelaceCard
|
||||
${this._renderMenuButton('expand') /* */}
|
||||
${this._renderMenuButton('folders')}
|
||||
${this._renderMenuButton('fullscreen')}
|
||||
${this._renderMenuButton('gallery')}
|
||||
${this._renderMenuButton('image') /* */}
|
||||
${this._renderMenuButton('info') /* */}
|
||||
${this._renderMenuButton('live')}
|
||||
|
||||
@@ -459,11 +459,13 @@
|
||||
"expand": "Expand",
|
||||
"folders": "Folders",
|
||||
"fullscreen": "Fullscreen",
|
||||
"gallery": "Gallery",
|
||||
"icon": "Icon",
|
||||
"image": "Image",
|
||||
"info": "Info",
|
||||
"iris": "Iris / Default View / Unhide menu",
|
||||
"live": "Live",
|
||||
"media": "Media",
|
||||
"media_player": "Send to media player",
|
||||
"microphone": "Microphone",
|
||||
"mute": "Mute / Unmute",
|
||||
@@ -631,8 +633,10 @@
|
||||
"current": "Current view",
|
||||
"folder": "Folder media",
|
||||
"folders": "Folders gallery",
|
||||
"gallery": "Default media gallery",
|
||||
"image": "Static image",
|
||||
"live": "Live view",
|
||||
"media": "Most recent default media item",
|
||||
"recording": "Most recent recording",
|
||||
"recordings": "Recordings gallery",
|
||||
"review": "Most recent media to review",
|
||||
|
||||
@@ -538,5 +538,4 @@
|
||||
--advanced-camera-card-overlay-message-scrollbar-color: rgba(0, 0, 0, 0.5);
|
||||
--advanced-camera-card-overlay-message-close-color: #000000;
|
||||
--app-header-text-color: white;
|
||||
|
||||
}
|
||||
|
||||
@@ -18,7 +18,6 @@ export const getCameraIDsForViewName = (
|
||||
switch (viewName) {
|
||||
case 'diagnostics':
|
||||
case 'image':
|
||||
case 'media':
|
||||
return cameraManager.getStore().getCameraIDs();
|
||||
|
||||
case 'folder':
|
||||
@@ -51,11 +50,13 @@ export const getCameraIDsForViewName = (
|
||||
? 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'],
|
||||
anyCapabilities: ['clips', 'snapshots', 'recordings', 'reviews'],
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
+8
-3
@@ -127,9 +127,14 @@ export class View {
|
||||
* Determine if a view is a gallery.
|
||||
*/
|
||||
public isGalleryView(): boolean {
|
||||
return ['clips', 'folders', 'snapshots', 'recordings', 'reviews'].includes(
|
||||
this.view,
|
||||
);
|
||||
return [
|
||||
'clips',
|
||||
'folders',
|
||||
'gallery',
|
||||
'snapshots',
|
||||
'recordings',
|
||||
'reviews',
|
||||
].includes(this.view);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user