Avoid carousel init duplication.
This commit is contained in:
@@ -11,10 +11,11 @@ import {
|
||||
} from 'lit';
|
||||
import { customElement, property } from 'lit/decorators.js';
|
||||
import { Ref, createRef, ref } from 'lit/directives/ref.js';
|
||||
import isEqual from 'lodash-es/isEqual';
|
||||
import throttle from 'lodash-es/throttle';
|
||||
import carouselStyle from '../scss/carousel.scss';
|
||||
import { TransitionEffect } from '../types';
|
||||
import { dispatchFrigateCardEvent } from '../utils/basic.js';
|
||||
import { dispatchFrigateCardEvent, isHTMLElement } from '../utils/basic.js';
|
||||
|
||||
export interface CarouselSelect {
|
||||
index: number;
|
||||
@@ -175,6 +176,13 @@ export class FrigateCardCarousel extends LitElement {
|
||||
this._carousel = undefined;
|
||||
}
|
||||
|
||||
protected _getSlideElements(): HTMLElement[] {
|
||||
return (
|
||||
this._refSlot.value?.assignedElements({ flatten: true }).filter(isHTMLElement) ??
|
||||
[]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize the carousel.
|
||||
*/
|
||||
@@ -187,7 +195,7 @@ export class FrigateCardCarousel extends LitElement {
|
||||
root: carouselNode,
|
||||
// As the slides are slotted, need to explicitly pull them out and pass
|
||||
// them to Embla.
|
||||
slides: this._refSlot.value?.assignedElements({ flatten: true }) as HTMLElement[],
|
||||
slides: this._getSlideElements(),
|
||||
};
|
||||
|
||||
if (carouselNode && nodes.slides) {
|
||||
@@ -256,10 +264,14 @@ export class FrigateCardCarousel extends LitElement {
|
||||
* Called when the slotted children in the carousel change.
|
||||
*/
|
||||
protected _slotChanged(): void {
|
||||
// Cannot just re-init, because the slide elements themselves may have
|
||||
// changed, and only a carousel init can pass in new (slotted) children. If
|
||||
this._destroyCarousel();
|
||||
this.requestUpdate();
|
||||
// Check whether the slotted elements have changed (without this check the
|
||||
// carousel initializations are duplicated).
|
||||
if (!isEqual(this._getSlideElements(), this._carousel?.slideNodes())) {
|
||||
// Cannot just re-init, because the slide elements themselves may have
|
||||
// changed, and only a carousel init can pass in new (slotted) children.
|
||||
this._destroyCarousel();
|
||||
this.requestUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
protected render(): TemplateResult | void {
|
||||
|
||||
@@ -1,8 +1,4 @@
|
||||
// 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,
|
||||
|
||||
+7
-1
@@ -225,4 +225,10 @@ export const setOrRemoveAttribute = (
|
||||
/**
|
||||
* Allow typescript to narrow types based on truthy filter.
|
||||
*/
|
||||
export const filterTruthy = <T>(x: T | false | undefined | null | '' | 0): x is T => !!x;
|
||||
export const isTruthy = <T>(x: T | false | undefined | null | '' | 0): x is T => !!x;
|
||||
|
||||
/**
|
||||
* Allow typescript to narrow types for HTMLElements.
|
||||
*/
|
||||
export const isHTMLElement = (element: unknown): element is HTMLElement =>
|
||||
element instanceof HTMLElement;
|
||||
|
||||
@@ -8,7 +8,7 @@ import {
|
||||
dayToDate,
|
||||
dispatchFrigateCardEvent,
|
||||
errorToConsole,
|
||||
filterTruthy,
|
||||
isTruthy,
|
||||
formatDate,
|
||||
formatDateAndTime,
|
||||
getDurationString,
|
||||
@@ -20,6 +20,7 @@ import {
|
||||
setify,
|
||||
setOrRemoveAttribute,
|
||||
sleep,
|
||||
isHTMLElement,
|
||||
} from '../../src/utils/basic';
|
||||
|
||||
// @vitest-environment jsdom
|
||||
@@ -248,11 +249,22 @@ describe('setOrRemoveAttribute', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('filterTruthy', () => {
|
||||
describe('isTruthy', () => {
|
||||
it('should return true for true', () => {
|
||||
expect(filterTruthy(true)).toBeTruthy();
|
||||
expect(isTruthy(true)).toBeTruthy();
|
||||
});
|
||||
it('should return false for false', () => {
|
||||
expect(filterTruthy(false)).toBeFalsy();
|
||||
expect(isTruthy(false)).toBeFalsy();
|
||||
});
|
||||
});
|
||||
|
||||
describe('isHTMLElement', () => {
|
||||
it('should return true for HTMLElement', () => {
|
||||
const htmlElement = document.createElement('div');
|
||||
expect(isHTMLElement(htmlElement)).toBeTruthy();
|
||||
});
|
||||
it('should return false for Element', () => {
|
||||
const svgElement = document.createElementNS('http://www.w3.org/2000/svg', 'circle');
|
||||
expect(isHTMLElement(svgElement)).toBeFalsy();
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user