Add menu overrides and remove menu conditions.
This commit is contained in:
+68
-54
@@ -133,13 +133,11 @@ export class FrigateCard extends LitElement {
|
|||||||
protected _hass?: HomeAssistant & ExtendedHomeAssistant;
|
protected _hass?: HomeAssistant & ExtendedHomeAssistant;
|
||||||
|
|
||||||
@state()
|
@state()
|
||||||
public config!: FrigateCardConfig;
|
public _baseConfig!: FrigateCardConfig;
|
||||||
|
|
||||||
@state()
|
@state()
|
||||||
public _overriddenConfig?: FrigateCardConfig;
|
public _overriddenConfig?: FrigateCardConfig;
|
||||||
|
|
||||||
protected _interactionTimerID: number | null = null;
|
|
||||||
|
|
||||||
@property({ attribute: false })
|
@property({ attribute: false })
|
||||||
protected _view?: View;
|
protected _view?: View;
|
||||||
|
|
||||||
@@ -152,6 +150,9 @@ export class FrigateCard extends LitElement {
|
|||||||
@query('frigate-card-elements')
|
@query('frigate-card-elements')
|
||||||
_elements?: FrigateCardElements;
|
_elements?: FrigateCardElements;
|
||||||
|
|
||||||
|
// Human interaction timer ID.
|
||||||
|
protected _interactionTimerID: number | null = null;
|
||||||
|
|
||||||
// Whether or not media is actively playing (live or clip).
|
// Whether or not media is actively playing (live or clip).
|
||||||
protected _mediaPlaying = false;
|
protected _mediaPlaying = false;
|
||||||
|
|
||||||
@@ -231,9 +232,10 @@ export class FrigateCard extends LitElement {
|
|||||||
};
|
};
|
||||||
|
|
||||||
this._overriddenConfig = getOverriddenConfig(
|
this._overriddenConfig = getOverriddenConfig(
|
||||||
this.config,
|
this._baseConfig,
|
||||||
this.config.overrides,
|
this._baseConfig.overrides,
|
||||||
this._conditionState) as FrigateCardConfig;
|
this._conditionState,
|
||||||
|
) as FrigateCardConfig;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -275,7 +277,7 @@ export class FrigateCard extends LitElement {
|
|||||||
protected _getMenuButtons(): MenuButton[] {
|
protected _getMenuButtons(): MenuButton[] {
|
||||||
const buttons: MenuButton[] = [];
|
const buttons: MenuButton[] = [];
|
||||||
|
|
||||||
if (this.config.menu.buttons.frigate) {
|
if (this._getConfig().menu.buttons.frigate) {
|
||||||
buttons.push(
|
buttons.push(
|
||||||
this._getFrigateCardMenuButton({
|
this._getFrigateCardMenuButton({
|
||||||
tap_action: 'frigate',
|
tap_action: 'frigate',
|
||||||
@@ -288,7 +290,11 @@ export class FrigateCard extends LitElement {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.config.menu.buttons.cameras && this._cameras && this._cameras.size > 1) {
|
if (
|
||||||
|
this._getConfig().menu.buttons.cameras &&
|
||||||
|
this._cameras &&
|
||||||
|
this._cameras.size > 1
|
||||||
|
) {
|
||||||
const menuItems = Array.from(this._cameras, ([camera, config]) => {
|
const menuItems = Array.from(this._cameras, ([camera, config]) => {
|
||||||
return {
|
return {
|
||||||
icon: getCameraIcon(this._hass, config),
|
icon: getCameraIcon(this._hass, config),
|
||||||
@@ -307,7 +313,7 @@ export class FrigateCard extends LitElement {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.config.menu.buttons.live) {
|
if (this._getConfig().menu.buttons.live) {
|
||||||
buttons.push(
|
buttons.push(
|
||||||
this._getFrigateCardMenuButton({
|
this._getFrigateCardMenuButton({
|
||||||
tap_action: 'live',
|
tap_action: 'live',
|
||||||
@@ -318,7 +324,7 @@ export class FrigateCard extends LitElement {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.config.menu.buttons.clips) {
|
if (this._getConfig().menu.buttons.clips) {
|
||||||
buttons.push(
|
buttons.push(
|
||||||
this._getFrigateCardMenuButton({
|
this._getFrigateCardMenuButton({
|
||||||
tap_action: 'clips',
|
tap_action: 'clips',
|
||||||
@@ -329,7 +335,7 @@ export class FrigateCard extends LitElement {
|
|||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
if (this.config.menu.buttons.snapshots) {
|
if (this._getConfig().menu.buttons.snapshots) {
|
||||||
buttons.push(
|
buttons.push(
|
||||||
this._getFrigateCardMenuButton({
|
this._getFrigateCardMenuButton({
|
||||||
tap_action: 'snapshots',
|
tap_action: 'snapshots',
|
||||||
@@ -340,7 +346,7 @@ export class FrigateCard extends LitElement {
|
|||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
if (this.config.menu.buttons.image) {
|
if (this._getConfig().menu.buttons.image) {
|
||||||
buttons.push(
|
buttons.push(
|
||||||
this._getFrigateCardMenuButton({
|
this._getFrigateCardMenuButton({
|
||||||
tap_action: 'image',
|
tap_action: 'image',
|
||||||
@@ -350,7 +356,7 @@ export class FrigateCard extends LitElement {
|
|||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
if (this.config.menu.buttons.download && this._view?.isViewerView()) {
|
if (this._getConfig().menu.buttons.download && this._view?.isViewerView()) {
|
||||||
buttons.push(
|
buttons.push(
|
||||||
this._getFrigateCardMenuButton({
|
this._getFrigateCardMenuButton({
|
||||||
tap_action: 'download',
|
tap_action: 'download',
|
||||||
@@ -362,7 +368,7 @@ export class FrigateCard extends LitElement {
|
|||||||
|
|
||||||
const cameraConfig = this._getSelectedCameraConfig();
|
const cameraConfig = this._getSelectedCameraConfig();
|
||||||
if (
|
if (
|
||||||
this.config.menu.buttons.frigate_ui &&
|
this._getConfig().menu.buttons.frigate_ui &&
|
||||||
cameraConfig &&
|
cameraConfig &&
|
||||||
cameraConfig.frigate_url
|
cameraConfig.frigate_url
|
||||||
) {
|
) {
|
||||||
@@ -374,7 +380,7 @@ export class FrigateCard extends LitElement {
|
|||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
if (this.config.menu.buttons.fullscreen && screenfull.isEnabled) {
|
if (this._getConfig().menu.buttons.fullscreen && screenfull.isEnabled) {
|
||||||
buttons.push(
|
buttons.push(
|
||||||
this._getFrigateCardMenuButton({
|
this._getFrigateCardMenuButton({
|
||||||
tap_action: 'fullscreen',
|
tap_action: 'fullscreen',
|
||||||
@@ -439,8 +445,8 @@ export class FrigateCard extends LitElement {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
if (this.config.cameras && Array.isArray(this.config.cameras)) {
|
if (this._getConfig().cameras && Array.isArray(this._getConfig().cameras)) {
|
||||||
await Promise.all(this.config.cameras.map(addCameraConfig.bind(this)));
|
await Promise.all(this._getConfig().cameras.map(addCameraConfig.bind(this)));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!cameras.size) {
|
if (!cameras.size) {
|
||||||
@@ -600,17 +606,25 @@ export class FrigateCard extends LitElement {
|
|||||||
getLovelace().setEditMode(true);
|
getLovelace().setEditMode(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.config = config;
|
this._baseConfig = config;
|
||||||
this._cameras = undefined;
|
this._cameras = undefined;
|
||||||
this._view = undefined;
|
this._view = undefined;
|
||||||
|
|
||||||
if (this.config.view.update_force) {
|
if (this._getConfig().view.update_force) {
|
||||||
// If update force is enabled, start a timer right away.
|
// If update force is enabled, start a timer right away.
|
||||||
this._resetInteractionTimer();
|
this._resetInteractionTimer();
|
||||||
}
|
}
|
||||||
this._changeView();
|
this._changeView();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Card the card config, prioritizing the overriden config if present.
|
||||||
|
* @returns A FrigateCardConfig.
|
||||||
|
*/
|
||||||
|
protected _getConfig(): FrigateCardConfig {
|
||||||
|
return this._overriddenConfig || this._baseConfig;
|
||||||
|
}
|
||||||
|
|
||||||
protected _changeView(args?: { view?: View; resetMessage?: boolean }): void {
|
protected _changeView(args?: { view?: View; resetMessage?: boolean }): void {
|
||||||
console.info(`Request to change view: ${JSON.stringify(args?.view?.view)}`);
|
console.info(`Request to change view: ${JSON.stringify(args?.view?.view)}`);
|
||||||
|
|
||||||
@@ -626,7 +640,7 @@ export class FrigateCard extends LitElement {
|
|||||||
|
|
||||||
if (camera) {
|
if (camera) {
|
||||||
this._view = new View({
|
this._view = new View({
|
||||||
view: this.config.view.default,
|
view: this._getConfig().view.default,
|
||||||
camera: camera,
|
camera: camera,
|
||||||
});
|
});
|
||||||
this._generateConditionState();
|
this._generateConditionState();
|
||||||
@@ -651,10 +665,6 @@ export class FrigateCard extends LitElement {
|
|||||||
* @returns True if the card should be updated.
|
* @returns True if the card should be updated.
|
||||||
*/
|
*/
|
||||||
protected shouldUpdate(changedProps: PropertyValues): boolean {
|
protected shouldUpdate(changedProps: PropertyValues): boolean {
|
||||||
if (!this.config) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (changedProps.size > 1) {
|
if (changedProps.size > 1) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -668,12 +678,12 @@ export class FrigateCard extends LitElement {
|
|||||||
// Assistant update if there's been recent interaction (e.g. clicks on the
|
// Assistant update if there's been recent interaction (e.g. clicks on the
|
||||||
// card) or if there is media active playing.
|
// card) or if there is media active playing.
|
||||||
if (
|
if (
|
||||||
(this.config.view.update_force ||
|
(this._getConfig().view.update_force ||
|
||||||
!(this._interactionTimerID && this._mediaPlaying)) &&
|
!(this._interactionTimerID && this._mediaPlaying)) &&
|
||||||
shouldUpdateBasedOnHass(
|
shouldUpdateBasedOnHass(
|
||||||
this._hass,
|
this._hass,
|
||||||
oldHass,
|
oldHass,
|
||||||
this.config.view.update_entities || [],
|
this._getConfig().view.update_entities || [],
|
||||||
)
|
)
|
||||||
) {
|
) {
|
||||||
// If entities being monitored have changed then reset the view to the
|
// If entities being monitored have changed then reset the view to the
|
||||||
@@ -868,18 +878,18 @@ export class FrigateCard extends LitElement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected _resetInteractionTimer(): void {
|
protected _resetInteractionTimer(): void {
|
||||||
if (this.config.view.timeout) {
|
if (this._getConfig().view.timeout) {
|
||||||
if (this._interactionTimerID) {
|
if (this._interactionTimerID) {
|
||||||
window.clearTimeout(this._interactionTimerID);
|
window.clearTimeout(this._interactionTimerID);
|
||||||
}
|
}
|
||||||
this._interactionTimerID = window.setTimeout(() => {
|
this._interactionTimerID = window.setTimeout(() => {
|
||||||
this._interactionTimerID = null;
|
this._interactionTimerID = null;
|
||||||
this._changeView();
|
this._changeView();
|
||||||
if (this.config.view.update_force) {
|
if (this._getConfig().view.update_force) {
|
||||||
// If force is enabled, the timer just resets and starts over.
|
// If force is enabled, the timer just resets and starts over.
|
||||||
this._resetInteractionTimer();
|
this._resetInteractionTimer();
|
||||||
}
|
}
|
||||||
}, this.config.view.timeout * 1000);
|
}, this._getConfig().view.timeout * 1000);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -889,12 +899,12 @@ export class FrigateCard extends LitElement {
|
|||||||
*/
|
*/
|
||||||
protected _renderMenu(): TemplateResult | void {
|
protected _renderMenu(): TemplateResult | void {
|
||||||
const classes = {
|
const classes = {
|
||||||
'hover-menu': this.config.menu.mode.startsWith('hover-'),
|
'hover-menu': this._getConfig().menu.mode.startsWith('hover-'),
|
||||||
};
|
};
|
||||||
return html`
|
return html`
|
||||||
<frigate-card-menu
|
<frigate-card-menu
|
||||||
.hass=${this._hass}
|
.hass=${this._hass}
|
||||||
.menuConfig=${this.config.menu}
|
.menuConfig=${this._getConfig().menu}
|
||||||
.buttons=${this._getMenuButtons()}
|
.buttons=${this._getMenuButtons()}
|
||||||
.conditionState=${this._conditionState}
|
.conditionState=${this._conditionState}
|
||||||
class="${classMap(classes)}"
|
class="${classMap(classes)}"
|
||||||
@@ -1003,7 +1013,7 @@ export class FrigateCard extends LitElement {
|
|||||||
* context.
|
* context.
|
||||||
*/
|
*/
|
||||||
protected _isAspectRatioEnforced(): boolean {
|
protected _isAspectRatioEnforced(): boolean {
|
||||||
const aspectRatioMode = this.config.dimensions.aspect_ratio_mode;
|
const aspectRatioMode = this._getConfig().dimensions.aspect_ratio_mode;
|
||||||
|
|
||||||
// Do not artifically constrain aspect ratio if:
|
// Do not artifically constrain aspect ratio if:
|
||||||
// - It's fullscreen.
|
// - It's fullscreen.
|
||||||
@@ -1027,12 +1037,12 @@ export class FrigateCard extends LitElement {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
const aspectRatioMode = this.config.dimensions.aspect_ratio_mode;
|
const aspectRatioMode = this._getConfig().dimensions.aspect_ratio_mode;
|
||||||
if (aspectRatioMode == 'dynamic' && this._mediaShowInfo) {
|
if (aspectRatioMode == 'dynamic' && this._mediaShowInfo) {
|
||||||
return (this._mediaShowInfo.height / this._mediaShowInfo.width) * 100;
|
return (this._mediaShowInfo.height / this._mediaShowInfo.width) * 100;
|
||||||
}
|
}
|
||||||
|
|
||||||
const defaultAspectRatio = this.config.dimensions.aspect_ratio;
|
const defaultAspectRatio = this._getConfig().dimensions.aspect_ratio;
|
||||||
if (defaultAspectRatio) {
|
if (defaultAspectRatio) {
|
||||||
return (defaultAspectRatio[1] / defaultAspectRatio[0]) * 100;
|
return (defaultAspectRatio[1] / defaultAspectRatio[0]) * 100;
|
||||||
} else {
|
} else {
|
||||||
@@ -1048,15 +1058,15 @@ export class FrigateCard extends LitElement {
|
|||||||
let specificActions: Actions | undefined = undefined;
|
let specificActions: Actions | undefined = undefined;
|
||||||
|
|
||||||
if (this._view?.is('live')) {
|
if (this._view?.is('live')) {
|
||||||
specificActions = this._overriddenConfig?.live.actions;
|
specificActions = this._getConfig().live.actions;
|
||||||
} else if (this._view?.isGalleryView()) {
|
} else if (this._view?.isGalleryView()) {
|
||||||
specificActions = this._overriddenConfig?.event_gallery?.actions;
|
specificActions = this._getConfig().event_gallery?.actions;
|
||||||
} else if (this._view?.isViewerView()) {
|
} else if (this._view?.isViewerView()) {
|
||||||
specificActions = this._overriddenConfig?.event_viewer.actions;
|
specificActions = this._getConfig().event_viewer.actions;
|
||||||
} else if (this._view?.is('image')) {
|
} else if (this._view?.is('image')) {
|
||||||
specificActions = this._overriddenConfig?.image?.actions;
|
specificActions = this._getConfig().image?.actions;
|
||||||
}
|
}
|
||||||
return { ...this.config.view.actions, ...specificActions };
|
return { ...this._getConfig().view.actions, ...specificActions };
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1096,16 +1106,16 @@ export class FrigateCard extends LitElement {
|
|||||||
@frigate-card:pause=${this._pauseHandler}
|
@frigate-card:pause=${this._pauseHandler}
|
||||||
@frigate-card:play=${this._playHandler}
|
@frigate-card:play=${this._playHandler}
|
||||||
>
|
>
|
||||||
${this.config.menu.mode == 'above' ? this._renderMenu() : ''}
|
${this._getConfig().menu.mode == 'above' ? this._renderMenu() : ''}
|
||||||
<div class="container outer" style="${styleMap(outerStyle)}">
|
<div class="container outer" style="${styleMap(outerStyle)}">
|
||||||
<div class="${classMap(contentClasses)}">
|
<div class="${classMap(contentClasses)}">
|
||||||
<div class="${classMap(pictureElementsClasses)}">
|
<div class="${classMap(pictureElementsClasses)}">
|
||||||
${this.config.elements
|
${this._getConfig().elements
|
||||||
? // Always show elements to allow for custom menu items (etc.) to
|
? // Always show elements to allow for custom menu items (etc.) to
|
||||||
// be present even if a particular view has an error.
|
// be present even if a particular view has an error.
|
||||||
html` <frigate-card-elements
|
html` <frigate-card-elements
|
||||||
.hass=${this._hass}
|
.hass=${this._hass}
|
||||||
.elements=${this.config.elements}
|
.elements=${this._getConfig().elements}
|
||||||
.conditionState=${this._conditionState}
|
.conditionState=${this._conditionState}
|
||||||
@frigate-card:menu-add=${(e) => {
|
@frigate-card:menu-add=${(e) => {
|
||||||
this._addDynamicMenuButton(e.detail);
|
this._addDynamicMenuButton(e.detail);
|
||||||
@@ -1141,7 +1151,7 @@ export class FrigateCard extends LitElement {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
${this.config.menu.mode != 'above' ? this._renderMenu() : ''}
|
${this._getConfig().menu.mode != 'above' ? this._renderMenu() : ''}
|
||||||
</ha-card>`;
|
</ha-card>`;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1156,22 +1166,22 @@ export class FrigateCard extends LitElement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const galleryClasses = {
|
const galleryClasses = {
|
||||||
hidden: this.config.live.preload && !this._view.isGalleryView(),
|
hidden: this._getConfig().live.preload && !this._view.isGalleryView(),
|
||||||
};
|
};
|
||||||
const viewerClasses = {
|
const viewerClasses = {
|
||||||
hidden: this.config.live.preload && !this._view.isViewerView(),
|
hidden: this._getConfig().live.preload && !this._view.isViewerView(),
|
||||||
};
|
};
|
||||||
const liveClasses = {
|
const liveClasses = {
|
||||||
hidden: this.config.live.preload && this._view.view != 'live',
|
hidden: this._getConfig().live.preload && this._view.view != 'live',
|
||||||
};
|
};
|
||||||
const imageClasses = {
|
const imageClasses = {
|
||||||
hidden: this.config.live.preload && this._view.view != 'image',
|
hidden: this._getConfig().live.preload && this._view.view != 'image',
|
||||||
};
|
};
|
||||||
|
|
||||||
return html`
|
return html`
|
||||||
${!this._message && this._view.is('image')
|
${!this._message && this._view.is('image')
|
||||||
? html` <frigate-card-image
|
? html` <frigate-card-image
|
||||||
.imageConfig=${this.config.image}
|
.imageConfig=${this._getConfig().image}
|
||||||
class="${classMap(imageClasses)}"
|
class="${classMap(imageClasses)}"
|
||||||
>
|
>
|
||||||
</frigate-card-image>`
|
</frigate-card-image>`
|
||||||
@@ -1196,25 +1206,29 @@ export class FrigateCard extends LitElement {
|
|||||||
this._view,
|
this._view,
|
||||||
cameraConfig,
|
cameraConfig,
|
||||||
)}
|
)}
|
||||||
.viewerConfig=${this.config.event_viewer}
|
.viewerConfig=${this._getConfig().event_viewer}
|
||||||
.resolvedMediaCache=${this._resolvedMediaCache}
|
.resolvedMediaCache=${this._resolvedMediaCache}
|
||||||
class="${classMap(viewerClasses)}"
|
class="${classMap(viewerClasses)}"
|
||||||
>
|
>
|
||||||
</frigate-card-viewer>`
|
</frigate-card-viewer>`
|
||||||
: ``}
|
: ``}
|
||||||
${
|
${
|
||||||
// Note the subtle difference in condition below vs the other views in order
|
// Note: Subtle difference in condition below vs the other views in order
|
||||||
// to always render the live view for live.preload mode.
|
// to always render the live view for live.preload mode.
|
||||||
(!this._message && this._view.is('live')) || this.config.live.preload
|
|
||||||
|
// Note: <frigate-card-live> uses the baseConfig rather than the
|
||||||
|
// overriden config, as it does it's own overriding as part of the
|
||||||
|
// camera carousel.
|
||||||
|
(!this._message && this._view.is('live')) || this._getConfig().live.preload
|
||||||
? html`
|
? html`
|
||||||
<frigate-card-live
|
<frigate-card-live
|
||||||
.hass=${this._hass}
|
.hass=${this._hass}
|
||||||
.view=${this._view}
|
.view=${this._view}
|
||||||
.liveConfig=${this.config.live}
|
.liveConfig=${this._baseConfig.live}
|
||||||
.conditionState=${this._conditionState}
|
.conditionState=${this._conditionState}
|
||||||
.liveOverrides=${getOverridesByKey(this.config.overrides, 'live')}
|
.liveOverrides=${getOverridesByKey(this._getConfig().overrides, 'live')}
|
||||||
.cameras=${this._cameras}
|
.cameras=${this._cameras}
|
||||||
.preload=${this.config.live.preload && !this._view.is('live')}
|
.preload=${this._getConfig().live.preload && !this._view.is('live')}
|
||||||
class="${classMap(liveClasses)}"
|
class="${classMap(liveClasses)}"
|
||||||
>
|
>
|
||||||
</frigate-card-live>
|
</frigate-card-live>
|
||||||
|
|||||||
+3
-10
@@ -6,7 +6,7 @@ import {
|
|||||||
html,
|
html,
|
||||||
unsafeCSS,
|
unsafeCSS,
|
||||||
} from 'lit';
|
} from 'lit';
|
||||||
import { customElement, property } from 'lit/decorators.js';
|
import { customElement, property, state } from 'lit/decorators.js';
|
||||||
import { classMap } from 'lit/directives/class-map.js';
|
import { classMap } from 'lit/directives/class-map.js';
|
||||||
import { styleMap } from 'lit/directives/style-map.js';
|
import { styleMap } from 'lit/directives/style-map.js';
|
||||||
|
|
||||||
@@ -28,7 +28,6 @@ import {
|
|||||||
} from '../common.js';
|
} from '../common.js';
|
||||||
|
|
||||||
import menuStyle from '../scss/menu.scss';
|
import menuStyle from '../scss/menu.scss';
|
||||||
import { ConditionState, evaluateCondition } from '../card-condition.js';
|
|
||||||
import { Corner } from '@material/mwc-menu';
|
import { Corner } from '@material/mwc-menu';
|
||||||
|
|
||||||
export const FRIGATE_BUTTON_MENU_ICON = 'frigate';
|
export const FRIGATE_BUTTON_MENU_ICON = 'frigate';
|
||||||
@@ -41,13 +40,13 @@ export class FrigateCardMenu extends LitElement {
|
|||||||
@property({ attribute: false })
|
@property({ attribute: false })
|
||||||
public hass?: HomeAssistant & ExtendedHomeAssistant;
|
public hass?: HomeAssistant & ExtendedHomeAssistant;
|
||||||
|
|
||||||
@property({ attribute: false })
|
|
||||||
set menuConfig(menuConfig: MenuConfig) {
|
set menuConfig(menuConfig: MenuConfig) {
|
||||||
this._menuConfig = menuConfig;
|
this._menuConfig = menuConfig;
|
||||||
if (menuConfig) {
|
if (menuConfig) {
|
||||||
this.style.setProperty('--frigate-card-menu-button-size', menuConfig.button_size);
|
this.style.setProperty('--frigate-card-menu-button-size', menuConfig.button_size);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@state()
|
||||||
protected _menuConfig?: MenuConfig;
|
protected _menuConfig?: MenuConfig;
|
||||||
|
|
||||||
@property({ attribute: false })
|
@property({ attribute: false })
|
||||||
@@ -56,9 +55,6 @@ export class FrigateCardMenu extends LitElement {
|
|||||||
@property({ attribute: false })
|
@property({ attribute: false })
|
||||||
public buttons: MenuButton[] = [];
|
public buttons: MenuButton[] = [];
|
||||||
|
|
||||||
@property({ attribute: false })
|
|
||||||
protected conditionState?: ConditionState;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handle an action on a menu button.
|
* Handle an action on a menu button.
|
||||||
* @param ev The action event.
|
* @param ev The action event.
|
||||||
@@ -185,10 +181,7 @@ export class FrigateCardMenu extends LitElement {
|
|||||||
}
|
}
|
||||||
const mode = this._menuConfig.mode;
|
const mode = this._menuConfig.mode;
|
||||||
|
|
||||||
if (
|
if (mode == 'none') {
|
||||||
mode == 'none' ||
|
|
||||||
!evaluateCondition(this._menuConfig.conditions, this.conditionState)
|
|
||||||
) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+25
-4
@@ -572,9 +572,28 @@ const menuConfigDefault = {
|
|||||||
},
|
},
|
||||||
button_size: '40px',
|
button_size: '40px',
|
||||||
};
|
};
|
||||||
const menuConfigSchema = z
|
|
||||||
|
const menuOverridableConfigSchema = z.object({
|
||||||
|
mode: z.enum(FRIGATE_MENU_MODES).optional(),
|
||||||
|
buttons: z
|
||||||
.object({
|
.object({
|
||||||
mode: z.enum(FRIGATE_MENU_MODES).optional().default(menuConfigDefault.mode),
|
frigate: z.boolean().optional(),
|
||||||
|
cameras: z.boolean().optional(),
|
||||||
|
live: z.boolean().optional(),
|
||||||
|
clips: z.boolean().optional(),
|
||||||
|
snapshots: z.boolean().optional(),
|
||||||
|
image: z.boolean().optional(),
|
||||||
|
download: z.boolean().optional(),
|
||||||
|
frigate_ui: z.boolean().optional(),
|
||||||
|
fullscreen: z.boolean().optional(),
|
||||||
|
})
|
||||||
|
.optional(),
|
||||||
|
button_size: z.string().optional(),
|
||||||
|
});
|
||||||
|
|
||||||
|
const menuConfigSchema = menuOverridableConfigSchema
|
||||||
|
.extend({
|
||||||
|
mode: menuOverridableConfigSchema.shape.mode.default(menuConfigDefault.mode),
|
||||||
buttons: z
|
buttons: z
|
||||||
.object({
|
.object({
|
||||||
frigate: z.boolean().default(menuConfigDefault.buttons.frigate),
|
frigate: z.boolean().default(menuConfigDefault.buttons.frigate),
|
||||||
@@ -588,8 +607,9 @@ const menuConfigSchema = z
|
|||||||
fullscreen: z.boolean().default(menuConfigDefault.buttons.fullscreen),
|
fullscreen: z.boolean().default(menuConfigDefault.buttons.fullscreen),
|
||||||
})
|
})
|
||||||
.default(menuConfigDefault.buttons),
|
.default(menuConfigDefault.buttons),
|
||||||
button_size: z.string().default(menuConfigDefault.button_size),
|
button_size: menuOverridableConfigSchema.shape.button_size.default(
|
||||||
conditions: frigateCardConditionSchema.optional(),
|
menuConfigDefault.button_size,
|
||||||
|
)
|
||||||
})
|
})
|
||||||
.default(menuConfigDefault);
|
.default(menuConfigDefault);
|
||||||
export type MenuConfig = z.infer<typeof menuConfigSchema>;
|
export type MenuConfig = z.infer<typeof menuConfigSchema>;
|
||||||
@@ -688,6 +708,7 @@ const dimensionsConfigSchema = z
|
|||||||
*/
|
*/
|
||||||
const overrideConfigurationSchema = z.object({
|
const overrideConfigurationSchema = z.object({
|
||||||
live: liveOverridableConfigSchema.optional(),
|
live: liveOverridableConfigSchema.optional(),
|
||||||
|
menu: menuOverridableConfigSchema.optional(),
|
||||||
});
|
});
|
||||||
export type OverrideConfigurationKey = keyof z.infer<typeof overrideConfigurationSchema>;
|
export type OverrideConfigurationKey = keyof z.infer<typeof overrideConfigurationSchema>;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user