Refactor thumbnail sizing.
This commit is contained in:
+25
-12
@@ -11,7 +11,12 @@ import {
|
|||||||
} from 'lit';
|
} from 'lit';
|
||||||
import { customElement, property } from 'lit/decorators.js';
|
import { customElement, property } from 'lit/decorators.js';
|
||||||
import galleryStyle from '../scss/gallery.scss';
|
import galleryStyle from '../scss/gallery.scss';
|
||||||
import { CameraConfig, frigateCardConfigDefaults, GalleryConfig } from '../types.js';
|
import {
|
||||||
|
CameraConfig,
|
||||||
|
frigateCardConfigDefaults,
|
||||||
|
GalleryConfig,
|
||||||
|
THUMBNAIL_WIDTH_MAX
|
||||||
|
} from '../types.js';
|
||||||
import { stopEventFromActivatingCardWideActions } from '../utils/action.js';
|
import { stopEventFromActivatingCardWideActions } from '../utils/action.js';
|
||||||
import {
|
import {
|
||||||
fetchChildMediaAndDispatchViewChange,
|
fetchChildMediaAndDispatchViewChange,
|
||||||
@@ -135,20 +140,28 @@ export class FrigateCardGalleryCore extends LitElement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handle gallery resize.
|
* Set gallery columns.
|
||||||
*/
|
*/
|
||||||
protected _resizeHandler(): void {
|
protected _setColumnCount(): void {
|
||||||
const thumbnailSize =
|
const thumbnailSize =
|
||||||
this.galleryConfig?.controls.thumbnails.size ??
|
this.galleryConfig?.controls.thumbnails.size ??
|
||||||
frigateCardConfigDefaults.event_gallery.controls.thumbnails.size;
|
frigateCardConfigDefaults.event_gallery.controls.thumbnails.size;
|
||||||
this.style.setProperty(
|
const columns = this.galleryConfig?.controls.thumbnails.show_details
|
||||||
'--frigate-card-gallery-columns',
|
? Math.max(1, Math.floor(this.clientWidth / THUMBNAIL_DETAILS_WIDTH_MIN))
|
||||||
String(
|
: Math.max(
|
||||||
!this.galleryConfig?.controls.thumbnails.show_details
|
1,
|
||||||
? Math.round(this.clientWidth / thumbnailSize)
|
Math.ceil(this.clientWidth / THUMBNAIL_WIDTH_MAX),
|
||||||
: Math.max(1, Math.floor(this.clientWidth / THUMBNAIL_DETAILS_WIDTH_MIN)),
|
Math.ceil(this.clientWidth / thumbnailSize),
|
||||||
),
|
);
|
||||||
);
|
|
||||||
|
this.style.setProperty('--frigate-card-gallery-columns', String(columns));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle gallery resize.
|
||||||
|
*/
|
||||||
|
protected _resizeHandler(): void {
|
||||||
|
this._setColumnCount();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -174,6 +187,7 @@ export class FrigateCardGalleryCore extends LitElement {
|
|||||||
} else {
|
} else {
|
||||||
this.removeAttribute('details');
|
this.removeAttribute('details');
|
||||||
}
|
}
|
||||||
|
this._setColumnCount();
|
||||||
if (this.galleryConfig?.controls.thumbnails.size) {
|
if (this.galleryConfig?.controls.thumbnails.size) {
|
||||||
this.style.setProperty(
|
this.style.setProperty(
|
||||||
'--frigate-card-thumbnail-size',
|
'--frigate-card-thumbnail-size',
|
||||||
@@ -230,7 +244,6 @@ export class FrigateCardGalleryCore extends LitElement {
|
|||||||
stopEventFromActivatingCardWideActions(ev);
|
stopEventFromActivatingCardWideActions(ev);
|
||||||
}}
|
}}
|
||||||
outlined=""
|
outlined=""
|
||||||
class="foo"
|
|
||||||
>
|
>
|
||||||
<div>${child.title}</div>
|
<div>${child.title}</div>
|
||||||
</ha-card>
|
</ha-card>
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ import { EmblaOptionsType } from 'embla-carousel';
|
|||||||
import { CSSResultGroup, html, PropertyValues, TemplateResult, unsafeCSS } from 'lit';
|
import { CSSResultGroup, html, PropertyValues, TemplateResult, unsafeCSS } from 'lit';
|
||||||
import { customElement, property, state } from 'lit/decorators.js';
|
import { customElement, property, state } from 'lit/decorators.js';
|
||||||
import { classMap } from 'lit/directives/class-map.js';
|
import { classMap } from 'lit/directives/class-map.js';
|
||||||
import { ifDefined } from 'lit/directives/if-defined.js';
|
|
||||||
import thumbnailCarouselStyle from '../scss/thumbnail-carousel.scss';
|
import thumbnailCarouselStyle from '../scss/thumbnail-carousel.scss';
|
||||||
import type { FrigateBrowseMediaSource, ThumbnailsControlConfig } from '../types.js';
|
import type { FrigateBrowseMediaSource, ThumbnailsControlConfig } from '../types.js';
|
||||||
import { stopEventFromActivatingCardWideActions } from '../utils/action.js';
|
import { stopEventFromActivatingCardWideActions } from '../utils/action.js';
|
||||||
@@ -120,6 +119,21 @@ export class FrigateCardThumbnailCarousel extends FrigateCardCarousel {
|
|||||||
return slides;
|
return slides;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called when an update will occur.
|
||||||
|
* @param changedProps The changed properties
|
||||||
|
*/
|
||||||
|
protected willUpdate(changedProps: PropertyValues): void {
|
||||||
|
if (changedProps.has('_config')) {
|
||||||
|
if (this._config?.size) {
|
||||||
|
this.style.setProperty(
|
||||||
|
'--frigate-card-thumbnail-size',
|
||||||
|
`${this._config.size}px`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The updated lifecycle callback for this element.
|
* The updated lifecycle callback for this element.
|
||||||
* @param changedProperties The properties that were changed in this render.
|
* @param changedProperties The properties that were changed in this render.
|
||||||
@@ -170,7 +184,6 @@ export class FrigateCardThumbnailCarousel extends FrigateCardCarousel {
|
|||||||
.childIndex=${childIndex}
|
.childIndex=${childIndex}
|
||||||
?details=${this._config?.show_details}
|
?details=${this._config?.show_details}
|
||||||
?controls=${this._config?.show_controls}
|
?controls=${this._config?.show_controls}
|
||||||
thumbnail_size=${ifDefined(this._config?.size)}
|
|
||||||
class="${classMap(classes)}"
|
class="${classMap(classes)}"
|
||||||
@click=${(ev) => {
|
@click=${(ev) => {
|
||||||
if (this._carousel && this._carousel.clickAllowed()) {
|
if (this._carousel && this._carousel.clickAllowed()) {
|
||||||
|
|||||||
@@ -128,11 +128,6 @@ export class FrigateCardThumbnail extends LitElement {
|
|||||||
@property({ attribute: true, type: Boolean })
|
@property({ attribute: true, type: Boolean })
|
||||||
public controls = false;
|
public controls = false;
|
||||||
|
|
||||||
@property({ attribute: true, type: Number })
|
|
||||||
set thumbnail_size(size: number) {
|
|
||||||
this.style.setProperty('--frigate-card-thumbnail-size', `${size}px`);
|
|
||||||
}
|
|
||||||
|
|
||||||
// ============================
|
// ============================
|
||||||
// Data-binding based interface
|
// Data-binding based interface
|
||||||
// ============================
|
// ============================
|
||||||
|
|||||||
@@ -497,9 +497,6 @@ export class FrigateCardTimelineCore extends LitElement {
|
|||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
|
|
||||||
const thumbnailSizeAttr = this.timelineConfig
|
|
||||||
? `thumbnail_size="${this.timelineConfig.controls.thumbnails.size}"`
|
|
||||||
: '';
|
|
||||||
const eventAttr = source.frigate?.event
|
const eventAttr = source.frigate?.event
|
||||||
? `event='${JSON.stringify(source.frigate.event)}'`
|
? `event='${JSON.stringify(source.frigate.event)}'`
|
||||||
: '';
|
: '';
|
||||||
@@ -516,7 +513,6 @@ export class FrigateCardTimelineCore extends LitElement {
|
|||||||
thumbnail="${source.thumbnail}"
|
thumbnail="${source.thumbnail}"
|
||||||
label="${source.title}"
|
label="${source.title}"
|
||||||
${eventAttr}
|
${eventAttr}
|
||||||
${thumbnailSizeAttr}
|
|
||||||
>
|
>
|
||||||
</frigate-card-thumbnail>`;
|
</frigate-card-thumbnail>`;
|
||||||
}
|
}
|
||||||
@@ -1022,7 +1018,6 @@ export class FrigateCardTimelineCore extends LitElement {
|
|||||||
'thumbnail',
|
'thumbnail',
|
||||||
'label',
|
'label',
|
||||||
'event',
|
'event',
|
||||||
'thumbnail_size',
|
|
||||||
],
|
],
|
||||||
div: ['title'],
|
div: ['title'],
|
||||||
span: ['style'],
|
span: ['style'],
|
||||||
@@ -1152,6 +1147,21 @@ export class FrigateCardTimelineCore extends LitElement {
|
|||||||
return newContext || null;
|
return newContext || null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called when an update will occur.
|
||||||
|
* @param changedProps The changed properties
|
||||||
|
*/
|
||||||
|
protected willUpdate(changedProps: PropertyValues): void {
|
||||||
|
if (changedProps.has('timelineConfig')) {
|
||||||
|
if (this.timelineConfig?.controls.thumbnails.size) {
|
||||||
|
this.style.setProperty(
|
||||||
|
'--frigate-card-thumbnail-size',
|
||||||
|
`${this.timelineConfig.controls.thumbnails.size}px`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called when the component is updated.
|
* Called when the component is updated.
|
||||||
* @param changedProperties The changed properties if any.
|
* @param changedProperties The changed properties if any.
|
||||||
|
|||||||
@@ -55,7 +55,6 @@ img,video {
|
|||||||
|
|
||||||
.embla__slide {
|
.embla__slide {
|
||||||
position: relative;
|
position: relative;
|
||||||
height: 100%;
|
|
||||||
overflow: visible;
|
overflow: visible;
|
||||||
}
|
}
|
||||||
:host([direction=vertical]) .embla__slide {
|
:host([direction=vertical]) .embla__slide {
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
:host {
|
:host {
|
||||||
--frigate-card-thumbnail-size: 100px;
|
|
||||||
--frigate-card-thumbnail-size-max: 175px;
|
--frigate-card-thumbnail-size-max: 175px;
|
||||||
--frigate-card-thumbnail-details-width: calc(var(--frigate-card-thumbnail-size) + 200px);
|
--frigate-card-thumbnail-details-width: calc(var(--frigate-card-thumbnail-size) + 200px);
|
||||||
}
|
}
|
||||||
+13
-10
@@ -1,8 +1,6 @@
|
|||||||
@use "const.scss";
|
|
||||||
|
|
||||||
:host {
|
:host {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: auto;
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
|
|
||||||
// Hide scrollbar: IE and Edge
|
// Hide scrollbar: IE and Edge
|
||||||
@@ -16,8 +14,8 @@
|
|||||||
|
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: repeat(var(--frigate-card-gallery-columns), minmax(0, 1fr));
|
grid-template-columns: repeat(var(--frigate-card-gallery-columns), minmax(0, 1fr));
|
||||||
grid-auto-rows: var(--frigate-card-thumbnail-size);
|
grid-auto-rows: 1fr;
|
||||||
grid-column-gap: var(--frigate-card-gallery-gap);
|
gap: var(--frigate-card-gallery-gap);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Hide scrollbar for Chrome, Safari and Opera
|
// Hide scrollbar for Chrome, Safari and Opera
|
||||||
@@ -32,16 +30,21 @@ ha-card {
|
|||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
opacity: 0.7;
|
opacity: 0.7;
|
||||||
color: var(--secondary-text-color, white);
|
color: var(--primary-text-color, white);
|
||||||
border: 2px ridge var(--secondary-text-color, black);
|
border: 2px ridge var(--primary-text-color, black);
|
||||||
border-radius: 5px;
|
border-radius: 5px;
|
||||||
background-color: var(--primary-background-color, black);
|
background-color: var(--primary-background-color, black);
|
||||||
padding: 10px;
|
padding: 10px;
|
||||||
line-height: 1;
|
line-height: 1;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
|
|
||||||
|
transition: transform 0.2s linear;
|
||||||
|
}
|
||||||
|
ha-card:hover {
|
||||||
|
transform: scale(1.04)
|
||||||
}
|
}
|
||||||
|
|
||||||
:host(:not([details])) ha-card,
|
ha-card, frigate-card-thumbnail {
|
||||||
:host(:not([details])) frigate-card-thumbnail {
|
height: 100%;
|
||||||
aspect-ratio: 1 / 1;
|
max-height: var(--frigate-card-thumbnail-size);
|
||||||
}
|
}
|
||||||
@@ -4,4 +4,5 @@
|
|||||||
|
|
||||||
.embla__slide {
|
.embla__slide {
|
||||||
flex: 0 0 100%;
|
flex: 0 0 100%;
|
||||||
|
height: 100%;
|
||||||
}
|
}
|
||||||
@@ -1,13 +1,13 @@
|
|||||||
@use "const.scss";
|
@use 'const.scss';
|
||||||
|
|
||||||
:host {
|
:host {
|
||||||
--frigate-card-carousel-thumbnail-opacity: 1.0;
|
--frigate-card-carousel-thumbnail-opacity: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
:host([direction=vertical]) {
|
:host([direction='vertical']) {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
}
|
}
|
||||||
:host([direction=horizontal]) {
|
:host([direction='horizontal']) {
|
||||||
// In fullscreen mode, without explicitly setting the height to auto Chrome
|
// In fullscreen mode, without explicitly setting the height to auto Chrome
|
||||||
// will construct a stylesheet with 100% height.
|
// will construct a stylesheet with 100% height.
|
||||||
height: auto;
|
height: auto;
|
||||||
@@ -19,14 +19,13 @@
|
|||||||
transition: opacity 0.6s ease;
|
transition: opacity 0.6s ease;
|
||||||
}
|
}
|
||||||
.embla__slide.slide-selected {
|
.embla__slide.slide-selected {
|
||||||
opacity: 1.0;
|
opacity: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
frigate-card-thumbnail[details] {
|
frigate-card-thumbnail {
|
||||||
width: var(--frigate-card-thumbnail-details-width);
|
|
||||||
height: var(--frigate-card-thumbnail-size);
|
|
||||||
}
|
|
||||||
frigate-card-thumbnail:not([details]) {
|
|
||||||
width: var(--frigate-card-thumbnail-size);
|
width: var(--frigate-card-thumbnail-size);
|
||||||
height: var(--frigate-card-thumbnail-size);
|
height: var(--frigate-card-thumbnail-size);
|
||||||
}
|
}
|
||||||
|
frigate-card-thumbnail[details] {
|
||||||
|
width: var(--frigate-card-thumbnail-details-width);
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,24 +1,24 @@
|
|||||||
:host {
|
:host {
|
||||||
display: block;
|
display: block;
|
||||||
height: 100%;
|
max-width: var(--frigate-card-thumbnail-size);
|
||||||
|
max-height: var(--frigate-card-thumbnail-size);
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
|
|
||||||
|
// Restrict images to a maximum of thumbnail size.
|
||||||
|
aspect-ratio: 1 / 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
img, ha-icon {
|
img, ha-icon {
|
||||||
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: 100%;
|
||||||
max-height: var(--frigate-card-thumbnail-size-max);
|
height: 100%;
|
||||||
|
|
||||||
// Not 'contain' as some thumbnails may vary in aspect-ratio slightly and
|
// Not 'contain' as some thumbnails may vary in aspect-ratio slightly and
|
||||||
// should be clipped to fill the thumbnail div whilst maintaining
|
// should be clipped to fill the thumbnail div whilst maintaining
|
||||||
// aspect-ratio.
|
// aspect-ratio.
|
||||||
object-fit: cover;
|
object-fit: cover;
|
||||||
|
|
||||||
// Restrict images to a maximum of thumbnail size.
|
|
||||||
aspect-ratio: 1 / 1;
|
|
||||||
height: 100%;
|
|
||||||
|
|
||||||
transition: transform 0.2s linear;
|
transition: transform 0.2s linear;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -4,11 +4,10 @@
|
|||||||
justify-content: center;
|
justify-content: center;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
|
||||||
height: 100%;
|
|
||||||
aspect-ratio: 1 / 1;
|
aspect-ratio: 1 / 1;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
max-width: var(--frigate-card-thumbnail-size-max);
|
max-width: var(--frigate-card-thumbnail-size);
|
||||||
max-height: var(--frigate-card-thumbnail-size-max);
|
max-height: var(--frigate-card-thumbnail-size);
|
||||||
padding: 10px;
|
padding: 10px;
|
||||||
|
|
||||||
border: 1px solid var(--secondary-color);
|
border: 1px solid var(--secondary-color);
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
@use "const.scss";
|
|
||||||
|
|
||||||
:host {
|
:host {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
@@ -7,6 +5,11 @@
|
|||||||
|
|
||||||
// Ensure control icons are relative to the thumbnail.
|
// Ensure control icons are relative to the thumbnail.
|
||||||
position: relative;
|
position: relative;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
:host(:not([details])) {
|
||||||
|
aspect-ratio: 1 / 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
:host([details]) {
|
:host([details]) {
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
@use 'vis-timeline/dist/vis-timeline-graph2d.css';
|
@use 'vis-timeline/dist/vis-timeline-graph2d.css';
|
||||||
@use 'drawer';
|
@use 'drawer';
|
||||||
|
@use 'const.scss';
|
||||||
|
|
||||||
:host {
|
:host {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
@@ -15,6 +16,14 @@
|
|||||||
position: relative;
|
position: relative;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
frigate-card-thumbnail {
|
||||||
|
height: var(--frigate-card-thumbnail-size);
|
||||||
|
width: var(--frigate-card-thumbnail-size);
|
||||||
|
}
|
||||||
|
frigate-card-thumbnail[details] {
|
||||||
|
width: var(--frigate-card-thumbnail-details-width);
|
||||||
|
}
|
||||||
|
|
||||||
div.timeline {
|
div.timeline {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user