Add 'image' view.
This commit is contained in:
+2
-1
@@ -21,12 +21,13 @@
|
||||
"home-assistant-js-websocket": "^5.11.1",
|
||||
"lit": "^2.0.2",
|
||||
"screenfull": "^5.1.0",
|
||||
"zod": "^3.9.8"
|
||||
"zod": "^3.10.0-beta.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.15.8",
|
||||
"@babel/plugin-proposal-class-properties": "^7.14.5",
|
||||
"@babel/plugin-proposal-decorators": "^7.15.8",
|
||||
"@rollup/plugin-image": "^2.1.1",
|
||||
"@rollup/plugin-json": "^4.1.0",
|
||||
"@typescript-eslint/eslint-plugin": "^4.33.0",
|
||||
"@typescript-eslint/parser": "^4.33.0",
|
||||
|
||||
@@ -6,6 +6,7 @@ import { terser } from 'rollup-plugin-terser';
|
||||
import serve from 'rollup-plugin-serve';
|
||||
import json from '@rollup/plugin-json';
|
||||
import styles from 'rollup-plugin-styles';
|
||||
import image from '@rollup/plugin-image';
|
||||
|
||||
const dev = process.env.ROLLUP_WATCH;
|
||||
|
||||
@@ -29,6 +30,7 @@ const plugins = [
|
||||
includePaths: ['./node_modules/'],
|
||||
},
|
||||
}),
|
||||
image(),
|
||||
nodeResolve({}),
|
||||
commonjs(),
|
||||
typescript(),
|
||||
|
||||
+25
-2
@@ -31,6 +31,7 @@ import type {
|
||||
} from './types';
|
||||
|
||||
import { CARD_VERSION, REPO_URL } from './const';
|
||||
import { FrigateCardElements } from './components/elements';
|
||||
import { FrigateCardMenu, MENU_HEIGHT } from './components/menu';
|
||||
import { View } from './view';
|
||||
import { homeAssistantWSRequest, shouldUpdateBasedOnHass } from './common';
|
||||
@@ -40,6 +41,7 @@ import { renderMessage, renderProgressIndicator } from './components/message';
|
||||
import './editor';
|
||||
import './components/elements';
|
||||
import './components/gallery';
|
||||
import './components/image';
|
||||
import './components/live';
|
||||
import './components/menu';
|
||||
import './components/message';
|
||||
@@ -48,7 +50,6 @@ import './patches/ha-camera-stream';
|
||||
import './patches/ha-hls-player';
|
||||
|
||||
import cardStyle from './scss/card.scss';
|
||||
import { FrigateCardElements } from './components/elements';
|
||||
|
||||
const MEDIA_HEIGHT_CUTOFF = 50;
|
||||
const MEDIA_WIDTH_CUTOFF = MEDIA_HEIGHT_CUTOFF;
|
||||
@@ -112,7 +113,7 @@ export class FrigateCard extends LitElement {
|
||||
|
||||
// A small cache to avoid needing to create a new list of entities every time
|
||||
// a hass update arrives.
|
||||
protected _entitiesToMonitor: string[] | null = null;
|
||||
protected _entitiesToMonitor: string[] = [];
|
||||
|
||||
// Information about the most recently loaded media item.
|
||||
protected _mediaInfo: MediaLoadInfo | null = null;
|
||||
@@ -197,6 +198,15 @@ export class FrigateCard extends LitElement {
|
||||
emphasize: this._view.is('snapshots'),
|
||||
});
|
||||
}
|
||||
if (this.config.menu_buttons?.image ?? false) {
|
||||
buttons.push({
|
||||
type: 'internal-menu-icon',
|
||||
card_action: 'image',
|
||||
title: localize('menu.image'),
|
||||
icon: 'mdi:image',
|
||||
emphasize: this._view.is('image'),
|
||||
});
|
||||
}
|
||||
if ((this.config.menu_buttons?.frigate_ui ?? true) && this.config.frigate_url) {
|
||||
buttons.push({
|
||||
type: 'internal-menu-icon',
|
||||
@@ -357,6 +367,7 @@ export class FrigateCard extends LitElement {
|
||||
case 'frigate':
|
||||
this._changeView();
|
||||
break;
|
||||
case 'image':
|
||||
case 'live':
|
||||
case 'clips':
|
||||
case 'snapshots':
|
||||
@@ -625,10 +636,22 @@ export class FrigateCard extends LitElement {
|
||||
const liveClasses = {
|
||||
hidden: this.config.live_preload && this._view.view != 'live',
|
||||
};
|
||||
const imageClasses = {
|
||||
hidden: this.config.live_preload && this._view.view != 'image',
|
||||
};
|
||||
|
||||
return html`
|
||||
<div class="${classMap(pictureElementsClasses)}">
|
||||
${this._message ? renderMessage(this._message) : ``}
|
||||
${!this._message && this._view.is('image')
|
||||
? html` <frigate-card-image
|
||||
.image=${this.config.image}
|
||||
class="${classMap(imageClasses)}"
|
||||
@frigate-card:media-load=${this._mediaLoadHandler}
|
||||
@frigate-card:message=${this._messageHandler}
|
||||
>
|
||||
</frigate-card-image>`
|
||||
: ``}
|
||||
${!this._message && this._view.isGalleryView()
|
||||
? html` <frigate-card-gallery
|
||||
.hass=${this._hass}
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
import { CSSResultGroup, LitElement, TemplateResult, html, unsafeCSS } from 'lit';
|
||||
import { customElement, property } from 'lit/decorators';
|
||||
|
||||
import { dispatchMediaLoadEvent } from '../common';
|
||||
|
||||
import imageStyle from '../scss/image.scss';
|
||||
import defaultImage from '../images/frigate-bird-in-sky.jpg'
|
||||
|
||||
@customElement('frigate-card-image')
|
||||
export class FrigateCardImage extends LitElement {
|
||||
@property({ attribute: false })
|
||||
protected image?: string;
|
||||
|
||||
protected render(): TemplateResult | void {
|
||||
return html` <img
|
||||
src=${this.image || defaultImage}
|
||||
@load=${(e) => {
|
||||
dispatchMediaLoadEvent(this, e);
|
||||
}}
|
||||
>`;
|
||||
}
|
||||
|
||||
static get styles(): CSSResultGroup {
|
||||
return unsafeCSS(imageStyle);
|
||||
}
|
||||
}
|
||||
Vendored
+1
@@ -1 +1,2 @@
|
||||
declare module '*.scss';
|
||||
declare module '*.jpg';
|
||||
|
||||
@@ -102,6 +102,7 @@ export class FrigateCardEditor extends LitElement implements LovelaceCardEditor
|
||||
snapshots: localize('menu.snapshots'),
|
||||
clip: localize('menu.clip'),
|
||||
snapshot: localize('menu.snapshot'),
|
||||
image: localize('menu.image'),
|
||||
};
|
||||
|
||||
const menuModes = {
|
||||
@@ -382,6 +383,18 @@ export class FrigateCardEditor extends LitElement implements LovelaceCardEditor
|
||||
></ha-switch>
|
||||
</ha-formfield>
|
||||
<br />
|
||||
<ha-formfield
|
||||
.label=${localize('editor.show_button') +
|
||||
': ' +
|
||||
localize('menu.image')}
|
||||
>
|
||||
<ha-switch
|
||||
.checked=${this._config?.menu_buttons?.image ?? false}
|
||||
.configValue=${'menu_buttons.image'}
|
||||
@change=${this._valueChanged}
|
||||
></ha-switch>
|
||||
</ha-formfield>
|
||||
<br />
|
||||
<ha-formfield
|
||||
.label=${localize('editor.show_button') +
|
||||
': ' +
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
# Image Copyright
|
||||
|
||||
## frigate-bird-in-sky.jpg
|
||||
|
||||
**Link**: https://www.flickr.com/photos/dianasch/47543120431
|
||||
|
||||
**Description**: A Frigate bird with a very large wingspan (7 ft) soaring overhead on Sanibel Island, Florida.
|
||||
|
||||
**Copyright**: Diana Robinson
|
||||
|
||||
**License**: https://creativecommons.org/licenses/by-nc-nd/2.0/
|
||||
|
||||
**Modifications**:
|
||||
|
||||
* Cropped for 16:9
|
||||
* Scaled down to 420x277
|
||||
* Gaussian blur 0.05
|
||||
* Quality @ 50%
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 8.2 KiB |
@@ -43,7 +43,8 @@
|
||||
"clip": "Latest Clip",
|
||||
"snapshot": "Latest Snapshot",
|
||||
"frigate_ui": "Frigate User Interface",
|
||||
"fullscreen": "Fullscreen"
|
||||
"fullscreen": "Fullscreen",
|
||||
"image": "Static Image"
|
||||
},
|
||||
"control": {
|
||||
"nextprev": "Media Next & Previous Controls",
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
img {
|
||||
max-width: 100%;
|
||||
display: block;
|
||||
margin: auto;
|
||||
}
|
||||
@@ -26,6 +26,7 @@ export const FRIGATE_CARD_VIEWS = [
|
||||
'clips',
|
||||
'snapshot',
|
||||
'snapshots',
|
||||
'image'
|
||||
] as const;
|
||||
export type FrigateCardView = typeof FRIGATE_CARD_VIEWS[number];
|
||||
|
||||
@@ -263,6 +264,7 @@ export const frigateCardConfigSchema = z.object({
|
||||
.default(180),
|
||||
live_provider: z.enum(LIVE_PROVIDERS).default('frigate'),
|
||||
live_preload: z.boolean().default(false),
|
||||
image: z.string().optional(),
|
||||
webrtc: z
|
||||
.object({
|
||||
entity: z.string().optional(),
|
||||
@@ -280,6 +282,7 @@ export const frigateCardConfigSchema = z.object({
|
||||
live: z.boolean().default(true),
|
||||
clips: z.boolean().default(true),
|
||||
snapshots: z.boolean().default(true),
|
||||
image: z.boolean().default(false),
|
||||
frigate_ui: z.boolean().default(true),
|
||||
fullscreen: z.boolean().default(true),
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user