custom_components/bahmcloud_store/panel/panel.js aktualisiert
This commit is contained in:
@@ -21,6 +21,9 @@ class BahmcloudStorePanel extends HTMLElement {
|
|||||||
this._readmeLoading = false;
|
this._readmeLoading = false;
|
||||||
this._readmeText = null;
|
this._readmeText = null;
|
||||||
this._readmeError = null;
|
this._readmeError = null;
|
||||||
|
|
||||||
|
// Prevent multiple concurrent markdown mounts
|
||||||
|
this._mdMountToken = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
set hass(hass) {
|
set hass(hass) {
|
||||||
@@ -335,6 +338,11 @@ class BahmcloudStorePanel extends HTMLElement {
|
|||||||
|
|
||||||
details{ margin-top: 10px; }
|
details{ margin-top: 10px; }
|
||||||
summary{ cursor:pointer; color: var(--bcs-accent); font-weight: 800; }
|
summary{ cursor:pointer; color: var(--bcs-accent); font-weight: 800; }
|
||||||
|
|
||||||
|
/* Make HA markdown look nice inside our card */
|
||||||
|
ha-markdown{
|
||||||
|
display:block;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<div class="mobilebar">
|
<div class="mobilebar">
|
||||||
@@ -388,9 +396,7 @@ class BahmcloudStorePanel extends HTMLElement {
|
|||||||
tag === "select" ||
|
tag === "select" ||
|
||||||
t.isContentEditable;
|
t.isContentEditable;
|
||||||
|
|
||||||
if (isEditable) {
|
if (isEditable) e.stopPropagation();
|
||||||
e.stopPropagation();
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
root.addEventListener("keydown", stopIfFormField, true);
|
root.addEventListener("keydown", stopIfFormField, true);
|
||||||
@@ -406,13 +412,12 @@ class BahmcloudStorePanel extends HTMLElement {
|
|||||||
const supported = new Set(["searchInput", "categorySelect", "addUrl", "addName"]);
|
const supported = new Set(["searchInput", "categorySelect", "addUrl", "addName"]);
|
||||||
if (!supported.has(ae.id)) return null;
|
if (!supported.has(ae.id)) return null;
|
||||||
|
|
||||||
const state = {
|
return {
|
||||||
id: ae.id,
|
id: ae.id,
|
||||||
value: ae.value,
|
value: ae.value,
|
||||||
selectionStart: typeof ae.selectionStart === "number" ? ae.selectionStart : null,
|
selectionStart: typeof ae.selectionStart === "number" ? ae.selectionStart : null,
|
||||||
selectionEnd: typeof ae.selectionEnd === "number" ? ae.selectionEnd : null,
|
selectionEnd: typeof ae.selectionEnd === "number" ? ae.selectionEnd : null,
|
||||||
};
|
};
|
||||||
return state;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_restoreFocusState(state) {
|
_restoreFocusState(state) {
|
||||||
@@ -431,7 +436,6 @@ class BahmcloudStorePanel extends HTMLElement {
|
|||||||
|
|
||||||
_update() {
|
_update() {
|
||||||
const root = this.shadowRoot;
|
const root = this.shadowRoot;
|
||||||
|
|
||||||
const focusState = this._captureFocusState();
|
const focusState = this._captureFocusState();
|
||||||
|
|
||||||
const content = root.getElementById("content");
|
const content = root.getElementById("content");
|
||||||
@@ -515,13 +519,11 @@ class BahmcloudStorePanel extends HTMLElement {
|
|||||||
: `<span class="badge">Index</span>`;
|
: `<span class="badge">Index</span>`;
|
||||||
|
|
||||||
const desc = r.description || "No description available.";
|
const desc = r.description || "No description available.";
|
||||||
|
|
||||||
const creator = r.owner ? `Creator: ${r.owner}` : "Creator: -";
|
const creator = r.owner ? `Creator: ${r.owner}` : "Creator: -";
|
||||||
|
const latest = r.latest_version ? `Latest: ${r.latest_version}` : "Latest: unknown";
|
||||||
const cat = r.category ? `Category: ${r.category}` : null;
|
const cat = r.category ? `Category: ${r.category}` : null;
|
||||||
const metaSrc = r.meta_source ? `Meta: ${r.meta_source}` : null;
|
const metaSrc = r.meta_source ? `Meta: ${r.meta_source}` : null;
|
||||||
|
|
||||||
const latest = r.latest_version ? `Latest: ${r.latest_version}` : "Latest: unknown";
|
|
||||||
|
|
||||||
const lineBits = [creator, latest, cat, metaSrc].filter(Boolean);
|
const lineBits = [creator, latest, cat, metaSrc].filter(Boolean);
|
||||||
|
|
||||||
return `
|
return `
|
||||||
@@ -552,7 +554,6 @@ class BahmcloudStorePanel extends HTMLElement {
|
|||||||
|
|
||||||
_wireStore() {
|
_wireStore() {
|
||||||
const root = this.shadowRoot;
|
const root = this.shadowRoot;
|
||||||
|
|
||||||
const search = root.getElementById("searchInput");
|
const search = root.getElementById("searchInput");
|
||||||
const cat = root.getElementById("categorySelect");
|
const cat = root.getElementById("categorySelect");
|
||||||
|
|
||||||
@@ -587,7 +588,6 @@ class BahmcloudStorePanel extends HTMLElement {
|
|||||||
: `<span class="badge">Index</span>`;
|
: `<span class="badge">Index</span>`;
|
||||||
|
|
||||||
const desc = r.description || "No description available.";
|
const desc = r.description || "No description available.";
|
||||||
|
|
||||||
const latest = r.latest_version ? `Latest: ${r.latest_version}` : "Latest: unknown";
|
const latest = r.latest_version ? `Latest: ${r.latest_version}` : "Latest: unknown";
|
||||||
|
|
||||||
const infoBits = [
|
const infoBits = [
|
||||||
@@ -659,6 +659,60 @@ class BahmcloudStorePanel extends HTMLElement {
|
|||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async _mountPrettyMarkdown(container, markdown) {
|
||||||
|
// token prevents race conditions when switching repos fast
|
||||||
|
const token = ++this._mdMountToken;
|
||||||
|
|
||||||
|
container.innerHTML = "";
|
||||||
|
|
||||||
|
// If user switched views/repo while we were waiting
|
||||||
|
const stillValid = () => token === this._mdMountToken && this._view === "detail" && !!this._readmeText;
|
||||||
|
|
||||||
|
// Wait until HA registers the component
|
||||||
|
try {
|
||||||
|
await customElements.whenDefined("ha-markdown");
|
||||||
|
} catch (_) {
|
||||||
|
// ignored
|
||||||
|
}
|
||||||
|
if (!stillValid()) return;
|
||||||
|
|
||||||
|
// Create markdown element
|
||||||
|
let el;
|
||||||
|
try {
|
||||||
|
el = document.createElement("ha-markdown");
|
||||||
|
} catch (_) {
|
||||||
|
el = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If creation failed, fallback to plain pre
|
||||||
|
if (!el) {
|
||||||
|
const pre = document.createElement("pre");
|
||||||
|
pre.className = "readme";
|
||||||
|
pre.textContent = markdown;
|
||||||
|
container.appendChild(pre);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Attach first (some HA internals react after connection)
|
||||||
|
container.appendChild(el);
|
||||||
|
|
||||||
|
// Set hass + content
|
||||||
|
try { el.hass = this._hass; } catch (_) {}
|
||||||
|
try { el.content = markdown; } catch (_) {
|
||||||
|
// some builds used `markdown` property in the past
|
||||||
|
try { el.markdown = markdown; } catch (_) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Nudge render (some builds need a microtask/frame after setting properties)
|
||||||
|
await new Promise((resolve) => requestAnimationFrame(resolve));
|
||||||
|
if (!stillValid()) return;
|
||||||
|
|
||||||
|
try { el.hass = this._hass; } catch (_) {}
|
||||||
|
try { el.content = markdown; } catch (_) {
|
||||||
|
try { el.markdown = markdown; } catch (_) {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
_wireDetail() {
|
_wireDetail() {
|
||||||
const root = this.shadowRoot;
|
const root = this.shadowRoot;
|
||||||
const container = root.getElementById("readmeContainer");
|
const container = root.getElementById("readmeContainer");
|
||||||
@@ -668,26 +722,8 @@ class BahmcloudStorePanel extends HTMLElement {
|
|||||||
|
|
||||||
if (!this._readmeText) return;
|
if (!this._readmeText) return;
|
||||||
|
|
||||||
// Only attempt ha-markdown if the custom element exists
|
// Always try pretty markdown; raw fallback is already available in <details>
|
||||||
const hasHaMarkdown = typeof customElements !== "undefined" && !!customElements.get("ha-markdown");
|
this._mountPrettyMarkdown(container, this._readmeText);
|
||||||
|
|
||||||
if (hasHaMarkdown) {
|
|
||||||
try {
|
|
||||||
const el = document.createElement("ha-markdown");
|
|
||||||
try { el.hass = this._hass; } catch (_) {}
|
|
||||||
el.content = this._readmeText;
|
|
||||||
container.appendChild(el);
|
|
||||||
return;
|
|
||||||
} catch (_) {
|
|
||||||
// fall through to raw fallback (details already exists)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// If ha-markdown is missing, show a minimal rendered area:
|
|
||||||
const pre = document.createElement("pre");
|
|
||||||
pre.className = "readme";
|
|
||||||
pre.textContent = this._readmeText;
|
|
||||||
container.appendChild(pre);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_renderFabs() {
|
_renderFabs() {
|
||||||
|
|||||||
Reference in New Issue
Block a user