/** * TaskMate Photo Gallery Card * A history grid of chore-evidence photos. Reads the activity sensor's * `photo_gallery` attribute and renders thumbnails. A card's can't send a * bearer token, so each photo path is signed via the `auth/sign_path` WS command * before use. * * Single layout, so it consumes the design tokens directly (like the routine * card). Every --tmd-* reference has the card's original value as its fallback, * so classic — which defines no tokens — renders exactly as it did before. */ const LitElement = customElements.get("hui-masonry-view") ? Object.getPrototypeOf(customElements.get("hui-masonry-view")) : Object.getPrototypeOf(customElements.get("hui-view")); const html = LitElement.prototype.html; const css = LitElement.prototype.css; const _safeColor = (c, d) => (typeof c === "string" && /^#[0-9a-fA-F]{3,8}$/.test(c) ? c : d); const DEFAULT_ACCENT = "#5d6d7e"; class TaskMatePhotoGalleryCard extends LitElement { static get properties() { return { hass: { type: Object }, config: { type: Object }, _signed: { state: true } }; } constructor() { super(); this._signed = {}; // photo_url -> signed path this._inflight = new Set(); } setConfig(config) { if (!config || !config.entity) { throw new Error("A TaskMate activity entity is required"); } this.config = config; } static getStubConfig() { return { entity: "sensor.taskmate_activity" }; } getCardSize() { return 4; } _t(key, params) { const fn = window.__taskmate_localize; return fn ? fn(this.hass, key, params) : key; } /** * Resolve the active design, stamp data-tm-design on the host, and set the * header accent. The accent is an inline host property, not a template *