Add support for expanding the card without fullscreen.
This commit is contained in:
@@ -12,6 +12,7 @@ import { copyConfig } from './config-mgmt';
|
||||
export interface ConditionState {
|
||||
view?: string;
|
||||
fullscreen?: boolean;
|
||||
expand?: boolean;
|
||||
camera?: string;
|
||||
state?: HassEntities;
|
||||
media_loaded?: boolean;
|
||||
@@ -37,6 +38,10 @@ function evaluateCondition(
|
||||
result &&=
|
||||
state.fullscreen !== undefined && condition.fullscreen == state.fullscreen;
|
||||
}
|
||||
if (condition?.expand !== undefined) {
|
||||
result &&=
|
||||
state.expand !== undefined && condition.expand == state.expand;
|
||||
}
|
||||
if (condition?.camera?.length) {
|
||||
result &&= !!state.camera && condition.camera.includes(state.camera);
|
||||
}
|
||||
|
||||
+59
-5
@@ -91,6 +91,7 @@ import cloneDeep from 'lodash-es/cloneDeep';
|
||||
import isEqual from 'lodash-es/isEqual';
|
||||
import merge from 'lodash-es/merge';
|
||||
import { FrigateCardInitializer } from './utils/initializer.js';
|
||||
import 'web-dialog';
|
||||
|
||||
/** A note on media callbacks:
|
||||
*
|
||||
@@ -175,6 +176,9 @@ class FrigateCard extends LitElement {
|
||||
@property({ attribute: 'panel', type: Boolean, reflect: true })
|
||||
protected _panel = false;
|
||||
|
||||
@state()
|
||||
protected _expand?: boolean = false;
|
||||
|
||||
protected _conditionState?: ConditionState;
|
||||
|
||||
protected _refMenu: Ref<FrigateCardMenu> = createRef();
|
||||
@@ -294,6 +298,7 @@ class FrigateCard extends LitElement {
|
||||
this._conditionState = {
|
||||
view: this._view?.view,
|
||||
fullscreen: screenfull.isEnabled && screenfull.isFullscreen,
|
||||
expand: this._expand,
|
||||
camera: this._view?.camera,
|
||||
media_loaded: !!this._currentMediaLoadedInfo,
|
||||
...(this._conditionManager?.hasHAStateConditions && {
|
||||
@@ -622,6 +627,17 @@ class FrigateCard extends LitElement {
|
||||
});
|
||||
}
|
||||
|
||||
buttons.push({
|
||||
icon: this._expand ? 'mdi:arrow-collapse-all' : 'mdi:arrow-expand-all',
|
||||
...this._getConfig().menu.buttons.expand,
|
||||
type: 'custom:frigate-card-menu-icon',
|
||||
title: localize('config.menu.buttons.expand'),
|
||||
tap_action: createFrigateCardCustomAction(
|
||||
'expand_toggle',
|
||||
) as FrigateCardCustomAction,
|
||||
style: this._expand ? this._getEmphasizedStyle() : {},
|
||||
});
|
||||
|
||||
if (
|
||||
this._mediaPlayers?.length &&
|
||||
(this._view?.isViewerView() ||
|
||||
@@ -1510,6 +1526,9 @@ class FrigateCard extends LitElement {
|
||||
case 'diagnostics':
|
||||
this._diagnostics();
|
||||
break;
|
||||
case 'expand_toggle':
|
||||
this._setExpand(!this._expand);
|
||||
break;
|
||||
default:
|
||||
console.warn(`Frigate card received unknown card action: ${action}`);
|
||||
}
|
||||
@@ -1784,6 +1803,13 @@ class FrigateCard extends LitElement {
|
||||
|
||||
this._lastValidMediaLoadedInfo = this._currentMediaLoadedInfo = mediaLoadedInfo;
|
||||
|
||||
// When a new media loads, set the aspect ratio for when the card is
|
||||
// expanded/popped-up.
|
||||
this.style.setProperty(
|
||||
'--frigate-card-expand-aspect-ratio',
|
||||
this._getAspectRatioStyle(),
|
||||
);
|
||||
|
||||
// An update may be required to draw elements.
|
||||
this._generateConditionState();
|
||||
this.requestUpdate();
|
||||
@@ -1869,12 +1895,20 @@ class FrigateCard extends LitElement {
|
||||
* @returns A padding percentage.
|
||||
*/
|
||||
protected _getAspectRatioStyle(): string {
|
||||
if (!this._isAspectRatioEnforced()) {
|
||||
// In expanded mode we must always set the aspect ratio since there are no
|
||||
// constraints on the size.
|
||||
|
||||
if (!this._expand && !this._isAspectRatioEnforced()) {
|
||||
return 'auto';
|
||||
}
|
||||
|
||||
const aspectRatioMode = this._getConfig().dimensions.aspect_ratio_mode;
|
||||
if (aspectRatioMode == 'dynamic' && this._lastValidMediaLoadedInfo) {
|
||||
|
||||
if (
|
||||
this._lastValidMediaLoadedInfo &&
|
||||
(aspectRatioMode === 'dynamic' ||
|
||||
(this._expand && aspectRatioMode === 'unconstrained'))
|
||||
) {
|
||||
return `${this._lastValidMediaLoadedInfo.width} / ${this._lastValidMediaLoadedInfo.height}`;
|
||||
}
|
||||
|
||||
@@ -1914,6 +1948,27 @@ class FrigateCard extends LitElement {
|
||||
return { ...this._getConfig().view.actions, ...specificActions };
|
||||
}
|
||||
|
||||
protected _setExpand(expand: boolean): void {
|
||||
this._expand = expand;
|
||||
this._generateConditionState();
|
||||
}
|
||||
|
||||
protected _renderInDialogIfNecessary(contents: TemplateResult): TemplateResult | void {
|
||||
if (this._expand) {
|
||||
return html` <web-dialog
|
||||
open
|
||||
center
|
||||
@close=${() => {
|
||||
this._setExpand(false);
|
||||
}}
|
||||
>
|
||||
${contents}
|
||||
</web-dialog>`;
|
||||
} else {
|
||||
return contents;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Master render method for the card.
|
||||
*/
|
||||
@@ -1947,8 +2002,7 @@ class FrigateCard extends LitElement {
|
||||
|
||||
// Caution: Keep the main div and the menu next to one another in order to
|
||||
// ensure the hover menu styling continues to work.
|
||||
|
||||
return html` <ha-card
|
||||
return this._renderInDialogIfNecessary(html` <ha-card
|
||||
id="ha-card"
|
||||
.actionHandler=${actionHandler({
|
||||
hasHold: frigateCardHasAction(actions.hold_action),
|
||||
@@ -1999,7 +2053,7 @@ class FrigateCard extends LitElement {
|
||||
>
|
||||
</frigate-card-elements>`
|
||||
: ``}
|
||||
</ha-card>`;
|
||||
</ha-card>`);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -206,7 +206,7 @@ export class FrigateCardCarousel extends LitElement {
|
||||
nodes,
|
||||
{
|
||||
axis: this.direction == 'horizontal' ? 'x' : 'y',
|
||||
speed: 20,
|
||||
speed: 30,
|
||||
startIndex: this.selected,
|
||||
...this.carouselOptions,
|
||||
},
|
||||
|
||||
@@ -1657,6 +1657,7 @@ export class FrigateCardEditor extends LitElement implements LovelaceCardEditor
|
||||
${this._renderMenuButton('download')}
|
||||
${this._renderMenuButton('camera_ui')}
|
||||
${this._renderMenuButton('fullscreen')}
|
||||
${this._renderMenuButton('expand')}
|
||||
${this._renderMenuButton('timeline')}
|
||||
${this._renderMenuButton('media_player')}
|
||||
</div>
|
||||
|
||||
@@ -240,6 +240,7 @@
|
||||
"clips": "Clips",
|
||||
"download": "Download",
|
||||
"enabled": "Button enabled",
|
||||
"expand": "Expand",
|
||||
"frigate": "Frigate menu / Default view",
|
||||
"fullscreen": "Fullscreen",
|
||||
"icon": "Icon",
|
||||
|
||||
@@ -239,6 +239,7 @@
|
||||
"clips": "Clip",
|
||||
"download": "Download",
|
||||
"enabled": "Pulsante abilitato",
|
||||
"expand": "",
|
||||
"frigate": "Frigate menu / Visualizzazione predefinita",
|
||||
"fullscreen": "A schermo intero",
|
||||
"icon": "Icona",
|
||||
|
||||
@@ -239,6 +239,7 @@
|
||||
"clips": "Clipes",
|
||||
"download": "Baixe a mídia do evento",
|
||||
"enabled": "Botão ativado",
|
||||
"expand": "",
|
||||
"frigate": "Frigate menu / Visualização padrão",
|
||||
"fullscreen": "Tela cheia",
|
||||
"icon": "Ícone",
|
||||
|
||||
@@ -85,6 +85,8 @@ ha-card {
|
||||
flex-direction: column;
|
||||
margin: auto;
|
||||
|
||||
border: 0px;
|
||||
|
||||
// Some elements (such as submenus) may need to extend beyond the card boundary.
|
||||
overflow: visible;
|
||||
width: 100%;
|
||||
@@ -151,3 +153,30 @@ frigate-card-live.hidden {
|
||||
:host(:-webkit-full-screen) frigate-card-menu {
|
||||
@include fullscreen-no-rounded-corners;
|
||||
}
|
||||
|
||||
/***************
|
||||
* Expanded mode
|
||||
***************/
|
||||
|
||||
web-dialog {
|
||||
--dialog-padding: 0px;
|
||||
--dialog-container-padding: 0px;
|
||||
|
||||
// The standard HA header is 56 pixels wide, so that much off the top (header)
|
||||
// and bottom (to maintain center), before doing the calculation of
|
||||
// max-height. This matters on small mobile devices in landscape orientation.
|
||||
--dialog-max-height: calc( ( 100vh - (2 * 56px) ) * 0.85 );
|
||||
--dialog-max-width: 85vw;
|
||||
|
||||
--dialog-width: none;
|
||||
--dialog-height: none;
|
||||
|
||||
// Allow submenus to flow outside the edge of the dialog.
|
||||
--dialog-overflow-x: visible;
|
||||
--dialog-overflow-y: visible;
|
||||
}
|
||||
|
||||
web-dialog::part(dialog) {
|
||||
aspect-ratio: var(--frigate-card-expand-aspect-ratio);
|
||||
height: 100%;
|
||||
}
|
||||
+12
-8
@@ -208,21 +208,22 @@ const frigateCardCustomActionsBaseSchema = customActionSchema.extend({
|
||||
});
|
||||
|
||||
const FRIGATE_CARD_GENERAL_ACTIONS = [
|
||||
'default',
|
||||
'camera_ui',
|
||||
'clip',
|
||||
'clips',
|
||||
'default',
|
||||
'diagnostics',
|
||||
'expand_toggle',
|
||||
'download',
|
||||
'fullscreen',
|
||||
'image',
|
||||
'live',
|
||||
'menu_toggle',
|
||||
'recording',
|
||||
'recordings',
|
||||
'snapshot',
|
||||
'snapshots',
|
||||
'timeline',
|
||||
'download',
|
||||
'camera_ui',
|
||||
'fullscreen',
|
||||
'menu_toggle',
|
||||
'diagnostics',
|
||||
'recording',
|
||||
'recordings',
|
||||
] as const;
|
||||
const FRIGATE_CARD_ACTIONS = [
|
||||
...FRIGATE_CARD_GENERAL_ACTIONS,
|
||||
@@ -580,6 +581,7 @@ export type MenuItem = MenuIcon | MenuStateIcon | MenuSubmenu | MenuSubmenuSelec
|
||||
const frigateCardConditionSchema = z.object({
|
||||
view: z.string().array().optional(),
|
||||
fullscreen: z.boolean().optional(),
|
||||
expand: z.boolean().optional(),
|
||||
camera: z.string().array().optional(),
|
||||
media_loaded: z.boolean().optional(),
|
||||
state: stateConditions.optional(),
|
||||
@@ -972,6 +974,7 @@ const menuConfigDefault = {
|
||||
download: visibleButtonDefault,
|
||||
camera_ui: visibleButtonDefault,
|
||||
fullscreen: visibleButtonDefault,
|
||||
expand: hiddenButtonDefault,
|
||||
media_player: visibleButtonDefault,
|
||||
recordings: hiddenButtonDefault,
|
||||
},
|
||||
@@ -1005,6 +1008,7 @@ const menuConfigSchema = z
|
||||
download: visibleButtonSchema.default(menuConfigDefault.buttons.download),
|
||||
camera_ui: visibleButtonSchema.default(menuConfigDefault.buttons.camera_ui),
|
||||
fullscreen: visibleButtonSchema.default(menuConfigDefault.buttons.fullscreen),
|
||||
expand: hiddenButtonSchema.default(menuConfigDefault.buttons.expand),
|
||||
media_player: visibleButtonSchema.default(
|
||||
menuConfigDefault.buttons.media_player,
|
||||
),
|
||||
|
||||
Reference in New Issue
Block a user