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 })
protected _expandedCameraIndex: number | null = null;
protected _viewModes = new Map([
['', ''],
['live', localize('config.view.views.live')],
['clips', localize('config.view.views.clips')],
['snapshots', localize('config.view.views.snapshots')],
['clip', localize('config.view.views.clip')],
['snapshot', localize('config.view.views.snapshot')],
['image', localize('config.view.views.image')],
]);
protected _viewModes = [
{ value: '', label: '' },
{ value: 'live', label: localize('config.view.views.live') },
{ value: 'clips', label: localize('config.view.views.clips') },
{ value: 'snapshots', label: localize('config.view.views.snapshots') },
{ value: 'clip', label: localize('config.view.views.clip') },
{ value: 'snapshot', label: localize('config.view.views.snapshot') },
{ value: 'image', label: localize('config.view.views.image') },
];
protected _cameraSelectViewModes = new Map([
protected _cameraSelectViewModes = [
...this._viewModes,
['current', localize('config.view.views.current')],
]);
{ value: 'current', label: localize('config.view.views.current') },
];
protected _menuModes = new Map([
['', ''],
['none', localize('config.menu.modes.none')],
['hidden-top', localize('config.menu.modes.hidden-top')],
['hidden-left', localize('config.menu.modes.hidden-left')],
['hidden-bottom', localize('config.menu.modes.hidden-bottom')],
['hidden-right', localize('config.menu.modes.hidden-right')],
['overlay-top', localize('config.menu.modes.overlay-top')],
['overlay-left', localize('config.menu.modes.overlay-left')],
['overlay-bottom', localize('config.menu.modes.overlay-bottom')],
['overlay-right', localize('config.menu.modes.overlay-right')],
['hover-top', localize('config.menu.modes.hover-top')],
['hover-left', localize('config.menu.modes.hover-left')],
['hover-bottom', localize('config.menu.modes.hover-bottom')],
['hover-right', localize('config.menu.modes.hover-right')],
['above', localize('config.menu.modes.above')],
['below', localize('config.menu.modes.below')],
]);
protected _menuModes = [
{ value: '', label: '' },
{ value: 'none', label: localize('config.menu.modes.none') },
{ value: 'hidden-top', label: localize('config.menu.modes.hidden-top') },
{ value: 'hidden-left', label: localize('config.menu.modes.hidden-left') },
{ value: 'hidden-bottom', label: localize('config.menu.modes.hidden-bottom') },
{ value: 'hidden-right', label: localize('config.menu.modes.hidden-right') },
{ value: 'overlay-top', label: localize('config.menu.modes.overlay-top') },
{ value: 'overlay-left', label: localize('config.menu.modes.overlay-left') },
{ value: 'overlay-bottom', label: localize('config.menu.modes.overlay-bottom') },
{ value: 'overlay-right', label: localize('config.menu.modes.overlay-right') },
{ value: 'hover-top', label: localize('config.menu.modes.hover-top') },
{ value: 'hover-left', label: localize('config.menu.modes.hover-left') },
{ value: 'hover-bottom', label: localize('config.menu.modes.hover-bottom') },
{ value: 'hover-right', label: localize('config.menu.modes.hover-right') },
{ value: 'above', label: localize('config.menu.modes.above') },
{ value: 'below', label: localize('config.menu.modes.below') },
];
protected _eventViewerNextPreviousControlStyles = new Map([
['', ''],
[
'thumbnails',
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')],
]);
protected _eventViewerNextPreviousControlStyles = [
{ value: '', label: '' },
{
value: 'thumbnails',
label: localize('config.event_viewer.controls.next_previous.styles.thumbnails'),
},
{
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([
['', ''],
['chevrons', localize('config.live.controls.next_previous.styles.chevrons')],
['icons', localize('config.live.controls.next_previous.styles.icons')],
['none', localize('config.live.controls.next_previous.styles.none')],
]);
protected _liveNextPreviousControlStyles = [
{ value: '', label: '' },
{
value: 'chevrons',
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([
['', ''],
['dynamic', localize('config.dimensions.aspect_ratio_modes.dynamic')],
['static', localize('config.dimensions.aspect_ratio_modes.static')],
['unconstrained', localize('config.dimensions.aspect_ratio_modes.unconstrained')],
]);
protected _aspectRatioModes = [
{ value: '', label: '' },
{
value: 'dynamic',
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([
['', ''],
['none', localize('config.event_viewer.controls.thumbnails.modes.none')],
['above', localize('config.event_viewer.controls.thumbnails.modes.above')],
['below', localize('config.event_viewer.controls.thumbnails.modes.below')],
]);
protected _thumbnailModes = [
{ value: '', label: '' },
{
value: 'none',
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([
['', ''],
['clips', localize('config.live.controls.thumbnails.medias.clips')],
['snapshots', localize('config.live.controls.thumbnails.medias.snapshots')],
]);
protected _thumbnailMedias = [
{ value: '', label: '' },
{ value: 'clips', label: localize('config.live.controls.thumbnails.medias.clips') },
{
value: 'snapshots',
label: localize('config.live.controls.thumbnails.medias.snapshots'),
},
];
protected _titleModes = new Map([
['', ''],
['none', localize('config.event_viewer.controls.title.modes.none')],
[
'popup-top-left',
localize('config.event_viewer.controls.title.modes.popup-top-left'),
],
[
'popup-top-right',
localize('config.event_viewer.controls.title.modes.popup-top-right'),
],
[
'popup-bottom-left',
localize('config.event_viewer.controls.title.modes.popup-bottom-left'),
],
[
'popup-bottom-right',
localize('config.event_viewer.controls.title.modes.popup-bottom-right'),
],
]);
protected _titleModes = [
{ value: '', label: '' },
{ value: 'none', label: localize('config.event_viewer.controls.title.modes.none') },
{
value: 'popup-top-left',
label: localize('config.event_viewer.controls.title.modes.popup-top-left'),
},
{
value: 'popup-top-right',
label: localize('config.event_viewer.controls.title.modes.popup-top-right'),
},
{
value: 'popup-bottom-left',
label: localize('config.event_viewer.controls.title.modes.popup-bottom-left'),
},
{
value: 'popup-bottom-right',
label: localize('config.event_viewer.controls.title.modes.popup-bottom-right'),
},
];
protected _transitionEffects = new Map([
['', ''],
['none', localize('config.event_viewer.transition_effects.none')],
['slide', localize('config.event_viewer.transition_effects.slide')],
]);
protected _transitionEffects = [
{ value: '', label: '' },
{ value: 'none', label: localize('config.event_viewer.transition_effects.none') },
{ value: 'slide', label: localize('config.event_viewer.transition_effects.slide') },
];
protected _imageModes = new Map([
['', ''],
['camera', localize('config.image.modes.camera')],
['screensaver', localize('config.image.modes.screensaver')],
['url', localize('config.image.modes.url')],
]);
protected _imageModes = [
{ value: '', label: '' },
{ value: 'camera', label: localize('config.image.modes.camera') },
{ value: 'screensaver', label: localize('config.image.modes.screensaver') },
{ value: 'url', label: localize('config.image.modes.url') },
];
public setConfig(config: RawFrigateCardConfig): void {
// 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 dropdown The downdown in an array or key/value dictionary.
* @param domain Only entities from this domain will be shown.
* @returns A rendered template.
*/
protected _renderDropdown(
protected _renderEntitySelector(
configPath: string,
dropdown: string[] | Map<string, string>,
domain: string,
): TemplateResult | void {
if (!this._config) {
return;
}
const keys = Array.isArray(dropdown) ? dropdown : [...dropdown.keys()];
return html`
<paper-dropdown-menu
<ha-selector
.hass=${this.hass}
.selector=${{ entity: { domain: domain } }}
.label=${this._getLabel(configPath)}
@value-changed=${this._valueChangedHandler}
.configValue=${configPath}
.value=${getConfigValue(this._config, configPath, '')}
.required=${false}
@value-changed=${(ev) => this._valueChangedHandler(configPath, ev)}
>
<paper-listbox
slot="dropdown-content"
.selected=${keys.indexOf(String(getConfigValue(this._config, configPath, '')))}
>
${keys.map(
(key) => html` <paper-item .label="${key}">
${Array.isArray(dropdown) ? key : dropdown.get(key)}
</paper-item>`,
)}
</paper-listbox>
</paper-dropdown-menu>
</ha-selector>
`;
}
/**
* Render an option/"select" selector.
* @param configPath The configuration path to set/read.
* @param options The options to show in the selector.
* @returns A rendered template.
*/
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.
* @returns A rendered template.
*/
protected _renderSlider(
protected _renderNumberInput(
configPath: string,
valueDefault: number,
icon: string,
min: number,
max: number,
min?: number,
max?: number,
): TemplateResult | void {
if (!this._config) {
return;
}
const value = Number(getConfigValue(this._config, configPath, valueDefault));
return html`<ha-labeled-slider
caption=${this._getLabel(configPath)}
icon=${icon}
max=${max}
min=${min}
?pin=${true}
value=${isNaN(value) ? valueDefault : value}
@value-changed=${this._valueChangedHandler.bind(this)}
.configValue=${configPath}
>
</ha-labeled-slider>`;
const mode = max === undefined ? 'box' : 'slider';
return html`
<ha-selector
.hass=${this.hass}
.selector=${{ number: { min: min || 0, max: max, mode: mode } }}
.label=${this._getLabel(configPath)}
.value=${isNaN(value) ? valueDefault : value}
.required=${false}
@value-changed=${(ev) => this._valueChangedHandler(configPath, ev)}
>
</ha-selector>
`;
}
/**
@@ -486,23 +536,27 @@ export class FrigateCardEditor extends LitElement implements LovelaceCardEditor
* Render a camera section.
* @param cameras The full array of cameras.
* @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.
* @returns A rendered template.
*/
protected _renderCamera(
cameras: RawFrigateCardConfigArray,
cameraIndex: number,
cameraEntities: string[],
addNewCamera?: boolean,
): TemplateResult | void {
const liveProviders = new Map([
['', ''],
['auto', localize('config.cameras.live_providers.auto')],
['ha', localize('config.cameras.live_providers.ha')],
['frigate-jsmpeg', localize('config.cameras.live_providers.frigate-jsmpeg')],
['webrtc-card', localize('config.cameras.live_providers.webrtc-card')],
]);
const liveProviders = [
{ value: '', label: '' },
{ value: 'auto', label: localize('config.cameras.live_providers.auto') },
{ value: 'ha', label: localize('config.cameras.live_providers.ha') },
{
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,
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-button>
</div>
${this._renderDropdown(
${this._renderEntitySelector(
getArrayConfigPath(CONF_CAMERAS_ARRAY_CAMERA_ENTITY, cameraIndex),
cameraEntities,
'camera',
)}
${this._renderStringInput(
getArrayConfigPath(CONF_CAMERAS_ARRAY_CAMERA_NAME, cameraIndex),
)}
${this._renderDropdown(
${this._renderOptionSelector(
getArrayConfigPath(CONF_CAMERAS_ARRAY_LIVE_PROVIDER, cameraIndex),
liveProviders,
)}
@@ -612,9 +666,9 @@ export class FrigateCardEditor extends LitElement implements LovelaceCardEditor
${this._renderStringInput(
getArrayConfigPath(CONF_CAMERAS_ARRAY_ID, cameraIndex),
)}
${this._renderDropdown(
${this._renderEntitySelector(
getArrayConfigPath(CONF_CAMERAS_ARRAY_WEBRTC_CARD_ENTITY, cameraIndex),
cameraEntities,
'camera',
)}
${this._renderStringInput(
getArrayConfigPath(CONF_CAMERAS_ARRAY_WEBRTC_CARD_URL, cameraIndex),
@@ -627,30 +681,45 @@ export class FrigateCardEditor extends LitElement implements LovelaceCardEditor
/**
* Render a string input field.
* @param configPath The configuration path to set/read.
* @param allowedPattern An allowed input pattern.
* @param type The allowable input
* @returns A rendered template.
*/
protected _renderStringInput(
configPath: string,
type?: 'text' | 'number',
type?:
| 'number'
| 'text'
| 'search'
| 'tel'
| 'url'
| 'email'
| 'password'
| 'date'
| 'month'
| 'week'
| 'time'
| 'datetime-local'
| 'color',
): TemplateResult | void {
if (!this._config) {
return;
}
const allowedPattern = type == 'number' ? '[0-9]' : undefined;
return html` <paper-input
label=${this._getLabel(configPath)}
.value=${getConfigValue(this._config, configPath, '')}
.configValue=${configPath}
type=${type || 'text'}
allowed-pattern=${ifDefined(allowedPattern)}
prevent-invalid-input=${ifDefined(allowedPattern)}
@change=${this._valueChangedHandler}
></paper-input>`;
return html`
<ha-selector
.hass=${this.hass}
.selector=${{ text: { type: type || 'text' } }}
.label=${this._getLabel(configPath)}
.value=${getConfigValue(this._config, configPath, '')}
.required=${false}
@value-changed=${(ev) => this._valueChangedHandler(configPath, ev)}
>
</ha-selector>
`;
}
/**
* Render a switch.
* Render a boolean selector.
* @param configPath The configuration path to set/read.
* @param valueDefault The default switch value if unset.
* @param label An optional switch label.
@@ -664,13 +733,18 @@ export class FrigateCardEditor extends LitElement implements LovelaceCardEditor
if (!this._config) {
return;
}
return html` <ha-formfield .label=${label || this._getLabel(configPath)}>
<ha-switch
.checked="${getConfigValue(this._config, configPath, valueDefault)}"
.configValue=${configPath}
@change=${this._valueChangedHandler}
></ha-switch>
</ha-formfield>`;
return html`
<ha-selector
.hass=${this.hass}
.selector=${{ boolean: {} }}
.label=${label || this._getLabel(configPath)}
.value=${getConfigValue(this._config, configPath, valueDefault)}
.required=${false}
@value-changed=${(ev) => this._valueChangedHandler(configPath, ev)}
>
</ha-selector>
`;
}
protected _updateConfig(config: RawFrigateCardConfig): void {
@@ -683,13 +757,15 @@ export class FrigateCardEditor extends LitElement implements LovelaceCardEditor
return html``;
}
// The climate more-info loads ha-switch and paper-dropdown-menu.
this._helpers.importMoreInfoControl('climate');
// The picture-glance editor loads the ha-selectors.
// 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 getShowButtonLabel = (configPath: string) =>
@@ -723,23 +799,27 @@ export class FrigateCardEditor extends LitElement implements LovelaceCardEditor
${this._renderOptionSetHeader('cameras')}
${options.cameras.show
? html` <div class="cameras">
${cameras.map((_, index) =>
this._renderCamera(cameras, index, cameraEntities),
)}
${this._renderCamera(cameras, cameras.length, cameraEntities, true)}
${cameras.map((_, index) => this._renderCamera(cameras, index))}
${this._renderCamera(cameras, cameras.length, true)}
</div>`
: ''}
${this._renderOptionSetHeader('view')}
${options.view.show
? html`
<div class="values">
${this._renderDropdown(CONF_VIEW_DEFAULT, this._viewModes)}
${this._renderDropdown(
${this._renderOptionSelector(CONF_VIEW_DEFAULT, this._viewModes)}
${this._renderOptionSelector(
CONF_VIEW_CAMERA_SELECT,
this._cameraSelectViewModes,
)}
${this._renderStringInput(CONF_VIEW_TIMEOUT_SECONDS, 'number')}
${this._renderStringInput(CONF_VIEW_UPDATE_SECONDS, 'number')}
${this._renderNumberInput(
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_CYCLE_CAMERA,
@@ -752,7 +832,7 @@ export class FrigateCardEditor extends LitElement implements LovelaceCardEditor
${options.menu.show
? html`
<div class="values">
${this._renderDropdown(CONF_MENU_MODE, this._menuModes)}
${this._renderOptionSelector(CONF_MENU_MODE, this._menuModes)}
${this._renderStringInput(CONF_MENU_BUTTON_SIZE)}
${this._renderSwitch(
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_UNLOAD, defaults.live.lazy_unload)}
${this._renderSwitch(CONF_LIVE_AUTO_UNMUTE, defaults.live.auto_unmute)}
${this._renderDropdown(
${this._renderOptionSelector(
CONF_LIVE_CONTROLS_NEXT_PREVIOUS_STYLE,
this._liveNextPreviousControlStyles,
)}
${this._renderStringInput(CONF_LIVE_CONTROLS_NEXT_PREVIOUS_SIZE)}
${this._renderDropdown(
${this._renderOptionSelector(
CONF_LIVE_CONTROLS_THUMBNAILS_MODE,
this._thumbnailModes,
)}
${this._renderDropdown(
${this._renderOptionSelector(
CONF_LIVE_CONTROLS_THUMBNAILS_MEDIA,
this._thumbnailMedias,
)}
${this._renderStringInput(CONF_LIVE_CONTROLS_THUMBNAILS_SIZE)}
${this._renderDropdown(CONF_LIVE_CONTROLS_TITLE_MODE, this._titleModes)}
${this._renderStringInput(
CONF_LIVE_CONTROLS_TITLE_DURATION_SECONDS,
'number',
${this._renderOptionSelector(
CONF_LIVE_CONTROLS_TITLE_MODE,
this._titleModes,
)}
${this._renderDropdown(
${this._renderNumberInput(
CONF_LIVE_CONTROLS_TITLE_DURATION_SECONDS,
defaults.live.controls.title.duration_seconds,
0,
60,
)}
${this._renderOptionSelector(
CONF_LIVE_TRANSITION_EFFECT,
this._transitionEffects,
)}
@@ -835,10 +920,9 @@ export class FrigateCardEditor extends LitElement implements LovelaceCardEditor
${this._renderOptionSetHeader('event_gallery')}
${options.event_gallery.show
? html` <div class="values">
${this._renderSlider(
${this._renderNumberInput(
CONF_EVENT_GALLERY_MIN_COLUMNS,
defaults.event_gallery.min_columns,
'mdi:view-column',
1,
10,
)}
@@ -863,25 +947,27 @@ export class FrigateCardEditor extends LitElement implements LovelaceCardEditor
CONF_EVENT_VIEWER_LAZY_LOAD,
defaults.event_viewer.lazy_load,
)}
${this._renderDropdown(
${this._renderOptionSelector(
CONF_EVENT_VIEWER_CONTROLS_NEXT_PREVIOUS_STYLE,
this._eventViewerNextPreviousControlStyles,
)}
${this._renderStringInput(CONF_EVENT_VIEWER_CONTROLS_NEXT_PREVIOUS_SIZE)}
${this._renderDropdown(
${this._renderOptionSelector(
CONF_EVENT_VIEWER_CONTROLS_THUMBNAILS_MODE,
this._thumbnailModes,
)}
${this._renderStringInput(CONF_EVENT_VIEWER_CONTROLS_THUMBNAILS_SIZE)}
${this._renderDropdown(
${this._renderOptionSelector(
CONF_EVENT_VIEWER_CONTROLS_TITLE_MODE,
this._titleModes,
)}
${this._renderStringInput(
${this._renderNumberInput(
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,
this._transitionEffects,
)}
@@ -890,18 +976,18 @@ export class FrigateCardEditor extends LitElement implements LovelaceCardEditor
${this._renderOptionSetHeader('image')}
${options.image.show
? html` <div class="values">
${this._renderDropdown(
CONF_IMAGE_MODE,
this._imageModes,
)}
${this._renderOptionSelector(CONF_IMAGE_MODE, this._imageModes)}
${this._renderStringInput(CONF_IMAGE_URL)}
${this._renderStringInput(CONF_IMAGE_REFRESH_SECONDS, 'number')}
${this._renderNumberInput(
CONF_IMAGE_REFRESH_SECONDS,
defaults.image.refresh_seconds,
)}
</div>`
: ''}
${this._renderOptionSetHeader('dimensions')}
${options.dimensions.show
? html` <div class="values">
${this._renderDropdown(
${this._renderOptionSelector(
CONF_DIMENSIONS_ASPECT_RATIO_MODE,
this._aspectRatioModes,
)}
@@ -981,36 +1067,27 @@ export class FrigateCardEditor extends LitElement implements LovelaceCardEditor
* Handle a changed option value.
* @param ev Event triggering the change.
*/
protected _valueChangedHandler(ev: {
target: (ConfigValueTarget & HTMLElement) | null;
}): void {
const target = ev.target;
if (!this._config || !this.hass || !target) {
protected _valueChangedHandler(
key: string,
ev: CustomEvent<{ value: unknown }>,
): void {
if (!this._config || !this.hass) {
return;
}
let value;
if ('checked' in target) {
value = target.checked;
} else if (typeof target.value === 'string') {
value = target.value?.trim();
if (target['type'] === 'number' && value != '') {
value = Number(value);
if (ev.detail && ev.detail.value !== undefined) {
value = ev.detail.value;
if (typeof value === 'string') {
value = value.trim();
}
} else {
value = target.value;
}
const key: string = target.configValue;
if (!key) {
return;
}
if (getConfigValue(this._config, key) === value) {
return;
}
const newConfig = copyConfig(this._config);
if (value === '' || typeof value === 'undefined') {
if (value === '' || value === undefined) {
deleteConfigValue(newConfig, key);
} else {
setConfigValue(newConfig, key, value);
+2 -2
View File
@@ -90,7 +90,7 @@
"popup-bottom-left": "Popup on the bottom left",
"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": {
"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;
margin-left: auto;
margin-right: 0px;
margin-bottom: 5px;
}
.cameras .controls ha-icon-button.button {
--mdc-icon-button-size: 32px;
+1 -1
View File
@@ -461,7 +461,7 @@ const titleControlConfigSchema = z.object({
'popup-bottom-right',
'popup-bottom-left',
]),
duration_seconds: z.number().min(0),
duration_seconds: z.number().min(0).max(60),
});
export type TitleControlConfig = z.infer<typeof titleControlConfigSchema>;