From 127129dcf5de438fc43d697cf1dd592e33176208 Mon Sep 17 00:00:00 2001 From: TheThomaas Date: Fri, 25 Sep 2026 16:56:31 +0200 Subject: [PATCH] Add timer card --- custom_components/cookcli/www/cookcli-card.js | 96 +++++++++++++++++++ .../cookcli/www/cookcli-recipe-strategy.js | 14 +-- 2 files changed, 100 insertions(+), 10 deletions(-) diff --git a/custom_components/cookcli/www/cookcli-card.js b/custom_components/cookcli/www/cookcli-card.js index 694172a..42e2ea9 100644 --- a/custom_components/cookcli/www/cookcli-card.js +++ b/custom_components/cookcli/www/cookcli-card.js @@ -787,9 +787,105 @@ class CookCliChecklistCard extends HTMLElement { } } +/** + * Enrobe circular-timer-card (karlis-vagalis/circular-timer-card) sans la + * modifier : superpose un bouton "Démarrer" tant que le minuteur est à + * l'état idle, avec la durée voulue (transmise à timer.start). Une fois + * démarré, le bouton disparaît et les actions natives de la carte prennent + * le relais (tap = pause/reprise, appui long = détail, double-tap = annuler). + * + * Config : + * type: custom:cookcli-timer-start-card + * entity: timer.xxx + * duration: "00:10:00" # HH:MM:SS, passé à timer.start au clic + * label: "10 min" # optionnel, affiché sur le bouton + * timer_card_config: {} # optionnel, transmis tel quel à + * # circular-timer-card (bins, color, layout…) + */ +class CookCliTimerStartCard extends HTMLElement { + setConfig(config) { + if (!config || !config.entity) { + throw new Error("La carte a besoin d'une `entity` (timer)."); + } + this._config = config; + this._state = null; + + if (!this.shadowRoot) this.attachShadow({ mode: "open" }); + this._buildDom(); + } + + getCardSize() { + return 4; + } + + _buildDom() { + this.shadowRoot.innerHTML = ` + +
+
+ +
+ `; + this._overlay = this.shadowRoot.querySelector(".overlay"); + this._overlay.querySelector("span").textContent = this._config.label + ? `Démarrer ${this._config.label}` + : "Démarrer"; + this._overlay.addEventListener("click", (ev) => this._onStart(ev)); + + this._inner = document.createElement("circular-timer-card"); + this._inner.setConfig({ + type: "custom:circular-timer-card", + entity: this._config.entity, + ...(this._config.timer_card_config || {}), + }); + this.shadowRoot.querySelector(".card-slot").appendChild(this._inner); + } + + _onStart(ev) { + ev.stopPropagation(); + if (!this._hass || !this._config.duration) return; + this._hass.callService("timer", "start", { + entity_id: this._config.entity, + duration: this._config.duration, + }); + } + + set hass(hass) { + this._hass = hass; + if (this._inner) this._inner.hass = hass; + const state = hass.states[this._config.entity]?.state; + if (state !== this._state) { + this._state = state; + this._overlay.classList.toggle("hidden", state !== "idle"); + } + } +} + customElements.define("cookcli-card", CookCliCard); customElements.define("cookcli-card-editor", CookCliCardEditor); customElements.define("cookcli-checklist-card", CookCliChecklistCard); +customElements.define("cookcli-timer-start-card", CookCliTimerStartCard); window.customCards = window.customCards || []; window.customCards.push({ diff --git a/custom_components/cookcli/www/cookcli-recipe-strategy.js b/custom_components/cookcli/www/cookcli-recipe-strategy.js index acf89c1..ce4a034 100644 --- a/custom_components/cookcli/www/cookcli-recipe-strategy.js +++ b/custom_components/cookcli/www/cookcli-recipe-strategy.js @@ -455,17 +455,11 @@ class CookCliRecipeViewStrategy extends HTMLElement { if (!seconds) continue; const label = `${timer.duration ?? ""} ${timer.unit ?? ""}`.trim(); leftCards.push({ - type: "button", - name: `Démarrer ${label}`, - icon: "mdi:timer-outline", - tap_action: { - action: "perform-action", - perform_action: "timer.start", - target: { entity_id: config.timer_entity }, - data: { duration: this._secondsToHms(seconds) }, - }, + type: "custom:cookcli-timer-start-card", + entity: config.timer_entity, + duration: this._secondsToHms(seconds), + label, }); - leftCards.push({ type: "custom:circular-timer-card", entity: config.timer_entity }); } }