Add initial editor support.

This commit is contained in:
Dermot Duffy
2022-04-10 08:30:26 -07:00
parent ce9ef97aea
commit b908f4dbc9
4 changed files with 79 additions and 26 deletions
+9 -15
View File
@@ -367,7 +367,6 @@ export class FrigateCardTimelineCore extends LitElement {
tooltipCallback: this._getTooltip.bind(this), tooltipCallback: this._getTooltip.bind(this),
}); });
protected _refTimeline: Ref<HTMLElement> = createRef(); protected _refTimeline: Ref<HTMLElement> = createRef();
protected _thumbnails?: FrigateBrowseMediaSource;
protected _timeline?: Timeline; protected _timeline?: Timeline;
/** /**
@@ -445,14 +444,13 @@ export class FrigateCardTimelineCore extends LitElement {
properties.start, properties.start,
properties.end, properties.end,
) )
.then((fetched: boolean) => { .then(() => {
if (fetched) {
this._generateThumbnails(); this._generateThumbnails();
}
}); });
// Update the view to ensure that future view changes do not cause a // Update the view to ensure that future view changes do not cause a
// scroll. // scroll.
console.info('=========> Evolve view from Range');
this.view this.view
?.evolve({ ?.evolve({
context: { context: {
@@ -470,19 +468,18 @@ export class FrigateCardTimelineCore extends LitElement {
*/ */
// eslint-disable-next-line @typescript-eslint/no-unused-vars // eslint-disable-next-line @typescript-eslint/no-unused-vars
protected _timelineSelectHandler(data: { items: string[]; event: Event }): void { protected _timelineSelectHandler(data: { items: string[]; event: Event }): void {
if (!this._thumbnails || !this._thumbnails.children) { if (!this.view?.target || !this.view?.target.children) {
return; return;
} }
const childIndex = data.items.length const childIndex = data.items.length
? this._thumbnails.children.findIndex( ? this.view.target.children.findIndex(
(child) => child.frigate?.event.id === data.items[0], (child) => child.frigate?.event.id === data.items[0],
) )
: null; : null;
console.info('=========> Evolve view from select');
this.view this.view
?.evolve({ ?.evolve({
target: this._thumbnails,
childIndex: childIndex, childIndex: childIndex,
}) })
.dispatchChangeEvent(this); .dispatchChangeEvent(this);
@@ -546,13 +543,12 @@ export class FrigateCardTimelineCore extends LitElement {
children: children, children: children,
}; };
if (!isEqual(target, this._thumbnails)) { if (!isEqual(target, this.view?.target)) {
this._thumbnails = target;
// Update the thumbnail carousel with the regenerated thumbnails. // Update the thumbnail carousel with the regenerated thumbnails.
console.info('=========> Evolve view from thumbnails');
this.view this.view
?.evolve({ ?.evolve({
target: this._thumbnails, target: target,
childIndex: childIndex < 0 ? null : childIndex, childIndex: childIndex < 0 ? null : childIndex,
}) })
.dispatchChangeEvent(this); .dispatchChangeEvent(this);
@@ -718,7 +714,6 @@ export class FrigateCardTimelineCore extends LitElement {
? this._getStartEndFromEvent(event) ? this._getStartEndFromEvent(event)
: this._getStartEnd(); : this._getStartEnd();
if (
await this._events.fetchEventsIfNecessary( await this._events.fetchEventsIfNecessary(
this, this,
this.hass, this.hass,
@@ -727,9 +722,7 @@ export class FrigateCardTimelineCore extends LitElement {
windowStart, windowStart,
windowEnd, windowEnd,
) )
) {
this._generateThumbnails(); this._generateThumbnails();
}
this._timeline.setSelection(event ? [event.id] : [], { this._timeline.setSelection(event ? [event.id] : [], {
focus: false, focus: false,
@@ -783,6 +776,7 @@ export class FrigateCardTimelineCore extends LitElement {
*/ */
protected updated(changedProperties: PropertyValues): void { protected updated(changedProperties: PropertyValues): void {
super.updated(changedProperties); super.updated(changedProperties);
console.info(changedProperties);
if (changedProperties.has('cameras')) { if (changedProperties.has('cameras')) {
this._events.clear(); this._events.clear();
+7
View File
@@ -84,6 +84,13 @@ export const CONF_IMAGE_MODE = `${CONF_IMAGE}.mode` as const;
export const CONF_IMAGE_REFRESH_SECONDS = `${CONF_IMAGE}.refresh_seconds` as const; export const CONF_IMAGE_REFRESH_SECONDS = `${CONF_IMAGE}.refresh_seconds` as const;
export const CONF_IMAGE_URL = `${CONF_IMAGE}.url` as const; export const CONF_IMAGE_URL = `${CONF_IMAGE}.url` as const;
export const CONF_TIMELINE = 'timeline' as const;
export const CONF_TIMELINE_CLUSTERING_THRESHOLD = `${CONF_TIMELINE}.clustering_threshold` as const;
export const CONF_TIMELINE_MEDIA = `${CONF_TIMELINE}.media` as const;
export const CONF_TIMELINE_CONTROLS_THUMBNAILS_MODE = `${CONF_TIMELINE}.controls.thumbnails.mode` as const;
export const CONF_TIMELINE_CONTROLS_THUMBNAILS_SIZE = `${CONF_TIMELINE}.controls.thumbnails.size` as const;
export const CONF_TIMELINE_CONTROLS_THUMBNAILS_SHOW_DETAILS = `${CONF_TIMELINE}.controls.thumbnails.show_details` as const;
export const CONF_MENU = 'menu' as const; export const CONF_MENU = 'menu' as const;
export const CONF_MENU_BUTTONS_FRIGATE = `${CONF_MENU}.buttons.frigate` as const; export const CONF_MENU_BUTTONS_FRIGATE = `${CONF_MENU}.buttons.frigate` as const;
export const CONF_MENU_BUTTONS_FRIGATE_UI = `${CONF_MENU}.buttons.frigate_ui` as const; export const CONF_MENU_BUTTONS_FRIGATE_UI = `${CONF_MENU}.buttons.frigate_ui` as const;
+34
View File
@@ -66,6 +66,11 @@ import {
CONF_MENU_BUTTONS_SNAPSHOTS, CONF_MENU_BUTTONS_SNAPSHOTS,
CONF_MENU_BUTTON_SIZE, CONF_MENU_BUTTON_SIZE,
CONF_MENU_MODE, CONF_MENU_MODE,
CONF_TIMELINE_CLUSTERING_THRESHOLD,
CONF_TIMELINE_CONTROLS_THUMBNAILS_MODE,
CONF_TIMELINE_CONTROLS_THUMBNAILS_SHOW_DETAILS,
CONF_TIMELINE_CONTROLS_THUMBNAILS_SIZE,
CONF_TIMELINE_MEDIA,
CONF_VIEW_CAMERA_SELECT, CONF_VIEW_CAMERA_SELECT,
CONF_VIEW_DEFAULT, CONF_VIEW_DEFAULT,
CONF_VIEW_TIMEOUT_SECONDS, CONF_VIEW_TIMEOUT_SECONDS,
@@ -147,6 +152,12 @@ const options: EditorOptions = {
secondary: localize('editor.image_secondary'), secondary: localize('editor.image_secondary'),
show: false, show: false,
}, },
timeline: {
icon: 'chart-gantt',
name: localize('editor.timeline'),
secondary: localize('editor.timeline_secondary'),
show: false,
},
dimensions: { dimensions: {
icon: 'aspect-ratio', icon: 'aspect-ratio',
name: localize('editor.dimensions'), name: localize('editor.dimensions'),
@@ -315,6 +326,13 @@ export class FrigateCardEditor extends LitElement implements LovelaceCardEditor
{ value: 'url', label: localize('config.image.modes.url') }, { value: 'url', label: localize('config.image.modes.url') },
]; ];
protected _timelineMediaTypes = [
{ value: '', label: '' },
{ value: 'all', label: localize('config.timeline.medias.all') },
{ value: 'clips', label: localize('config.timeline.medias.clips') },
{ value: 'snapshots', label: localize('config.timeline.medias.snapshots') },
];
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
// partially or completely invalid. It's more useful to have a partially // partially or completely invalid. It's more useful to have a partially
@@ -969,6 +987,22 @@ export class FrigateCardEditor extends LitElement implements LovelaceCardEditor
${this._renderNumberInput(CONF_IMAGE_REFRESH_SECONDS)} ${this._renderNumberInput(CONF_IMAGE_REFRESH_SECONDS)}
</div>` </div>`
: ''} : ''}
${this._renderOptionSetHeader('timeline')}
${options.timeline.show
? html` <div class="values">
${this._renderNumberInput(CONF_TIMELINE_CLUSTERING_THRESHOLD)}
${this._renderOptionSelector(CONF_TIMELINE_MEDIA, this._timelineMediaTypes)}
${this._renderOptionSelector(
CONF_TIMELINE_CONTROLS_THUMBNAILS_MODE,
this._thumbnailModes,
)}
${this._renderStringInput(CONF_TIMELINE_CONTROLS_THUMBNAILS_SIZE)}
${this._renderSwitch(
CONF_TIMELINE_CONTROLS_THUMBNAILS_SHOW_DETAILS,
defaults.event_viewer.controls.thumbnails.show_details,
)}
</div>`
: ''}
${this._renderOptionSetHeader('dimensions')} ${this._renderOptionSetHeader('dimensions')}
${options.dimensions.show ${options.dimensions.show
? html` <div class="values"> ? html` <div class="values">
+19 -1
View File
@@ -169,6 +169,22 @@
}, },
"button_size": "Menu button size (e.g. '40px')" "button_size": "Menu button size (e.g. '40px')"
}, },
"timeline": {
"clustering_threshold": "The count of events at which they are clustered",
"media": "The media the timeline displays",
"medias": {
"all": "All media types",
"clips": "Clips",
"snapshots": "Snapshots"
},
"controls": {
"thumbnails": {
"mode": "Timeline thumbnails mode",
"size": "Timeline thumbnails size (e.g. '100px')",
"show_details": "Show event details with thumbnails"
}
}
},
"dimensions": { "dimensions": {
"aspect_ratio": "Default aspect ratio (e.g. '16:9')", "aspect_ratio": "Default aspect ratio (e.g. '16:9')",
"aspect_ratio_mode": "Aspect ratio mode", "aspect_ratio_mode": "Aspect ratio mode",
@@ -208,7 +224,9 @@
"add_new_camera": "Add new camera", "add_new_camera": "Add new camera",
"camera": "Camera", "camera": "Camera",
"overrides": "Overrides are active", "overrides": "Overrides are active",
"overrides_secondary": "Dynamic configuration overrides detected" "overrides_secondary": "Dynamic configuration overrides detected",
"timeline": "Timeline",
"timeline_secondary": "Event timeline options"
}, },
"event": { "event": {
"start": "Start", "start": "Start",