Refactor interaction requirement. Add indicator
This commit is contained in:
parent
a3cd0c9fd6
commit
1109980d61
@ -812,9 +812,11 @@ const ScreenSaverMixin = (SuperClass) => {
|
|||||||
this._listeners = {};
|
this._listeners = {};
|
||||||
this._brightness = 255;
|
this._brightness = 255;
|
||||||
const panel = (this._panel = document.createElement("div"));
|
const panel = (this._panel = document.createElement("div"));
|
||||||
panel.setAttribute("browser-mod", "");
|
document.body.append(panel);
|
||||||
|
panel.classList.add("browser-mod-blackout");
|
||||||
panel.attachShadow({ mode: "open" });
|
panel.attachShadow({ mode: "open" });
|
||||||
const styleEl = document.createElement("style");
|
const styleEl = document.createElement("style");
|
||||||
|
panel.shadowRoot.append(styleEl);
|
||||||
styleEl.innerHTML = `
|
styleEl.innerHTML = `
|
||||||
:host {
|
:host {
|
||||||
background: rgba(0,0,0, var(--darkness));
|
background: rgba(0,0,0, var(--darkness));
|
||||||
@ -833,8 +835,6 @@ const ScreenSaverMixin = (SuperClass) => {
|
|||||||
background: rgba(0,0,0,1);
|
background: rgba(0,0,0,1);
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
panel.shadowRoot.appendChild(styleEl);
|
|
||||||
document.body.appendChild(panel);
|
|
||||||
this.addEventListener("command-screen_off", () => this._screen_off());
|
this.addEventListener("command-screen_off", () => this._screen_off());
|
||||||
this.addEventListener("command-screen_on", (ev) => this._screen_on(ev));
|
this.addEventListener("command-screen_on", (ev) => this._screen_on(ev));
|
||||||
this.connectionPromise.then(() => this._screen_on());
|
this.connectionPromise.then(() => this._screen_on());
|
||||||
@ -882,11 +882,11 @@ const MediaPlayerMixin = (SuperClass) => {
|
|||||||
for (const ev of ["play", "pause", "ended", "volumechange"]) {
|
for (const ev of ["play", "pause", "ended", "volumechange"]) {
|
||||||
this.player.addEventListener(ev, () => this._player_update());
|
this.player.addEventListener(ev, () => this._player_update());
|
||||||
}
|
}
|
||||||
window.addEventListener("pointerdown", () => {
|
this.firstInteraction.then(() => {
|
||||||
this._player_enabled = true;
|
this._player_enabled = true;
|
||||||
if (!this.player.ended)
|
if (!this.player.ended)
|
||||||
this.player.play();
|
this.player.play();
|
||||||
}, { once: true });
|
});
|
||||||
this.addEventListener("command-player-play", (ev) => {
|
this.addEventListener("command-player-play", (ev) => {
|
||||||
var _a;
|
var _a;
|
||||||
if ((_a = ev.detail) === null || _a === void 0 ? void 0 : _a.media_content_id)
|
if ((_a = ev.detail) === null || _a === void 0 ? void 0 : _a.media_content_id)
|
||||||
@ -940,24 +940,33 @@ const CameraMixin = (SuperClass) => {
|
|||||||
constructor() {
|
constructor() {
|
||||||
super();
|
super();
|
||||||
this._framerate = 2;
|
this._framerate = 2;
|
||||||
window.addEventListener("pointerdown", () => {
|
this._setup_camera();
|
||||||
this._setup_camera();
|
|
||||||
}, { once: true });
|
|
||||||
}
|
}
|
||||||
async _setup_camera() {
|
async _setup_camera() {
|
||||||
if (this._video)
|
if (this._video)
|
||||||
return;
|
return;
|
||||||
await this.connectionPromise;
|
await this.connectionPromise;
|
||||||
|
await this.firstInteraction;
|
||||||
if (!this.cameraEnabled)
|
if (!this.cameraEnabled)
|
||||||
return;
|
return;
|
||||||
|
const div = document.createElement("div");
|
||||||
|
document.body.append(div);
|
||||||
|
div.classList.add("browser-mod-camera");
|
||||||
|
div.attachShadow({ mode: "open" });
|
||||||
|
const styleEl = document.createElement("style");
|
||||||
|
div.shadowRoot.append(styleEl);
|
||||||
|
styleEl.innerHTML = `
|
||||||
|
:host {
|
||||||
|
display: none;
|
||||||
|
}`;
|
||||||
const video = (this._video = document.createElement("video"));
|
const video = (this._video = document.createElement("video"));
|
||||||
|
div.shadowRoot.append(video);
|
||||||
video.autoplay = true;
|
video.autoplay = true;
|
||||||
video.playsInline = true;
|
video.playsInline = true;
|
||||||
video.style.display = "none";
|
video.style.display = "none";
|
||||||
const canvas = (this._canvas = document.createElement("canvas"));
|
const canvas = (this._canvas = document.createElement("canvas"));
|
||||||
|
div.shadowRoot.append(canvas);
|
||||||
canvas.style.display = "none";
|
canvas.style.display = "none";
|
||||||
document.body.appendChild(video);
|
|
||||||
document.body.appendChild(canvas);
|
|
||||||
if (!navigator.mediaDevices)
|
if (!navigator.mediaDevices)
|
||||||
return;
|
return;
|
||||||
const stream = await navigator.mediaDevices.getUserMedia({
|
const stream = await navigator.mediaDevices.getUserMedia({
|
||||||
@ -994,6 +1003,44 @@ const CameraMixin = (SuperClass) => {
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const RequireInteractMixin = (SuperClass) => {
|
||||||
|
return class RequireInteractMixinClass extends SuperClass {
|
||||||
|
constructor() {
|
||||||
|
super();
|
||||||
|
this.firstInteraction = new Promise((resolve) => {
|
||||||
|
this._interactionResolve = resolve;
|
||||||
|
});
|
||||||
|
window.addEventListener("pointerdown", this._interactionResolve);
|
||||||
|
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;
|
||||||
|
}`;
|
||||||
|
const icon = document.createElement("ha-icon");
|
||||||
|
interactSymbol.shadowRoot.append(icon);
|
||||||
|
icon.icon = "mdi:gesture-tap";
|
||||||
|
await this.firstInteraction;
|
||||||
|
interactSymbol.remove();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
var name = "browser_mod";
|
var name = "browser_mod";
|
||||||
var version = "2.0.0b0";
|
var version = "2.0.0b0";
|
||||||
var description = "";
|
var description = "";
|
||||||
@ -1041,7 +1088,7 @@ var pjson = {
|
|||||||
// FullyKioskMixin,
|
// FullyKioskMixin,
|
||||||
// BrowserModMediaPlayerMixin,
|
// BrowserModMediaPlayerMixin,
|
||||||
// ]) {
|
// ]) {
|
||||||
class BrowserMod extends CameraMixin(MediaPlayerMixin(ScreenSaverMixin(ConnectionMixin(EventTarget)))) {
|
class BrowserMod extends CameraMixin(MediaPlayerMixin(ScreenSaverMixin(RequireInteractMixin(ConnectionMixin(EventTarget))))) {
|
||||||
constructor() {
|
constructor() {
|
||||||
super();
|
super();
|
||||||
this.entity_id = deviceID.replace("-", "_");
|
this.entity_id = deviceID.replace("-", "_");
|
||||||
|
@ -60,6 +60,7 @@ const i=(i,e)=>"method"===e.kind&&e.descriptor&&!("value"in e.descriptor)?{...e,
|
|||||||
*/var n;null!=(null===(n=window.HTMLSlotElement)||void 0===n?void 0:n.prototype.assignedElements)?(o,n)=>o.assignedElements(n):(o,n)=>o.assignedNodes(n).filter((o=>o.nodeType===Node.ELEMENT_NODE));
|
*/var n;null!=(null===(n=window.HTMLSlotElement)||void 0===n?void 0:n.prototype.assignedElements)?(o,n)=>o.assignedElements(n):(o,n)=>o.assignedNodes(n).filter((o=>o.nodeType===Node.ELEMENT_NODE));
|
||||||
|
|
||||||
// Loads in ha-config-dashboard which is used to copy styling
|
// Loads in ha-config-dashboard which is used to copy styling
|
||||||
|
// Also provides ha-settings-row
|
||||||
const loadDevTools = async () => {
|
const loadDevTools = async () => {
|
||||||
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l;
|
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l;
|
||||||
if (customElements.get("ha-config-dashboard"))
|
if (customElements.get("ha-config-dashboard"))
|
||||||
@ -202,19 +203,12 @@ loadDevTools().then(() => {
|
|||||||
>
|
>
|
||||||
<ha-icon .icon=${"mdi:delete"}></ha-icon>
|
<ha-icon .icon=${"mdi:delete"}></ha-icon>
|
||||||
</ha-icon-button>
|
</ha-icon-button>
|
||||||
<ha-icon-button>
|
|
||||||
<ha-icon .icon=${"mdi:wrench"}></ha-icon>
|
|
||||||
</ha-icon-button>
|
|
||||||
</ha-settings-row>`)}
|
</ha-settings-row>`)}
|
||||||
</div>
|
</div>
|
||||||
</ha-card>
|
</ha-card>
|
||||||
|
|
||||||
<ha-card outlined header="Tweaks">
|
<ha-card outlined header="Tweaks">
|
||||||
<div class="card-content">
|
<div class="card-content">
|
||||||
<ha-settings-row>
|
|
||||||
<span slot="heading">Auto enable devices</span>
|
|
||||||
<ha-switch></ha-switch>
|
|
||||||
</ha-settings-row>
|
|
||||||
<ha-settings-row>
|
<ha-settings-row>
|
||||||
<span slot="heading">User sidebar</span>
|
<span slot="heading">User sidebar</span>
|
||||||
<span slot="description"
|
<span slot="description"
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
// Loads in ha-config-dashboard which is used to copy styling
|
// Loads in ha-config-dashboard which is used to copy styling
|
||||||
|
// Also provides ha-settings-row
|
||||||
export const loadDevTools = async () => {
|
export const loadDevTools = async () => {
|
||||||
if (customElements.get("ha-config-dashboard")) return;
|
if (customElements.get("ha-config-dashboard")) return;
|
||||||
const ppResolver = document.createElement("partial-panel-resolver");
|
const ppResolver = document.createElement("partial-panel-resolver");
|
||||||
|
@ -134,9 +134,6 @@ loadDevTools().then(() => {
|
|||||||
>
|
>
|
||||||
<ha-icon .icon=${"mdi:delete"}></ha-icon>
|
<ha-icon .icon=${"mdi:delete"}></ha-icon>
|
||||||
</ha-icon-button>
|
</ha-icon-button>
|
||||||
<ha-icon-button>
|
|
||||||
<ha-icon .icon=${"mdi:wrench"}></ha-icon>
|
|
||||||
</ha-icon-button>
|
|
||||||
</ha-settings-row>`
|
</ha-settings-row>`
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
@ -144,10 +141,6 @@ loadDevTools().then(() => {
|
|||||||
|
|
||||||
<ha-card outlined header="Tweaks">
|
<ha-card outlined header="Tweaks">
|
||||||
<div class="card-content">
|
<div class="card-content">
|
||||||
<ha-settings-row>
|
|
||||||
<span slot="heading">Auto enable devices</span>
|
|
||||||
<ha-switch></ha-switch>
|
|
||||||
</ha-settings-row>
|
|
||||||
<ha-settings-row>
|
<ha-settings-row>
|
||||||
<span slot="heading">User sidebar</span>
|
<span slot="heading">User sidebar</span>
|
||||||
<span slot="description"
|
<span slot="description"
|
||||||
|
@ -8,30 +8,37 @@ export const CameraMixin = (SuperClass) => {
|
|||||||
super();
|
super();
|
||||||
this._framerate = 2;
|
this._framerate = 2;
|
||||||
|
|
||||||
window.addEventListener(
|
this._setup_camera();
|
||||||
"pointerdown",
|
|
||||||
() => {
|
|
||||||
this._setup_camera();
|
|
||||||
},
|
|
||||||
{ once: true }
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async _setup_camera() {
|
async _setup_camera() {
|
||||||
if (this._video) return;
|
if (this._video) return;
|
||||||
await this.connectionPromise;
|
await this.connectionPromise;
|
||||||
|
await this.firstInteraction;
|
||||||
if (!this.cameraEnabled) return;
|
if (!this.cameraEnabled) return;
|
||||||
|
|
||||||
|
const div = document.createElement("div");
|
||||||
|
document.body.append(div);
|
||||||
|
div.classList.add("browser-mod-camera");
|
||||||
|
div.attachShadow({ mode: "open" });
|
||||||
|
|
||||||
|
const styleEl = document.createElement("style");
|
||||||
|
div.shadowRoot.append(styleEl);
|
||||||
|
styleEl.innerHTML = `
|
||||||
|
:host {
|
||||||
|
display: none;
|
||||||
|
}`;
|
||||||
|
|
||||||
const video = (this._video = document.createElement("video"));
|
const video = (this._video = document.createElement("video"));
|
||||||
|
div.shadowRoot.append(video);
|
||||||
video.autoplay = true;
|
video.autoplay = true;
|
||||||
video.playsInline = true;
|
video.playsInline = true;
|
||||||
video.style.display = "none";
|
video.style.display = "none";
|
||||||
|
|
||||||
const canvas = (this._canvas = document.createElement("canvas"));
|
const canvas = (this._canvas = document.createElement("canvas"));
|
||||||
|
div.shadowRoot.append(canvas);
|
||||||
canvas.style.display = "none";
|
canvas.style.display = "none";
|
||||||
|
|
||||||
document.body.appendChild(video);
|
|
||||||
document.body.appendChild(canvas);
|
|
||||||
|
|
||||||
if (!navigator.mediaDevices) return;
|
if (!navigator.mediaDevices) return;
|
||||||
|
|
||||||
const stream = await navigator.mediaDevices.getUserMedia({
|
const stream = await navigator.mediaDevices.getUserMedia({
|
||||||
|
@ -10,6 +10,7 @@ import { ConnectionMixin } from "./connection";
|
|||||||
import { ScreenSaverMixin } from "./screensaver";
|
import { ScreenSaverMixin } from "./screensaver";
|
||||||
import { MediaPlayerMixin } from "./mediaPlayer";
|
import { MediaPlayerMixin } from "./mediaPlayer";
|
||||||
import { CameraMixin } from "./camera";
|
import { CameraMixin } from "./camera";
|
||||||
|
import { RequireInteractMixin } from "./require-interact";
|
||||||
import { FullyKioskMixin } from "./fullyKiosk";
|
import { FullyKioskMixin } from "./fullyKiosk";
|
||||||
import { BrowserModScreensaverMixin } from "./screensaver";
|
import { BrowserModScreensaverMixin } from "./screensaver";
|
||||||
import { BrowserModPopupsMixin } from "./popups";
|
import { BrowserModPopupsMixin } from "./popups";
|
||||||
@ -28,7 +29,9 @@ const ext = (baseClass, mixins) =>
|
|||||||
// BrowserModMediaPlayerMixin,
|
// BrowserModMediaPlayerMixin,
|
||||||
// ]) {
|
// ]) {
|
||||||
export class BrowserMod extends CameraMixin(
|
export class BrowserMod extends CameraMixin(
|
||||||
MediaPlayerMixin(ScreenSaverMixin(ConnectionMixin(EventTarget)))
|
MediaPlayerMixin(
|
||||||
|
ScreenSaverMixin(RequireInteractMixin(ConnectionMixin(EventTarget)))
|
||||||
|
)
|
||||||
) {
|
) {
|
||||||
constructor() {
|
constructor() {
|
||||||
super();
|
super();
|
||||||
|
@ -13,14 +13,10 @@ export const MediaPlayerMixin = (SuperClass) => {
|
|||||||
this.player.addEventListener(ev, () => this._player_update());
|
this.player.addEventListener(ev, () => this._player_update());
|
||||||
}
|
}
|
||||||
|
|
||||||
window.addEventListener(
|
this.firstInteraction.then(() => {
|
||||||
"pointerdown",
|
this._player_enabled = true;
|
||||||
() => {
|
if (!this.player.ended) this.player.play();
|
||||||
this._player_enabled = true;
|
});
|
||||||
if (!this.player.ended) this.player.play();
|
|
||||||
},
|
|
||||||
{ once: true }
|
|
||||||
);
|
|
||||||
|
|
||||||
this.addEventListener("command-player-play", (ev) => {
|
this.addEventListener("command-player-play", (ev) => {
|
||||||
if (ev.detail?.media_content_id)
|
if (ev.detail?.media_content_id)
|
||||||
|
47
js/plugin/require-interact.ts
Normal file
47
js/plugin/require-interact.ts
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
export const RequireInteractMixin = (SuperClass) => {
|
||||||
|
return class RequireInteractMixinClass extends SuperClass {
|
||||||
|
private _interactionResolve;
|
||||||
|
public firstInteraction = new Promise((resolve) => {
|
||||||
|
this._interactionResolve = resolve;
|
||||||
|
});
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
super();
|
||||||
|
|
||||||
|
window.addEventListener("pointerdown", this._interactionResolve);
|
||||||
|
|
||||||
|
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;
|
||||||
|
}`;
|
||||||
|
|
||||||
|
const icon = document.createElement("ha-icon");
|
||||||
|
interactSymbol.shadowRoot.append(icon);
|
||||||
|
(icon as any).icon = "mdi:gesture-tap";
|
||||||
|
|
||||||
|
await this.firstInteraction;
|
||||||
|
interactSymbol.remove();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
};
|
@ -8,9 +8,12 @@ export const ScreenSaverMixin = (SuperClass) => {
|
|||||||
super();
|
super();
|
||||||
|
|
||||||
const panel = (this._panel = document.createElement("div"));
|
const panel = (this._panel = document.createElement("div"));
|
||||||
panel.setAttribute("browser-mod", "");
|
document.body.append(panel);
|
||||||
|
panel.classList.add("browser-mod-blackout");
|
||||||
panel.attachShadow({ mode: "open" });
|
panel.attachShadow({ mode: "open" });
|
||||||
|
|
||||||
const styleEl = document.createElement("style");
|
const styleEl = document.createElement("style");
|
||||||
|
panel.shadowRoot.append(styleEl);
|
||||||
styleEl.innerHTML = `
|
styleEl.innerHTML = `
|
||||||
:host {
|
:host {
|
||||||
background: rgba(0,0,0, var(--darkness));
|
background: rgba(0,0,0, var(--darkness));
|
||||||
@ -29,8 +32,6 @@ export const ScreenSaverMixin = (SuperClass) => {
|
|||||||
background: rgba(0,0,0,1);
|
background: rgba(0,0,0,1);
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
panel.shadowRoot.appendChild(styleEl);
|
|
||||||
document.body.appendChild(panel);
|
|
||||||
|
|
||||||
this.addEventListener("command-screen_off", () => this._screen_off());
|
this.addEventListener("command-screen_off", () => this._screen_off());
|
||||||
this.addEventListener("command-screen_on", (ev) => this._screen_on(ev));
|
this.addEventListener("command-screen_on", (ev) => this._screen_on(ev));
|
||||||
|
Loading…
x
Reference in New Issue
Block a user