Implement support for {start,end}_tap actions.

This commit is contained in:
Dermot Duffy
2022-01-25 22:01:09 -08:00
parent 6119423b41
commit de763f3e56
5 changed files with 69 additions and 20 deletions
+5
View File
@@ -117,6 +117,8 @@ class ActionHandler extends HTMLElement implements ActionHandler {
this.held = true;
}, this.holdTime);
}
fireEvent(element, 'action', { action: 'start_tap' });
};
const end = (ev: Event): void => {
@@ -133,6 +135,9 @@ class ActionHandler extends HTMLElement implements ActionHandler {
this.stopAnimation();
this.timer = undefined;
}
fireEvent(element, 'action', { action: 'end_tap' });
if (options?.hasHold && this.held) {
fireEvent(element, 'action', { action: 'hold' });
} else if (options?.hasDoubleClick) {
+15 -10
View File
@@ -14,7 +14,6 @@ import {
HomeAssistant,
LovelaceCardEditor,
getLovelace,
handleAction,
hasAction,
} from 'custom-card-helpers';
import screenfull from 'screenfull';
@@ -46,6 +45,7 @@ import {
contentsChanged,
convertActionToFrigateCardCustomAction,
createFrigateCardCustomAction,
frigateCardHandleAction,
getActionConfigGivenAction,
getCameraIcon,
getCameraTitle,
@@ -102,8 +102,8 @@ import {
*
* The card supports actions being configured in a number of places (e.g. tap on an
* element, double_tap on a menu item, hold on the live view). These actions are
* handled by handleAction() from custom-card-helpers. For Frigate-card specific
* actions, handleAction() call will result in an ll-custom DOM event being
* handled frigateCardHandleAction(). For Frigate-card specific actions,
* frigateCardHandleAction() call will result in an ll-custom DOM event being
* fired, which needs to be caught at the card level to handle.
*/
@@ -880,6 +880,8 @@ export class FrigateCard extends LitElement {
hold_action?: ActionType;
tap_action?: ActionType;
double_tap_action?: ActionType;
start_tap_action?: ActionType;
end_tap_action?: ActionType;
},
): void {
const interaction = ev.detail.action;
@@ -888,12 +890,17 @@ export class FrigateCard extends LitElement {
config &&
node &&
interaction &&
// Don't call handleAction() unless there is explicitly an action defined
// (as it uses a default that is unhelpful for views that have default
// tap/click actions).
// Don't call frigateCardHandleAction() unless there is explicitly an
// action defined (as it uses a default that is unhelpful for views that
// have default tap/click actions).
getActionConfigGivenAction(interaction, config)
) {
handleAction(node, this._hass as HomeAssistant, config, ev.detail.action);
frigateCardHandleAction(
node,
this._hass as HomeAssistant,
config,
ev.detail.action,
);
}
// Set the 'screensaver' timer.
@@ -950,9 +957,7 @@ export class FrigateCard extends LitElement {
* @returns `true` if it's allowed, `false` otherwise.
*/
protected _isAutomatedViewUpdateAllowed(): boolean {
return (
this._getConfig().view.update_force || !this._interactionTimerID
);
return this._getConfig().view.update_force || !this._interactionTimerID;
}
/**
+41 -5
View File
@@ -1,5 +1,9 @@
import { HassEntity, MessageBase } from 'home-assistant-js-websocket';
import { HomeAssistant, stateIcon } from 'custom-card-helpers';
import {
HomeAssistant,
handleActionConfig,
stateIcon,
} from 'custom-card-helpers';
import { StyleInfo } from 'lit/directives/style-map';
import { ZodSchema, z } from 'zod';
import { isEqual } from 'lodash-es';
@@ -302,10 +306,12 @@ export function getActionConfigGivenAction(
hold_action?: ActionType;
tap_action?: ActionType;
double_tap_action?: ActionType;
start_tap_action?: ActionType;
end_tap_action?: ActionType;
},
): ActionType | null {
): ActionType | undefined {
if (!interaction || !config) {
return null;
return undefined;
}
if (interaction == 'tap' && config.tap_action) {
return config.tap_action;
@@ -313,8 +319,12 @@ export function getActionConfigGivenAction(
return config.hold_action;
} else if (interaction == 'double_tap' && config.double_tap_action) {
return config.double_tap_action;
} else if (interaction == 'end_tap' && config.end_tap_action) {
return config.end_tap_action;
} else if (interaction == 'start_tap' && config.start_tap_action) {
return config.start_tap_action;
}
return null;
return undefined;
}
/**
@@ -479,4 +489,30 @@ export function arrayMove(target: unknown[], from: number, to: number): void {
*/
export function contentsChanged(n: unknown, o: unknown): boolean {
return !isEqual(n, o);
}
}
/**
* Frigate card custom version of handleAction
* (https://github.com/custom-cards/custom-card-helpers/blob/master/src/handle-action.ts)
* that handles the custom action events the card supports.
* @param node The node that fired the event.
* @param hass The Home Assistant object.
* @param config The multi-action configuration.
* @param action The action string (e.g. 'hold')
*/
export const frigateCardHandleAction = (
node: HTMLElement,
hass: HomeAssistant,
config: {
entity?: string;
camera_image?: string;
hold_action?: ActionType;
tap_action?: ActionType;
double_tap_action?: ActionType;
start_tap_action?: ActionType;
end_tap_action?: ActionType;
},
action: string,
): void => {
handleActionConfig(node, hass, config, getActionConfigGivenAction(action, config));
};
+3 -2
View File
@@ -1,4 +1,4 @@
import { HASSDomEvent, HomeAssistant, handleAction, hasAction } from 'custom-card-helpers';
import { HASSDomEvent, HomeAssistant, hasAction } from 'custom-card-helpers';
import { CSSResultGroup, LitElement, TemplateResult, html, unsafeCSS } from 'lit';
import { customElement, property, state } from 'lit/decorators.js';
import { classMap } from 'lit/directives/class-map.js';
@@ -18,6 +18,7 @@ import type {
} from '../types.js';
import {
convertActionToFrigateCardCustomAction,
frigateCardHandleAction,
getActionConfigGivenAction,
refreshDynamicStateParameters,
} from '../common.js';
@@ -103,7 +104,7 @@ export class FrigateCardMenu extends LitElement {
// Collapse menu after the user clicks on something.
this.expanded = false;
handleAction(this, this.hass as HomeAssistant, config, interaction);
frigateCardHandleAction(this, this.hass as HomeAssistant, config, interaction);
}
/**
+5 -3
View File
@@ -162,14 +162,16 @@ const actionBaseSchema = z
tap_action: actionSchema.optional(),
hold_action: actionSchema.optional(),
double_tap_action: actionSchema.optional(),
start_tap_action: actionSchema.optional(),
end_tap_action: actionSchema.optional(),
})
// Passthrough to allow (at least) entity/camera_image to go through. This
// card doesn't need these attributes, but handleAction() in
// custom_card_helpers may depending on how the action is configured.
.passthrough();
export type Actions = z.infer<typeof actionBaseSchema>;
const actionsSchema = z.object({
// Passthrough to allow (at least) entity/camera_image to go through. This
// card doesn't need these attributes, but handleAction() in
// custom_card_helpers may depending on how the action is configured.
actions: actionBaseSchema.optional(),
});