hass-browser_mod/js/plugin/require-interact.ts

84 lines
2.1 KiB
TypeScript

export const RequireInteractMixin = (SuperClass) => {
return class RequireInteractMixinClass extends SuperClass {
private _interactionResolve;
public firstInteraction = new Promise((resolve) => {
this._interactionResolve = resolve;
});
constructor() {
super();
this.show_indicator();
}
async show_indicator() {
await this.connectionPromise;
if (!this.registered) return;
const interactSymbol = document.createElement("div");
document.body.append(interactSymbol);
interactSymbol.classList.add("browser-mod-require-interaction");
interactSymbol.attachShadow({ mode: "open" });
const styleEl = document.createElement("style");
interactSymbol.shadowRoot.append(styleEl);
styleEl.innerHTML = `
:host {
position: fixed;
right: 8px;
bottom: 8px;
color: var(--warning-color, red);
opacity: 0.5;
--mdc-icon-size: 48px;
}
ha-icon::before {
content: "Browser\\00a0Mod";
font-size: 0.75rem;
position: absolute;
right: 0;
bottom: 90%;
}
video {
display: none;
}
`;
const icon = document.createElement("ha-icon");
interactSymbol.shadowRoot.append(icon);
(icon as any).icon = "mdi:gesture-tap";
// If we are allowed to play a video, we can assume no interaction is needed
const video = (this._video = document.createElement("video"));
interactSymbol.shadowRoot.append(video);
const vPlay = video.play();
if (vPlay) {
vPlay
.then(() => {
this._interactionResolve();
video.pause();
})
.catch((e) => {
if (e.name === "AbortError") {
this._interactionResolve();
}
});
}
window.addEventListener(
"pointerdown",
() => {
this._interactionResolve();
},
{ once: true }
);
// if (this.fully) this._interactionResolve();
await this.firstInteraction;
interactSymbol.remove();
}
};
};