Fix carousel forgetting its position in certain circumstances.
This commit is contained in:
+22
-10
@@ -44,6 +44,12 @@ export class FrigateCardCarousel extends LitElement {
|
|||||||
@property({ attribute: true })
|
@property({ attribute: true })
|
||||||
public transitionEffect?: TransitionEffect;
|
public transitionEffect?: TransitionEffect;
|
||||||
|
|
||||||
|
// An override to the startIndex, used to preserve the current carousel
|
||||||
|
// position after the carousel is destroyed (so it can be restored if
|
||||||
|
// recreated).
|
||||||
|
// See: https://github.com/dermotduffy/frigate-hass-card/issues/775
|
||||||
|
protected _savedStartIndex: number | null = null;
|
||||||
|
|
||||||
protected _refSlot: Ref<HTMLSlotElement> = createRef();
|
protected _refSlot: Ref<HTMLSlotElement> = createRef();
|
||||||
|
|
||||||
protected _carousel?: EmblaCarouselType;
|
protected _carousel?: EmblaCarouselType;
|
||||||
@@ -75,7 +81,7 @@ export class FrigateCardCarousel extends LitElement {
|
|||||||
// Destroy the carousel when the component is disconnected, which forces the
|
// Destroy the carousel when the component is disconnected, which forces the
|
||||||
// plugins (which may have registered event handlers) to also be destroyed.
|
// plugins (which may have registered event handlers) to also be destroyed.
|
||||||
// The carousel will automatically reconstruct if the component is re-rendered.
|
// The carousel will automatically reconstruct if the component is re-rendered.
|
||||||
this._destroyCarousel();
|
this._destroyCarousel({ savePosition: true });
|
||||||
super.disconnectedCallback();
|
super.disconnectedCallback();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -90,7 +96,7 @@ export class FrigateCardCarousel extends LitElement {
|
|||||||
'carouselPlugins',
|
'carouselPlugins',
|
||||||
] as const;
|
] as const;
|
||||||
if (destroyProperties.some((prop) => changedProps.has(prop))) {
|
if (destroyProperties.some((prop) => changedProps.has(prop))) {
|
||||||
this._destroyCarousel();
|
this._destroyCarousel({ savePosition: true });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -195,17 +201,19 @@ export class FrigateCardCarousel extends LitElement {
|
|||||||
updated(changedProperties: PropertyValues): void {
|
updated(changedProperties: PropertyValues): void {
|
||||||
super.updated(changedProperties);
|
super.updated(changedProperties);
|
||||||
|
|
||||||
if (!this._carousel) {
|
|
||||||
this.updateComplete.then(() => {
|
|
||||||
// Re-check for the carousel to prevent a double init.
|
|
||||||
if (!this._carousel) {
|
if (!this._carousel) {
|
||||||
this._initCarousel();
|
this._initCarousel();
|
||||||
}
|
}
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected _destroyCarousel(): void {
|
/**
|
||||||
|
* Destroy the carousel.
|
||||||
|
* @param options If `savePosition` is set the existing carousel position
|
||||||
|
* will be saved so it can be restored if the carousel is recreated.
|
||||||
|
*/
|
||||||
|
protected _destroyCarousel(options?: { savePosition: boolean }): void {
|
||||||
|
this._savedStartIndex =
|
||||||
|
(options?.savePosition ? this._carousel?.selectedScrollSnap() : null) ?? null;
|
||||||
if (this._carousel) {
|
if (this._carousel) {
|
||||||
this._carousel.destroy();
|
this._carousel.destroy();
|
||||||
}
|
}
|
||||||
@@ -234,6 +242,7 @@ export class FrigateCardCarousel extends LitElement {
|
|||||||
axis: this.direction == 'horizontal' ? 'x' : 'y',
|
axis: this.direction == 'horizontal' ? 'x' : 'y',
|
||||||
speed: 20,
|
speed: 20,
|
||||||
...this.carouselOptions,
|
...this.carouselOptions,
|
||||||
|
...(this._savedStartIndex && { startIndex: this._savedStartIndex }),
|
||||||
},
|
},
|
||||||
this.carouselPlugins,
|
this.carouselPlugins,
|
||||||
);
|
);
|
||||||
@@ -276,8 +285,11 @@ export class FrigateCardCarousel extends LitElement {
|
|||||||
*/
|
*/
|
||||||
protected _slotChanged(): void {
|
protected _slotChanged(): void {
|
||||||
// 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.
|
// changed, and only a carousel init can pass in new (slotted) children. If
|
||||||
this._destroyCarousel();
|
// the slides themselves change, any position the user has set is assumed to
|
||||||
|
// be abandoned and so the startIndex is reset to whatever the carousel was
|
||||||
|
// originally configured with.
|
||||||
|
this._destroyCarousel({ savePosition: false });
|
||||||
this.requestUpdate();
|
this.requestUpdate();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -284,9 +284,8 @@ export class FrigateCardLiveCarousel extends LitElement {
|
|||||||
const oldView = changedProperties.get('view') as View | undefined;
|
const oldView = changedProperties.get('view') as View | undefined;
|
||||||
if (
|
if (
|
||||||
frigateCardCarousel &&
|
frigateCardCarousel &&
|
||||||
oldView &&
|
|
||||||
this.view?.camera &&
|
this.view?.camera &&
|
||||||
this.view?.camera != oldView.camera
|
(!oldView || this.view?.camera !== oldView.camera)
|
||||||
) {
|
) {
|
||||||
const slide: number | undefined = this._cameraToSlide[this.view.camera];
|
const slide: number | undefined = this._cameraToSlide[this.view.camera];
|
||||||
if (
|
if (
|
||||||
|
|||||||
Reference in New Issue
Block a user