Initial code for major engine refactor.
This commit is contained in:
@@ -15,22 +15,19 @@ import thumbnailCarouselStyle from '../scss/thumbnail-carousel.scss';
|
||||
import {
|
||||
CameraConfig,
|
||||
ExtendedHomeAssistant,
|
||||
FrigateBrowseMediaSource,
|
||||
ThumbnailsControlConfig,
|
||||
} from '../types.js';
|
||||
import { stopEventFromActivatingCardWideActions } from '../utils/action.js';
|
||||
import { contentsChanged, dispatchFrigateCardEvent } from '../utils/basic.js';
|
||||
import { isTrueMedia } from '../utils/ha/browse-media';
|
||||
import { View } from '../view.js';
|
||||
import { dispatchFrigateCardEvent } from '../utils/basic.js';
|
||||
import { MediaQueriesResults, View } from '../view.js';
|
||||
import { FrigateCardCarousel } from './carousel.js';
|
||||
import './thumbnail.js';
|
||||
import './carousel.js';
|
||||
import { ifDefined } from 'lit/directives/if-defined.js';
|
||||
import { DataManager } from '../utils/data/data-manager.js';
|
||||
|
||||
export interface ThumbnailCarouselTap {
|
||||
slideIndex: number;
|
||||
target: FrigateBrowseMediaSource;
|
||||
childIndex: number;
|
||||
queryResults: MediaQueriesResults;
|
||||
}
|
||||
|
||||
@customElement('frigate-card-thumbnail-carousel')
|
||||
@@ -41,14 +38,12 @@ export class FrigateCardThumbnailCarousel extends LitElement {
|
||||
@property({ attribute: false })
|
||||
public view?: Readonly<View>;
|
||||
|
||||
// Use contentsChanged here to avoid the carousel rebuilding and resetting in
|
||||
// front of the user, unless the contents have actually changed.
|
||||
@property({ attribute: false, hasChanged: contentsChanged })
|
||||
public target?: FrigateBrowseMediaSource | null;
|
||||
|
||||
@property({ attribute: false })
|
||||
public cameras?: Map<string, CameraConfig>;
|
||||
|
||||
@property({ attribute: false })
|
||||
public dataManager?: DataManager;
|
||||
|
||||
protected _refCarousel: Ref<FrigateCardCarousel> = createRef();
|
||||
|
||||
// Thumbnail carousels can expand (e.g. drawer-based carousels after the main
|
||||
@@ -59,10 +54,14 @@ export class FrigateCardThumbnailCarousel extends LitElement {
|
||||
@property({ attribute: false })
|
||||
public config?: ThumbnailsControlConfig;
|
||||
|
||||
@property({ attribute: true, type: Number, reflect: true })
|
||||
public selected?: number;
|
||||
@property({ attribute: false })
|
||||
public selected? = 0;
|
||||
|
||||
protected _carouselOptions?: EmblaOptionsType = {
|
||||
containScroll: 'keepSnaps',
|
||||
dragFree: true,
|
||||
};
|
||||
|
||||
protected _carouselOptions?: EmblaOptionsType;
|
||||
protected _carouselPlugins: EmblaPluginType[] = [
|
||||
WheelGesturesPlugin({
|
||||
// Whether the carousel is vertical or horizontal, interpret y-axis wheel
|
||||
@@ -99,31 +98,20 @@ export class FrigateCardThumbnailCarousel extends LitElement {
|
||||
super.disconnectedCallback();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the Embla options to use.
|
||||
* @returns An EmblaOptionsType object or undefined for no options.
|
||||
*/
|
||||
protected _getOptions(): EmblaOptionsType {
|
||||
return {
|
||||
containScroll: 'keepSnaps',
|
||||
dragFree: true,
|
||||
startIndex: this.selected ?? 0,
|
||||
};
|
||||
}
|
||||
/**
|
||||
* Get slides to include in the render.
|
||||
* @returns The slides to include in the render.
|
||||
*/
|
||||
protected _getSlides(): TemplateResult[] {
|
||||
if (!this.target || !this.target.children || !this.target.children.length) {
|
||||
if (!this.view?.query || !this.view.queryResults?.hasResults()) {
|
||||
return [];
|
||||
}
|
||||
|
||||
const slides: TemplateResult[] = [];
|
||||
for (let i = 0; i < this.target.children.length; ++i) {
|
||||
const thumbnail = this._renderThumbnail(this.target, i, slides.length);
|
||||
for (let i = 0; i < this.view.queryResults.getResultsCount(); ++i) {
|
||||
const thumbnail = this._renderThumbnail(i);
|
||||
if (thumbnail) {
|
||||
slides.push(thumbnail);
|
||||
slides[i] = thumbnail;
|
||||
}
|
||||
}
|
||||
return slides;
|
||||
@@ -152,30 +140,6 @@ export class FrigateCardThumbnailCarousel extends LitElement {
|
||||
this.selected === undefined ? '1.0' : '0.4',
|
||||
);
|
||||
}
|
||||
|
||||
if (!this._carouselOptions) {
|
||||
// Want to set the initial carousel options just before the first render
|
||||
// in order to get the startIndex correct in the options. It is not safe
|
||||
// to rely on carouselScrollTo() post update, since the nested carousel
|
||||
// may not yet be actual rendered/created.
|
||||
this._carouselOptions = this._getOptions();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The updated lifecycle callback for this element.
|
||||
* @param changedProperties The properties that were changed in this render.
|
||||
*/
|
||||
updated(changedProperties: PropertyValues): void {
|
||||
super.updated(changedProperties);
|
||||
|
||||
if (changedProperties.has('selected')) {
|
||||
this.updateComplete.then(() => {
|
||||
if (this.selected !== undefined) {
|
||||
this._refCarousel.value?.carouselScrollTo(this.selected);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -183,45 +147,40 @@ export class FrigateCardThumbnailCarousel extends LitElement {
|
||||
* @param mediaToRender The media item to render.
|
||||
* @returns A template or void if the item could not be rendered.
|
||||
*/
|
||||
protected _renderThumbnail(
|
||||
parent: FrigateBrowseMediaSource,
|
||||
childIndex: number,
|
||||
slideIndex: number,
|
||||
): TemplateResult | void {
|
||||
if (
|
||||
!parent.children ||
|
||||
!parent.children.length ||
|
||||
!isTrueMedia(parent.children[childIndex])
|
||||
) {
|
||||
protected _renderThumbnail(index: number): TemplateResult | void {
|
||||
const media = this.view?.queryResults?.getResult(index) ?? null;
|
||||
const cameraConfig = media ? this.cameras?.get(media.getCameraID()) : null;
|
||||
if (!media || !cameraConfig || !this.view) {
|
||||
return;
|
||||
}
|
||||
|
||||
const classes = {
|
||||
embla__slide: true,
|
||||
'slide-selected': this.selected === childIndex,
|
||||
'slide-selected': this.selected === index,
|
||||
};
|
||||
|
||||
const cameraConfig = this.view?.camera ? this.cameras?.get(this.view.camera) : null;
|
||||
return html` <frigate-card-thumbnail
|
||||
class="${classMap(classes)}"
|
||||
.dataManager=${this.dataManager}
|
||||
.hass=${this.hass}
|
||||
.media=${media}
|
||||
.cameraConfig=${cameraConfig}
|
||||
.view=${this.view}
|
||||
.target=${parent}
|
||||
.childIndex=${childIndex}
|
||||
.mediaSeek=${this.view?.context?.mediaViewer?.seek.get(childIndex)}
|
||||
.cameraConfig=${cameraConfig ?? undefined}
|
||||
?details=${this.config?.show_details}
|
||||
.mediaSeek=${this.view?.context?.mediaViewer?.seek.get(index)}
|
||||
?details=${!!this.config?.show_details}
|
||||
?show_favorite_control=${this.config?.show_favorite_control}
|
||||
?show_timeline_control=${this.config?.show_timeline_control}
|
||||
class="${classMap(classes)}"
|
||||
@click=${(ev) => {
|
||||
if (this._refCarousel.value?.carouselClickAllowed()) {
|
||||
@click=${(ev: Event) => {
|
||||
if (
|
||||
this.view &&
|
||||
this.view.queryResults &&
|
||||
this._refCarousel.value?.carouselClickAllowed()
|
||||
) {
|
||||
dispatchFrigateCardEvent<ThumbnailCarouselTap>(
|
||||
this,
|
||||
'thumbnail-carousel:tap',
|
||||
{
|
||||
slideIndex: slideIndex,
|
||||
target: parent,
|
||||
childIndex: childIndex,
|
||||
queryResults: this.view.queryResults.clone().selectResult(index),
|
||||
},
|
||||
);
|
||||
}
|
||||
@@ -257,6 +216,7 @@ export class FrigateCardThumbnailCarousel extends LitElement {
|
||||
return html`<frigate-card-carousel
|
||||
${ref(this._refCarousel)}
|
||||
direction=${ifDefined(this._getDirection())}
|
||||
.selected=${this.selected ?? 0}
|
||||
.carouselOptions=${this._carouselOptions}
|
||||
.carouselPlugins=${this._carouselPlugins}
|
||||
>
|
||||
|
||||
Reference in New Issue
Block a user