class WallPanelPanel extends HTMLElement { constructor() { super(); this._hass = null; this._panel = null; this._narrow = false; this._pollTimer = null; this._activePanelUrl = ''; this.attachShadow({ mode: 'open' }); } set hass(hass) { this._hass = hass; this._render(); } set panel(panel) { this._panel = panel; this._render(); } set narrow(narrow) { this._narrow = Boolean(narrow); this._render(); } connectedCallback() { this._render(); } disconnectedCallback() { if (this._pollTimer) { window.clearInterval(this._pollTimer); this._pollTimer = null; } } _resolveUrl(rawUrl) { const value = String(rawUrl || '').trim(); if (!value) { return ''; } try { const url = new URL(value, window.location.href); if (!url.searchParams.has('embed')) { url.searchParams.set('embed', '1'); } if (!url.searchParams.has('mode')) { url.searchParams.set('mode', 'ha'); } return url.toString(); } catch (error) { return value; } } _panelConfig() { const config = this._panel?.config || {}; const customConfig = config._panel_custom || {}; return customConfig.config || customConfig || config; } _configUrl() { return '/api/wall_panel/panel'; } _legacyConfigUrl() { const payload = this._panelConfig(); const entryId = String(payload.entry_id || '').trim(); if (!entryId) { return ''; } return `/api/wall_panel/config/${encodeURIComponent(entryId)}`; } _proxyUrl() { const payload = this._panelConfig(); const entryId = String(payload.entry_id || '').trim(); if (!entryId) { return ''; } return `/api/wall_panel/proxy/${encodeURIComponent(entryId)}/`; } _hasPanelUrl() { const payload = this._panelConfig(); const panelUrl = String(payload.panel_url || payload.ingress_url || '').trim(); return panelUrl !== ''; } _renderMessage(title, body, extra = '') { if (!this.shadowRoot) { return; } this.shadowRoot.innerHTML = `
${title}
${body}
${extra}
`; } _renderIframe(panelUrl) { if (!this.shadowRoot) { return; } const wrap = this.shadowRoot.querySelector('.wrap'); if (!wrap) { return; } const iframe = document.createElement('iframe'); iframe.src = panelUrl; iframe.loading = 'eager'; iframe.referrerPolicy = 'no-referrer'; iframe.allow = 'autoplay; fullscreen; picture-in-picture'; iframe.style.width = '100%'; iframe.style.height = '100%'; iframe.style.border = '0'; iframe.style.display = 'block'; iframe.style.background = 'transparent'; iframe.addEventListener('load', () => { this._activePanelUrl = panelUrl; }); wrap.replaceChildren(iframe); } async _tryAttachPanel() { const payload = this._panelConfig(); const proxyUrl = this._proxyUrl(); if (proxyUrl && proxyUrl === this._activePanelUrl) { return; } if (proxyUrl && this._hasPanelUrl()) { this._renderIframe(proxyUrl); return; } const panelUrl = this._resolveUrl(payload.panel_url || payload.ingress_url || ''); const configUrl = this._configUrl(); this._renderMessage( 'Waiting for Wall Panel', panelUrl ? 'Open this panel through Home Assistant after the add-on URL is configured.' : 'Set the PHP panel URL in the integration options.', configUrl ? `${configUrl}` : '' ); } _render() { if (!this.shadowRoot) { return; } if (this._pollTimer) { window.clearInterval(this._pollTimer); this._pollTimer = null; } this._tryAttachPanel(); this._pollTimer = window.setInterval(() => { this._tryAttachPanel(); }, 2000); } } if (!customElements.get('wall-panel-panel')) { customElements.define('wall-panel-panel', WallPanelPanel); }