Initial skeleton timeline.
This commit is contained in:
@@ -7,7 +7,7 @@ import {
|
||||
PropertyValues,
|
||||
} from 'lit';
|
||||
import {
|
||||
BrowseMediaSource,
|
||||
FrigateBrowseMediaSource,
|
||||
ExtendedHomeAssistant,
|
||||
CameraConfig,
|
||||
JSMPEGConfig,
|
||||
@@ -140,7 +140,7 @@ export class FrigateCardLive extends LitElement {
|
||||
if (!browseMediaParams) {
|
||||
return;
|
||||
}
|
||||
let parent: BrowseMediaSource | null;
|
||||
let parent: FrigateBrowseMediaSource | null;
|
||||
try {
|
||||
parent = await BrowseMediaUtil.browseMediaQuery(this.hass, browseMediaParams);
|
||||
} catch (e) {
|
||||
|
||||
@@ -3,7 +3,7 @@ import { CSSResultGroup, TemplateResult, html, unsafeCSS } from 'lit';
|
||||
import { EmblaOptionsType } from 'embla-carousel';
|
||||
import { customElement, property } from 'lit/decorators.js';
|
||||
|
||||
import type { BrowseMediaSource, ThumbnailsControlConfig } from '../types.js';
|
||||
import type { FrigateBrowseMediaSource, ThumbnailsControlConfig } from '../types.js';
|
||||
import { FrigateCardCarousel } from './carousel.js';
|
||||
import { dispatchFrigateCardEvent, stopEventFromActivatingCardWideActions } from '../common.js';
|
||||
|
||||
@@ -11,14 +11,14 @@ import thumbnailCarouselStyle from '../scss/thumbnail-carousel.scss';
|
||||
|
||||
export interface ThumbnailCarouselTap {
|
||||
slideIndex: number;
|
||||
target: BrowseMediaSource;
|
||||
target: FrigateBrowseMediaSource;
|
||||
childIndex: number;
|
||||
}
|
||||
|
||||
@customElement('frigate-card-thumbnail-carousel')
|
||||
export class FrigateCardThumbnailCarousel extends FrigateCardCarousel {
|
||||
@property({ attribute: false })
|
||||
protected target?: BrowseMediaSource;
|
||||
protected target?: FrigateBrowseMediaSource;
|
||||
|
||||
protected _tapSelected?;
|
||||
|
||||
@@ -96,7 +96,7 @@ export class FrigateCardThumbnailCarousel extends FrigateCardCarousel {
|
||||
* @returns A template or void if the item could not be rendered.
|
||||
*/
|
||||
protected _renderThumbnail(
|
||||
parent: BrowseMediaSource,
|
||||
parent: FrigateBrowseMediaSource,
|
||||
childIndex: number,
|
||||
slideIndex: number,
|
||||
): TemplateResult | void {
|
||||
|
||||
@@ -0,0 +1,112 @@
|
||||
import {
|
||||
CSSResultGroup,
|
||||
LitElement,
|
||||
TemplateResult,
|
||||
html,
|
||||
unsafeCSS,
|
||||
PropertyValues,
|
||||
} from 'lit';
|
||||
import { DataSet } from 'vis-data/esnext';
|
||||
import { HomeAssistant } from 'custom-card-helpers';
|
||||
import { Timeline } from 'vis-timeline/esnext';
|
||||
import { customElement, property } from 'lit/decorators.js';
|
||||
import { createRef, ref, Ref } from 'lit/directives/ref';
|
||||
|
||||
import { BrowseMediaUtil } from '../browse-media-util';
|
||||
import { CameraConfig, ExtendedHomeAssistant } from '../types';
|
||||
import { View } from '../view';
|
||||
import { renderProgressIndicator } from './message';
|
||||
|
||||
import timelineStyle from '../scss/timeline.scss';
|
||||
|
||||
interface FrigateCardTimelineData {
|
||||
id: string;
|
||||
content: string;
|
||||
start: number;
|
||||
}
|
||||
|
||||
@customElement('frigate-card-timeline')
|
||||
export class FrigateCardTimeline extends LitElement {
|
||||
@property({ attribute: false })
|
||||
protected hass?: HomeAssistant & ExtendedHomeAssistant;
|
||||
|
||||
@property({ attribute: false })
|
||||
protected view?: Readonly<View>;
|
||||
|
||||
@property({ attribute: false })
|
||||
protected cameraConfig?: CameraConfig;
|
||||
|
||||
protected _timelineRef: Ref<HTMLElement> = createRef();
|
||||
protected _timeline?: Timeline;
|
||||
|
||||
/**
|
||||
* Master render method.
|
||||
* @returns A rendered template.
|
||||
*/
|
||||
protected render(): TemplateResult | void {
|
||||
if (!this.hass || !this.view || !this.cameraConfig) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!this.view.target) {
|
||||
const browseMediaQueryParameters =
|
||||
BrowseMediaUtil.getBrowseMediaQueryParametersOrDispatchError(
|
||||
this,
|
||||
this.view,
|
||||
this.cameraConfig,
|
||||
);
|
||||
if (!browseMediaQueryParameters) {
|
||||
return;
|
||||
}
|
||||
|
||||
BrowseMediaUtil.fetchLatestMediaAndDispatchViewChange(
|
||||
this,
|
||||
this.hass,
|
||||
this.view,
|
||||
browseMediaQueryParameters,
|
||||
);
|
||||
return renderProgressIndicator();
|
||||
}
|
||||
return html` <div id="timeline" ${ref(this._timelineRef)}></div>`;
|
||||
}
|
||||
|
||||
protected _buildDataset(): DataSet<FrigateCardTimelineData> {
|
||||
const items: FrigateCardTimelineData[] = [];
|
||||
|
||||
this.view?.target?.children?.forEach((child) => {
|
||||
if (child.frigate) {
|
||||
const item = {
|
||||
id: child.media_content_id,
|
||||
content: child.frigate.event.id,
|
||||
start: child.frigate.event.start_time * 1000,
|
||||
};
|
||||
if (child.frigate.event.end_time) {
|
||||
//item['end'] = child.frigate.event.end_time * 1000;
|
||||
}
|
||||
items.push(item);
|
||||
}
|
||||
});
|
||||
return new DataSet(items);
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
protected updated(_changedProperties: PropertyValues): void {
|
||||
// Configuration for the Timeline
|
||||
const options = {
|
||||
minHeight: '300px',
|
||||
};
|
||||
|
||||
// Create a Timeline
|
||||
if (this._timelineRef.value && !this._timeline) {
|
||||
this._timeline = new Timeline(
|
||||
this._timelineRef.value,
|
||||
this._buildDataset(),
|
||||
options,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
static get styles(): CSSResultGroup {
|
||||
return unsafeCSS(timelineStyle);
|
||||
}
|
||||
}
|
||||
@@ -18,7 +18,7 @@ import { AutoMediaPlugin } from './embla-plugins/automedia.js';
|
||||
import type {
|
||||
BrowseMediaNeighbors,
|
||||
BrowseMediaQueryParameters,
|
||||
BrowseMediaSource,
|
||||
FrigateBrowseMediaSource,
|
||||
CameraConfig,
|
||||
ExtendedHomeAssistant,
|
||||
MediaShowInfo,
|
||||
@@ -210,14 +210,17 @@ export class FrigateCardViewerCarousel extends FrigateCardMediaCarousel {
|
||||
@property({ attribute: false })
|
||||
protected resolvedMediaCache?: ResolvedMediaCache;
|
||||
|
||||
// Mapping of slide # to BrowseMediaSource child #.
|
||||
// Mapping of slide # to FrigateBrowseMediaSource child #.
|
||||
// (Folders are not media items that can be rendered).
|
||||
protected _slideToChild: Record<number, number> = {};
|
||||
|
||||
// A task to resolve target media if lazy loading is disabled.
|
||||
protected _mediaResolutionTask = new Task<[BrowseMediaSource | undefined], void>(
|
||||
protected _mediaResolutionTask = new Task<
|
||||
[FrigateBrowseMediaSource | undefined],
|
||||
void
|
||||
>(
|
||||
this,
|
||||
async ([target]: (BrowseMediaSource | undefined)[]): Promise<void> => {
|
||||
async ([target]: (FrigateBrowseMediaSource | undefined)[]): Promise<void> => {
|
||||
for (
|
||||
let i = 0;
|
||||
!this.viewerConfig?.lazy_load &&
|
||||
@@ -280,7 +283,7 @@ export class FrigateCardViewerCarousel extends FrigateCardMediaCarousel {
|
||||
/**
|
||||
* Unmute the media on the selected slide.
|
||||
*/
|
||||
protected _autoUnmuteHandler(): void {
|
||||
protected _autoUnmuteHandler(): void {
|
||||
if (this.viewerConfig?.auto_unmute) {
|
||||
super._autoUnmuteHandler();
|
||||
}
|
||||
@@ -308,7 +311,7 @@ export class FrigateCardViewerCarousel extends FrigateCardMediaCarousel {
|
||||
* Get the transition effect to use.
|
||||
* @returns An TransitionEffect object.
|
||||
*/
|
||||
protected _getTransitionEffect(): TransitionEffect | undefined {
|
||||
protected _getTransitionEffect(): TransitionEffect | undefined {
|
||||
return this.viewerConfig?.transition_effect;
|
||||
}
|
||||
|
||||
@@ -398,7 +401,7 @@ export class FrigateCardViewerCarousel extends FrigateCardMediaCarousel {
|
||||
* @returns The view that would show the matching clip.
|
||||
*/
|
||||
protected async _findRelatedClipView(
|
||||
snapshot: BrowseMediaSource,
|
||||
snapshot: FrigateBrowseMediaSource,
|
||||
): Promise<View | null> {
|
||||
if (
|
||||
!this.hass ||
|
||||
@@ -445,7 +448,7 @@ export class FrigateCardViewerCarousel extends FrigateCardMediaCarousel {
|
||||
return null;
|
||||
}
|
||||
|
||||
let clips: BrowseMediaSource | null;
|
||||
let clips: FrigateBrowseMediaSource | null;
|
||||
|
||||
try {
|
||||
clips = await BrowseMediaUtil.browseMediaQuery(this.hass, {
|
||||
@@ -689,7 +692,7 @@ export class FrigateCardViewerCarousel extends FrigateCardMediaCarousel {
|
||||
}
|
||||
|
||||
protected _renderMediaItem(
|
||||
mediaToRender: BrowseMediaSource,
|
||||
mediaToRender: FrigateBrowseMediaSource,
|
||||
slideIndex: number,
|
||||
): TemplateResult | void {
|
||||
// Skip folders as they cannot be rendered by this viewer.
|
||||
|
||||
Reference in New Issue
Block a user