diff --git a/src/components/carousel.ts b/src/components/carousel.ts index 351bf339..c7de9885 100644 --- a/src/components/carousel.ts +++ b/src/components/carousel.ts @@ -1,20 +1,16 @@ import EmblaCarousel, { EmblaCarouselType, EmblaOptionsType } from 'embla-carousel'; import { EmblaNodesType } from 'embla-carousel/components'; -import { - CreatePluginType, - EmblaPluginsType, - LoosePluginType, -} from 'embla-carousel/components/Plugins'; +import { CreatePluginType, LoosePluginType } from 'embla-carousel/components/Plugins'; import { CSSResultGroup, - html, LitElement, PropertyValues, TemplateResult, + html, unsafeCSS, } from 'lit'; import { customElement, property } from 'lit/decorators.js'; -import { createRef, ref, Ref } from 'lit/directives/ref.js'; +import { Ref, createRef, ref } from 'lit/directives/ref.js'; import throttle from 'lodash-es/throttle'; import carouselStyle from '../scss/carousel.scss'; import { TransitionEffect } from '../types'; @@ -101,8 +97,8 @@ export class FrigateCardCarousel extends LitElement { * Get the selected slide. * @returns A CarouselSelect object (index & element). */ - public getCarouselSelected(): CarouselSelect | null { - const index = this._carousel?.selectedScrollSnap(); + public getCarouselSelected(slide?: number): CarouselSelect | null { + const index = slide ?? this._carousel?.selectedScrollSnap(); const element = index !== undefined ? this._carousel?.slideNodes()[index] ?? null : null; if (index !== undefined && element) { @@ -151,13 +147,6 @@ export class FrigateCardCarousel extends LitElement { } } - /** - * Get the live carousel plugins. - */ - public getCarouselPlugins(): EmblaPluginsType | null { - return this._carousel?.plugins() ?? null; - } - /** * The updated lifecycle callback for this element. * @param changedProperties The properties that were changed in this render. @@ -212,8 +201,8 @@ export class FrigateCardCarousel extends LitElement { }, this.carouselPlugins, ); - const selectSlide = (): void => { - const selected = this.getCarouselSelected(); + const selectSlide = (slide?: number): void => { + const selected = this.getCarouselSelected(slide); if (selected) { dispatchFrigateCardEvent(this, 'carousel:select', selected); } @@ -223,8 +212,24 @@ export class FrigateCardCarousel extends LitElement { this.requestUpdate(); }; - this._carousel.on('init', selectSlide); - this._carousel.on('select', selectSlide); + this._carousel.on( + 'init', + // On initialization selectedScrollSnap() will return 0, even if the + // startIndex during initialization is different, as such we override + // the selected slide as returned by the carousel. This need should be + // verified in future versions of Embla (tested as necessary on v7.0.9). + // Test case: + // + // - Start in `live` view in grid mode. + // - Select any camera that is not the first one. + // - Go to non-grid mode. + // - Go back to grid mode. + // - If successful, thumbnails will load correctly (and the query and + // queryResults in the view will be set vs having been reset in + // `_setViewCameraID` in `live.ts`). + () => selectSlide(this.selected), + ); + this._carousel.on('select', () => selectSlide()); this._carousel.on('scroll', () => { this._scrolling = true; }); diff --git a/src/components/media-carousel.ts b/src/components/media-carousel.ts index 470e564b..8e8a2f0e 100644 --- a/src/components/media-carousel.ts +++ b/src/components/media-carousel.ts @@ -3,6 +3,7 @@ import { CSSResultGroup, html, LitElement, TemplateResult, unsafeCSS } from 'lit import { customElement, property } from 'lit/decorators.js'; import { ifDefined } from 'lit/directives/if-defined.js'; import { createRef, ref, Ref } from 'lit/directives/ref.js'; +import debounce from 'lodash-es/debounce'; import mediaCarouselStyle from '../scss/media-carousel.scss'; import type { MediaLoadedInfo, @@ -15,14 +16,13 @@ import { dispatchExistingMediaLoadedInfoAsEvent, isValidMediaLoadedInfo, } from '../utils/media-info.js'; +import { Timer } from '../utils/timer'; import { CarouselSelect, EmblaCarouselPlugins, FrigateCardCarousel } from './carousel'; +import './carousel.js'; import { AutoMediaType } from './embla-plugins/automedia.js'; import './next-prev-control.js'; -import './carousel.js'; import { FrigateCardNextPreviousControl } from './next-prev-control.js'; import { FrigateCardTitleControl } from './title-control.js'; -import debounce from 'lodash-es/debounce'; -import { Timer } from '../utils/timer'; interface CarouselMediaLoadedInfo { slide: number; diff --git a/src/components/media-grid.ts b/src/components/media-grid.ts index 344e82cc..2c2f5d72 100644 --- a/src/components/media-grid.ts +++ b/src/components/media-grid.ts @@ -1,6 +1,8 @@ // TODO: Performance of video scanning (pause/play?) // TODO: Investigate query spam during a grid load // TODO: Do I need column max? +// TODO: frigate-card-live-go2rtc.hidden double media load event. +// TODO: Why am I creating so many carousels in the race-condition issue? Expecting 5, getting 10. import { CSSResultGroup, diff --git a/src/components/viewer.ts b/src/components/viewer.ts index b18c4ded..dfcb896f 100644 --- a/src/components/viewer.ts +++ b/src/components/viewer.ts @@ -253,7 +253,7 @@ export class FrigateCardViewerCarousel extends LitElement { } /** - * The the HLS player on a slide (or current slide if not provided.) + * Get the media player on a slide (or current slide if not provided). * @param slide An optional slide. * @returns The FrigateCardMediaPlayer or null if not found. */