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;
}