Small cleanups and README.

This commit is contained in:
Dermot Duffy
2021-11-14 07:42:47 -08:00
parent fc3033a0fe
commit 256fee9061
4 changed files with 85 additions and 16 deletions
+14 -6
View File
@@ -126,7 +126,7 @@ All variables listed are under a `live:` section.
### Event Viewer options
The `event_viewer` is used for viewing all `clip` and `snapshot` media, in a media carousel. All variables listed are under a `event_viewer:` section.
The `event_viewer` is used for viewing all `clip` and `snapshot` media, in a media carousel. All variables listed are under an `event_viewer:` section.
| Option | Default | Description |
| - | - | - |
@@ -503,10 +503,10 @@ This card supports several different views:
| Key | Description |
| ------------- | --------------------------------------------- |
|`live` (default)| Shows the live camera view, either the name Frigate view or [WebRTC](#webrtc) if configured.|
|`snapshots`|Shows the snapshot gallery for this camera/zone/label.|
|`snapshot`|Shows the most recent snapshot for this camera/zone/label. Can also be accessed by holding down the `snapshots` menu icon.|
|`clips`|Shows the clip gallery for this camera/zone/label.|
|`clip`|Shows the most recent clip for this camera/zone/label. Can also be accessed by holding down the `clips` menu icon.|
|`snapshots`|Shows an event gallery of snapshots for this camera/zone/label.|
|`snapshot`|Shows an event viewer for the most recent snapshot for this camera/zone/label. Can also be accessed by holding down the `snapshots` menu icon.|
|`clips`|Shows an event gallery of clips for this camera/zone/label.|
|`clip`|Shows an event viewer for the most recent clip for this camera/zone/label. Can also be accessed by holding down the `clips` menu icon.|
|`image`|Shows a static image specified by the `image` parameter, can be used as a discrete default view or a screensaver (via `view_timeout`).|
### Automatic updates in the `clip` or `snapshot` view
@@ -552,7 +552,15 @@ specific overriding the less specific (see example below).
The format for actions is the standard Home Assistant [action
format](https://www.home-assistant.io/lovelace/actions/#tap-action) as well as
the custom [Frigate card action](#frigate-card-action) to trigger card changes.
the custom [Frigate card action](#frigate-card-action) to trigger Frigate card
changes.
**Note:** The card itself obviously relies on human interactions to function
(e.g. `tap` on the menu should activate that button, `tap` on a gallery thumbnail
should open that piece of media, etc). These internal actions are executed
_also_, which means that a card-wide `tap` action probably isn't that useful as
it may be disorienting to the user and will trigger on all kinds of basic
interaction on the card (e.g. tapping/clicking a menu button).
### Example
+20 -3
View File
@@ -212,6 +212,11 @@ export class FrigateCard extends LitElement {
} as FrigateCardConfig;
}
/**
* Get a FrigateCard MenuButton given a set of parameters.
* @param params Menu button parameters.
* @returns A MenuButton.
*/
protected _getFrigateCardMenuButton(
params: GetFrigateCardMenuButtonParameters,
): MenuButton {
@@ -598,10 +603,14 @@ export class FrigateCard extends LitElement {
/**
* Handle a request for a card action.
* @param action The action requested (e.g. clips, fullscreen)
* @param ev The action requested.
*/
protected _cardActionHandler(event: CustomEvent<ActionType>): void {
const frigateCardAction = convertActionToFrigateCardCustomAction(event.detail);
protected _cardActionHandler(ev: CustomEvent<ActionType>): void {
// These interactions should only be handled by the card, as nothing
// upstream has the user-provided configuration.
ev.stopPropagation();
const frigateCardAction = convertActionToFrigateCardCustomAction(ev.detail);
if (!frigateCardAction) {
return;
}
@@ -670,6 +679,10 @@ export class FrigateCard extends LitElement {
}, this.config.view.timeout * 1000);
}
/**
* Handle an action called on an element.
* @param ev The actionHandler event.
*/
protected _actionHandler(
ev: CustomEvent,
config?: {
@@ -866,6 +879,10 @@ export class FrigateCard extends LitElement {
}
}
/**
* Merge card-wide and view-specific actions.
* @returns A combined set of action.
*/
protected _getMergedActions(): Actions {
let specificActions: Actions | undefined = undefined;
+16
View File
@@ -258,6 +258,11 @@ export function isValidMediaShowInfo(info: MediaShowInfo): boolean {
);
}
/**
* Convert a generic Action to a FrigateCardCustomAction if it parses correctly.
* @param action The generic action configuration.
* @returns A FrigateCardCustomAction or null if it cannot be converted.
*/
export function convertActionToFrigateCardCustomAction(
action: ActionType,
): FrigateCardCustomAction | null {
@@ -267,6 +272,11 @@ export function convertActionToFrigateCardCustomAction(
return parseResult.success ? parseResult.data : null;
}
/**
* Create a Frigate card custom action.
* @param action The Frigate card action string (e.g. 'fullscreen')
* @returns A FrigateCardCustomAction for that action string.
*/
export function createFrigateCardCustomAction(action: string): FrigateCardCustomAction {
return {
action: 'fire-dom-event',
@@ -274,6 +284,12 @@ export function createFrigateCardCustomAction(action: string): FrigateCardCustom
};
}
/**
* Get an action configuration given a config and an interaction (e.g. 'tap').
* @param interaction The interaction: `tap`, `hold` or `double_tap`
* @param config The configuration containing multiple actions.
* @returns The relevant action configuration or null if none found.
*/
export function getActionConfigGivenAction(
interaction?: string,
config?: {
+35 -7
View File
@@ -30,7 +30,9 @@ import menuStyle from '../scss/menu.scss';
export const MENU_HEIGHT = 46;
export const FRIGATE_BUTTON_MENU_ICON = 'frigate';
// A menu for the Frigate card.
/**
* A menu for the FrigateCard.
*/
@customElement('frigate-card-menu')
export class FrigateCardMenu extends LitElement {
@property({ attribute: false })
@@ -51,14 +53,23 @@ export class FrigateCardMenu extends LitElement {
@property({ attribute: false })
public buttons: MenuButton[] = [];
/**
* Handle an action on a menu button.
* @param ev The action event.
* @param button The button configuration.
*/
protected _actionHandler(ev: CustomEvent, button: MenuButton): void {
if (!ev) {
return;
}
// These interactions should only be handled by the card, as nothing
// upstream has the user-provided configuration.
ev.stopPropagation();
const interaction: string = ev.detail.action;
const action = getActionConfigGivenAction(interaction, button);
if (!action) {
if (!action || !interaction) {
return;
}
@@ -81,7 +92,11 @@ export class FrigateCardMenu extends LitElement {
handleAction(this, this.hass as HomeAssistant, button, interaction);
}
// Determine whether the menu should be updated.
/**
* Determine whether the menu should be updated.
* @param changedProps The changed properties.
* @returns `true` if the menu should be updated, otherwise `false`.
*/
protected shouldUpdate(changedProps: PropertyValues): boolean {
const oldHass = changedProps.get('hass') as HomeAssistant | undefined;
@@ -100,13 +115,21 @@ export class FrigateCardMenu extends LitElement {
return shouldUpdateBasedOnHass(this.hass, oldHass, entities);
}
/**
* Get the style of emphasized menu items.
* @returns A StyleInfo.
*/
public static getEmphasizedStyle(): StyleInfo {
return {
color: 'var(--primary-color, white)',
};
}
// Render a menu button.
/**
* Render a button.
* @param button The button configuration to render.
* @returns A rendered template or void.
*/
protected _renderButton(button: MenuButton): TemplateResult | void {
let state: HassEntity | null = null;
let title = button.title;
@@ -163,7 +186,10 @@ export class FrigateCardMenu extends LitElement {
</ha-icon-button>`;
}
// Render the menu.
/**
* Render the menu.
* @returns A rendered template or void.
*/
protected render(): TemplateResult | void {
if (!this._menuConfig) {
return;
@@ -200,8 +226,10 @@ export class FrigateCardMenu extends LitElement {
`;
}
// Return compiled CSS styles (thus safe to use with unsafeCSS).
static get styles(): CSSResultGroup {
/**
* Get styles.
*/
static get styles(): CSSResultGroup {
return unsafeCSS(menuStyle);
}
}