First version of gallery refactor to use thumbnails.
This commit is contained in:
+111
-95
@@ -1,22 +1,35 @@
|
||||
// TODO: Add details & controls & size support
|
||||
// TODO: Remove mini support if it's not actually needed?
|
||||
// TODO: automatic upgrade for thumbnail sizes in px
|
||||
// TODO: automatic remove of min_columns
|
||||
|
||||
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||
import { CSSResultGroup, LitElement, TemplateResult, html, unsafeCSS } from 'lit';
|
||||
import {
|
||||
CSSResultGroup,
|
||||
LitElement,
|
||||
PropertyValues,
|
||||
TemplateResult,
|
||||
css,
|
||||
html,
|
||||
unsafeCSS,
|
||||
} from 'lit';
|
||||
import { HomeAssistant } from 'custom-card-helpers';
|
||||
import { customElement, property, state } from 'lit/decorators.js';
|
||||
import { styleMap } from 'lit/directives/style-map.js';
|
||||
import { customElement, property } from 'lit/decorators.js';
|
||||
|
||||
import {
|
||||
CameraConfig,
|
||||
ExtendedHomeAssistant,
|
||||
GalleryConfig,
|
||||
THUMBNAIL_WIDTH_MAX,
|
||||
frigateCardConfigDefaults,
|
||||
} from '../types.js';
|
||||
import { BrowseMediaUtil } from '../browse-media-util.js';
|
||||
import { View } from '../view.js';
|
||||
import { localize } from '../localize/localize.js';
|
||||
import { THUMBNAIL_DETAILS_WIDTH_MIN } from './thumbnail.js';
|
||||
import { renderProgressIndicator } from './message.js';
|
||||
import { stopEventFromActivatingCardWideActions } from '../common.js';
|
||||
|
||||
import './thumbnail.js';
|
||||
|
||||
import galleryStyle from '../scss/gallery.scss';
|
||||
|
||||
@customElement('frigate-card-gallery')
|
||||
@@ -77,7 +90,13 @@ export class FrigateCardGallery extends LitElement {
|
||||
* Get element styles.
|
||||
*/
|
||||
static get styles(): CSSResultGroup {
|
||||
return unsafeCSS(galleryStyle);
|
||||
return css`
|
||||
:host {
|
||||
display: block;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
`;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -94,9 +113,6 @@ export class FrigateCardGalleryCore extends LitElement {
|
||||
|
||||
protected _resizeObserver: ResizeObserver;
|
||||
|
||||
@state()
|
||||
protected _columns = frigateCardConfigDefaults.event_gallery.min_columns;
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
this._resizeObserver = new ResizeObserver(this._resizeHandler.bind(this));
|
||||
@@ -122,10 +138,16 @@ export class FrigateCardGalleryCore extends LitElement {
|
||||
* Handle gallery resize.
|
||||
*/
|
||||
protected _resizeHandler(): void {
|
||||
this._columns = Math.max(
|
||||
this.galleryConfig?.min_columns ??
|
||||
frigateCardConfigDefaults.event_gallery.min_columns,
|
||||
Math.ceil(this.clientWidth / THUMBNAIL_WIDTH_MAX),
|
||||
const thumbnailSize =
|
||||
this.galleryConfig?.controls.thumbnails.size ??
|
||||
frigateCardConfigDefaults.event_gallery.controls.thumbnails.size;
|
||||
this.style.setProperty(
|
||||
'--frigate-card-gallery-columns',
|
||||
String(
|
||||
!this.galleryConfig?.controls.thumbnails.show_details
|
||||
? Math.round(this.clientWidth / thumbnailSize)
|
||||
: Math.max(1, Math.floor(this.clientWidth / THUMBNAIL_DETAILS_WIDTH_MIN)),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -141,6 +163,26 @@ export class FrigateCardGalleryCore extends LitElement {
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when an update will occur.
|
||||
* @param changedProps The changed properties
|
||||
*/
|
||||
protected willUpdate(changedProps: PropertyValues): void {
|
||||
if (changedProps.has('galleryConfig')) {
|
||||
if (this.galleryConfig?.controls.thumbnails.show_details) {
|
||||
this.setAttribute('details', '');
|
||||
} else {
|
||||
this.removeAttribute('details');
|
||||
}
|
||||
if (this.galleryConfig?.controls.thumbnails.size) {
|
||||
this.style.setProperty(
|
||||
'--frigate-card-thumbnail-size',
|
||||
`${this.galleryConfig.controls.thumbnails.size}px`,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Master render method.
|
||||
* @returns A rendered template.
|
||||
@@ -156,93 +198,67 @@ export class FrigateCardGalleryCore extends LitElement {
|
||||
return html``;
|
||||
}
|
||||
|
||||
const itemStyle = {
|
||||
// Controls the number of columns in the gallery (allows for 5px gutter).
|
||||
width: `calc(${100 / this._columns}% - 5.25px)`,
|
||||
};
|
||||
|
||||
const folderStyle = {
|
||||
// Values derived from experimentation on typical Lovelace card sizes.
|
||||
'font-size': `${Math.min(
|
||||
1.1,
|
||||
(0.6 * (this.clientWidth / this._columns)) / 50.0,
|
||||
)}em`,
|
||||
};
|
||||
|
||||
return html` <ul class="mdc-image-list frigate-card-gallery">
|
||||
return html`
|
||||
${this._showBackArrow()
|
||||
? html`<li class="mdc-image-list__item" style="${styleMap(itemStyle)}">
|
||||
<div class="mdc-image-list__image-aspect-container">
|
||||
<div class="mdc-image-list__image">
|
||||
<ha-card
|
||||
@click=${(ev) => {
|
||||
if (this.view && this.view.previous) {
|
||||
this.view.previous.dispatchChangeEvent(this);
|
||||
}
|
||||
stopEventFromActivatingCardWideActions(ev);
|
||||
}}
|
||||
outlined=""
|
||||
class="frigate-card-gallery-folder"
|
||||
>
|
||||
<ha-icon .icon=${'mdi:arrow-left'}></ha-icon>
|
||||
</ha-card>
|
||||
</div>
|
||||
</div>
|
||||
</li>`
|
||||
? html` <ha-card
|
||||
@click=${(ev) => {
|
||||
if (this.view && this.view.previous) {
|
||||
this.view.previous.dispatchChangeEvent(this);
|
||||
}
|
||||
stopEventFromActivatingCardWideActions(ev);
|
||||
}}
|
||||
outlined=""
|
||||
>
|
||||
<ha-icon .icon=${'mdi:arrow-left'}></ha-icon>
|
||||
</ha-card>`
|
||||
: ''}
|
||||
${this.view.target.children.map(
|
||||
(child, index) =>
|
||||
html` <li class="mdc-image-list__item" style="${styleMap(itemStyle)}">
|
||||
<div class="mdc-image-list__image-aspect-container">
|
||||
${child.can_expand
|
||||
? html`<div class="mdc-image-list__image">
|
||||
<ha-card
|
||||
@click=${(ev) => {
|
||||
if (this.hass && this.view) {
|
||||
BrowseMediaUtil.fetchChildMediaAndDispatchViewChange(
|
||||
this,
|
||||
this.hass,
|
||||
this.view,
|
||||
child,
|
||||
);
|
||||
}
|
||||
stopEventFromActivatingCardWideActions(ev);
|
||||
}}
|
||||
outlined=""
|
||||
class="frigate-card-gallery-folder"
|
||||
>
|
||||
<div style="${styleMap(folderStyle)}">${child.title}</div>
|
||||
</ha-card>
|
||||
</div>`
|
||||
: child.thumbnail
|
||||
? html`<img
|
||||
aria-label="${child.title}"
|
||||
class="mdc-image-list__image"
|
||||
src="${child.thumbnail}"
|
||||
title="${child.title}"
|
||||
@click=${(ev: Event) => {
|
||||
if (this.view) {
|
||||
this.view
|
||||
.evolve({
|
||||
view: this.view.is('clips') ? 'clip' : 'snapshot',
|
||||
childIndex: index,
|
||||
})
|
||||
.dispatchChangeEvent(this);
|
||||
}
|
||||
stopEventFromActivatingCardWideActions(ev);
|
||||
}}
|
||||
/>${child.frigate?.event?.retain_indefinitely
|
||||
? html`<ha-icon
|
||||
class="favorite"
|
||||
icon="mdi:star"
|
||||
title=${localize('thumbnail.retain_indefinitely')}
|
||||
/>`
|
||||
: ``}`
|
||||
: ``}
|
||||
</div>
|
||||
</li>`,
|
||||
html`
|
||||
${child.can_expand
|
||||
? html`
|
||||
<ha-card
|
||||
@click=${(ev) => {
|
||||
if (this.hass && this.view) {
|
||||
BrowseMediaUtil.fetchChildMediaAndDispatchViewChange(
|
||||
this,
|
||||
this.hass,
|
||||
this.view,
|
||||
child,
|
||||
);
|
||||
}
|
||||
stopEventFromActivatingCardWideActions(ev);
|
||||
}}
|
||||
outlined=""
|
||||
class="foo"
|
||||
>
|
||||
<div>${child.title}</div>
|
||||
</ha-card>
|
||||
`
|
||||
: child.thumbnail
|
||||
? html`<frigate-card-thumbnail
|
||||
.view=${this.view}
|
||||
.target=${this.view?.target ?? null}
|
||||
.childIndex=${index}
|
||||
?details=${!!this.galleryConfig?.controls.thumbnails.show_details}
|
||||
?controls=${!!this.galleryConfig?.controls.thumbnails.show_controls}
|
||||
@click=${(ev: Event) => {
|
||||
if (this.view) {
|
||||
this.view
|
||||
.evolve({
|
||||
view: this.view.is('clips') ? 'clip' : 'snapshot',
|
||||
childIndex: index,
|
||||
})
|
||||
.dispatchChangeEvent(this);
|
||||
}
|
||||
stopEventFromActivatingCardWideActions(ev);
|
||||
}}
|
||||
>
|
||||
</frigate-card-thumbnail>`
|
||||
: ``}
|
||||
`,
|
||||
)}
|
||||
</ul>`;
|
||||
`;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user