Convert editor to use new ha-selector components.

This commit is contained in:
Dermot Duffy
2022-02-27 16:12:21 -08:00
parent 96da213341
commit b179eddab7
4 changed files with 298 additions and 220 deletions
+294 -217
View File
@@ -177,110 +177,140 @@ export class FrigateCardEditor extends LitElement implements LovelaceCardEditor
@property({ attribute: false }) @property({ attribute: false })
protected _expandedCameraIndex: number | null = null; protected _expandedCameraIndex: number | null = null;
protected _viewModes = new Map([ protected _viewModes = [
['', ''], { value: '', label: '' },
['live', localize('config.view.views.live')], { value: 'live', label: localize('config.view.views.live') },
['clips', localize('config.view.views.clips')], { value: 'clips', label: localize('config.view.views.clips') },
['snapshots', localize('config.view.views.snapshots')], { value: 'snapshots', label: localize('config.view.views.snapshots') },
['clip', localize('config.view.views.clip')], { value: 'clip', label: localize('config.view.views.clip') },
['snapshot', localize('config.view.views.snapshot')], { value: 'snapshot', label: localize('config.view.views.snapshot') },
['image', localize('config.view.views.image')], { value: 'image', label: localize('config.view.views.image') },
]); ];
protected _cameraSelectViewModes = new Map([ protected _cameraSelectViewModes = [
...this._viewModes, ...this._viewModes,
['current', localize('config.view.views.current')], { value: 'current', label: localize('config.view.views.current') },
]); ];
protected _menuModes = new Map([ protected _menuModes = [
['', ''], { value: '', label: '' },
['none', localize('config.menu.modes.none')], { value: 'none', label: localize('config.menu.modes.none') },
['hidden-top', localize('config.menu.modes.hidden-top')], { value: 'hidden-top', label: localize('config.menu.modes.hidden-top') },
['hidden-left', localize('config.menu.modes.hidden-left')], { value: 'hidden-left', label: localize('config.menu.modes.hidden-left') },
['hidden-bottom', localize('config.menu.modes.hidden-bottom')], { value: 'hidden-bottom', label: localize('config.menu.modes.hidden-bottom') },
['hidden-right', localize('config.menu.modes.hidden-right')], { value: 'hidden-right', label: localize('config.menu.modes.hidden-right') },
['overlay-top', localize('config.menu.modes.overlay-top')], { value: 'overlay-top', label: localize('config.menu.modes.overlay-top') },
['overlay-left', localize('config.menu.modes.overlay-left')], { value: 'overlay-left', label: localize('config.menu.modes.overlay-left') },
['overlay-bottom', localize('config.menu.modes.overlay-bottom')], { value: 'overlay-bottom', label: localize('config.menu.modes.overlay-bottom') },
['overlay-right', localize('config.menu.modes.overlay-right')], { value: 'overlay-right', label: localize('config.menu.modes.overlay-right') },
['hover-top', localize('config.menu.modes.hover-top')], { value: 'hover-top', label: localize('config.menu.modes.hover-top') },
['hover-left', localize('config.menu.modes.hover-left')], { value: 'hover-left', label: localize('config.menu.modes.hover-left') },
['hover-bottom', localize('config.menu.modes.hover-bottom')], { value: 'hover-bottom', label: localize('config.menu.modes.hover-bottom') },
['hover-right', localize('config.menu.modes.hover-right')], { value: 'hover-right', label: localize('config.menu.modes.hover-right') },
['above', localize('config.menu.modes.above')], { value: 'above', label: localize('config.menu.modes.above') },
['below', localize('config.menu.modes.below')], { value: 'below', label: localize('config.menu.modes.below') },
]); ];
protected _eventViewerNextPreviousControlStyles = new Map([ protected _eventViewerNextPreviousControlStyles = [
['', ''], { value: '', label: '' },
[ {
'thumbnails', value: 'thumbnails',
localize('config.event_viewer.controls.next_previous.styles.thumbnails'), label: localize('config.event_viewer.controls.next_previous.styles.thumbnails'),
], },
['chevrons', localize('config.event_viewer.controls.next_previous.styles.chevrons')], {
['none', localize('config.event_viewer.controls.next_previous.styles.none')], value: 'chevrons',
]); label: localize('config.event_viewer.controls.next_previous.styles.chevrons'),
},
{
value: 'none',
label: localize('config.event_viewer.controls.next_previous.styles.none'),
},
];
protected _liveNextPreviousControlStyles = new Map([ protected _liveNextPreviousControlStyles = [
['', ''], { value: '', label: '' },
['chevrons', localize('config.live.controls.next_previous.styles.chevrons')], {
['icons', localize('config.live.controls.next_previous.styles.icons')], value: 'chevrons',
['none', localize('config.live.controls.next_previous.styles.none')], label: localize('config.live.controls.next_previous.styles.chevrons'),
]); },
{
value: 'icons',
label: localize('config.live.controls.next_previous.styles.icons'),
},
{ value: 'none', label: localize('config.live.controls.next_previous.styles.none') },
];
protected _aspectRatioModes = new Map([ protected _aspectRatioModes = [
['', ''], { value: '', label: '' },
['dynamic', localize('config.dimensions.aspect_ratio_modes.dynamic')], {
['static', localize('config.dimensions.aspect_ratio_modes.static')], value: 'dynamic',
['unconstrained', localize('config.dimensions.aspect_ratio_modes.unconstrained')], label: localize('config.dimensions.aspect_ratio_modes.dynamic'),
]); },
{ value: 'static', label: localize('config.dimensions.aspect_ratio_modes.static') },
{
value: 'unconstrained',
label: localize('config.dimensions.aspect_ratio_modes.unconstrained'),
},
];
protected _thumbnailModes = new Map([ protected _thumbnailModes = [
['', ''], { value: '', label: '' },
['none', localize('config.event_viewer.controls.thumbnails.modes.none')], {
['above', localize('config.event_viewer.controls.thumbnails.modes.above')], value: 'none',
['below', localize('config.event_viewer.controls.thumbnails.modes.below')], label: localize('config.event_viewer.controls.thumbnails.modes.none'),
]); },
{
value: 'above',
label: localize('config.event_viewer.controls.thumbnails.modes.above'),
},
{
value: 'below',
label: localize('config.event_viewer.controls.thumbnails.modes.below'),
},
];
protected _thumbnailMedias = new Map([ protected _thumbnailMedias = [
['', ''], { value: '', label: '' },
['clips', localize('config.live.controls.thumbnails.medias.clips')], { value: 'clips', label: localize('config.live.controls.thumbnails.medias.clips') },
['snapshots', localize('config.live.controls.thumbnails.medias.snapshots')], {
]); value: 'snapshots',
label: localize('config.live.controls.thumbnails.medias.snapshots'),
},
];
protected _titleModes = new Map([ protected _titleModes = [
['', ''], { value: '', label: '' },
['none', localize('config.event_viewer.controls.title.modes.none')], { value: 'none', label: localize('config.event_viewer.controls.title.modes.none') },
[ {
'popup-top-left', value: 'popup-top-left',
localize('config.event_viewer.controls.title.modes.popup-top-left'), label: localize('config.event_viewer.controls.title.modes.popup-top-left'),
], },
[ {
'popup-top-right', value: 'popup-top-right',
localize('config.event_viewer.controls.title.modes.popup-top-right'), label: localize('config.event_viewer.controls.title.modes.popup-top-right'),
], },
[ {
'popup-bottom-left', value: 'popup-bottom-left',
localize('config.event_viewer.controls.title.modes.popup-bottom-left'), label: localize('config.event_viewer.controls.title.modes.popup-bottom-left'),
], },
[ {
'popup-bottom-right', value: 'popup-bottom-right',
localize('config.event_viewer.controls.title.modes.popup-bottom-right'), label: localize('config.event_viewer.controls.title.modes.popup-bottom-right'),
], },
]); ];
protected _transitionEffects = new Map([ protected _transitionEffects = [
['', ''], { value: '', label: '' },
['none', localize('config.event_viewer.transition_effects.none')], { value: 'none', label: localize('config.event_viewer.transition_effects.none') },
['slide', localize('config.event_viewer.transition_effects.slide')], { value: 'slide', label: localize('config.event_viewer.transition_effects.slide') },
]); ];
protected _imageModes = new Map([ protected _imageModes = [
['', ''], { value: '', label: '' },
['camera', localize('config.image.modes.camera')], { value: 'camera', label: localize('config.image.modes.camera') },
['screensaver', localize('config.image.modes.screensaver')], { value: 'screensaver', label: localize('config.image.modes.screensaver') },
['url', localize('config.image.modes.url')], { value: 'url', label: localize('config.image.modes.url') },
]); ];
public setConfig(config: RawFrigateCardConfig): void { public setConfig(config: RawFrigateCardConfig): void {
// Note: This does not use Zod to parse the configuration, so it may be // Note: This does not use Zod to parse the configuration, so it may be
@@ -352,37 +382,56 @@ export class FrigateCardEditor extends LitElement implements LovelaceCardEditor
} }
/** /**
* Render a dropdown menu. * Render an entity selector.
* @param configPath The configuration path to set/read. * @param configPath The configuration path to set/read.
* @param dropdown The downdown in an array or key/value dictionary. * @param domain Only entities from this domain will be shown.
* @returns A rendered template. * @returns A rendered template.
*/ */
protected _renderDropdown( protected _renderEntitySelector(
configPath: string, configPath: string,
dropdown: string[] | Map<string, string>, domain: string,
): TemplateResult | void { ): TemplateResult | void {
if (!this._config) { if (!this._config) {
return; return;
} }
const keys = Array.isArray(dropdown) ? dropdown : [...dropdown.keys()];
return html` return html`
<paper-dropdown-menu <ha-selector
.hass=${this.hass}
.selector=${{ entity: { domain: domain } }}
.label=${this._getLabel(configPath)} .label=${this._getLabel(configPath)}
@value-changed=${this._valueChangedHandler} .value=${getConfigValue(this._config, configPath, '')}
.configValue=${configPath} .required=${false}
@value-changed=${(ev) => this._valueChangedHandler(configPath, ev)}
> >
<paper-listbox </ha-selector>
slot="dropdown-content" `;
.selected=${keys.indexOf(String(getConfigValue(this._config, configPath, '')))} }
>
${keys.map( /**
(key) => html` <paper-item .label="${key}"> * Render an option/"select" selector.
${Array.isArray(dropdown) ? key : dropdown.get(key)} * @param configPath The configuration path to set/read.
</paper-item>`, * @param options The options to show in the selector.
)} * @returns A rendered template.
</paper-listbox> */
</paper-dropdown-menu> protected _renderOptionSelector(
configPath: string,
options: string[] | { value: string; label: string }[],
): TemplateResult | void {
if (!this._config) {
return;
}
return html`
<ha-selector
.hass=${this.hass}
.selector=${{ select: { options: options } }}
.label=${this._getLabel(configPath)}
.value=${getConfigValue(this._config, configPath, '')}
.required=${false}
@value-changed=${(ev) => this._valueChangedHandler(configPath, ev)}
>
</ha-selector>
`; `;
} }
@@ -395,28 +444,29 @@ export class FrigateCardEditor extends LitElement implements LovelaceCardEditor
* @param max The maximum value. * @param max The maximum value.
* @returns A rendered template. * @returns A rendered template.
*/ */
protected _renderSlider( protected _renderNumberInput(
configPath: string, configPath: string,
valueDefault: number, valueDefault: number,
icon: string, min?: number,
min: number, max?: number,
max: number,
): TemplateResult | void { ): TemplateResult | void {
if (!this._config) { if (!this._config) {
return; return;
} }
const value = Number(getConfigValue(this._config, configPath, valueDefault)); const value = Number(getConfigValue(this._config, configPath, valueDefault));
return html`<ha-labeled-slider const mode = max === undefined ? 'box' : 'slider';
caption=${this._getLabel(configPath)}
icon=${icon} return html`
max=${max} <ha-selector
min=${min} .hass=${this.hass}
?pin=${true} .selector=${{ number: { min: min || 0, max: max, mode: mode } }}
value=${isNaN(value) ? valueDefault : value} .label=${this._getLabel(configPath)}
@value-changed=${this._valueChangedHandler.bind(this)} .value=${isNaN(value) ? valueDefault : value}
.configValue=${configPath} .required=${false}
> @value-changed=${(ev) => this._valueChangedHandler(configPath, ev)}
</ha-labeled-slider>`; >
</ha-selector>
`;
} }
/** /**
@@ -486,23 +536,27 @@ export class FrigateCardEditor extends LitElement implements LovelaceCardEditor
* Render a camera section. * Render a camera section.
* @param cameras The full array of cameras. * @param cameras The full array of cameras.
* @param cameraIndex The index (in the array) to render. * @param cameraIndex The index (in the array) to render.
* @param cameraEntities The full list of camera entities.
* @param addNewCamera Whether or not this is a section to add a new non-existent camera. * @param addNewCamera Whether or not this is a section to add a new non-existent camera.
* @returns A rendered template. * @returns A rendered template.
*/ */
protected _renderCamera( protected _renderCamera(
cameras: RawFrigateCardConfigArray, cameras: RawFrigateCardConfigArray,
cameraIndex: number, cameraIndex: number,
cameraEntities: string[],
addNewCamera?: boolean, addNewCamera?: boolean,
): TemplateResult | void { ): TemplateResult | void {
const liveProviders = new Map([ const liveProviders = [
['', ''], { value: '', label: '' },
['auto', localize('config.cameras.live_providers.auto')], { value: 'auto', label: localize('config.cameras.live_providers.auto') },
['ha', localize('config.cameras.live_providers.ha')], { value: 'ha', label: localize('config.cameras.live_providers.ha') },
['frigate-jsmpeg', localize('config.cameras.live_providers.frigate-jsmpeg')], {
['webrtc-card', localize('config.cameras.live_providers.webrtc-card')], value: 'frigate-jsmpeg',
]); label: localize('config.cameras.live_providers.frigate-jsmpeg'),
},
{
value: 'webrtc-card',
label: localize('config.cameras.live_providers.webrtc-card'),
},
];
// Make a new config and update the editor with changes on it, // Make a new config and update the editor with changes on it,
const modifyConfig = (func: (config: RawFrigateCardConfig) => boolean): void => { const modifyConfig = (func: (config: RawFrigateCardConfig) => boolean): void => {
@@ -580,14 +634,14 @@ export class FrigateCardEditor extends LitElement implements LovelaceCardEditor
<ha-icon icon="mdi:delete"></ha-icon> <ha-icon icon="mdi:delete"></ha-icon>
</ha-icon-button> </ha-icon-button>
</div> </div>
${this._renderDropdown( ${this._renderEntitySelector(
getArrayConfigPath(CONF_CAMERAS_ARRAY_CAMERA_ENTITY, cameraIndex), getArrayConfigPath(CONF_CAMERAS_ARRAY_CAMERA_ENTITY, cameraIndex),
cameraEntities, 'camera',
)} )}
${this._renderStringInput( ${this._renderStringInput(
getArrayConfigPath(CONF_CAMERAS_ARRAY_CAMERA_NAME, cameraIndex), getArrayConfigPath(CONF_CAMERAS_ARRAY_CAMERA_NAME, cameraIndex),
)} )}
${this._renderDropdown( ${this._renderOptionSelector(
getArrayConfigPath(CONF_CAMERAS_ARRAY_LIVE_PROVIDER, cameraIndex), getArrayConfigPath(CONF_CAMERAS_ARRAY_LIVE_PROVIDER, cameraIndex),
liveProviders, liveProviders,
)} )}
@@ -612,9 +666,9 @@ export class FrigateCardEditor extends LitElement implements LovelaceCardEditor
${this._renderStringInput( ${this._renderStringInput(
getArrayConfigPath(CONF_CAMERAS_ARRAY_ID, cameraIndex), getArrayConfigPath(CONF_CAMERAS_ARRAY_ID, cameraIndex),
)} )}
${this._renderDropdown( ${this._renderEntitySelector(
getArrayConfigPath(CONF_CAMERAS_ARRAY_WEBRTC_CARD_ENTITY, cameraIndex), getArrayConfigPath(CONF_CAMERAS_ARRAY_WEBRTC_CARD_ENTITY, cameraIndex),
cameraEntities, 'camera',
)} )}
${this._renderStringInput( ${this._renderStringInput(
getArrayConfigPath(CONF_CAMERAS_ARRAY_WEBRTC_CARD_URL, cameraIndex), getArrayConfigPath(CONF_CAMERAS_ARRAY_WEBRTC_CARD_URL, cameraIndex),
@@ -627,30 +681,45 @@ export class FrigateCardEditor extends LitElement implements LovelaceCardEditor
/** /**
* Render a string input field. * Render a string input field.
* @param configPath The configuration path to set/read. * @param configPath The configuration path to set/read.
* @param allowedPattern An allowed input pattern. * @param type The allowable input
* @returns A rendered template. * @returns A rendered template.
*/ */
protected _renderStringInput( protected _renderStringInput(
configPath: string, configPath: string,
type?: 'text' | 'number', type?:
| 'number'
| 'text'
| 'search'
| 'tel'
| 'url'
| 'email'
| 'password'
| 'date'
| 'month'
| 'week'
| 'time'
| 'datetime-local'
| 'color',
): TemplateResult | void { ): TemplateResult | void {
if (!this._config) { if (!this._config) {
return; return;
} }
const allowedPattern = type == 'number' ? '[0-9]' : undefined;
return html` <paper-input return html`
label=${this._getLabel(configPath)} <ha-selector
.value=${getConfigValue(this._config, configPath, '')} .hass=${this.hass}
.configValue=${configPath} .selector=${{ text: { type: type || 'text' } }}
type=${type || 'text'} .label=${this._getLabel(configPath)}
allowed-pattern=${ifDefined(allowedPattern)} .value=${getConfigValue(this._config, configPath, '')}
prevent-invalid-input=${ifDefined(allowedPattern)} .required=${false}
@change=${this._valueChangedHandler} @value-changed=${(ev) => this._valueChangedHandler(configPath, ev)}
></paper-input>`; >
</ha-selector>
`;
} }
/** /**
* Render a switch. * Render a boolean selector.
* @param configPath The configuration path to set/read. * @param configPath The configuration path to set/read.
* @param valueDefault The default switch value if unset. * @param valueDefault The default switch value if unset.
* @param label An optional switch label. * @param label An optional switch label.
@@ -664,13 +733,18 @@ export class FrigateCardEditor extends LitElement implements LovelaceCardEditor
if (!this._config) { if (!this._config) {
return; return;
} }
return html` <ha-formfield .label=${label || this._getLabel(configPath)}>
<ha-switch return html`
.checked="${getConfigValue(this._config, configPath, valueDefault)}" <ha-selector
.configValue=${configPath} .hass=${this.hass}
@change=${this._valueChangedHandler} .selector=${{ boolean: {} }}
></ha-switch> .label=${label || this._getLabel(configPath)}
</ha-formfield>`; .value=${getConfigValue(this._config, configPath, valueDefault)}
.required=${false}
@value-changed=${(ev) => this._valueChangedHandler(configPath, ev)}
>
</ha-selector>
`;
} }
protected _updateConfig(config: RawFrigateCardConfig): void { protected _updateConfig(config: RawFrigateCardConfig): void {
@@ -683,13 +757,15 @@ export class FrigateCardEditor extends LitElement implements LovelaceCardEditor
return html``; return html``;
} }
// The climate more-info loads ha-switch and paper-dropdown-menu. // The picture-glance editor loads the ha-selectors.
this._helpers.importMoreInfoControl('climate'); // See: https://github.com/thomasloven/hass-config/wiki/PreLoading-Lovelace-Elements
const pictureGlance = this._helpers.createCardElement({
type: 'picture-glance',
entities: [],
camera_image: 'dummy-to-load-components',
});
pictureGlance.constructor.getConfigElement();
// The light more-info loads ha-labeled-slider.
this._helpers.importMoreInfoControl('light');
const cameraEntities = this._getEntities('camera');
const defaults = frigateCardConfigDefaults; const defaults = frigateCardConfigDefaults;
const getShowButtonLabel = (configPath: string) => const getShowButtonLabel = (configPath: string) =>
@@ -723,23 +799,27 @@ export class FrigateCardEditor extends LitElement implements LovelaceCardEditor
${this._renderOptionSetHeader('cameras')} ${this._renderOptionSetHeader('cameras')}
${options.cameras.show ${options.cameras.show
? html` <div class="cameras"> ? html` <div class="cameras">
${cameras.map((_, index) => ${cameras.map((_, index) => this._renderCamera(cameras, index))}
this._renderCamera(cameras, index, cameraEntities), ${this._renderCamera(cameras, cameras.length, true)}
)}
${this._renderCamera(cameras, cameras.length, cameraEntities, true)}
</div>` </div>`
: ''} : ''}
${this._renderOptionSetHeader('view')} ${this._renderOptionSetHeader('view')}
${options.view.show ${options.view.show
? html` ? html`
<div class="values"> <div class="values">
${this._renderDropdown(CONF_VIEW_DEFAULT, this._viewModes)} ${this._renderOptionSelector(CONF_VIEW_DEFAULT, this._viewModes)}
${this._renderDropdown( ${this._renderOptionSelector(
CONF_VIEW_CAMERA_SELECT, CONF_VIEW_CAMERA_SELECT,
this._cameraSelectViewModes, this._cameraSelectViewModes,
)} )}
${this._renderStringInput(CONF_VIEW_TIMEOUT_SECONDS, 'number')} ${this._renderNumberInput(
${this._renderStringInput(CONF_VIEW_UPDATE_SECONDS, 'number')} CONF_VIEW_TIMEOUT_SECONDS,
defaults.view.timeout_seconds,
)}
${this._renderNumberInput(
CONF_VIEW_UPDATE_SECONDS,
defaults.view.update_seconds,
)}
${this._renderSwitch(CONF_VIEW_UPDATE_FORCE, defaults.view.update_force)} ${this._renderSwitch(CONF_VIEW_UPDATE_FORCE, defaults.view.update_force)}
${this._renderSwitch( ${this._renderSwitch(
CONF_VIEW_UPDATE_CYCLE_CAMERA, CONF_VIEW_UPDATE_CYCLE_CAMERA,
@@ -752,7 +832,7 @@ export class FrigateCardEditor extends LitElement implements LovelaceCardEditor
${options.menu.show ${options.menu.show
? html` ? html`
<div class="values"> <div class="values">
${this._renderDropdown(CONF_MENU_MODE, this._menuModes)} ${this._renderOptionSelector(CONF_MENU_MODE, this._menuModes)}
${this._renderStringInput(CONF_MENU_BUTTON_SIZE)} ${this._renderStringInput(CONF_MENU_BUTTON_SIZE)}
${this._renderSwitch( ${this._renderSwitch(
CONF_MENU_BUTTONS_FRIGATE, CONF_MENU_BUTTONS_FRIGATE,
@@ -806,26 +886,31 @@ export class FrigateCardEditor extends LitElement implements LovelaceCardEditor
${this._renderSwitch(CONF_LIVE_LAZY_LOAD, defaults.live.lazy_load)} ${this._renderSwitch(CONF_LIVE_LAZY_LOAD, defaults.live.lazy_load)}
${this._renderSwitch(CONF_LIVE_LAZY_UNLOAD, defaults.live.lazy_unload)} ${this._renderSwitch(CONF_LIVE_LAZY_UNLOAD, defaults.live.lazy_unload)}
${this._renderSwitch(CONF_LIVE_AUTO_UNMUTE, defaults.live.auto_unmute)} ${this._renderSwitch(CONF_LIVE_AUTO_UNMUTE, defaults.live.auto_unmute)}
${this._renderDropdown( ${this._renderOptionSelector(
CONF_LIVE_CONTROLS_NEXT_PREVIOUS_STYLE, CONF_LIVE_CONTROLS_NEXT_PREVIOUS_STYLE,
this._liveNextPreviousControlStyles, this._liveNextPreviousControlStyles,
)} )}
${this._renderStringInput(CONF_LIVE_CONTROLS_NEXT_PREVIOUS_SIZE)} ${this._renderStringInput(CONF_LIVE_CONTROLS_NEXT_PREVIOUS_SIZE)}
${this._renderDropdown( ${this._renderOptionSelector(
CONF_LIVE_CONTROLS_THUMBNAILS_MODE, CONF_LIVE_CONTROLS_THUMBNAILS_MODE,
this._thumbnailModes, this._thumbnailModes,
)} )}
${this._renderDropdown( ${this._renderOptionSelector(
CONF_LIVE_CONTROLS_THUMBNAILS_MEDIA, CONF_LIVE_CONTROLS_THUMBNAILS_MEDIA,
this._thumbnailMedias, this._thumbnailMedias,
)} )}
${this._renderStringInput(CONF_LIVE_CONTROLS_THUMBNAILS_SIZE)} ${this._renderStringInput(CONF_LIVE_CONTROLS_THUMBNAILS_SIZE)}
${this._renderDropdown(CONF_LIVE_CONTROLS_TITLE_MODE, this._titleModes)} ${this._renderOptionSelector(
${this._renderStringInput( CONF_LIVE_CONTROLS_TITLE_MODE,
CONF_LIVE_CONTROLS_TITLE_DURATION_SECONDS, this._titleModes,
'number',
)} )}
${this._renderDropdown( ${this._renderNumberInput(
CONF_LIVE_CONTROLS_TITLE_DURATION_SECONDS,
defaults.live.controls.title.duration_seconds,
0,
60,
)}
${this._renderOptionSelector(
CONF_LIVE_TRANSITION_EFFECT, CONF_LIVE_TRANSITION_EFFECT,
this._transitionEffects, this._transitionEffects,
)} )}
@@ -835,10 +920,9 @@ export class FrigateCardEditor extends LitElement implements LovelaceCardEditor
${this._renderOptionSetHeader('event_gallery')} ${this._renderOptionSetHeader('event_gallery')}
${options.event_gallery.show ${options.event_gallery.show
? html` <div class="values"> ? html` <div class="values">
${this._renderSlider( ${this._renderNumberInput(
CONF_EVENT_GALLERY_MIN_COLUMNS, CONF_EVENT_GALLERY_MIN_COLUMNS,
defaults.event_gallery.min_columns, defaults.event_gallery.min_columns,
'mdi:view-column',
1, 1,
10, 10,
)} )}
@@ -863,25 +947,27 @@ export class FrigateCardEditor extends LitElement implements LovelaceCardEditor
CONF_EVENT_VIEWER_LAZY_LOAD, CONF_EVENT_VIEWER_LAZY_LOAD,
defaults.event_viewer.lazy_load, defaults.event_viewer.lazy_load,
)} )}
${this._renderDropdown( ${this._renderOptionSelector(
CONF_EVENT_VIEWER_CONTROLS_NEXT_PREVIOUS_STYLE, CONF_EVENT_VIEWER_CONTROLS_NEXT_PREVIOUS_STYLE,
this._eventViewerNextPreviousControlStyles, this._eventViewerNextPreviousControlStyles,
)} )}
${this._renderStringInput(CONF_EVENT_VIEWER_CONTROLS_NEXT_PREVIOUS_SIZE)} ${this._renderStringInput(CONF_EVENT_VIEWER_CONTROLS_NEXT_PREVIOUS_SIZE)}
${this._renderDropdown( ${this._renderOptionSelector(
CONF_EVENT_VIEWER_CONTROLS_THUMBNAILS_MODE, CONF_EVENT_VIEWER_CONTROLS_THUMBNAILS_MODE,
this._thumbnailModes, this._thumbnailModes,
)} )}
${this._renderStringInput(CONF_EVENT_VIEWER_CONTROLS_THUMBNAILS_SIZE)} ${this._renderStringInput(CONF_EVENT_VIEWER_CONTROLS_THUMBNAILS_SIZE)}
${this._renderDropdown( ${this._renderOptionSelector(
CONF_EVENT_VIEWER_CONTROLS_TITLE_MODE, CONF_EVENT_VIEWER_CONTROLS_TITLE_MODE,
this._titleModes, this._titleModes,
)} )}
${this._renderStringInput( ${this._renderNumberInput(
CONF_EVENT_VIEWER_CONTROLS_TITLE_DURATION_SECONDS, CONF_EVENT_VIEWER_CONTROLS_TITLE_DURATION_SECONDS,
'number', defaults.event_viewer.controls.title.duration_seconds,
0,
60,
)} )}
${this._renderDropdown( ${this._renderOptionSelector(
CONF_EVENT_VIEWER_TRANSITION_EFFECT, CONF_EVENT_VIEWER_TRANSITION_EFFECT,
this._transitionEffects, this._transitionEffects,
)} )}
@@ -890,18 +976,18 @@ export class FrigateCardEditor extends LitElement implements LovelaceCardEditor
${this._renderOptionSetHeader('image')} ${this._renderOptionSetHeader('image')}
${options.image.show ${options.image.show
? html` <div class="values"> ? html` <div class="values">
${this._renderDropdown( ${this._renderOptionSelector(CONF_IMAGE_MODE, this._imageModes)}
CONF_IMAGE_MODE,
this._imageModes,
)}
${this._renderStringInput(CONF_IMAGE_URL)} ${this._renderStringInput(CONF_IMAGE_URL)}
${this._renderStringInput(CONF_IMAGE_REFRESH_SECONDS, 'number')} ${this._renderNumberInput(
CONF_IMAGE_REFRESH_SECONDS,
defaults.image.refresh_seconds,
)}
</div>` </div>`
: ''} : ''}
${this._renderOptionSetHeader('dimensions')} ${this._renderOptionSetHeader('dimensions')}
${options.dimensions.show ${options.dimensions.show
? html` <div class="values"> ? html` <div class="values">
${this._renderDropdown( ${this._renderOptionSelector(
CONF_DIMENSIONS_ASPECT_RATIO_MODE, CONF_DIMENSIONS_ASPECT_RATIO_MODE,
this._aspectRatioModes, this._aspectRatioModes,
)} )}
@@ -981,36 +1067,27 @@ export class FrigateCardEditor extends LitElement implements LovelaceCardEditor
* Handle a changed option value. * Handle a changed option value.
* @param ev Event triggering the change. * @param ev Event triggering the change.
*/ */
protected _valueChangedHandler(ev: { protected _valueChangedHandler(
target: (ConfigValueTarget & HTMLElement) | null; key: string,
}): void { ev: CustomEvent<{ value: unknown }>,
const target = ev.target; ): void {
if (!this._config || !this.hass || !target) { if (!this._config || !this.hass) {
return; return;
} }
let value; let value;
if ('checked' in target) { if (ev.detail && ev.detail.value !== undefined) {
value = target.checked; value = ev.detail.value;
} else if (typeof target.value === 'string') { if (typeof value === 'string') {
value = target.value?.trim(); value = value.trim();
if (target['type'] === 'number' && value != '') {
value = Number(value);
} }
} else {
value = target.value;
} }
const key: string = target.configValue;
if (!key) {
return;
}
if (getConfigValue(this._config, key) === value) { if (getConfigValue(this._config, key) === value) {
return; return;
} }
const newConfig = copyConfig(this._config); const newConfig = copyConfig(this._config);
if (value === '' || typeof value === 'undefined') { if (value === '' || value === undefined) {
deleteConfigValue(newConfig, key); deleteConfigValue(newConfig, key);
} else { } else {
setConfigValue(newConfig, key, value); setConfigValue(newConfig, key, value);
+2 -2
View File
@@ -90,7 +90,7 @@
"popup-bottom-left": "Popup on the bottom left", "popup-bottom-left": "Popup on the bottom left",
"popup-bottom-right": "Popup on the bottom right" "popup-bottom-right": "Popup on the bottom right"
}, },
"duration_seconds": "Seconds to display popup title in Event Viewer (0=forever)" "duration_seconds": "Seconds to display popup title (0=forever)"
} }
} }
}, },
@@ -122,7 +122,7 @@
}, },
"title": { "title": {
"mode": "Live media title display mode", "mode": "Live media title display mode",
"duration_seconds": "Seconds to display popup title in Live view (0=forever)" "duration_seconds": "Seconds to display popup title (0=forever)"
} }
} }
}, },
+1
View File
@@ -69,6 +69,7 @@ div.upgrade span {
display: inline-block; display: inline-block;
margin-left: auto; margin-left: auto;
margin-right: 0px; margin-right: 0px;
margin-bottom: 5px;
} }
.cameras .controls ha-icon-button.button { .cameras .controls ha-icon-button.button {
--mdc-icon-button-size: 32px; --mdc-icon-button-size: 32px;
+1 -1
View File
@@ -461,7 +461,7 @@ const titleControlConfigSchema = z.object({
'popup-bottom-right', 'popup-bottom-right',
'popup-bottom-left', 'popup-bottom-left',
]), ]),
duration_seconds: z.number().min(0), duration_seconds: z.number().min(0).max(60),
}); });
export type TitleControlConfig = z.infer<typeof titleControlConfigSchema>; export type TitleControlConfig = z.infer<typeof titleControlConfigSchema>;