Fix carousel resizing in certain circumstances.

This commit is contained in:
Dermot Duffy
2022-02-01 21:57:28 -08:00
parent 322a44c2c7
commit 2ea25a4a99
3 changed files with 19 additions and 19 deletions
+1 -1
View File
@@ -105,7 +105,7 @@ export class FrigateCardGalleryCore extends LitElement {
*/ */
connectedCallback(): void { connectedCallback(): void {
super.connectedCallback(); super.connectedCallback();
this._resizeObserver?.observe(this); this._resizeObserver.observe(this);
} }
/** /**
+17 -17
View File
@@ -30,6 +30,16 @@ export class FrigateCardMediaCarousel extends FrigateCardCarousel {
protected _titleControlRef: Ref<FrigateCardTitleControl> = createRef(); protected _titleControlRef: Ref<FrigateCardTitleControl> = createRef();
protected _titleTimerID: number | null = null; protected _titleTimerID: number | null = null;
// This carousel may be resized by Lovelace resizes, window resizes,
// fullscreen, etc. Always call the adaptive height handler when the size
// changes.
protected _resizeObserver: ResizeObserver;
constructor() {
super();
this._resizeObserver = new ResizeObserver(this._adaptiveHeightHandler.bind(this));
}
/** /**
* Play the media on the selected slide. May be overridden to control when * Play the media on the selected slide. May be overridden to control when
* autoplay should happen. * autoplay should happen.
@@ -42,7 +52,7 @@ export class FrigateCardMediaCarousel extends FrigateCardCarousel {
* Unmute the media on the selected slide. May be overridden to control when * Unmute the media on the selected slide. May be overridden to control when
* autoplay should happen. * autoplay should happen.
*/ */
protected _autoUnmuteHandler(): void { protected _autoUnmuteHandler(): void {
(this._plugins['AutoMediaPlugin'] as AutoMediaPluginType | undefined)?.unmute(); (this._plugins['AutoMediaPlugin'] as AutoMediaPluginType | undefined)?.unmute();
} }
@@ -81,6 +91,7 @@ export class FrigateCardMediaCarousel extends FrigateCardCarousel {
this.addEventListener('frigate-card:media-show', this._autoUnmuteHandler); this.addEventListener('frigate-card:media-show', this._autoUnmuteHandler);
this.addEventListener('frigate-card:media-show', this._adaptiveHeightHandler); this.addEventListener('frigate-card:media-show', this._adaptiveHeightHandler);
this.addEventListener('frigate-card:media-show', this._titleHandler); this.addEventListener('frigate-card:media-show', this._titleHandler);
this._resizeObserver.observe(this);
} }
/** /**
@@ -92,6 +103,7 @@ export class FrigateCardMediaCarousel extends FrigateCardCarousel {
this.removeEventListener('frigate-card:media-show', this._autoUnmuteHandler); this.removeEventListener('frigate-card:media-show', this._autoUnmuteHandler);
this.removeEventListener('frigate-card:media-show', this._adaptiveHeightHandler); this.removeEventListener('frigate-card:media-show', this._adaptiveHeightHandler);
this.removeEventListener('frigate-card:media-show', this._titleHandler); this.removeEventListener('frigate-card:media-show', this._titleHandler);
this._resizeObserver.disconnect();
} }
protected _destroyCarousel(): void { protected _destroyCarousel(): void {
@@ -138,37 +150,25 @@ export class FrigateCardMediaCarousel extends FrigateCardCarousel {
if (!this._carousel) { if (!this._carousel) {
return; return;
} }
const slide = this._carousel?.selectedScrollSnap() const slide = this._carousel?.selectedScrollSnap();
if (slide !== undefined) { if (slide !== undefined) {
this._carousel.containerNode().style.removeProperty('max-height');
const slides = this._carousel.slideNodes(); const slides = this._carousel.slideNodes();
const height = slides[slide].getBoundingClientRect().height; const height = slides[slide].getBoundingClientRect().height;
if (height > 0) { if (height > 0) {
this._carousel.containerNode().style.maxHeight = `${height}px`; this._carousel.containerNode().style.maxHeight = `${height}px`;
} else {
this._carousel.containerNode().style.removeProperty('max-height');
} }
} }
}; };
// Hack: This method attempts to measure the height of the slides in view in // Hack: This method attempts to measure the height of the selected slide in
// order to set the overall carousel height to match. This method is // order to set the overall carousel height to match. This method is
// triggered from `frigate-card:media-show` events, which are usually in // triggered from `frigate-card:media-show` events, which are usually in
// turn triggered from media/metadata load events from media players. // turn triggered from media/metadata load events from media players.
// Sufficient time needs to be allowed after these metadata load events to // Sufficient time needs to be allowed after these metadata load events to
// allow the browser to repaint the element heights, so that we can get the // allow the browser to repaint the element heights, so that we can get the
// right values here. requestAnimationFrame() works well in most cases -- // right values here. requestAnimationFrame() works well for this.
// except for (at least) the Home Assistant Android Companion app. For that
// case, waiting longer appears to make a difference and reliably gets the
// carousel to the correct height (the litmus test case is: In the Android
// app, choose a live view and while it's loading, click the fullscreen
// button. Without a short delay here, it will calculate the sizes relative
// to the pre-fullscreen height).
//
// As this call is cheap, we use both the requestAnimationFrame() and
// setTimeout() approaches in parallel to ensure immediate response in a
// browser, and slightly slower (but correct) response in the Companion app.
window.requestAnimationFrame(adaptCarouselHeight); window.requestAnimationFrame(adaptCarouselHeight);
window.setTimeout(adaptCarouselHeight, 500);
} }
/** /**
+1 -1
View File
@@ -8,5 +8,5 @@
webrtc-camera ha-card { webrtc-camera ha-card {
box-shadow: none; box-shadow: none;
border-radius: 0px; border-radius: 0px;
background-color: var(--secondary-background-color, black); background-color: black;
} }