Fullscreen improvements (esp. portrait media)

This commit is contained in:
Dermot Duffy
2021-09-26 14:05:06 -07:00
parent 2ab4e064f4
commit 7c0e0133ee
6 changed files with 63 additions and 21 deletions
+36 -12
View File
@@ -192,7 +192,7 @@ export class FrigateCard extends LitElement {
description: localize('menu.frigate_ui'),
});
}
if ((this.config.menu_buttons?.fullscreen ?? false) && screenfull.isEnabled) {
if ((this.config.menu_buttons?.fullscreen ?? true) && screenfull.isEnabled) {
buttons.set('fullscreen', {
icon: screenfull.isFullscreen ? 'mdi:fullscreen-exit' : 'mdi:fullscreen',
description: localize('menu.fullscreen'),
@@ -418,14 +418,15 @@ export class FrigateCard extends LitElement {
protected _getAspectRatioPadding(): number | null {
const aspect_ratio_mode = this.config.dimensions?.aspect_ratio_mode ?? 'dynamic';
// Do not constrain aspect ratio if either it's entire disabled or it's a
// media view (i.e. not the gallery) and there's a loaded media item in
// dynamic mode (as the aspect_ratio is essentially whatever the media
// dimensions are).
// Do not artifically constrain aspect ratio if:
// - It's fullscreen.
// - Aspect ratio enforcement is disabled.
// - Or it's a media view (i.e. not the gallery) and there's a loaded media
// item.
if (
(screenfull.isEnabled && screenfull.isFullscreen) ||
aspect_ratio_mode == 'unconstrained' ||
(!this._view.isGalleryView() && aspect_ratio_mode == 'dynamic' && this._mediaInfo)
(this._view.isMediaView() && aspect_ratio_mode == 'dynamic' && this._mediaInfo)
) {
return null;
}
@@ -452,11 +453,34 @@ export class FrigateCard extends LitElement {
}
const padding = this._getAspectRatioPadding();
let containerStyleMap = {};
const outerStyle = {}, innerStyle = {};
// Padding to force a particular aspect ratio.
if (padding != null) {
containerStyleMap = {
'padding-top': `${padding}%`,
};
outerStyle['padding-top'] = `${padding}%`;
}
// Special treatment required when:
//
// - It's in fullscreen mode
// - It's viewing a media clip
// - And the media clip is taller than wider (portrait)
//
// We cannot seem to scale the video by height in CSS without actually
// styling the underlying video element (which we do not have access to as
// it's buried past multiple shadow roots), so instead scale the width in
// terms of'vh' (viewport height) in proportion to the aspect-ratio of the
// media.
if (
screenfull.isEnabled &&
screenfull.isFullscreen &&
this._view.isMediaView() &&
this._mediaInfo &&
this._mediaInfo.width < this._mediaInfo.height
) {
innerStyle['max-width'] = `${
(100 * this._mediaInfo.width) / this._mediaInfo.height
}vh`;
}
const contentClasses = {
@@ -466,8 +490,8 @@ export class FrigateCard extends LitElement {
return html` <ha-card @click=${this._interactionHandler}>
${this.config.menu_mode == 'above' ? this._renderMenu() : ''}
<div class="container outer" style="${styleMap(containerStyleMap)}">
<div class="${classMap(contentClasses)}">
<div class="container outer" style="${styleMap(outerStyle)}">
<div class="${classMap(contentClasses)}" style="${styleMap(innerStyle)}">
${this._view.is('clips') || this._view.is('snapshots')
? html` <frigate-card-gallery
.hass=${this._hass}
+12
View File
@@ -386,6 +386,18 @@ export class FrigateCardEditor extends LitElement implements LovelaceCardEditor
@change=${this._valueChanged}
></ha-switch>
</ha-formfield>
<br />
<ha-formfield
.label=${localize('editor.show_button') +
': ' +
localize('menu.fullscreen')}
>
<ha-switch
.checked=${this._config?.menu_buttons?.frigate_ui ?? true}
.configValue=${'menu_buttons.fullscreen'}
@change=${this._valueChanged}
></ha-switch>
</ha-formfield>
<br />`
: ''}
<div class="option" @click=${this._toggleOption} .option=${'advanced'}>
+4 -2
View File
@@ -31,8 +31,10 @@ customElements.whenDefined("ha-hls-player").then(() => {
.muted=${this.muted}
?playsinline=${this.playsInline}
?controls=${this.controls}
@loadedmetadata=${(e) => dispatchMediaLoadEvent(this, e)}
@loadeddata=${this._elementResized}
@loadeddata=${(e) => {
this._elementResized();
dispatchMediaLoadEvent(this, e);
}}
@pause=${() => dispatchPauseEvent(this)}
@play=${() => dispatchPlayEvent(this)}
></video>
+6 -6
View File
@@ -2,19 +2,18 @@
position: relative;
overflow: auto;
height: 100%;
width: 100%;
margin: auto;
display: flex;
justify-content: center;
}
.frigate-card-contents {
width: 100%;
height: 100%;
margin: auto;
overflow: auto;
-ms-overflow-style: none; /* Hide scrollbar: IE and Edge */
scrollbar-width: none; /* Hide scrollbar: Firefox */
// Vertically align items in case the container is larger than the media (e.g.
// fullscreen mode, or forced aspect ratios).
display: flex;
align-items: center;
}
/* Hide scrollbar for Chrome, Safari and Opera */
@@ -61,6 +60,7 @@ ha-card a {
frigate-card-gallery, frigate-card-viewer, frigate-card-live {
width: 100%;
display: block;
}
frigate-card-gallery {
height: 100%;
+1 -1
View File
@@ -82,7 +82,7 @@ export const frigateCardConfigSchema = z.object({
clips: z.boolean().default(true),
snapshots: z.boolean().default(true),
frigate_ui: z.boolean().default(true),
fullscreen: z.boolean().default(false),
fullscreen: z.boolean().default(true),
})
.optional(),
entities: z
+4
View File
@@ -28,6 +28,10 @@ export class View {
return this.view == 'clips' || this.view == 'snapshots';
}
public isMediaView(): boolean {
return !this.isGalleryView();
}
get media(): BrowseMediaSource | undefined {
if (this.target) {
if (this.target.children && this.childIndex !== undefined) {