Add support for disabling zoom.
This commit is contained in:
@@ -26,7 +26,6 @@ import { View } from '../view/view.js';
|
||||
import { dispatchErrorMessageEvent } from './message.js';
|
||||
import { contentsChanged } from '../utils/basic.js';
|
||||
import isEqual from 'lodash-es/isEqual';
|
||||
import './zoomer.js';
|
||||
|
||||
// See TOKEN_CHANGE_INTERVAL in https://github.com/home-assistant/core/blob/dev/homeassistant/components/camera/__init__.py .
|
||||
const HASS_REJECTION_CUTOFF_MS = 5 * 60 * 1000;
|
||||
@@ -42,9 +41,6 @@ export class FrigateCardImage extends LitElement {
|
||||
@property({ attribute: false })
|
||||
public cameraConfig?: CameraConfig;
|
||||
|
||||
@property({ attribute: false })
|
||||
public supportZoom = false;
|
||||
|
||||
// Using contentsChanged to ensure overridden configs (e.g. when the
|
||||
// 'show_image_during_load' option is true for live views, an overridden
|
||||
// config may be used here).
|
||||
@@ -115,6 +111,10 @@ export class FrigateCardImage extends LitElement {
|
||||
);
|
||||
}
|
||||
updateElementStyleFromMediaLayoutConfig(this, this.imageConfig?.layout);
|
||||
|
||||
if (changedProps.has('imageConfig') && this.imageConfig?.zoomable) {
|
||||
import('./zoomer.js');
|
||||
}
|
||||
}
|
||||
|
||||
// If the camera or view changed, immediately discard the old value (view to
|
||||
@@ -235,10 +235,10 @@ export class FrigateCardImage extends LitElement {
|
||||
}
|
||||
}
|
||||
|
||||
protected _renderZoom(contents: TemplateResult): TemplateResult {
|
||||
return this.supportZoom
|
||||
? html` <frigate-card-zoomer>${contents}</frigate-card-zoomer>`
|
||||
: contents;
|
||||
protected _useZoomIfRequired(template: TemplateResult): TemplateResult {
|
||||
return this.imageConfig?.zoomable
|
||||
? html` <frigate-card-zoomer> ${template} </frigate-card-zoomer>`
|
||||
: template;
|
||||
}
|
||||
|
||||
protected render(): TemplateResult | void {
|
||||
@@ -246,7 +246,7 @@ export class FrigateCardImage extends LitElement {
|
||||
// Note the use of live() below to ensure the update will restore the image
|
||||
// src if it's been changed via _forceSafeImage().
|
||||
return src
|
||||
? this._renderZoom(html` <img
|
||||
? this._useZoomIfRequired(html` <img
|
||||
${ref(this._refImage)}
|
||||
src=${live(src)}
|
||||
@load=${(ev: Event) => {
|
||||
|
||||
@@ -59,6 +59,10 @@ export class FrigateCardLiveImage extends LitElement implements FrigateCardMedia
|
||||
mode: this.cameraConfig.image.url ? ('url' as const) : ('camera' as const),
|
||||
refresh_seconds: this._playing ? this.cameraConfig.image.refresh_seconds : 0,
|
||||
url: this.cameraConfig.image.url,
|
||||
|
||||
// The live provider will take care of zoom.
|
||||
zoomable: false,
|
||||
|
||||
// Don't need to pass layout options as FrigateCardLiveProvider has
|
||||
// already taken care of this for us.
|
||||
}}
|
||||
|
||||
+77
-64
@@ -54,7 +54,6 @@ import { dispatchErrorMessageEvent, dispatchMessageEvent } from '../message.js';
|
||||
import '../next-prev-control.js';
|
||||
import '../surround.js';
|
||||
import '../title-control.js';
|
||||
import '../zoomer.js';
|
||||
import { AutoMediaPlugin } from './../embla-plugins/automedia.js';
|
||||
import { Lazyload } from './../embla-plugins/lazyload.js';
|
||||
|
||||
@@ -525,7 +524,12 @@ export class FrigateCardLiveCarousel extends LitElement {
|
||||
cameraConfig: CameraConfig,
|
||||
slideIndex: number,
|
||||
): TemplateResult | void {
|
||||
if (!this.liveConfig || !this.hass || !this.cameraManager || !this.conditionControllerEpoch) {
|
||||
if (
|
||||
!this.liveConfig ||
|
||||
!this.hass ||
|
||||
!this.cameraManager ||
|
||||
!this.conditionControllerEpoch
|
||||
) {
|
||||
return;
|
||||
}
|
||||
// The condition controller object contains the currently live camera, which
|
||||
@@ -545,7 +549,9 @@ export class FrigateCardLiveCarousel extends LitElement {
|
||||
<div class="embla__slide">
|
||||
<frigate-card-live-provider
|
||||
?disabled=${this.liveConfig.lazy_load}
|
||||
.microphoneStream=${this.view?.camera === cameraID ? this.microphoneStream : undefined}
|
||||
.microphoneStream=${this.view?.camera === cameraID
|
||||
? this.microphoneStream
|
||||
: undefined}
|
||||
.cameraConfig=${cameraConfig}
|
||||
.cameraEndpoints=${guard(
|
||||
[this.cameraManager, cameraID],
|
||||
@@ -848,6 +854,9 @@ export class FrigateCardLiveProvider
|
||||
if (this.liveConfig?.show_image_during_load) {
|
||||
this._importPromises.push(import('./live-image.js'));
|
||||
}
|
||||
if (this.liveConfig?.zoomable) {
|
||||
this._importPromises.push(import('./../zoomer.js'));
|
||||
}
|
||||
}
|
||||
if (changedProps.has('cameraConfig')) {
|
||||
const provider = this._getResolvedProvider();
|
||||
@@ -874,6 +883,17 @@ export class FrigateCardLiveProvider
|
||||
return result;
|
||||
}
|
||||
|
||||
protected _useZoomIfRequired(template: TemplateResult): TemplateResult {
|
||||
return this.liveConfig?.zoomable
|
||||
? html` <frigate-card-zoomer
|
||||
@frigate-card:zoom:zoomed=${() => this.setControls(false)}
|
||||
@frigate-card:zoom:unzoomed=${() => this.setControls(true)}
|
||||
>
|
||||
${template}
|
||||
</frigate-card-zoomer>`
|
||||
: template;
|
||||
}
|
||||
|
||||
/**
|
||||
* Master render method.
|
||||
* @returns A rendered template.
|
||||
@@ -894,42 +914,36 @@ export class FrigateCardLiveProvider
|
||||
hidden: showImageDuringLoading,
|
||||
};
|
||||
|
||||
return html`
|
||||
<frigate-card-zoomer
|
||||
@frigate-card:zoom:zoomed=${() => this.setControls(false)}
|
||||
@frigate-card:zoom:unzoomed=${() => this.setControls(true)}
|
||||
>
|
||||
${showImageDuringLoading || provider === 'image'
|
||||
? html`
|
||||
<frigate-card-live-image
|
||||
${ref(this._refProvider)}
|
||||
.hass=${this.hass}
|
||||
.cameraConfig=${this.cameraConfig}
|
||||
@frigate-card:media:loaded=${(ev: Event) => {
|
||||
if (provider === 'image') {
|
||||
// Only count the media has loaded if the required provider is
|
||||
// the image (not just the temporary image shown during
|
||||
// loading).
|
||||
this._videoMediaShowHandler();
|
||||
} else {
|
||||
ev.stopPropagation();
|
||||
}
|
||||
}}
|
||||
>
|
||||
</frigate-card-live-image
|
||||
></frigate-card-zoomer>`
|
||||
: html``}
|
||||
${provider === 'ha'
|
||||
? html` <frigate-card-live-ha
|
||||
${ref(this._refProvider)}
|
||||
class=${classMap(providerClasses)}
|
||||
.hass=${this.hass}
|
||||
.cameraConfig=${this.cameraConfig}
|
||||
@frigate-card:media:loaded=${this._videoMediaShowHandler.bind(this)}
|
||||
>
|
||||
</frigate-card-live-ha>`
|
||||
: provider === 'go2rtc'
|
||||
? html`<frigate-card-live-go2rtc
|
||||
return this._useZoomIfRequired(html`
|
||||
${showImageDuringLoading || provider === 'image'
|
||||
? html` <frigate-card-live-image
|
||||
${ref(this._refProvider)}
|
||||
.hass=${this.hass}
|
||||
.cameraConfig=${this.cameraConfig}
|
||||
@frigate-card:media:loaded=${(ev: Event) => {
|
||||
if (provider === 'image') {
|
||||
// Only count the media has loaded if the required provider is
|
||||
// the image (not just the temporary image shown during
|
||||
// loading).
|
||||
this._videoMediaShowHandler();
|
||||
} else {
|
||||
ev.stopPropagation();
|
||||
}
|
||||
}}
|
||||
>
|
||||
</frigate-card-live-image>`
|
||||
: html``}
|
||||
${provider === 'ha'
|
||||
? html` <frigate-card-live-ha
|
||||
${ref(this._refProvider)}
|
||||
class=${classMap(providerClasses)}
|
||||
.hass=${this.hass}
|
||||
.cameraConfig=${this.cameraConfig}
|
||||
@frigate-card:media:loaded=${this._videoMediaShowHandler.bind(this)}
|
||||
>
|
||||
</frigate-card-live-ha>`
|
||||
: provider === 'go2rtc'
|
||||
? html`<frigate-card-live-go2rtc
|
||||
${ref(this._refProvider)}
|
||||
class=${classMap(providerClasses)}
|
||||
.hass=${this.hass}
|
||||
@@ -940,31 +954,30 @@ export class FrigateCardLiveProvider
|
||||
@frigate-card:media:loaded=${this._videoMediaShowHandler.bind(this)}
|
||||
>
|
||||
</frigate-card-live-webrtc-card>`
|
||||
: provider === 'webrtc-card'
|
||||
? html`<frigate-card-live-webrtc-card
|
||||
${ref(this._refProvider)}
|
||||
class=${classMap(providerClasses)}
|
||||
.hass=${this.hass}
|
||||
.cameraConfig=${this.cameraConfig}
|
||||
.cameraEndpoints=${this.cameraEndpoints}
|
||||
.cardWideConfig=${this.cardWideConfig}
|
||||
@frigate-card:media:loaded=${this._videoMediaShowHandler.bind(this)}
|
||||
>
|
||||
</frigate-card-live-webrtc-card>`
|
||||
: provider === 'jsmpeg'
|
||||
? html` <frigate-card-live-jsmpeg
|
||||
${ref(this._refProvider)}
|
||||
class=${classMap(providerClasses)}
|
||||
.hass=${this.hass}
|
||||
.cameraConfig=${this.cameraConfig}
|
||||
.cameraEndpoints=${this.cameraEndpoints}
|
||||
.cardWideConfig=${this.cardWideConfig}
|
||||
@frigate-card:media:loaded=${this._videoMediaShowHandler.bind(this)}
|
||||
>
|
||||
</frigate-card-live-jsmpeg>`
|
||||
: html``}
|
||||
</frigate-card-zoomer>
|
||||
`;
|
||||
: provider === 'webrtc-card'
|
||||
? html`<frigate-card-live-webrtc-card
|
||||
${ref(this._refProvider)}
|
||||
class=${classMap(providerClasses)}
|
||||
.hass=${this.hass}
|
||||
.cameraConfig=${this.cameraConfig}
|
||||
.cameraEndpoints=${this.cameraEndpoints}
|
||||
.cardWideConfig=${this.cardWideConfig}
|
||||
@frigate-card:media:loaded=${this._videoMediaShowHandler.bind(this)}
|
||||
>
|
||||
</frigate-card-live-webrtc-card>`
|
||||
: provider === 'jsmpeg'
|
||||
? html` <frigate-card-live-jsmpeg
|
||||
${ref(this._refProvider)}
|
||||
class=${classMap(providerClasses)}
|
||||
.hass=${this.hass}
|
||||
.cameraConfig=${this.cameraConfig}
|
||||
.cameraEndpoints=${this.cameraEndpoints}
|
||||
.cardWideConfig=${this.cardWideConfig}
|
||||
@frigate-card:media:loaded=${this._videoMediaShowHandler.bind(this)}
|
||||
>
|
||||
</frigate-card-live-jsmpeg>`
|
||||
: html``}
|
||||
`);
|
||||
}
|
||||
|
||||
static get styles(): CSSResultGroup {
|
||||
|
||||
+70
-61
@@ -47,7 +47,6 @@ import { MediaQueriesClassifier } from '../view/media-queries-classifier';
|
||||
import { MediaQueriesResults } from '../view/media-queries-results.js';
|
||||
import { VideoContentType, ViewMedia } from '../view/media.js';
|
||||
import { View } from '../view/view.js';
|
||||
import './zoomer.js';
|
||||
import type { CarouselSelect } from './carousel.js';
|
||||
import { AutoMediaPlugin } from './embla-plugins/automedia.js';
|
||||
import { Lazyload } from './embla-plugins/lazyload.js';
|
||||
@@ -683,6 +682,21 @@ export class FrigateCardViewerProvider
|
||||
this.requestUpdate();
|
||||
});
|
||||
}
|
||||
|
||||
if (changedProps.has('viewerConfig') && this.viewerConfig?.zoomable) {
|
||||
import('./zoomer.js');
|
||||
}
|
||||
}
|
||||
|
||||
protected _useZoomIfRequired(template: TemplateResult): TemplateResult {
|
||||
return this.viewerConfig?.zoomable
|
||||
? html` <frigate-card-zoomer
|
||||
@frigate-card:zoom:zoomed=${() => this.setControls(false)}
|
||||
@frigate-card:zoom:unzoomed=${() => this.setControls(true)}
|
||||
>
|
||||
${template}
|
||||
</frigate-card-zoomer>`
|
||||
: template;
|
||||
}
|
||||
|
||||
protected render(): TemplateResult | void {
|
||||
@@ -702,68 +716,63 @@ export class FrigateCardViewerProvider
|
||||
});
|
||||
}
|
||||
|
||||
return html`
|
||||
<frigate-card-zoomer
|
||||
@frigate-card:zoom:zoomed=${() => this.setControls(false)}
|
||||
@frigate-card:zoom:unzoomed=${() => this.setControls(true)}
|
||||
>
|
||||
${ViewMediaClassifier.isVideo(this.media)
|
||||
? this.media.getVideoContentType() === VideoContentType.HLS
|
||||
? html`<frigate-card-ha-hls-player
|
||||
${ref(this._refFrigateCardMediaPlayer)}
|
||||
allow-exoplayer
|
||||
aria-label="${this.media.getTitle() ?? ''}"
|
||||
?autoplay=${false}
|
||||
controls
|
||||
muted
|
||||
playsinline
|
||||
title="${this.media.getTitle() ?? ''}"
|
||||
url=${canonicalizeHAURL(this.hass, resolvedMedia?.url) ?? ''}
|
||||
.hass=${this.hass}
|
||||
>
|
||||
</frigate-card-ha-hls-player>`
|
||||
: html`
|
||||
<video
|
||||
${ref(this._refVideoProvider)}
|
||||
aria-label="${this.media.getTitle() ?? ''}"
|
||||
title="${this.media.getTitle() ?? ''}"
|
||||
muted
|
||||
controls
|
||||
playsinline
|
||||
?autoplay=${false}
|
||||
@loadedmetadata=${(ev: Event) => {
|
||||
if (ev.target) {
|
||||
hideMediaControlsTemporarily(
|
||||
ev.target as HTMLVideoElement,
|
||||
MEDIA_LOAD_CONTROLS_HIDE_SECONDS,
|
||||
);
|
||||
}
|
||||
}}
|
||||
@loadeddata=${(ev: Event) => {
|
||||
dispatchMediaLoadedEvent(this, ev);
|
||||
}}
|
||||
>
|
||||
<source
|
||||
src=${canonicalizeHAURL(this.hass, resolvedMedia?.url) ?? ''}
|
||||
type="video/mp4"
|
||||
/>
|
||||
</video>
|
||||
`
|
||||
: html`<img
|
||||
return this._useZoomIfRequired(html`
|
||||
${ViewMediaClassifier.isVideo(this.media)
|
||||
? this.media.getVideoContentType() === VideoContentType.HLS
|
||||
? html`<frigate-card-ha-hls-player
|
||||
${ref(this._refFrigateCardMediaPlayer)}
|
||||
allow-exoplayer
|
||||
aria-label="${this.media.getTitle() ?? ''}"
|
||||
src="${canonicalizeHAURL(this.hass, resolvedMedia?.url) ?? ''}"
|
||||
?autoplay=${false}
|
||||
controls
|
||||
muted
|
||||
playsinline
|
||||
title="${this.media.getTitle() ?? ''}"
|
||||
@click=${() => {
|
||||
if (this.viewerConfig?.snapshot_click_plays_clip) {
|
||||
this._dispatchRelatedClipView();
|
||||
}
|
||||
}}
|
||||
@load=${(e: Event) => {
|
||||
dispatchMediaLoadedEvent(this, e);
|
||||
}}
|
||||
/>`}
|
||||
</frigate-card-zoomer>
|
||||
`;
|
||||
url=${canonicalizeHAURL(this.hass, resolvedMedia?.url) ?? ''}
|
||||
.hass=${this.hass}
|
||||
>
|
||||
</frigate-card-ha-hls-player>`
|
||||
: html`
|
||||
<video
|
||||
${ref(this._refVideoProvider)}
|
||||
aria-label="${this.media.getTitle() ?? ''}"
|
||||
title="${this.media.getTitle() ?? ''}"
|
||||
muted
|
||||
controls
|
||||
playsinline
|
||||
?autoplay=${false}
|
||||
@loadedmetadata=${(ev: Event) => {
|
||||
if (ev.target) {
|
||||
hideMediaControlsTemporarily(
|
||||
ev.target as HTMLVideoElement,
|
||||
MEDIA_LOAD_CONTROLS_HIDE_SECONDS,
|
||||
);
|
||||
}
|
||||
}}
|
||||
@loadeddata=${(ev: Event) => {
|
||||
dispatchMediaLoadedEvent(this, ev);
|
||||
}}
|
||||
>
|
||||
<source
|
||||
src=${canonicalizeHAURL(this.hass, resolvedMedia?.url) ?? ''}
|
||||
type="video/mp4"
|
||||
/>
|
||||
</video>
|
||||
`
|
||||
: html`<img
|
||||
aria-label="${this.media.getTitle() ?? ''}"
|
||||
src="${canonicalizeHAURL(this.hass, resolvedMedia?.url) ?? ''}"
|
||||
title="${this.media.getTitle() ?? ''}"
|
||||
@click=${() => {
|
||||
if (this.viewerConfig?.snapshot_click_plays_clip) {
|
||||
this._dispatchRelatedClipView();
|
||||
}
|
||||
}}
|
||||
@load=${(e: Event) => {
|
||||
dispatchMediaLoadedEvent(this, e);
|
||||
}}
|
||||
/>`}
|
||||
`);
|
||||
}
|
||||
|
||||
static get styles(): CSSResultGroup {
|
||||
|
||||
Reference in New Issue
Block a user