Automated upgrade of non-px units.
This commit is contained in:
@@ -170,7 +170,7 @@ menu:
|
|||||||
| Option | Default | Overridable | Description |
|
| Option | Default | Overridable | Description |
|
||||||
| - | - | - | - |
|
| - | - | - | - |
|
||||||
| `mode` | `hidden-top` | :white_check_mark: | The menu mode to show by default. See [menu modes](#menu-modes) below.|
|
| `mode` | `hidden-top` | :white_check_mark: | The menu mode to show by default. See [menu modes](#menu-modes) below.|
|
||||||
| `button_size` | 40 | :white_check_mark: | The size of the menu buttons in pixels.|
|
| `button_size` | 40 | :white_check_mark: | The size of the menu buttons in pixels. Must be >= `20`.|
|
||||||
| `buttons` | | :white_check_mark: | Whether to show or hide built-in buttons. See below. |
|
| `buttons` | | :white_check_mark: | Whether to show or hide built-in buttons. See below. |
|
||||||
|
|
||||||
#### Menu Options: Buttons
|
#### Menu Options: Buttons
|
||||||
@@ -258,7 +258,7 @@ live:
|
|||||||
| Option | Default | Overridable | Description |
|
| Option | Default | Overridable | Description |
|
||||||
| - | - | - | - |
|
| - | - | - | - |
|
||||||
| `mode` | `none` | :white_check_mark: | Whether to show the thumbnail carousel `below` the media, `above` the media, in a drawer to the `left` or `right` of the media or to hide it entirely (`none`).|
|
| `mode` | `none` | :white_check_mark: | Whether to show the thumbnail carousel `below` the media, `above` the media, in a drawer to the `left` or `right` of the media or to hide it entirely (`none`).|
|
||||||
| `size` | 100 | :white_check_mark: | The size of the thumbnails in the thumbnail carousel in pixels.|
|
| `size` | 100 | :white_check_mark: | The size of the thumbnails in the thumbnail carousel in pixels. Must be >= `75` and <= `175`. |
|
||||||
| `show_details` | `false` | :white_check_mark: | Whether to show event details (e.g. duration, start time, object detected, etc) alongside the thumbnail.|
|
| `show_details` | `false` | :white_check_mark: | Whether to show event details (e.g. duration, start time, object detected, etc) alongside the thumbnail.|
|
||||||
| `show_controls` | `true` | :white_check_mark: | Whether to show event controls (e.g. timeline icon, favorite icon) alongside the thumbnail.|
|
| `show_controls` | `true` | :white_check_mark: | Whether to show event controls (e.g. timeline icon, favorite icon) alongside the thumbnail.|
|
||||||
| `media` | `clips` | :white_check_mark: | Whether to show `clips` or `snapshots` in the thumbnail carousel in the `live` view.|
|
| `media` | `clips` | :white_check_mark: | Whether to show `clips` or `snapshots` in the thumbnail carousel in the `live` view.|
|
||||||
@@ -276,7 +276,7 @@ live:
|
|||||||
| Option | Default | Overridable | Description |
|
| Option | Default | Overridable | Description |
|
||||||
| - | - | - | - |
|
| - | - | - | - |
|
||||||
| `style` | `chevrons` | :white_check_mark: | When viewing live cameras, what kind of controls to show to move to the previous/next camera. Acceptable values: `chevrons`, `icons`, `none` . |
|
| `style` | `chevrons` | :white_check_mark: | When viewing live cameras, what kind of controls to show to move to the previous/next camera. Acceptable values: `chevrons`, `icons`, `none` . |
|
||||||
| `size` | 48 | :white_check_mark: | The size of the next/previous controls in pixels.|
|
| `size` | 48 | :white_check_mark: | The size of the next/previous controls in pixels. Must be >= `20`. |
|
||||||
|
|
||||||
<a name="live-controls-title"></a>
|
<a name="live-controls-title"></a>
|
||||||
|
|
||||||
@@ -328,7 +328,7 @@ event_viewer:
|
|||||||
| Option | Default | Overridable | Description |
|
| Option | Default | Overridable | Description |
|
||||||
| - | - | - | - |
|
| - | - | - | - |
|
||||||
| `style` | `thumbnails` | :heavy_multiplication_x: | When viewing media, what kind of controls to show to move to the previous/next media item. Acceptable values: `thumbnails`, `chevrons`, `none` . |
|
| `style` | `thumbnails` | :heavy_multiplication_x: | When viewing media, what kind of controls to show to move to the previous/next media item. Acceptable values: `thumbnails`, `chevrons`, `none` . |
|
||||||
| `size` | 48 | :heavy_multiplication_x: | The size of the next/previous controls in pixels.|
|
| `size` | 48 | :heavy_multiplication_x: | The size of the next/previous controls in pixels. Must be >= `20`.|
|
||||||
|
|
||||||
#### Event Viewer Controls: Thumbnails
|
#### Event Viewer Controls: Thumbnails
|
||||||
|
|
||||||
@@ -343,7 +343,7 @@ event_viewer:
|
|||||||
| Option | Default | Overridable | Description |
|
| Option | Default | Overridable | Description |
|
||||||
| - | - | - | - |
|
| - | - | - | - |
|
||||||
| `mode` | `none` | :heavy_multiplication_x: | Whether to show the thumbnail carousel `below` the media, `above` the media, in a drawer to the `left` or `right` of the media or to hide it entirely (`none`).|
|
| `mode` | `none` | :heavy_multiplication_x: | Whether to show the thumbnail carousel `below` the media, `above` the media, in a drawer to the `left` or `right` of the media or to hide it entirely (`none`).|
|
||||||
| `size` | 100 | :heavy_multiplication_x: | The size of the thumbnails in the thumbnail carousel pixels.|
|
| `size` | 100 | :heavy_multiplication_x: | The size of the thumbnails in the thumbnail carousel pixels. Must be >= `75` and <= `175`.|
|
||||||
| `show_details` | `false` | :heavy_multiplication_x: | Whether to show event details (e.g. duration, start time, object detected, etc) alongside the thumbnail.|
|
| `show_details` | `false` | :heavy_multiplication_x: | Whether to show event details (e.g. duration, start time, object detected, etc) alongside the thumbnail.|
|
||||||
| `show_controls` | `true` | :heavy_multiplication_x: | Whether to show event controls (e.g. timeline icon, favorite icon) alongside the thumbnail.|
|
| `show_controls` | `true` | :heavy_multiplication_x: | Whether to show event controls (e.g. timeline icon, favorite icon) alongside the thumbnail.|
|
||||||
|
|
||||||
@@ -374,7 +374,7 @@ event_gallery:
|
|||||||
|
|
||||||
| Option | Default | Overridable | Description |
|
| Option | Default | Overridable | Description |
|
||||||
| - | - | - | - |
|
| - | - | - | - |
|
||||||
| `size` | 100 | :heavy_multiplication_x: | The size of the thumbnails in the event gallery in pixels.|
|
| `size` | 100 | :heavy_multiplication_x: | The size of the thumbnails in the event gallery in pixels. Must be >= `75` and <= `175`.|
|
||||||
| `show_details` | `false` | :heavy_multiplication_x: | Whether to show event details (e.g. duration, start time, object detected, etc) alongside the thumbnail.|
|
| `show_details` | `false` | :heavy_multiplication_x: | Whether to show event details (e.g. duration, start time, object detected, etc) alongside the thumbnail.|
|
||||||
| `show_controls` | `true` | :heavy_multiplication_x: | Whether to show event controls (e.g. timeline icon, favorite icon) alongside the thumbnail.|
|
| `show_controls` | `true` | :heavy_multiplication_x: | Whether to show event controls (e.g. timeline icon, favorite icon) alongside the thumbnail.|
|
||||||
| `actions` | | :heavy_multiplication_x: | Actions to use for all views that use the `event_gallery` (e.g. `clips`, `snapshots`). See [actions](#actions) below.|
|
| `actions` | | :heavy_multiplication_x: | Actions to use for all views that use the `event_gallery` (e.g. `clips`, `snapshots`). See [actions](#actions) below.|
|
||||||
@@ -425,7 +425,7 @@ timeline:
|
|||||||
| Option | Default | Overridable | Description |
|
| Option | Default | Overridable | Description |
|
||||||
| - | - | - | - |
|
| - | - | - | - |
|
||||||
| `mode` | `none` | :heavy_multiplication_x: | Whether to show the thumbnail carousel `below` the media, `above` the media, in a drawer to the `left` or `right` of the media or to hide it entirely (`none`).|
|
| `mode` | `none` | :heavy_multiplication_x: | Whether to show the thumbnail carousel `below` the media, `above` the media, in a drawer to the `left` or `right` of the media or to hide it entirely (`none`).|
|
||||||
| `size` | 100 | :heavy_multiplication_x: | The size of the thumbnails in the thumbnail carousel in pixels.|
|
| `size` | 100 | :heavy_multiplication_x: | The size of the thumbnails in the thumbnail carousel in pixels. Must be >= `75` and <= `175`.|
|
||||||
| `show_details` | `false` | :heavy_multiplication_x: | Whether to show event details (e.g. duration, start time, object detected, etc) alongside the thumbnail.|
|
| `show_details` | `false` | :heavy_multiplication_x: | Whether to show event details (e.g. duration, start time, object detected, etc) alongside the thumbnail.|
|
||||||
| `show_controls` | `true` | :heavy_multiplication_x: | Whether to show event controls (e.g. timeline icon, favorite icon) alongside the thumbnail.|
|
| `show_controls` | `true` | :heavy_multiplication_x: | Whether to show event controls (e.g. timeline icon, favorite icon) alongside the thumbnail.|
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
// TODO: Add details & controls & size support
|
|
||||||
// TODO: automatic upgrade for thumbnail sizes in px and menu buttons in px
|
|
||||||
// TODO: automatic remove of min_columns
|
// TODO: automatic remove of min_columns
|
||||||
|
|
||||||
/* eslint-disable @typescript-eslint/no-explicit-any */
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||||
|
|||||||
+98
-37
@@ -1,4 +1,4 @@
|
|||||||
import { get, set } from 'lodash-es';
|
import { get, isEqual, set } from 'lodash-es';
|
||||||
import {
|
import {
|
||||||
CONF_CAMERAS,
|
CONF_CAMERAS,
|
||||||
CONF_CAMERAS_ARRAY_CAMERA_ENTITY,
|
CONF_CAMERAS_ARRAY_CAMERA_ENTITY,
|
||||||
@@ -11,7 +11,10 @@ import {
|
|||||||
CONF_EVENT_VIEWER_AUTO_PLAY,
|
CONF_EVENT_VIEWER_AUTO_PLAY,
|
||||||
CONF_EVENT_VIEWER_CONTROLS_NEXT_PREVIOUS_SIZE,
|
CONF_EVENT_VIEWER_CONTROLS_NEXT_PREVIOUS_SIZE,
|
||||||
CONF_EVENT_VIEWER_CONTROLS_NEXT_PREVIOUS_STYLE,
|
CONF_EVENT_VIEWER_CONTROLS_NEXT_PREVIOUS_STYLE,
|
||||||
|
CONF_EVENT_VIEWER_CONTROLS_THUMBNAILS_SIZE,
|
||||||
CONF_IMAGE_URL,
|
CONF_IMAGE_URL,
|
||||||
|
CONF_LIVE_CONTROLS_NEXT_PREVIOUS_SIZE,
|
||||||
|
CONF_LIVE_CONTROLS_THUMBNAILS_SIZE,
|
||||||
CONF_LIVE_PRELOAD,
|
CONF_LIVE_PRELOAD,
|
||||||
CONF_LIVE_WEBRTC_CARD,
|
CONF_LIVE_WEBRTC_CARD,
|
||||||
CONF_MENU,
|
CONF_MENU,
|
||||||
@@ -22,7 +25,13 @@ import {
|
|||||||
CONF_VIEW_TIMEOUT_SECONDS,
|
CONF_VIEW_TIMEOUT_SECONDS,
|
||||||
CONF_VIEW_UPDATE_ENTITIES,
|
CONF_VIEW_UPDATE_ENTITIES,
|
||||||
} from './const';
|
} from './const';
|
||||||
import { RawFrigateCardConfig, RawFrigateCardConfigArray } from './types';
|
import {
|
||||||
|
BUTTON_SIZE_MIN,
|
||||||
|
RawFrigateCardConfig,
|
||||||
|
RawFrigateCardConfigArray,
|
||||||
|
THUMBNAIL_WIDTH_MAX,
|
||||||
|
THUMBNAIL_WIDTH_MIN,
|
||||||
|
} from './types';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set a configuration value.
|
* Set a configuration value.
|
||||||
@@ -131,7 +140,7 @@ export const copyConfig = function (obj: RawFrigateCardConfig): RawFrigateCardCo
|
|||||||
* @param value The value.
|
* @param value The value.
|
||||||
* @returns `true` is the value is not an object.
|
* @returns `true` is the value is not an object.
|
||||||
*/
|
*/
|
||||||
const isNotObject = function (value: unknown) {
|
const isNotObject = function (value: unknown): unknown | undefined {
|
||||||
return typeof value !== 'object' ? value : undefined;
|
return typeof value !== 'object' ? value : undefined;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -140,10 +149,46 @@ const isNotObject = function (value: unknown) {
|
|||||||
* @param value The value.
|
* @param value The value.
|
||||||
* @returns A number or undefined.
|
* @returns A number or undefined.
|
||||||
*/
|
*/
|
||||||
const toNumberOrIgnore = function (value: unknown) {
|
const toNumberOrIgnore = function (value: unknown): number | undefined {
|
||||||
return isNaN(value as number) ? undefined : Number(value);
|
return isNaN(value as number) ? undefined : Number(value);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a transform that will cap a numeric value.
|
||||||
|
* @param value The value.
|
||||||
|
* @returns A number or null.
|
||||||
|
*/
|
||||||
|
const createRangedTransform = function (
|
||||||
|
transform: (value: unknown) => unknown,
|
||||||
|
min?: number,
|
||||||
|
max?: number,
|
||||||
|
): (valueIn: unknown) => unknown {
|
||||||
|
return (value: unknown): unknown => {
|
||||||
|
let transformed = transform(value);
|
||||||
|
if (typeof transformed !== 'number') {
|
||||||
|
return transformed;
|
||||||
|
}
|
||||||
|
transformed = min ? Math.max(min, transformed as number) : transformed;
|
||||||
|
transformed = max ? Math.min(max, transformed as number) : transformed;
|
||||||
|
return transformed;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
const toPixelsOrDelete = function (value: unknown): number | null | undefined {
|
||||||
|
// Ignore the value if it's a number.
|
||||||
|
if (typeof value === 'number') {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
// Delete the value if it's not a string.
|
||||||
|
if (typeof value !== 'string') {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
// Remove 'px' and return the number, unless it's an invalid number -- then
|
||||||
|
// delete it.
|
||||||
|
value = value.replace(/px$/i, '');
|
||||||
|
return isNaN(value as number) ? null : Number(value);
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Move a property from one location to another.
|
* Move a property from one location to another.
|
||||||
* @param obj The configuration object in which the property resides.
|
* @param obj The configuration object in which the property resides.
|
||||||
@@ -158,13 +203,21 @@ export const moveConfigValue = (
|
|||||||
newPath: string,
|
newPath: string,
|
||||||
transform?: (valueIn: unknown) => unknown,
|
transform?: (valueIn: unknown) => unknown,
|
||||||
): boolean => {
|
): boolean => {
|
||||||
let value = getConfigValue(obj, oldPath);
|
const inValue = getConfigValue(obj, oldPath);
|
||||||
if (transform) {
|
if (inValue === undefined) {
|
||||||
value = transform(value);
|
return false;
|
||||||
}
|
}
|
||||||
if (typeof value !== 'undefined') {
|
const outValue = transform ? transform(inValue) : inValue;
|
||||||
|
if (oldPath === newPath && isEqual(inValue, outValue)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (outValue === null) {
|
||||||
deleteConfigValue(obj, oldPath);
|
deleteConfigValue(obj, oldPath);
|
||||||
setConfigValue(obj, newPath, value);
|
return true;
|
||||||
|
}
|
||||||
|
if (outValue !== undefined) {
|
||||||
|
deleteConfigValue(obj, oldPath);
|
||||||
|
setConfigValue(obj, newPath, outValue);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
@@ -197,33 +250,6 @@ const upgradeMoveTo = function (
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
|
||||||
* Upgrade a property by changing it if it is present.
|
|
||||||
* @param path The property path.
|
|
||||||
* @param transform A callback that transforms the old value to the new value,
|
|
||||||
* if undefined is returned the property is removed.
|
|
||||||
* @returns `true` if the configuration was modified.
|
|
||||||
*/
|
|
||||||
const upgradeChangeIfPresent = function (
|
|
||||||
path: string,
|
|
||||||
transform: (valueIn: unknown) => unknown,
|
|
||||||
): (obj: RawFrigateCardConfig) => boolean {
|
|
||||||
return function (obj: RawFrigateCardConfig): boolean {
|
|
||||||
const oldValue = getConfigValue(obj, path);
|
|
||||||
if (oldValue !== undefined) {
|
|
||||||
const newValue = transform(oldValue);
|
|
||||||
if (newValue === undefined) {
|
|
||||||
deleteConfigValue(obj, path);
|
|
||||||
return true;
|
|
||||||
} else if (newValue !== oldValue) {
|
|
||||||
setConfigValue(obj, path, newValue);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Upgrade by moving a property from one location to another, and moving a
|
* Upgrade by moving a property from one location to another, and moving a
|
||||||
* property specified in a top-level overrides object.
|
* property specified in a top-level overrides object.
|
||||||
@@ -249,6 +275,19 @@ const upgradeMoveToWithOverrides = function (
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Upgrade a property in place with overrides.
|
||||||
|
* @param path The old property path.
|
||||||
|
* @param transform An optional transform for the value.
|
||||||
|
* @returns A function that returns `true` if the configuration was modified.
|
||||||
|
*/
|
||||||
|
const upgradeWithOverrides = function (
|
||||||
|
path: string,
|
||||||
|
transform?: (valueIn: unknown) => unknown,
|
||||||
|
): (obj: RawFrigateCardConfig) => boolean {
|
||||||
|
return upgradeMoveToWithOverrides(path, path, transform);
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Given a path to an array, apply an upgrade to each object in the array.
|
* Given a path to an array, apply an upgrade to each object in the array.
|
||||||
* @param arrayPath The path to the array to upgrade.
|
* @param arrayPath The path to the array to upgrade.
|
||||||
@@ -377,11 +416,33 @@ const UPGRADES = [
|
|||||||
// v3.0.0-rc.1 -> v3.0.0-rc.2
|
// v3.0.0-rc.1 -> v3.0.0-rc.2
|
||||||
upgradeArrayValue(
|
upgradeArrayValue(
|
||||||
CONF_CAMERAS,
|
CONF_CAMERAS,
|
||||||
upgradeChangeIfPresent('live_provider', (val) =>
|
upgradeWithOverrides('live_provider', (val) =>
|
||||||
val === 'frigate' ? 'ha' : val === 'webrtc' ? 'webrtc-card' : val,
|
val === 'frigate' ? 'ha' : val === 'webrtc' ? 'webrtc-card' : val,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
upgradeArrayValue(CONF_CAMERAS, upgradeMoveTo('webrtc', 'webrtc_card')),
|
upgradeArrayValue(CONF_CAMERAS, upgradeMoveTo('webrtc', 'webrtc_card')),
|
||||||
upgradeMoveToWithOverrides('live.webrtc', CONF_LIVE_WEBRTC_CARD),
|
upgradeMoveToWithOverrides('live.webrtc', CONF_LIVE_WEBRTC_CARD),
|
||||||
upgradeMoveToWithOverrides('image.src', CONF_IMAGE_URL),
|
upgradeMoveToWithOverrides('image.src', CONF_IMAGE_URL),
|
||||||
|
|
||||||
|
// v3.0.0 -> v4.0.0-rc.1
|
||||||
|
upgradeWithOverrides(
|
||||||
|
CONF_LIVE_CONTROLS_THUMBNAILS_SIZE,
|
||||||
|
createRangedTransform(toPixelsOrDelete, THUMBNAIL_WIDTH_MIN, THUMBNAIL_WIDTH_MAX),
|
||||||
|
),
|
||||||
|
upgradeWithOverrides(
|
||||||
|
CONF_EVENT_VIEWER_CONTROLS_THUMBNAILS_SIZE,
|
||||||
|
createRangedTransform(toPixelsOrDelete, THUMBNAIL_WIDTH_MIN, THUMBNAIL_WIDTH_MAX),
|
||||||
|
),
|
||||||
|
upgradeWithOverrides(
|
||||||
|
CONF_LIVE_CONTROLS_NEXT_PREVIOUS_SIZE,
|
||||||
|
createRangedTransform(toPixelsOrDelete, BUTTON_SIZE_MIN),
|
||||||
|
),
|
||||||
|
upgradeWithOverrides(
|
||||||
|
CONF_EVENT_VIEWER_CONTROLS_NEXT_PREVIOUS_SIZE,
|
||||||
|
createRangedTransform(toPixelsOrDelete, BUTTON_SIZE_MIN),
|
||||||
|
),
|
||||||
|
upgradeWithOverrides(
|
||||||
|
CONF_MENU_BUTTON_SIZE,
|
||||||
|
createRangedTransform(toPixelsOrDelete, BUTTON_SIZE_MIN),
|
||||||
|
),
|
||||||
];
|
];
|
||||||
|
|||||||
+10
-3
@@ -5,6 +5,7 @@ import { customElement, property, state } from 'lit/decorators.js';
|
|||||||
import { HomeAssistant, LovelaceCardEditor, fireEvent } from 'custom-card-helpers';
|
import { HomeAssistant, LovelaceCardEditor, fireEvent } from 'custom-card-helpers';
|
||||||
import { localize } from './localize/localize.js';
|
import { localize } from './localize/localize.js';
|
||||||
import {
|
import {
|
||||||
|
BUTTON_SIZE_MIN,
|
||||||
RawFrigateCardConfig,
|
RawFrigateCardConfig,
|
||||||
RawFrigateCardConfigArray,
|
RawFrigateCardConfigArray,
|
||||||
THUMBNAIL_WIDTH_MAX,
|
THUMBNAIL_WIDTH_MAX,
|
||||||
@@ -847,7 +848,7 @@ export class FrigateCardEditor extends LitElement implements LovelaceCardEditor
|
|||||||
? html`
|
? html`
|
||||||
<div class="values">
|
<div class="values">
|
||||||
${this._renderOptionSelector(CONF_MENU_MODE, this._menuModes)}
|
${this._renderOptionSelector(CONF_MENU_MODE, this._menuModes)}
|
||||||
${this._renderNumberInput(CONF_MENU_BUTTON_SIZE)}
|
${this._renderNumberInput(CONF_MENU_BUTTON_SIZE, BUTTON_SIZE_MIN)}
|
||||||
${this._renderSwitch(
|
${this._renderSwitch(
|
||||||
CONF_MENU_BUTTONS_FRIGATE,
|
CONF_MENU_BUTTONS_FRIGATE,
|
||||||
defaults.menu.buttons.frigate,
|
defaults.menu.buttons.frigate,
|
||||||
@@ -904,7 +905,10 @@ export class FrigateCardEditor extends LitElement implements LovelaceCardEditor
|
|||||||
CONF_LIVE_CONTROLS_NEXT_PREVIOUS_STYLE,
|
CONF_LIVE_CONTROLS_NEXT_PREVIOUS_STYLE,
|
||||||
this._liveNextPreviousControlStyles,
|
this._liveNextPreviousControlStyles,
|
||||||
)}
|
)}
|
||||||
${this._renderNumberInput(CONF_LIVE_CONTROLS_NEXT_PREVIOUS_SIZE)}
|
${this._renderNumberInput(
|
||||||
|
CONF_LIVE_CONTROLS_NEXT_PREVIOUS_SIZE,
|
||||||
|
BUTTON_SIZE_MIN,
|
||||||
|
)}
|
||||||
${this._renderOptionSelector(
|
${this._renderOptionSelector(
|
||||||
CONF_LIVE_CONTROLS_THUMBNAILS_MODE,
|
CONF_LIVE_CONTROLS_THUMBNAILS_MODE,
|
||||||
this._thumbnailModes,
|
this._thumbnailModes,
|
||||||
@@ -983,7 +987,10 @@ export class FrigateCardEditor extends LitElement implements LovelaceCardEditor
|
|||||||
CONF_EVENT_VIEWER_CONTROLS_NEXT_PREVIOUS_STYLE,
|
CONF_EVENT_VIEWER_CONTROLS_NEXT_PREVIOUS_STYLE,
|
||||||
this._eventViewerNextPreviousControlStyles,
|
this._eventViewerNextPreviousControlStyles,
|
||||||
)}
|
)}
|
||||||
${this._renderNumberInput(CONF_EVENT_VIEWER_CONTROLS_NEXT_PREVIOUS_SIZE)}
|
${this._renderNumberInput(
|
||||||
|
CONF_EVENT_VIEWER_CONTROLS_NEXT_PREVIOUS_SIZE,
|
||||||
|
BUTTON_SIZE_MIN,
|
||||||
|
)}
|
||||||
${this._renderOptionSelector(
|
${this._renderOptionSelector(
|
||||||
CONF_EVENT_VIEWER_CONTROLS_THUMBNAILS_MODE,
|
CONF_EVENT_VIEWER_CONTROLS_THUMBNAILS_MODE,
|
||||||
this._thumbnailModes,
|
this._thumbnailModes,
|
||||||
|
|||||||
+6
-3
@@ -14,7 +14,10 @@ import { z } from 'zod';
|
|||||||
|
|
||||||
import { deepRemoveDefaults } from './zod-util';
|
import { deepRemoveDefaults } from './zod-util';
|
||||||
|
|
||||||
// The maximum width thumbnail Frigate returns
|
// The min allowed size of buttons.
|
||||||
|
export const BUTTON_SIZE_MIN = 20;
|
||||||
|
|
||||||
|
// The min/max width thumbnail (Frigate returns a maximum of 175px).
|
||||||
export const THUMBNAIL_WIDTH_MAX = 175;
|
export const THUMBNAIL_WIDTH_MAX = 175;
|
||||||
export const THUMBNAIL_WIDTH_MIN = 75;
|
export const THUMBNAIL_WIDTH_MIN = 75;
|
||||||
|
|
||||||
@@ -455,7 +458,7 @@ export type ThumbnailsControlConfig = z.infer<typeof thumbnailsControlSchema>;
|
|||||||
|
|
||||||
const nextPreviousControlConfigSchema = z.object({
|
const nextPreviousControlConfigSchema = z.object({
|
||||||
style: z.enum(['none', 'chevrons', 'icons', 'thumbnails']),
|
style: z.enum(['none', 'chevrons', 'icons', 'thumbnails']),
|
||||||
size: z.number().min(1),
|
size: z.number().min(BUTTON_SIZE_MIN),
|
||||||
});
|
});
|
||||||
export type NextPreviousControlConfig = z.infer<typeof nextPreviousControlConfigSchema>;
|
export type NextPreviousControlConfig = z.infer<typeof nextPreviousControlConfigSchema>;
|
||||||
|
|
||||||
@@ -638,7 +641,7 @@ 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.number().min(1).default(menuConfigDefault.button_size),
|
button_size: z.number().min(BUTTON_SIZE_MIN).default(menuConfigDefault.button_size),
|
||||||
})
|
})
|
||||||
.default(menuConfigDefault);
|
.default(menuConfigDefault);
|
||||||
export type MenuConfig = z.infer<typeof menuConfigSchema>;
|
export type MenuConfig = z.infer<typeof menuConfigSchema>;
|
||||||
|
|||||||
Reference in New Issue
Block a user