Avoid carousel init duplication.
This commit is contained in:
@@ -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 }) || [];
|
||||||
|
|||||||
@@ -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
@@ -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;
|
||||||
|
|||||||
@@ -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();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user