Add support for fetching thumnails separately
This commit is contained in:
@@ -1,5 +1,4 @@
|
|||||||
/* eslint-disable @typescript-eslint/no-explicit-any */
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||||
import { HomeAssistant } from 'custom-card-helpers';
|
|
||||||
import {
|
import {
|
||||||
css,
|
css,
|
||||||
CSSResultGroup,
|
CSSResultGroup,
|
||||||
@@ -13,6 +12,7 @@ import { customElement, property } from 'lit/decorators.js';
|
|||||||
import galleryStyle from '../scss/gallery.scss';
|
import galleryStyle from '../scss/gallery.scss';
|
||||||
import {
|
import {
|
||||||
CameraConfig,
|
CameraConfig,
|
||||||
|
ExtendedHomeAssistant,
|
||||||
frigateCardConfigDefaults,
|
frigateCardConfigDefaults,
|
||||||
GalleryConfig,
|
GalleryConfig,
|
||||||
THUMBNAIL_WIDTH_MAX,
|
THUMBNAIL_WIDTH_MAX,
|
||||||
@@ -31,7 +31,7 @@ import { THUMBNAIL_DETAILS_WIDTH_MIN } from './thumbnail.js';
|
|||||||
@customElement('frigate-card-gallery')
|
@customElement('frigate-card-gallery')
|
||||||
export class FrigateCardGallery extends LitElement {
|
export class FrigateCardGallery extends LitElement {
|
||||||
@property({ attribute: false })
|
@property({ attribute: false })
|
||||||
public hass?: HomeAssistant;
|
public hass?: ExtendedHomeAssistant;
|
||||||
|
|
||||||
@property({ attribute: false })
|
@property({ attribute: false })
|
||||||
public view?: Readonly<View>;
|
public view?: Readonly<View>;
|
||||||
@@ -109,7 +109,7 @@ export class FrigateCardGallery extends LitElement {
|
|||||||
@customElement('frigate-card-gallery-core')
|
@customElement('frigate-card-gallery-core')
|
||||||
export class FrigateCardGalleryCore extends LitElement {
|
export class FrigateCardGalleryCore extends LitElement {
|
||||||
@property({ attribute: false })
|
@property({ attribute: false })
|
||||||
public hass?: HomeAssistant;
|
public hass?: ExtendedHomeAssistant;
|
||||||
|
|
||||||
@property({ attribute: false })
|
@property({ attribute: false })
|
||||||
public view?: Readonly<View>;
|
public view?: Readonly<View>;
|
||||||
|
|||||||
@@ -138,6 +138,19 @@ export class FrigateCardLive extends LitElement {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determine whether the element should be updated.
|
||||||
|
* @param _changedProps The changed properties if any.
|
||||||
|
* @returns `true` if the element should be updated.
|
||||||
|
*/
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||||
|
protected shouldUpdate(_changedProps: PropertyValues): boolean {
|
||||||
|
// Don't process updates if it's in the background and a message was
|
||||||
|
// received (otherwise an error message thrown by the background live
|
||||||
|
// component may continually be re-spammed hitting performance).
|
||||||
|
return !this._inBackground || !this._messageReceivedPostRender;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Component connected callback.
|
* Component connected callback.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
import { HomeAssistant } from 'custom-card-helpers';
|
|
||||||
import {
|
import {
|
||||||
CSSResultGroup,
|
CSSResultGroup,
|
||||||
html,
|
html,
|
||||||
@@ -12,6 +11,7 @@ import surroundThumbnailsStyle from '../scss/surround.scss';
|
|||||||
import {
|
import {
|
||||||
BrowseMediaQueryParameters,
|
BrowseMediaQueryParameters,
|
||||||
CameraConfig,
|
CameraConfig,
|
||||||
|
ExtendedHomeAssistant,
|
||||||
FrigateBrowseMediaSource,
|
FrigateBrowseMediaSource,
|
||||||
FrigateCardError,
|
FrigateCardError,
|
||||||
FrigateCardView,
|
FrigateCardView,
|
||||||
@@ -30,7 +30,7 @@ import { ThumbnailCarouselTap } from './thumbnail-carousel.js';
|
|||||||
@customElement('frigate-card-surround-thumbnails')
|
@customElement('frigate-card-surround-thumbnails')
|
||||||
export class FrigateCardSurround extends LitElement {
|
export class FrigateCardSurround extends LitElement {
|
||||||
@property({ attribute: false })
|
@property({ attribute: false })
|
||||||
public hass?: HomeAssistant;
|
public hass?: ExtendedHomeAssistant;
|
||||||
|
|
||||||
@property({ attribute: false })
|
@property({ attribute: false })
|
||||||
public view?: Readonly<View>;
|
public view?: Readonly<View>;
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
import { HomeAssistant } from 'custom-card-helpers';
|
|
||||||
import { EmblaOptionsType, EmblaPluginType } from 'embla-carousel';
|
import { EmblaOptionsType, EmblaPluginType } from 'embla-carousel';
|
||||||
import { WheelGesturesPlugin } from 'embla-carousel-wheel-gestures';
|
import { WheelGesturesPlugin } from 'embla-carousel-wheel-gestures';
|
||||||
import {
|
import {
|
||||||
@@ -15,6 +14,7 @@ import { createRef, ref, Ref } from 'lit/directives/ref.js';
|
|||||||
import thumbnailCarouselStyle from '../scss/thumbnail-carousel.scss';
|
import thumbnailCarouselStyle from '../scss/thumbnail-carousel.scss';
|
||||||
import {
|
import {
|
||||||
CameraConfig,
|
CameraConfig,
|
||||||
|
ExtendedHomeAssistant,
|
||||||
FrigateBrowseMediaSource,
|
FrigateBrowseMediaSource,
|
||||||
ThumbnailsControlConfig,
|
ThumbnailsControlConfig,
|
||||||
} from '../types.js';
|
} from '../types.js';
|
||||||
@@ -36,7 +36,7 @@ export interface ThumbnailCarouselTap {
|
|||||||
@customElement('frigate-card-thumbnail-carousel')
|
@customElement('frigate-card-thumbnail-carousel')
|
||||||
export class FrigateCardThumbnailCarousel extends LitElement {
|
export class FrigateCardThumbnailCarousel extends LitElement {
|
||||||
@property({ attribute: false })
|
@property({ attribute: false })
|
||||||
public hass?: HomeAssistant;
|
public hass?: ExtendedHomeAssistant;
|
||||||
|
|
||||||
@property({ attribute: false })
|
@property({ attribute: false })
|
||||||
public view?: Readonly<View>;
|
public view?: Readonly<View>;
|
||||||
|
|||||||
+60
-15
@@ -1,4 +1,4 @@
|
|||||||
import { HomeAssistant } from 'custom-card-helpers';
|
import { Task } from '@lit-labs/task/task.js';
|
||||||
import { format, fromUnixTime } from 'date-fns';
|
import { format, fromUnixTime } from 'date-fns';
|
||||||
import { CSSResult, html, LitElement, TemplateResult, unsafeCSS } from 'lit';
|
import { CSSResult, html, LitElement, TemplateResult, unsafeCSS } from 'lit';
|
||||||
import { customElement, property } from 'lit/decorators.js';
|
import { customElement, property } from 'lit/decorators.js';
|
||||||
@@ -9,6 +9,7 @@ import thumbnailFeatureEventStyle from '../scss/thumbnail-feature-event.scss';
|
|||||||
import thumbnailFeatureRecordingStyle from '../scss/thumbnail-feature-recording.scss';
|
import thumbnailFeatureRecordingStyle from '../scss/thumbnail-feature-recording.scss';
|
||||||
import thumbnailStyle from '../scss/thumbnail.scss';
|
import thumbnailStyle from '../scss/thumbnail.scss';
|
||||||
import type {
|
import type {
|
||||||
|
ExtendedHomeAssistant,
|
||||||
FrigateBrowseMediaSource,
|
FrigateBrowseMediaSource,
|
||||||
FrigateEvent,
|
FrigateEvent,
|
||||||
FrigateRecording,
|
FrigateRecording,
|
||||||
@@ -17,7 +18,9 @@ import { stopEventFromActivatingCardWideActions } from '../utils/action.js';
|
|||||||
import { errorToConsole, prettifyTitle } from '../utils/basic.js';
|
import { errorToConsole, prettifyTitle } from '../utils/basic.js';
|
||||||
import { retainEvent } from '../utils/frigate.js';
|
import { retainEvent } from '../utils/frigate.js';
|
||||||
import { getEventDurationString } from '../utils/ha/browse-media.js';
|
import { getEventDurationString } from '../utils/ha/browse-media.js';
|
||||||
|
import { homeAssistantSignPath } from '../utils/ha/index.js';
|
||||||
import { View } from '../view.js';
|
import { View } from '../view.js';
|
||||||
|
import { dispatchFrigateCardErrorEvent, renderProgressIndicator } from './message.js';
|
||||||
|
|
||||||
// The minimum width of a thumbnail with details enabled.
|
// The minimum width of a thumbnail with details enabled.
|
||||||
export const THUMBNAIL_DETAILS_WIDTH_MIN = 300;
|
export const THUMBNAIL_DETAILS_WIDTH_MIN = 300;
|
||||||
@@ -27,10 +30,51 @@ export class FrigateCardThumbnailFeatureEvent extends LitElement {
|
|||||||
@property({ attribute: false })
|
@property({ attribute: false })
|
||||||
public thumbnail?: string;
|
public thumbnail?: string;
|
||||||
|
|
||||||
|
@property({ attribute: false })
|
||||||
|
public hass?: ExtendedHomeAssistant;
|
||||||
|
|
||||||
|
protected _signThumbnailTask = new Task(
|
||||||
|
this,
|
||||||
|
this._signThumbnail.bind(this),
|
||||||
|
// Do not re-run the task if hass changes, unless it was previously undefined.
|
||||||
|
(): [boolean, string | undefined] => [!!this.hass, this.thumbnail],
|
||||||
|
);
|
||||||
|
|
||||||
|
public count = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sign a thumbnail URL if necessary. May throw.
|
||||||
|
* @param param0 A list of lit-task dependencies.
|
||||||
|
* @returns A signed URL or null.
|
||||||
|
*/
|
||||||
|
protected async _signThumbnail([haveHASS, thumbnail]: [
|
||||||
|
boolean,
|
||||||
|
string | undefined,
|
||||||
|
]): Promise<string | null> {
|
||||||
|
this.count++;
|
||||||
|
if (!haveHASS || !this.hass || !thumbnail) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
if (this.thumbnail?.startsWith('data:')) {
|
||||||
|
return this.thumbnail;
|
||||||
|
}
|
||||||
|
return await homeAssistantSignPath(this.hass, thumbnail);
|
||||||
|
}
|
||||||
|
|
||||||
protected render(): TemplateResult | void {
|
protected render(): TemplateResult | void {
|
||||||
return html`
|
return html`
|
||||||
${this.thumbnail
|
${this.thumbnail
|
||||||
? html`<img src="${this.thumbnail}" />`
|
? html` ${this._signThumbnailTask.render({
|
||||||
|
initial: () => renderProgressIndicator(),
|
||||||
|
pending: () => renderProgressIndicator(),
|
||||||
|
error: (e: unknown) => {
|
||||||
|
errorToConsole(e as Error);
|
||||||
|
dispatchFrigateCardErrorEvent(this, e as Error);
|
||||||
|
},
|
||||||
|
complete: (signedThumbnail: string | null) => {
|
||||||
|
return signedThumbnail ? html`<img src="${signedThumbnail}" />` : html``;
|
||||||
|
},
|
||||||
|
})}`
|
||||||
: html`<ha-icon
|
: html`<ha-icon
|
||||||
icon="mdi:image-off"
|
icon="mdi:image-off"
|
||||||
title=${localize('thumbnail.no_thumbnail')}
|
title=${localize('thumbnail.no_thumbnail')}
|
||||||
@@ -134,35 +178,35 @@ export class FrigateCardThumbnail extends LitElement {
|
|||||||
@property({ attribute: true, type: Boolean })
|
@property({ attribute: true, type: Boolean })
|
||||||
public show_timeline_control = false;
|
public show_timeline_control = false;
|
||||||
|
|
||||||
// ============================
|
// ======================
|
||||||
// Data-binding based interface
|
// Target-based interface
|
||||||
// ============================
|
// ======================
|
||||||
@property({ attribute: false })
|
|
||||||
public view?: Readonly<View>;
|
|
||||||
|
|
||||||
@property({ attribute: false })
|
@property({ attribute: false })
|
||||||
public target?: FrigateBrowseMediaSource | null;
|
public target?: FrigateBrowseMediaSource | null;
|
||||||
|
|
||||||
@property({ attribute: false })
|
@property({ attribute: false })
|
||||||
public childIndex?: number;
|
public childIndex?: number;
|
||||||
|
|
||||||
// =============================================================
|
// ===================================================
|
||||||
// Overrides that can be used if data bindings are not available
|
// Raw interface (can override target-based interface)
|
||||||
// =============================================================
|
// ===================================================
|
||||||
@property({ attribute: true })
|
@property({ attribute: true })
|
||||||
public thumbnail?: string;
|
public thumbnail?: string;
|
||||||
|
|
||||||
@property({ attribute: true })
|
@property({ attribute: true })
|
||||||
public label?: string;
|
public label?: string;
|
||||||
|
|
||||||
@property({ attribute: true })
|
@property({ attribute: false })
|
||||||
public event?: string;
|
public event?: FrigateEvent;
|
||||||
|
|
||||||
// ================================
|
// ================================
|
||||||
// Optional parameters for controls
|
// Optional parameters for controls
|
||||||
// ================================
|
// ================================
|
||||||
@property({ attribute: false })
|
@property({ attribute: false })
|
||||||
public hass?: HomeAssistant;
|
public view?: Readonly<View>;
|
||||||
|
|
||||||
|
@property({ attribute: false })
|
||||||
|
public hass?: ExtendedHomeAssistant;
|
||||||
|
|
||||||
@property({ attribute: false })
|
@property({ attribute: false })
|
||||||
public clientID?: string;
|
public clientID?: string;
|
||||||
@@ -188,7 +232,7 @@ export class FrigateCardThumbnail extends LitElement {
|
|||||||
|
|
||||||
// Always give the overrides preference (if specified).
|
// Always give the overrides preference (if specified).
|
||||||
if (this.event) {
|
if (this.event) {
|
||||||
event = JSON.parse(this.event);
|
event = this.event;
|
||||||
}
|
}
|
||||||
thumbnail = this.thumbnail ? this.thumbnail : thumbnail;
|
thumbnail = this.thumbnail ? this.thumbnail : thumbnail;
|
||||||
label = this.label ? this.label : label;
|
label = this.label ? this.label : label;
|
||||||
@@ -206,6 +250,7 @@ export class FrigateCardThumbnail extends LitElement {
|
|||||||
? html`<frigate-card-thumbnail-feature-event
|
? html`<frigate-card-thumbnail-feature-event
|
||||||
aria-label="${label ?? ''}"
|
aria-label="${label ?? ''}"
|
||||||
title="${label ?? ''}"
|
title="${label ?? ''}"
|
||||||
|
.hass=${this.hass}
|
||||||
.thumbnail=${thumbnail ?? undefined}
|
.thumbnail=${thumbnail ?? undefined}
|
||||||
.label=${label ?? undefined}
|
.label=${label ?? undefined}
|
||||||
></frigate-card-thumbnail-feature-event>`
|
></frigate-card-thumbnail-feature-event>`
|
||||||
|
|||||||
+90
-34
@@ -96,7 +96,10 @@ interface CameraRecordings {
|
|||||||
summary: RecordingSummary;
|
summary: RecordingSummary;
|
||||||
}
|
}
|
||||||
|
|
||||||
const isHoverableDevice = window.matchMedia('(hover: hover) and (pointer: fine)');
|
// An event used to fetch the HASS object. See "Special note" below.
|
||||||
|
class HASSRequestEvent extends Event {
|
||||||
|
public hass?: ExtendedHomeAssistant;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A manager to maintain/fetch timeline events.
|
* A manager to maintain/fetch timeline events.
|
||||||
@@ -117,17 +120,6 @@ class TimelineDataManager {
|
|||||||
// than this).
|
// than this).
|
||||||
protected _maxAgeSeconds: number = TIMELINE_DATA_MANAGER_MAX_AGE_SECONDS;
|
protected _maxAgeSeconds: number = TIMELINE_DATA_MANAGER_MAX_AGE_SECONDS;
|
||||||
|
|
||||||
protected _contentCallback?: (source: FrigateBrowseMediaSource) => string;
|
|
||||||
protected _tooltipCallback?: (source: FrigateBrowseMediaSource) => string;
|
|
||||||
|
|
||||||
constructor(params?: {
|
|
||||||
contentCallback?: (source: FrigateBrowseMediaSource) => string;
|
|
||||||
tooltipCallback?: (source: FrigateBrowseMediaSource) => string;
|
|
||||||
}) {
|
|
||||||
this._contentCallback = params?.contentCallback;
|
|
||||||
this._tooltipCallback = params?.tooltipCallback;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get the last event fetch date.
|
// Get the last event fetch date.
|
||||||
get lastFetchDate(): Date | null {
|
get lastFetchDate(): Date | null {
|
||||||
return this._dateFetch ?? null;
|
return this._dateFetch ?? null;
|
||||||
@@ -178,8 +170,7 @@ class TimelineDataManager {
|
|||||||
item = {
|
item = {
|
||||||
id: event.id,
|
id: event.id,
|
||||||
group: camera,
|
group: camera,
|
||||||
content: this._contentCallback?.(child) ?? '',
|
content: '',
|
||||||
title: this._tooltipCallback?.(child) ?? '',
|
|
||||||
start: event.start_time * 1000,
|
start: event.start_time * 1000,
|
||||||
event: event,
|
event: event,
|
||||||
};
|
};
|
||||||
@@ -423,6 +414,62 @@ class TimelineDataManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A simgple thumbnail wrapper class for use in the timeline where LIT data
|
||||||
|
* bindings are not available.
|
||||||
|
*/
|
||||||
|
@customElement('frigate-card-timeline-thumbnail')
|
||||||
|
export class FrigateCardTimelineThumbnail extends LitElement {
|
||||||
|
@property({ attribute: true })
|
||||||
|
public thumbnail?: string;
|
||||||
|
|
||||||
|
@property({ attribute: true, type: Boolean })
|
||||||
|
public details = false;
|
||||||
|
|
||||||
|
@property({ attribute: true })
|
||||||
|
public event?: string;
|
||||||
|
|
||||||
|
@property({ attribute: true })
|
||||||
|
public label?: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Master render method.
|
||||||
|
* @returns A rendered template.
|
||||||
|
*/
|
||||||
|
protected render(): TemplateResult | void {
|
||||||
|
// Don't display tooltips on touch devices, they just get in the way of
|
||||||
|
// the drawer.
|
||||||
|
if (!this.thumbnail || !this.event) {
|
||||||
|
return html``;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Special note on what's going on here:
|
||||||
|
*
|
||||||
|
* This component does not have access to HASS, as there's no way to pass it
|
||||||
|
* in via the string-based tooltip that timeline supports. Instead dispatch
|
||||||
|
* an event to request HASS which the timeline adds to the event object
|
||||||
|
* before execution continues.
|
||||||
|
*/
|
||||||
|
const hassRequest = new HASSRequestEvent(`frigate-card:timeline:hass-request`, {
|
||||||
|
composed: true,
|
||||||
|
bubbles: true,
|
||||||
|
});
|
||||||
|
this.dispatchEvent(hassRequest);
|
||||||
|
if (!hassRequest.hass) {
|
||||||
|
return html``;
|
||||||
|
}
|
||||||
|
|
||||||
|
return html` <frigate-card-thumbnail
|
||||||
|
.hass=${hassRequest.hass}
|
||||||
|
.event=${JSON.parse(this.event)}
|
||||||
|
.label=${this.label}
|
||||||
|
.thumbnail=${this.thumbnail}
|
||||||
|
?details=${this.details}
|
||||||
|
>
|
||||||
|
</frigate-card-thumbnail>`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@customElement('frigate-card-timeline')
|
@customElement('frigate-card-timeline')
|
||||||
export class FrigateCardTimeline extends LitElement {
|
export class FrigateCardTimeline extends LitElement {
|
||||||
@property({ attribute: false })
|
@property({ attribute: false })
|
||||||
@@ -484,9 +531,8 @@ export class FrigateCardTimelineCore extends LitElement {
|
|||||||
@property({ attribute: false })
|
@property({ attribute: false })
|
||||||
public timelineConfig?: TimelineConfig;
|
public timelineConfig?: TimelineConfig;
|
||||||
|
|
||||||
protected _data = new TimelineDataManager({
|
protected _data = new TimelineDataManager();
|
||||||
tooltipCallback: this._getTooltip.bind(this),
|
|
||||||
});
|
|
||||||
protected _refTimeline: Ref<HTMLElement> = createRef();
|
protected _refTimeline: Ref<HTMLElement> = createRef();
|
||||||
protected _timeline?: Timeline;
|
protected _timeline?: Timeline;
|
||||||
|
|
||||||
@@ -495,13 +541,18 @@ export class FrigateCardTimelineCore extends LitElement {
|
|||||||
protected _pointerHeld = false;
|
protected _pointerHeld = false;
|
||||||
protected _ignoreClick = false;
|
protected _ignoreClick = false;
|
||||||
|
|
||||||
|
protected static _isHoverableDevice = window.matchMedia(
|
||||||
|
'(hover: hover) and (pointer: fine)',
|
||||||
|
).matches;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get a tooltip for a given timeline event.
|
* Get a tooltip for a given timeline event.
|
||||||
* @param source The FrigateBrowseMediaSource in question.
|
* @param source The FrigateBrowseMediaSource in question.
|
||||||
* @returns The tooltip as a string to render.
|
* @returns The tooltip as a string to render.
|
||||||
*/
|
*/
|
||||||
protected _getTooltip(source: FrigateBrowseMediaSource): string {
|
protected _getTooltip(item: TimelineItem): string {
|
||||||
if (!isHoverableDevice.matches) {
|
const source = (<FrigateCardTimelineItem>item).source;
|
||||||
|
if (!FrigateCardTimelineCore._isHoverableDevice || !source) {
|
||||||
// Don't display tooltips on touch devices, they just get in the way of
|
// Don't display tooltips on touch devices, they just get in the way of
|
||||||
// the drawer.
|
// the drawer.
|
||||||
return '';
|
return '';
|
||||||
@@ -518,13 +569,13 @@ export class FrigateCardTimelineCore extends LitElement {
|
|||||||
// Note that changes to attributes here must be mirrored in the xss
|
// Note that changes to attributes here must be mirrored in the xss
|
||||||
// whitelist in `_getOptions()` .
|
// whitelist in `_getOptions()` .
|
||||||
return `
|
return `
|
||||||
<frigate-card-thumbnail
|
<frigate-card-timeline-thumbnail
|
||||||
${detailsAttr}
|
|
||||||
thumbnail="${source.thumbnail}"
|
thumbnail="${source.thumbnail}"
|
||||||
label="${source.title}"
|
${detailsAttr}
|
||||||
${eventAttr}
|
${eventAttr}
|
||||||
|
label="${source.title}"
|
||||||
>
|
>
|
||||||
</frigate-card-thumbnail>`;
|
</frigate-card-timeline-thumbnail>`;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -544,6 +595,9 @@ export class FrigateCardTimelineCore extends LitElement {
|
|||||||
};
|
};
|
||||||
|
|
||||||
return html`<div
|
return html`<div
|
||||||
|
@frigate-card:timeline:hass-request=${(request: HASSRequestEvent) => {
|
||||||
|
request.hass = this.hass;
|
||||||
|
}}
|
||||||
class="${classMap(timelineClasses)}"
|
class="${classMap(timelineClasses)}"
|
||||||
${ref(this._refTimeline)}
|
${ref(this._refTimeline)}
|
||||||
></div>`;
|
></div>`;
|
||||||
@@ -735,7 +789,7 @@ export class FrigateCardTimelineCore extends LitElement {
|
|||||||
properties: TimelineEventPropertiesResult,
|
properties: TimelineEventPropertiesResult,
|
||||||
): void {
|
): void {
|
||||||
if (properties.event && this._pointerHeld) {
|
if (properties.event && this._pointerHeld) {
|
||||||
// An event will have been set when it's a human changes the range,
|
// An event will have been set when it's a human changes the range.
|
||||||
this._ignoreClick = true;
|
this._ignoreClick = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1052,12 +1106,18 @@ export class FrigateCardTimelineCore extends LitElement {
|
|||||||
tooltip: {
|
tooltip: {
|
||||||
followMouse: true,
|
followMouse: true,
|
||||||
overflowMethod: 'cap',
|
overflowMethod: 'cap',
|
||||||
|
template: this._getTooltip.bind(this),
|
||||||
},
|
},
|
||||||
xss: {
|
xss: {
|
||||||
disabled: false,
|
disabled: false,
|
||||||
filterOptions: {
|
filterOptions: {
|
||||||
whiteList: {
|
whiteList: {
|
||||||
'frigate-card-thumbnail': ['details', 'thumbnail', 'label', 'event'],
|
'frigate-card-timeline-thumbnail': [
|
||||||
|
'details',
|
||||||
|
'thumbnail',
|
||||||
|
'label',
|
||||||
|
'event',
|
||||||
|
],
|
||||||
div: ['title'],
|
div: ['title'],
|
||||||
span: ['style'],
|
span: ['style'],
|
||||||
},
|
},
|
||||||
@@ -1229,14 +1289,9 @@ export class FrigateCardTimelineCore extends LitElement {
|
|||||||
// Don't show an empty timeline, show a message instead.
|
// Don't show an empty timeline, show a message instead.
|
||||||
const groups = this._getGroups();
|
const groups = this._getGroups();
|
||||||
if (!groups.length) {
|
if (!groups.length) {
|
||||||
dispatchMessageEvent(
|
dispatchMessageEvent(this, localize('error.timeline_no_cameras'), 'info', {
|
||||||
this,
|
|
||||||
localize('error.timeline_no_cameras'),
|
|
||||||
'info',
|
|
||||||
{
|
|
||||||
icon: 'mdi:chart-gantt',
|
icon: 'mdi:chart-gantt',
|
||||||
}
|
});
|
||||||
);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1257,10 +1312,10 @@ export class FrigateCardTimelineCore extends LitElement {
|
|||||||
this._timeline.on('mouseDown', () => {
|
this._timeline.on('mouseDown', () => {
|
||||||
this._pointerHeld = true;
|
this._pointerHeld = true;
|
||||||
this._ignoreClick = false;
|
this._ignoreClick = false;
|
||||||
})
|
});
|
||||||
this._timeline.on('mouseUp', () => {
|
this._timeline.on('mouseUp', () => {
|
||||||
this._pointerHeld = false;
|
this._pointerHeld = false;
|
||||||
})
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1279,6 +1334,7 @@ export class FrigateCardTimelineCore extends LitElement {
|
|||||||
|
|
||||||
declare global {
|
declare global {
|
||||||
interface HTMLElementTagNameMap {
|
interface HTMLElementTagNameMap {
|
||||||
|
'frigate-card-timeline-thumbnail': FrigateCardTimelineThumbnail;
|
||||||
'frigate-card-timeline-core': FrigateCardTimelineCore;
|
'frigate-card-timeline-core': FrigateCardTimelineCore;
|
||||||
'frigate-card-timeline': FrigateCardTimeline;
|
'frigate-card-timeline': FrigateCardTimeline;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,7 +8,8 @@ img {
|
|||||||
}
|
}
|
||||||
|
|
||||||
img,
|
img,
|
||||||
ha-icon {
|
ha-icon,
|
||||||
|
frigate-card-progress-indicator {
|
||||||
border-radius: var(--ha-card-border-radius, 4px);
|
border-radius: var(--ha-card-border-radius, 4px);
|
||||||
|
|
||||||
max-width: var(--frigate-card-thumbnail-size);
|
max-width: var(--frigate-card-thumbnail-size);
|
||||||
|
|||||||
Reference in New Issue
Block a user