From 4dcfe3031d19ba8d1f8735a481f0400ad3a76854 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20Lov=C3=A9n?= Date: Sun, 10 Jan 2021 13:52:28 +0100 Subject: [PATCH] Allow multiple tap/hold/doubletap actions. --- src/data/lovelace.ts | 8 +- src/panels/lovelace/common/handle-action.ts | 117 +++++++++--------- .../lovelace/components/hui-action-editor.ts | 9 ++ .../config-elements/hui-button-card-editor.ts | 1 + .../config-elements/hui-light-card-editor.ts | 1 + .../hui-picture-card-editor.ts | 2 +- .../hui-picture-entity-card-editor.ts | 9 +- .../hui-picture-glance-card-editor.ts | 9 +- src/panels/lovelace/editor/types.ts | 1 + src/translations/en.json | 4 +- 10 files changed, 100 insertions(+), 61 deletions(-) diff --git a/src/data/lovelace.ts b/src/data/lovelace.ts index 090bb0dfc0..32886dfc36 100644 --- a/src/data/lovelace.ts +++ b/src/data/lovelace.ts @@ -148,6 +148,11 @@ export interface CustomActionConfig extends BaseActionConfig { action: "fire-dom-event"; } +export interface MultipleActionConfig extends BaseActionConfig { + action: "multiple"; + actions: ActionConfig[]; +} + export interface BaseActionConfig { confirmation?: ConfirmationRestrictionConfig; } @@ -168,7 +173,8 @@ export type ActionConfig = | UrlActionConfig | MoreInfoActionConfig | NoActionConfig - | CustomActionConfig; + | CustomActionConfig + | MultipleActionConfig; type LovelaceUpdatedEvent = HassEventBase & { event_type: "lovelace_updated"; diff --git a/src/panels/lovelace/common/handle-action.ts b/src/panels/lovelace/common/handle-action.ts index bb6467b2c1..15c3b7d26a 100644 --- a/src/panels/lovelace/common/handle-action.ts +++ b/src/panels/lovelace/common/handle-action.ts @@ -40,69 +40,74 @@ export const handleAction = async ( }; } - if ( - actionConfig.confirmation && - (!actionConfig.confirmation.exemptions || - !actionConfig.confirmation.exemptions.some( - (e) => e.user === hass!.user!.id - )) - ) { - forwardHaptic("warning"); + const actionConfigs = + actionConfig.action === "multiple" ? actionConfig.actions : [actionConfig]; + for await (actionConfig of actionConfigs) { if ( - !(await showConfirmationDialog(node, { - text: - actionConfig.confirmation.text || - hass.localize( - "ui.panel.lovelace.cards.action_confirmation", - "action", - actionConfig.action - ), - })) + actionConfig.confirmation && + (!actionConfig.confirmation.exemptions || + !actionConfig.confirmation.exemptions.some( + (e) => e.user === hass!.user!.id + )) ) { - return; - } - } + forwardHaptic("warning"); - switch (actionConfig.action) { - case "more-info": { - if (config.entity || config.camera_image) { - fireEvent(node, "hass-more-info", { - entityId: config.entity ? config.entity : config.camera_image!, - }); - } - break; - } - case "navigate": - if (actionConfig.navigation_path) { - navigate(node, actionConfig.navigation_path); - } - break; - case "url": { - if (actionConfig.url_path) { - window.open(actionConfig.url_path); - } - break; - } - case "toggle": { - if (config.entity) { - toggleEntity(hass, config.entity!); - forwardHaptic("light"); - } - break; - } - case "call-service": { - if (!actionConfig.service) { - forwardHaptic("failure"); + if ( + !(await showConfirmationDialog(node, { + text: + actionConfig.confirmation.text || + hass.localize( + "ui.panel.lovelace.cards.action_confirmation", + "action", + actionConfig.action + ), + })) + ) { return; } - const [domain, service] = actionConfig.service.split(".", 2); - hass.callService(domain, service, actionConfig.service_data); - forwardHaptic("light"); - break; } - case "fire-dom-event": { - fireEvent(node, "ll-custom", actionConfig); + + switch (actionConfig.action) { + case "more-info": { + if (config.entity || config.camera_image) { + fireEvent(node, "hass-more-info", { + entityId: config.entity ? config.entity : config.camera_image!, + }); + } + break; + } + case "navigate": + if (actionConfig.navigation_path) { + navigate(node, actionConfig.navigation_path); + } + break; + case "url": { + if (actionConfig.url_path) { + window.open(actionConfig.url_path); + } + break; + } + case "toggle": { + if (config.entity) { + toggleEntity(hass, config.entity!); + forwardHaptic("light"); + } + break; + } + case "call-service": { + if (!actionConfig.service) { + forwardHaptic("failure"); + return; + } + const [domain, service] = actionConfig.service.split(".", 2); + hass.callService(domain, service, actionConfig.service_data); + forwardHaptic("light"); + break; + } + case "fire-dom-event": { + fireEvent(node, "ll-custom", actionConfig); + } } } }; diff --git a/src/panels/lovelace/components/hui-action-editor.ts b/src/panels/lovelace/components/hui-action-editor.ts index 7946138d6e..78d72b9865 100644 --- a/src/panels/lovelace/components/hui-action-editor.ts +++ b/src/panels/lovelace/components/hui-action-editor.ts @@ -130,6 +130,15 @@ export class HuiActionEditor extends LitElement { ` : ""} + ${this.config?.action === "multiple" + ? html` + + ${this.hass!.localize( + "ui.panel.lovelace.editor.action-editor.editor_multiple_actions" + )} + + ` + : ""} `; } diff --git a/src/panels/lovelace/editor/config-elements/hui-button-card-editor.ts b/src/panels/lovelace/editor/config-elements/hui-button-card-editor.ts index 2b4ff6acfd..32813fe46e 100644 --- a/src/panels/lovelace/editor/config-elements/hui-button-card-editor.ts +++ b/src/panels/lovelace/editor/config-elements/hui-button-card-editor.ts @@ -46,6 +46,7 @@ const actions = [ "url", "call-service", "none", + "multiple", ]; @customElement("hui-button-card-editor") diff --git a/src/panels/lovelace/editor/config-elements/hui-light-card-editor.ts b/src/panels/lovelace/editor/config-elements/hui-light-card-editor.ts index 3a21299e95..931e50b94a 100644 --- a/src/panels/lovelace/editor/config-elements/hui-light-card-editor.ts +++ b/src/panels/lovelace/editor/config-elements/hui-light-card-editor.ts @@ -82,6 +82,7 @@ export class HuiLightCardEditor extends LitElement "url", "call-service", "none", + "multiple", ]; return html` diff --git a/src/panels/lovelace/editor/config-elements/hui-picture-card-editor.ts b/src/panels/lovelace/editor/config-elements/hui-picture-card-editor.ts index 26d66d2baf..1ecd7a07e5 100644 --- a/src/panels/lovelace/editor/config-elements/hui-picture-card-editor.ts +++ b/src/panels/lovelace/editor/config-elements/hui-picture-card-editor.ts @@ -60,7 +60,7 @@ export class HuiPictureCardEditor extends LitElement return html``; } - const actions = ["navigate", "url", "call-service", "none"]; + const actions = ["navigate", "url", "call-service", "none", "multiple"]; return html`
diff --git a/src/panels/lovelace/editor/config-elements/hui-picture-entity-card-editor.ts b/src/panels/lovelace/editor/config-elements/hui-picture-entity-card-editor.ts index 927d233888..6f76b8c9a9 100644 --- a/src/panels/lovelace/editor/config-elements/hui-picture-entity-card-editor.ts +++ b/src/panels/lovelace/editor/config-elements/hui-picture-entity-card-editor.ts @@ -104,7 +104,14 @@ export class HuiPictureEntityCardEditor extends LitElement return html``; } - const actions = ["more-info", "toggle", "navigate", "call-service", "none"]; + const actions = [ + "more-info", + "toggle", + "navigate", + "call-service", + "none", + "multiple", + ]; const views = ["auto", "live"]; const dir = computeRTLDirection(this.hass!); diff --git a/src/panels/lovelace/editor/config-elements/hui-picture-glance-card-editor.ts b/src/panels/lovelace/editor/config-elements/hui-picture-glance-card-editor.ts index 43d4816e03..aa9ff82d89 100644 --- a/src/panels/lovelace/editor/config-elements/hui-picture-glance-card-editor.ts +++ b/src/panels/lovelace/editor/config-elements/hui-picture-glance-card-editor.ts @@ -108,7 +108,14 @@ export class HuiPictureGlanceCardEditor extends LitElement return html``; } - const actions = ["more-info", "toggle", "navigate", "call-service", "none"]; + const actions = [ + "more-info", + "toggle", + "navigate", + "call-service", + "none", + "multiple", + ]; const views = ["auto", "live"]; return html` diff --git a/src/panels/lovelace/editor/types.ts b/src/panels/lovelace/editor/types.ts index 3f657062a6..d42b65b731 100644 --- a/src/panels/lovelace/editor/types.ts +++ b/src/panels/lovelace/editor/types.ts @@ -98,6 +98,7 @@ export const actionConfigStruct = object({ url_path: optional(string()), service: optional(string()), service_data: optional(object()), + actions: optional(array()), }); const buttonEntitiesRowConfigStruct = object({ diff --git a/src/translations/en.json b/src/translations/en.json index 1e9d22dd61..58e356dac0 100755 --- a/src/translations/en.json +++ b/src/translations/en.json @@ -2564,6 +2564,7 @@ "action-editor": { "navigation_path": "Navigation Path", "url_path": "URL Path", + "editor_multiple_actions": "Multiple actions can only be entered in the code editor", "editor_service_data": "Service data can only be entered in the code editor", "actions": { "default_action": "Default Action", @@ -2572,7 +2573,8 @@ "toggle": "Toggle", "navigate": "Navigate", "url": "URL", - "none": "No Action" + "none": "No Action", + "multiple": "Multiple actions" } }, "card": {