Add support for top, left, bottom, right menus.
This commit is contained in:
+8
-2
@@ -105,8 +105,14 @@ export class FrigateCardEditor extends LitElement implements LovelaceCardEditor
|
|||||||
|
|
||||||
const menuModes = {
|
const menuModes = {
|
||||||
'': '',
|
'': '',
|
||||||
hidden: 'Hidden',
|
'hidden-top': 'Hidden Top',
|
||||||
overlay: 'Overlay',
|
'hidden-left': 'Hidden Left',
|
||||||
|
'hidden-bottom': 'Hidden Bottom',
|
||||||
|
'hidden-right': 'Hidden Right',
|
||||||
|
'overlay-top': 'Overlay Top',
|
||||||
|
'overlay-left': 'Overlay Left',
|
||||||
|
'overlay-bottom': 'Overlay Bottom',
|
||||||
|
'overlay-right': 'Overlay Right',
|
||||||
above: 'Above',
|
above: 'Above',
|
||||||
below: 'Below',
|
below: 'Below',
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
/* Base: Not used directly */
|
.frigate-card-menu {
|
||||||
.frigate-card-menu-base {
|
|
||||||
z-index: 1;
|
z-index: 1;
|
||||||
height: 56px;
|
height: 56px;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
@@ -8,24 +7,32 @@
|
|||||||
*/
|
*/
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
}
|
}
|
||||||
|
.frigate-card-menu.overlay-hidden {
|
||||||
/* Small 'F' button for hidden menu */
|
|
||||||
.frigate-card-menu-hidden {
|
|
||||||
@extend .frigate-card-menu-base;
|
|
||||||
position: absolute;
|
position: absolute;
|
||||||
width: 56px;
|
width: 56px;
|
||||||
}
|
}
|
||||||
|
.frigate-card-menu.overlay-hidden.left {
|
||||||
/* Expanded overlay menu */
|
left: 0px;
|
||||||
.frigate-card-menu-overlay {
|
}
|
||||||
@extend .frigate-card-menu-hidden;
|
.frigate-card-menu.overlay-hidden.right {
|
||||||
|
right: 0px;
|
||||||
|
}
|
||||||
|
.frigate-card-menu.overlay-hidden.top {
|
||||||
|
top: 0px;
|
||||||
|
}
|
||||||
|
.frigate-card-menu.overlay-hidden.bottom {
|
||||||
|
bottom: 0px;
|
||||||
|
}
|
||||||
|
.frigate-card-menu.overlay-hidden.expanded-horizontal {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
background: linear-gradient(90deg, rgba(0,0,0,0.3), rgba(0,0,0,0))
|
background: linear-gradient(90deg, rgba(0,0,0,0.3), rgba(0,0,0,0));
|
||||||
|
}
|
||||||
|
.frigate-card-menu.overlay-hidden.expanded-vertical {
|
||||||
|
height: 100%;
|
||||||
|
background: linear-gradient(180deg, rgba(0,0,0,0.3), rgba(0,0,0,0));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Full above/below menu */
|
/* Full above/below menu */
|
||||||
.frigate-card-menu-full {
|
.frigate-card-menu.full {
|
||||||
@extend .frigate-card-menu-base;
|
|
||||||
width: 100%;
|
width: 100%;
|
||||||
background: var(--secondary-background-color);
|
background: var(--secondary-background-color);
|
||||||
}
|
}
|
||||||
@@ -44,7 +51,6 @@ ha-icon-button.button {
|
|||||||
pointer-events: auto;
|
pointer-events: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
ha-icon-button.emphasized-button {
|
ha-icon-button.button.emphasize {
|
||||||
@extend ha-icon-button, .button;
|
|
||||||
color: var(--primary-color, white);
|
color: var(--primary-color, white);
|
||||||
}
|
}
|
||||||
@@ -102,15 +102,15 @@ webrtc-camera ha-card {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.frigate-media-controls.previous {
|
.frigate-media-controls.previous {
|
||||||
left: 20px;
|
left: 50px;
|
||||||
}
|
}
|
||||||
.frigate-media-controls.previous:hover {
|
.frigate-media-controls.previous:hover {
|
||||||
left: 8px;
|
left: 38px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.frigate-media-controls.next {
|
.frigate-media-controls.next {
|
||||||
right: 20px;
|
right: 50px;
|
||||||
}
|
}
|
||||||
.frigate-media-controls.next:hover {
|
.frigate-media-controls.next:hover {
|
||||||
right: 8px;
|
right: 38px;
|
||||||
}
|
}
|
||||||
+30
-16
@@ -14,6 +14,7 @@ import {
|
|||||||
|
|
||||||
import { NodePart } from 'lit-html';
|
import { NodePart } from 'lit-html';
|
||||||
import { until } from 'lit-html/directives/until.js';
|
import { until } from 'lit-html/directives/until.js';
|
||||||
|
import { classMap } from 'lit-html/directives/class-map.js';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
HomeAssistant,
|
HomeAssistant,
|
||||||
@@ -107,7 +108,7 @@ export class FrigateCardMenu extends LitElement {
|
|||||||
static FRIGATE_CARD_MENU_ID: string = 'frigate-card-menu-id' as const;
|
static FRIGATE_CARD_MENU_ID: string = 'frigate-card-menu-id' as const;
|
||||||
|
|
||||||
@property({ attribute: false })
|
@property({ attribute: false })
|
||||||
protected menuMode: FrigateMenuMode = 'hidden';
|
protected menuMode: FrigateMenuMode = 'hidden-top';
|
||||||
|
|
||||||
@property({ attribute: false })
|
@property({ attribute: false })
|
||||||
protected expand = false;
|
protected expand = false;
|
||||||
@@ -120,7 +121,7 @@ export class FrigateCardMenu extends LitElement {
|
|||||||
|
|
||||||
// Call the callback.
|
// Call the callback.
|
||||||
protected _callAction(name: string): void {
|
protected _callAction(name: string): void {
|
||||||
if (this.menuMode == 'hidden') {
|
if (this.menuMode.startsWith('hidden-')) {
|
||||||
if (name == 'frigate') {
|
if (name == 'frigate') {
|
||||||
this.expand = !this.expand;
|
this.expand = !this.expand;
|
||||||
return;
|
return;
|
||||||
@@ -136,8 +137,13 @@ export class FrigateCardMenu extends LitElement {
|
|||||||
|
|
||||||
// Render a menu button.
|
// Render a menu button.
|
||||||
protected _renderButton(name: string, button: MenuButton): TemplateResult {
|
protected _renderButton(name: string, button: MenuButton): TemplateResult {
|
||||||
|
const classes = {
|
||||||
|
button: true,
|
||||||
|
emphasize: button.emphasize ?? false,
|
||||||
|
};
|
||||||
|
|
||||||
return html` <ha-icon-button
|
return html` <ha-icon-button
|
||||||
class=${button.emphasize ? 'emphasized-button' : 'button'}
|
class="${classMap(classes)}"
|
||||||
icon=${button.icon || 'mdi:gesture-tap-button'}
|
icon=${button.icon || 'mdi:gesture-tap-button'}
|
||||||
data-toggle="tooltip"
|
data-toggle="tooltip"
|
||||||
title=${button.description}
|
title=${button.description}
|
||||||
@@ -148,26 +154,34 @@ export class FrigateCardMenu extends LitElement {
|
|||||||
// Render the Frigate menu button.
|
// Render the Frigate menu button.
|
||||||
protected _renderFrigateButton(name: string, button: MenuButton): TemplateResult {
|
protected _renderFrigateButton(name: string, button: MenuButton): TemplateResult {
|
||||||
const icon =
|
const icon =
|
||||||
this.menuMode != 'hidden' || this.expand
|
this.menuMode.startsWith('hidden-') && !this.expand
|
||||||
? 'mdi:alpha-f-box'
|
? 'mdi:alpha-f-box-outline'
|
||||||
: 'mdi:alpha-f-box-outline';
|
: 'mdi:alpha-f-box';
|
||||||
|
|
||||||
return this._renderButton(name, Object.assign({}, button, { icon: icon }));
|
return this._renderButton(name, Object.assign({}, button, { icon: icon }));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Render the menu.
|
// Render the menu.
|
||||||
protected render(): TemplateResult | void | ((part: NodePart) => Promise<void>) {
|
protected render(): TemplateResult | void | ((part: NodePart) => Promise<void>) {
|
||||||
let menuClass = 'frigate-card-menu-full';
|
const classes = {
|
||||||
if (['hidden', 'overlay'].includes(this.menuMode)) {
|
'frigate-card-menu': true,
|
||||||
if (this.menuMode == 'overlay' || this.expand) {
|
'overlay-hidden':
|
||||||
menuClass = 'frigate-card-menu-overlay';
|
this.menuMode.startsWith('hidden-') || this.menuMode.startsWith('overlay-'),
|
||||||
} else {
|
'expanded-horizontal':
|
||||||
menuClass = 'frigate-card-menu-hidden';
|
(this.menuMode.startsWith('overlay-') || this.expand) &&
|
||||||
}
|
(this.menuMode.endsWith('-top') || this.menuMode.endsWith('-bottom')),
|
||||||
}
|
'expanded-vertical':
|
||||||
|
(this.menuMode.startsWith('overlay-') || this.expand) &&
|
||||||
|
(this.menuMode.endsWith('-left') || this.menuMode.endsWith('-right')),
|
||||||
|
full: ['above', 'below'].includes(this.menuMode),
|
||||||
|
left: this.menuMode.endsWith('-left'),
|
||||||
|
right: this.menuMode.endsWith('-right'),
|
||||||
|
top: this.menuMode.endsWith('-top'),
|
||||||
|
bottom: this.menuMode.endsWith('-bottom'),
|
||||||
|
};
|
||||||
|
|
||||||
return html`
|
return html`
|
||||||
<div class=${menuClass}>
|
<div class=${classMap(classes)}>
|
||||||
${Array.from(this.buttons.keys()).map((name) => {
|
${Array.from(this.buttons.keys()).map((name) => {
|
||||||
const button = this.buttons.get(name);
|
const button = this.buttons.get(name);
|
||||||
if (button) {
|
if (button) {
|
||||||
@@ -523,7 +537,7 @@ export class FrigateCard extends LitElement {
|
|||||||
outlined=""
|
outlined=""
|
||||||
class="frigate-card-image-list-folder"
|
class="frigate-card-image-list-folder"
|
||||||
>
|
>
|
||||||
<ha-icon .icon=${"mdi:arrow-left"}></ha-icon>
|
<ha-icon .icon=${'mdi:arrow-left'}></ha-icon>
|
||||||
</ha-card>
|
</ha-card>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
+9
-3
@@ -25,8 +25,14 @@ export const FRIGATE_CARD_VIEWS = [
|
|||||||
export type FrigateCardView = typeof FRIGATE_CARD_VIEWS[number];
|
export type FrigateCardView = typeof FRIGATE_CARD_VIEWS[number];
|
||||||
|
|
||||||
export const FRIGATE_MENU_MODES = [
|
export const FRIGATE_MENU_MODES = [
|
||||||
'hidden',
|
'hidden-top',
|
||||||
'overlay',
|
'hidden-left',
|
||||||
|
'hidden-bottom',
|
||||||
|
'hidden-right',
|
||||||
|
'overlay-top',
|
||||||
|
'overlay-left',
|
||||||
|
'overlay-bottom',
|
||||||
|
'overlay-right',
|
||||||
'above',
|
'above',
|
||||||
'below',
|
'below',
|
||||||
] as const;
|
] as const;
|
||||||
@@ -55,7 +61,7 @@ export const frigateCardConfigSchema = z.object({
|
|||||||
label: z.string().optional(),
|
label: z.string().optional(),
|
||||||
zone: z.string().optional(),
|
zone: z.string().optional(),
|
||||||
autoplay_clip: z.boolean().default(false),
|
autoplay_clip: z.boolean().default(false),
|
||||||
menu_mode: z.enum(FRIGATE_MENU_MODES).optional().default('hidden'),
|
menu_mode: z.enum(FRIGATE_MENU_MODES).optional().default('hidden-top'),
|
||||||
|
|
||||||
// Stock lovelace card config.
|
// Stock lovelace card config.
|
||||||
type: z.string(),
|
type: z.string(),
|
||||||
|
|||||||
Reference in New Issue
Block a user