Avoid carousel init duplication.

This commit is contained in:
Dermot Duffy
2023-08-13 10:00:29 -07:00
parent c61ceb905d
commit b4595867b3
4 changed files with 42 additions and 16 deletions
+15 -3
View File
@@ -11,10 +11,11 @@ import {
} from 'lit'; } from 'lit';
import { customElement, property } from 'lit/decorators.js'; import { customElement, property } from 'lit/decorators.js';
import { Ref, createRef, ref } from 'lit/directives/ref.js'; import { Ref, createRef, ref } from 'lit/directives/ref.js';
import isEqual from 'lodash-es/isEqual';
import throttle from 'lodash-es/throttle'; import throttle from 'lodash-es/throttle';
import carouselStyle from '../scss/carousel.scss'; import carouselStyle from '../scss/carousel.scss';
import { TransitionEffect } from '../types'; import { TransitionEffect } from '../types';
import { dispatchFrigateCardEvent } from '../utils/basic.js'; import { dispatchFrigateCardEvent, isHTMLElement } from '../utils/basic.js';
export interface CarouselSelect { export interface CarouselSelect {
index: number; index: number;
@@ -175,6 +176,13 @@ export class FrigateCardCarousel extends LitElement {
this._carousel = undefined; this._carousel = undefined;
} }
protected _getSlideElements(): HTMLElement[] {
return (
this._refSlot.value?.assignedElements({ flatten: true }).filter(isHTMLElement) ??
[]
);
}
/** /**
* Initialize the carousel. * Initialize the carousel.
*/ */
@@ -187,7 +195,7 @@ export class FrigateCardCarousel extends LitElement {
root: carouselNode, root: carouselNode,
// As the slides are slotted, need to explicitly pull them out and pass // As the slides are slotted, need to explicitly pull them out and pass
// them to Embla. // them to Embla.
slides: this._refSlot.value?.assignedElements({ flatten: true }) as HTMLElement[], slides: this._getSlideElements(),
}; };
if (carouselNode && nodes.slides) { if (carouselNode && nodes.slides) {
@@ -256,11 +264,15 @@ export class FrigateCardCarousel extends LitElement {
* Called when the slotted children in the carousel change. * Called when the slotted children in the carousel change.
*/ */
protected _slotChanged(): void { protected _slotChanged(): void {
// 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 // Cannot just re-init, because the slide elements themselves may have
// changed, and only a carousel init can pass in new (slotted) children. If // changed, and only a carousel init can pass in new (slotted) children.
this._destroyCarousel(); this._destroyCarousel();
this.requestUpdate(); this.requestUpdate();
} }
}
protected render(): TemplateResult | void { protected render(): TemplateResult | void {
const slides = this._refSlot.value?.assignedElements({ flatten: true }) || []; const slides = this._refSlot.value?.assignedElements({ flatten: true }) || [];
-4
View File
@@ -1,8 +1,4 @@
// TODO: Performance of video scanning (pause/play?) // 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 { import {
CSSResultGroup, CSSResultGroup,
+7 -1
View File
@@ -225,4 +225,10 @@ export const setOrRemoveAttribute = (
/** /**
* Allow typescript to narrow types based on truthy filter. * 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;
+16 -4
View File
@@ -8,7 +8,7 @@ import {
dayToDate, dayToDate,
dispatchFrigateCardEvent, dispatchFrigateCardEvent,
errorToConsole, errorToConsole,
filterTruthy, isTruthy,
formatDate, formatDate,
formatDateAndTime, formatDateAndTime,
getDurationString, getDurationString,
@@ -20,6 +20,7 @@ import {
setify, setify,
setOrRemoveAttribute, setOrRemoveAttribute,
sleep, sleep,
isHTMLElement,
} from '../../src/utils/basic'; } from '../../src/utils/basic';
// @vitest-environment jsdom // @vitest-environment jsdom
@@ -248,11 +249,22 @@ describe('setOrRemoveAttribute', () => {
}); });
}); });
describe('filterTruthy', () => { describe('isTruthy', () => {
it('should return true for true', () => { it('should return true for true', () => {
expect(filterTruthy(true)).toBeTruthy(); expect(isTruthy(true)).toBeTruthy();
}); });
it('should return false for false', () => { 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();
}); });
}); });