diff --git a/README.md b/README.md index 07d8695e..0b56faa6 100644 --- a/README.md +++ b/README.md @@ -170,7 +170,7 @@ menu: | Option | Default | Overridable | Description | | - | - | - | - | | `mode` | `hidden-top` | :white_check_mark: | The menu mode to show by default. See [menu modes](#menu-modes) below.| -| `button_size` | `40px` | :white_check_mark: | The size of the menu buttons [in CSS Units](https://www.w3schools.com/cssref/css_units.asp).| +| `button_size` | 40 | :white_check_mark: | The size of the menu buttons in pixels. Must be >= `20`.| | `buttons` | | :white_check_mark: | Whether to show or hide built-in buttons. See below. | #### Menu Options: Buttons @@ -258,7 +258,7 @@ live: | Option | Default | Overridable | Description | | - | - | - | - | | `mode` | `none` | :white_check_mark: | Whether to show the thumbnail carousel `below` the media, `above` the media, in a drawer to the `left` or `right` of the media or to hide it entirely (`none`).| -| `size` | `100px` | :white_check_mark: | The size of the thumbnails in the thumbnail carousel [in CSS Units](https://www.w3schools.com/cssref/css_units.asp).| +| `size` | 100 | :white_check_mark: | The size of the thumbnails in the thumbnail carousel in pixels. Must be >= `75` and <= `175`. | | `show_details` | `false` | :white_check_mark: | Whether to show event details (e.g. duration, start time, object detected, etc) alongside the thumbnail.| | `show_controls` | `true` | :white_check_mark: | Whether to show event controls (e.g. timeline icon, favorite icon) alongside the thumbnail.| | `media` | `clips` | :white_check_mark: | Whether to show `clips` or `snapshots` in the thumbnail carousel in the `live` view.| @@ -276,7 +276,7 @@ live: | Option | Default | Overridable | Description | | - | - | - | - | | `style` | `chevrons` | :white_check_mark: | When viewing live cameras, what kind of controls to show to move to the previous/next camera. Acceptable values: `chevrons`, `icons`, `none` . | -| `size` | `48px` | :white_check_mark: | The size of the next/previous controls [in CSS Units](https://www.w3schools.com/cssref/css_units.asp).| +| `size` | 48 | :white_check_mark: | The size of the next/previous controls in pixels. Must be >= `20`. | @@ -328,7 +328,7 @@ event_viewer: | Option | Default | Overridable | Description | | - | - | - | - | | `style` | `thumbnails` | :heavy_multiplication_x: | When viewing media, what kind of controls to show to move to the previous/next media item. Acceptable values: `thumbnails`, `chevrons`, `none` . | -| `size` | `48px` | :heavy_multiplication_x: | The size of the next/previous controls [in CSS Units](https://www.w3schools.com/cssref/css_units.asp).| +| `size` | 48 | :heavy_multiplication_x: | The size of the next/previous controls in pixels. Must be >= `20`.| #### Event Viewer Controls: Thumbnails @@ -343,7 +343,7 @@ event_viewer: | Option | Default | Overridable | Description | | - | - | - | - | | `mode` | `none` | :heavy_multiplication_x: | Whether to show the thumbnail carousel `below` the media, `above` the media, in a drawer to the `left` or `right` of the media or to hide it entirely (`none`).| -| `size` | `100px` | :heavy_multiplication_x: | The size of the thumbnails in the thumbnail carousel [in CSS Units](https://www.w3schools.com/cssref/css_units.asp).| +| `size` | 100 | :heavy_multiplication_x: | The size of the thumbnails in the thumbnail carousel pixels. Must be >= `75` and <= `175`.| | `show_details` | `false` | :heavy_multiplication_x: | Whether to show event details (e.g. duration, start time, object detected, etc) alongside the thumbnail.| | `show_controls` | `true` | :heavy_multiplication_x: | Whether to show event controls (e.g. timeline icon, favorite icon) alongside the thumbnail.| @@ -374,7 +374,9 @@ event_gallery: | Option | Default | Overridable | Description | | - | - | - | - | -| `min_columns` | `5` | :heavy_multiplication_x: | The minimum number of columns to show in the gallery -- smaller values will render fewer but larger thumbnail columns. Thumbnails will never be stretched beyond their intrinsic size (typically `175px`). All available space (in normal mode, or fullscreen mode) will be occupied by the gallery, so more columns than `min_columns` will often be rendered if space allows for more full-sized thumbnails. For normal sized Lovelace cards (`492px` wide), this typically means there'll never be fewer than 3 columns rendered (as otherwise the thumbnails would need to stretch beyond their actual size). Must be `1 <= x <= 10`. | +| `size` | 100 | :heavy_multiplication_x: | The size of the thumbnails in the event gallery in pixels. Must be >= `75` and <= `175`.| +| `show_details` | `false` | :heavy_multiplication_x: | Whether to show event details (e.g. duration, start time, object detected, etc) alongside the thumbnail.| +| `show_controls` | `true` | :heavy_multiplication_x: | Whether to show event controls (e.g. timeline icon, favorite icon) alongside the thumbnail.| | `actions` | | :heavy_multiplication_x: | Actions to use for all views that use the `event_gallery` (e.g. `clips`, `snapshots`). See [actions](#actions) below.| ### Image Options @@ -423,7 +425,7 @@ timeline: | Option | Default | Overridable | Description | | - | - | - | - | | `mode` | `none` | :heavy_multiplication_x: | Whether to show the thumbnail carousel `below` the media, `above` the media, in a drawer to the `left` or `right` of the media or to hide it entirely (`none`).| -| `size` | `100px` | :heavy_multiplication_x: | The size of the thumbnails in the thumbnail carousel [in CSS Units](https://www.w3schools.com/cssref/css_units.asp).| +| `size` | 100 | :heavy_multiplication_x: | The size of the thumbnails in the thumbnail carousel in pixels. Must be >= `75` and <= `175`.| | `show_details` | `false` | :heavy_multiplication_x: | Whether to show event details (e.g. duration, start time, object detected, etc) alongside the thumbnail.| | `show_controls` | `true` | :heavy_multiplication_x: | Whether to show event controls (e.g. timeline icon, favorite icon) alongside the thumbnail.| diff --git a/package.json b/package.json index 91ddb3fd..65585378 100644 --- a/package.json +++ b/package.json @@ -18,7 +18,6 @@ "@cycjimmy/jsmpeg-player": "^5.1.1", "@egjs/hammerjs": "^2.0.17", "@lit-labs/task": "^1.1.1", - "@material/image-list": "^13.0.0", "@material/mwc-menu": "^0.25.3", "@material/rtl": "^13.0.0", "@types/bluebird": "^3.5.36", @@ -32,7 +31,7 @@ "keycharm": "^0.4.0", "lit": "^2.2.1", "lodash-es": "^4.17.21", - "moment": "^2.29.1", + "moment": "^2.29.2", "propagating-hammerjs": "^2.0.1", "quick-lru": "^6.1.0", "screenfull": "^6.0.1", diff --git a/src/components/gallery.ts b/src/components/gallery.ts index b83c8382..3ab4f931 100644 --- a/src/components/gallery.ts +++ b/src/components/gallery.ts @@ -1,22 +1,30 @@ /* 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 +85,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 +108,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 +133,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 +158,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 +193,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`