From 42c8251c20570c1a3f8c9f0538225641a2b430a6 Mon Sep 17 00:00:00 2001 From: Dermot Duffy Date: Fri, 3 Jun 2022 21:44:13 -0700 Subject: [PATCH] Refactor thumbnail sizing. --- src/components/gallery.ts | 37 +++++++++++++++-------- src/components/thumbnail-carousel.ts | 17 +++++++++-- src/components/thumbnail.ts | 5 --- src/components/timeline.ts | 20 +++++++++--- src/scss/carousel.scss | 1 - src/scss/const.scss | 1 - src/scss/gallery.scss | 25 ++++++++------- src/scss/media-carousel.scss | 1 + src/scss/thumbnail-carousel.scss | 21 ++++++------- src/scss/thumbnail-feature-event.scss | 14 ++++----- src/scss/thumbnail-feature-recording.scss | 7 ++--- src/scss/thumbnail.scss | 7 +++-- src/scss/timeline-core.scss | 9 ++++++ 13 files changed, 104 insertions(+), 61 deletions(-) diff --git a/src/components/gallery.ts b/src/components/gallery.ts index 80fabf2a..92cb52d8 100644 --- a/src/components/gallery.ts +++ b/src/components/gallery.ts @@ -11,7 +11,12 @@ import { } from 'lit'; import { customElement, property } from 'lit/decorators.js'; 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 { fetchChildMediaAndDispatchViewChange, @@ -135,20 +140,28 @@ export class FrigateCardGalleryCore extends LitElement { } /** - * Handle gallery resize. + * Set gallery columns. */ - protected _resizeHandler(): void { + protected _setColumnCount(): void { 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)), - ), - ); + const columns = this.galleryConfig?.controls.thumbnails.show_details + ? Math.max(1, Math.floor(this.clientWidth / THUMBNAIL_DETAILS_WIDTH_MIN)) + : Math.max( + 1, + Math.ceil(this.clientWidth / THUMBNAIL_WIDTH_MAX), + 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 { this.removeAttribute('details'); } + this._setColumnCount(); if (this.galleryConfig?.controls.thumbnails.size) { this.style.setProperty( '--frigate-card-thumbnail-size', @@ -230,7 +244,6 @@ export class FrigateCardGalleryCore extends LitElement { stopEventFromActivatingCardWideActions(ev); }} outlined="" - class="foo" >
${child.title}
diff --git a/src/components/thumbnail-carousel.ts b/src/components/thumbnail-carousel.ts index d62d1711..54b515da 100644 --- a/src/components/thumbnail-carousel.ts +++ b/src/components/thumbnail-carousel.ts @@ -2,7 +2,6 @@ import { EmblaOptionsType } from 'embla-carousel'; import { CSSResultGroup, html, PropertyValues, TemplateResult, unsafeCSS } from 'lit'; import { customElement, property, state } from 'lit/decorators.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 type { FrigateBrowseMediaSource, ThumbnailsControlConfig } from '../types.js'; import { stopEventFromActivatingCardWideActions } from '../utils/action.js'; @@ -120,6 +119,21 @@ export class FrigateCardThumbnailCarousel extends FrigateCardCarousel { 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. * @param changedProperties The properties that were changed in this render. @@ -170,7 +184,6 @@ export class FrigateCardThumbnailCarousel extends FrigateCardCarousel { .childIndex=${childIndex} ?details=${this._config?.show_details} ?controls=${this._config?.show_controls} - thumbnail_size=${ifDefined(this._config?.size)} class="${classMap(classes)}" @click=${(ev) => { if (this._carousel && this._carousel.clickAllowed()) { diff --git a/src/components/thumbnail.ts b/src/components/thumbnail.ts index cc5676bb..e052440f 100644 --- a/src/components/thumbnail.ts +++ b/src/components/thumbnail.ts @@ -128,11 +128,6 @@ export class FrigateCardThumbnail extends LitElement { @property({ attribute: true, type: Boolean }) 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 // ============================ diff --git a/src/components/timeline.ts b/src/components/timeline.ts index 0fd14ee0..67784235 100644 --- a/src/components/timeline.ts +++ b/src/components/timeline.ts @@ -497,9 +497,6 @@ export class FrigateCardTimelineCore extends LitElement { return ''; } - const thumbnailSizeAttr = this.timelineConfig - ? `thumbnail_size="${this.timelineConfig.controls.thumbnails.size}"` - : ''; const eventAttr = source.frigate?.event ? `event='${JSON.stringify(source.frigate.event)}'` : ''; @@ -516,7 +513,6 @@ export class FrigateCardTimelineCore extends LitElement { thumbnail="${source.thumbnail}" label="${source.title}" ${eventAttr} - ${thumbnailSizeAttr} > `; } @@ -1022,7 +1018,6 @@ export class FrigateCardTimelineCore extends LitElement { 'thumbnail', 'label', 'event', - 'thumbnail_size', ], div: ['title'], span: ['style'], @@ -1152,6 +1147,21 @@ export class FrigateCardTimelineCore extends LitElement { 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. * @param changedProperties The changed properties if any. diff --git a/src/scss/carousel.scss b/src/scss/carousel.scss index 32dc9147..d72a6def 100644 --- a/src/scss/carousel.scss +++ b/src/scss/carousel.scss @@ -55,7 +55,6 @@ img,video { .embla__slide { position: relative; - height: 100%; overflow: visible; } :host([direction=vertical]) .embla__slide { diff --git a/src/scss/const.scss b/src/scss/const.scss index 38cc2113..8c612c78 100644 --- a/src/scss/const.scss +++ b/src/scss/const.scss @@ -1,5 +1,4 @@ :host { - --frigate-card-thumbnail-size: 100px; --frigate-card-thumbnail-size-max: 175px; --frigate-card-thumbnail-details-width: calc(var(--frigate-card-thumbnail-size) + 200px); } \ No newline at end of file diff --git a/src/scss/gallery.scss b/src/scss/gallery.scss index 2777fd32..09c63520 100644 --- a/src/scss/gallery.scss +++ b/src/scss/gallery.scss @@ -1,8 +1,6 @@ -@use "const.scss"; - :host { width: 100%; - height: 100%; + height: auto; overflow: auto; // Hide scrollbar: IE and Edge @@ -16,8 +14,8 @@ display: grid; grid-template-columns: repeat(var(--frigate-card-gallery-columns), minmax(0, 1fr)); - grid-auto-rows: var(--frigate-card-thumbnail-size); - grid-column-gap: var(--frigate-card-gallery-gap); + grid-auto-rows: 1fr; + gap: var(--frigate-card-gallery-gap); } // Hide scrollbar for Chrome, Safari and Opera @@ -32,16 +30,21 @@ ha-card { box-sizing: border-box; text-align: center; opacity: 0.7; - color: var(--secondary-text-color, white); - border: 2px ridge var(--secondary-text-color, black); + color: var(--primary-text-color, white); + border: 2px ridge var(--primary-text-color, black); border-radius: 5px; background-color: var(--primary-background-color, black); padding: 10px; line-height: 1; overflow: hidden; + + transition: transform 0.2s linear; +} +ha-card:hover { + transform: scale(1.04) } -:host(:not([details])) ha-card, -:host(:not([details])) frigate-card-thumbnail { - aspect-ratio: 1 / 1; -} +ha-card, frigate-card-thumbnail { + height: 100%; + max-height: var(--frigate-card-thumbnail-size); +} \ No newline at end of file diff --git a/src/scss/media-carousel.scss b/src/scss/media-carousel.scss index 5611628f..d0d0142d 100644 --- a/src/scss/media-carousel.scss +++ b/src/scss/media-carousel.scss @@ -4,4 +4,5 @@ .embla__slide { flex: 0 0 100%; + height: 100%; } \ No newline at end of file diff --git a/src/scss/thumbnail-carousel.scss b/src/scss/thumbnail-carousel.scss index 033d09fd..71f70170 100644 --- a/src/scss/thumbnail-carousel.scss +++ b/src/scss/thumbnail-carousel.scss @@ -1,13 +1,13 @@ -@use "const.scss"; +@use 'const.scss'; :host { - --frigate-card-carousel-thumbnail-opacity: 1.0; + --frigate-card-carousel-thumbnail-opacity: 1; } -:host([direction=vertical]) { +:host([direction='vertical']) { height: 100%; } -:host([direction=horizontal]) { +:host([direction='horizontal']) { // In fullscreen mode, without explicitly setting the height to auto Chrome // will construct a stylesheet with 100% height. height: auto; @@ -19,14 +19,13 @@ transition: opacity 0.6s ease; } .embla__slide.slide-selected { - opacity: 1.0; + opacity: 1; } -frigate-card-thumbnail[details] { - width: var(--frigate-card-thumbnail-details-width); - height: var(--frigate-card-thumbnail-size); -} -frigate-card-thumbnail:not([details]) { +frigate-card-thumbnail { width: var(--frigate-card-thumbnail-size); height: var(--frigate-card-thumbnail-size); -} \ No newline at end of file +} +frigate-card-thumbnail[details] { + width: var(--frigate-card-thumbnail-details-width); +} diff --git a/src/scss/thumbnail-feature-event.scss b/src/scss/thumbnail-feature-event.scss index 49100d67..790147ff 100644 --- a/src/scss/thumbnail-feature-event.scss +++ b/src/scss/thumbnail-feature-event.scss @@ -1,24 +1,24 @@ :host { display: block; - height: 100%; + max-width: var(--frigate-card-thumbnail-size); + max-height: var(--frigate-card-thumbnail-size); overflow: hidden; + + // Restrict images to a maximum of thumbnail size. + aspect-ratio: 1 / 1; } img, ha-icon { border-radius: var(--ha-card-border-radius, 4px); - max-width: var(--frigate-card-thumbnail-size-max); - max-height: var(--frigate-card-thumbnail-size-max); + width: 100%; + height: 100%; // Not 'contain' as some thumbnails may vary in aspect-ratio slightly and // should be clipped to fill the thumbnail div whilst maintaining // aspect-ratio. object-fit: cover; - // Restrict images to a maximum of thumbnail size. - aspect-ratio: 1 / 1; - height: 100%; - transition: transform 0.2s linear; } diff --git a/src/scss/thumbnail-feature-recording.scss b/src/scss/thumbnail-feature-recording.scss index 590ec46c..a165b971 100644 --- a/src/scss/thumbnail-feature-recording.scss +++ b/src/scss/thumbnail-feature-recording.scss @@ -4,11 +4,10 @@ justify-content: center; align-items: center; - height: 100%; aspect-ratio: 1 / 1; overflow: hidden; - max-width: var(--frigate-card-thumbnail-size-max); - max-height: var(--frigate-card-thumbnail-size-max); + max-width: var(--frigate-card-thumbnail-size); + max-height: var(--frigate-card-thumbnail-size); padding: 10px; border: 1px solid var(--secondary-color); @@ -27,4 +26,4 @@ div.title { font-size: 1.5rem; -} \ No newline at end of file +} diff --git a/src/scss/thumbnail.scss b/src/scss/thumbnail.scss index 22c6b23a..35a443a8 100644 --- a/src/scss/thumbnail.scss +++ b/src/scss/thumbnail.scss @@ -1,5 +1,3 @@ -@use "const.scss"; - :host { display: flex; flex-direction: row; @@ -7,6 +5,11 @@ // Ensure control icons are relative to the thumbnail. position: relative; + overflow: hidden; +} + +:host(:not([details])) { + aspect-ratio: 1 / 1; } :host([details]) { diff --git a/src/scss/timeline-core.scss b/src/scss/timeline-core.scss index 1230e864..84c4cab0 100644 --- a/src/scss/timeline-core.scss +++ b/src/scss/timeline-core.scss @@ -1,5 +1,6 @@ @use 'vis-timeline/dist/vis-timeline-graph2d.css'; @use 'drawer'; +@use 'const.scss'; :host { width: 100%; @@ -15,6 +16,14 @@ 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 { flex: 1; }