Linting and remove duplicate code

This commit is contained in:
Thomas Lovén 2021-05-10 09:41:47 +00:00
parent f342c20b91
commit f4ca95d436
14 changed files with 1356 additions and 3754 deletions

File diff suppressed because one or more lines are too long

View File

@ -1,30 +1,28 @@
import { registerCard } from "card-tools/src/editor"; const bases = [
customElements.whenDefined("home-assistant-main"),
const bases = [customElements.whenDefined('home-assistant-main'), customElements.whenDefined('hui-view')]; customElements.whenDefined("hui-view"),
];
Promise.race(bases).then(() => { Promise.race(bases).then(() => {
const LitElement = customElements.get("home-assistant-main")
const LitElement = customElements.get('home-assistant-main') ? Object.getPrototypeOf(customElements.get("home-assistant-main"))
? Object.getPrototypeOf(customElements.get('home-assistant-main')) : Object.getPrototypeOf(customElements.get("hui-view"));
: Object.getPrototypeOf(customElements.get('hui-view'));
const html = LitElement.prototype.html; const html = LitElement.prototype.html;
const css = LitElement.prototype.css; const css = LitElement.prototype.css;
class BrowserPlayerEditor extends LitElement { class BrowserPlayerEditor extends LitElement {
setConfig(config) { setConfig(config) {}
render() {
} return html` <div>Nothing to configure.</div> `;
render() { }
return html`
<div>
Nothing to configure.
</div>
`;
}
} }
if(!customElements.get("browser-player-editor")) { if (!customElements.get("browser-player-editor")) {
customElements.define("browser-player-editor", BrowserPlayerEditor); customElements.define("browser-player-editor", BrowserPlayerEditor);
window.customCards = window.customCards || []; window.customCards = window.customCards || [];
window.customCards.push({type:"browser-player", name: "Browser Player", preview: true}); window.customCards.push({
type: "browser-player",
name: "Browser Player",
preview: true,
});
} }
}); });

View File

@ -1,138 +1,136 @@
import { deviceID, setDeviceID } from "card-tools/src/deviceId" import { deviceID, setDeviceID } from "card-tools/src/deviceID";
import { moreInfo } from "card-tools/src/more-info" import { moreInfo } from "card-tools/src/more-info";
import "./browser-player-editor.js" import "./browser-player-editor.js";
const bases = [customElements.whenDefined('home-assistant-main'), customElements.whenDefined('hui-view')]; const bases = [
customElements.whenDefined("home-assistant-main"),
customElements.whenDefined("hui-view"),
];
Promise.race(bases).then(() => { Promise.race(bases).then(() => {
const LitElement = customElements.get("home-assistant-main")
? Object.getPrototypeOf(customElements.get("home-assistant-main"))
: Object.getPrototypeOf(customElements.get("hui-view"));
const html = LitElement.prototype.html;
const css = LitElement.prototype.css;
const LitElement = customElements.get('home-assistant-main') class BrowserPlayer extends LitElement {
? Object.getPrototypeOf(customElements.get('home-assistant-main')) static get properties() {
: Object.getPrototypeOf(customElements.get('hui-view')); return {
const html = LitElement.prototype.html; hass: {},
const css = LitElement.prototype.css; };
class BrowserPlayer extends LitElement {
static get properties() {
return {
hass: {},
};
}
static getConfigElement() {
return document.createElement("browser-player-editor");
}
static getStubConfig() {
return {};
}
setConfig(config) {
this._config = config;
for (const event of ["play", "pause", "ended", "volumechange", "canplay", "loadeddata"])
window.browser_mod.player.addEventListener(event, () => this.requestUpdate());
}
handleMute(ev) {
window.browser_mod.player_mute();
}
handleVolumeChange(ev) {
const vol = parseFloat(ev.target.value);
window.browser_mod.player_set_volume(vol);
}
handleMoreInfo(ev) {
moreInfo("media_player."+window.browser_mod.entity_id);
}
handlePlayPause(ev) {
if (window.browser_mod.player.paused)
window.browser_mod.player_play();
else
window.browser_mod.player_pause();
}
setDeviceID() {
const newID = prompt("Set deviceID", deviceID);
if (newID !== deviceID) {
setDeviceID(newID);
this.requestUpdate();
} }
}
render() { static getConfigElement() {
if(!window.browser_mod) { return document.createElement("browser-player-editor");
window.setTimeout(() => this.requestUpdate(), 100);
return html``;
} }
const player = window.browser_mod.player; static getStubConfig() {
return html` return {};
<ha-card> }
<div class="card-content">
<ha-icon-button setConfig(config) {
.icon=${player.muted this._config = config;
? "mdi:volume-off" for (const event of [
: "mdi:volume-high" "play",
"pause",
"ended",
"volumechange",
"canplay",
"loadeddata",
])
window.browser_mod.player.addEventListener(event, () =>
this.requestUpdate()
);
}
handleMute(ev) {
window.browser_mod.player_mute();
}
handleVolumeChange(ev) {
const vol = parseFloat(ev.target.value);
window.browser_mod.player_set_volume(vol);
}
handleMoreInfo(ev) {
moreInfo("media_player." + window.browser_mod.entity_id);
}
handlePlayPause(ev) {
if (window.browser_mod.player.paused) window.browser_mod.player_play();
else window.browser_mod.player_pause();
}
setDeviceID() {
const newID = prompt("Set deviceID", deviceID);
if (newID !== deviceID) {
setDeviceID(newID);
this.requestUpdate();
}
}
render() {
if (!window.browser_mod) {
window.setTimeout(() => this.requestUpdate(), 100);
return html``;
}
const player = window.browser_mod.player;
return html`
<ha-card>
<div class="card-content">
<ha-icon-button
.icon=${player.muted ? "mdi:volume-off" : "mdi:volume-high"}
@click=${this.handleMute}
></ha-icon-button>
<ha-slider
min="0"
max="1"
step="0.01"
?disabled=${player.muted}
value=${player.volume}
@change=${this.handleVolumeChange}
></ha-slider>
${window.browser_mod.player_state === "stopped"
? html`<div class="placeholder"></div>`
: html`
<ha-icon-button
.icon=${player.paused ? "mdi:play" : "mdi:pause"}
@click=${this.handlePlayPause}
highlight
></ha-icon-button>
`}
<ha-icon-button
.icon=${"mdi:cog"}
@click=${this.handleMoreInfo}
></ha-icon-button>
</div>
<div class="device-id" @click=${this.setDeviceID}>${deviceID}</div>
</ha-card>
`;
}
static get styles() {
return css`
paper-icon-button[highlight] {
color: var(--accent-color);
} }
@click=${this.handleMute} .card-content {
></ha-icon-button> display: flex;
<ha-slider justify-content: center;
min=0 }
max=1 .placeholder {
step=0.01 width: 24px;
?disabled=${player.muted} padding: 8px;
value=${player.volume} }
@change=${this.handleVolumeChange} .device-id {
></ha-slider> opacity: 0.7;
font-size: xx-small;
${window.browser_mod.player_state === "stopped" margin-top: -10px;
? html`<div class="placeholder"></div>` user-select: all;
: html` -webkit-user-select: all;
<ha-icon-button -moz-user-select: all;
.icon=${player.paused -ms-user-select: all;
? "mdi:play" }
: "mdi:pause" `;
} }
@click=${this.handlePlayPause}
highlight
></ha-icon-button>
`}
<ha-icon-button
.icon=${"mdi:cog"}
@click=${this.handleMoreInfo}
></ha-icon-button>
</div>
<div class="device-id" @click=${this.setDeviceID}>
${deviceID}
</div>
</ha-card>
`;
} }
static get styles() { if (!customElements.get("browser-player"))
return css` customElements.define("browser-player", BrowserPlayer);
paper-icon-button[highlight] {
color: var(--accent-color);
}
.card-content {
display: flex;
justify-content: center;
}
.placeholder {
width: 24px;
padding: 8px;
}
.device-id {
opacity: 0.7;
font-size: xx-small;
margin-top: -10px;
user-select: all;
-webkit-user-select: all;
-moz-user-select: all;
-ms-user-select: all;
}
`
}
}
if(!customElements.get("browser-player"))
customElements.define("browser-player", BrowserPlayer);
}); });

View File

@ -1,36 +1,52 @@
import { fireEvent } from "card-tools/src/event"; import { fireEvent } from "card-tools/src/event";
export const BrowserModBrowserMixin = (C) => class extends C { export const BrowserModBrowserMixin = (C) =>
class extends C {
constructor() { constructor() {
super(); super();
document.addEventListener("visibilitychange", () => this.sensor_update()); document.addEventListener("visibilitychange", () => this.sensor_update());
window.addEventListener("location-changed", () => this.sensor_update()); window.addEventListener("location-changed", () => this.sensor_update());
window.setInterval(() => this.sensor_update(), 10000); window.setInterval(() => this.sensor_update(), 10000);
} }
sensor_update() { sensor_update() {
const update = async () => { const update = async () => {
const battery = navigator.getBattery ? await navigator.getBattery() : undefined; const battery = navigator.getBattery
this.sendUpdate({browser: { ? await navigator.getBattery()
path: window.location.pathname, : undefined;
visibility: document.visibilityState, this.sendUpdate({
userAgent: navigator.userAgent, browser: {
currentUser: this._hass &&this._hass.user && this._hass.user.name, path: window.location.pathname,
fullyKiosk: this.isFully, visibility: document.visibilityState,
width: window.innerWidth, userAgent: navigator.userAgent,
height: window.innerHeight, currentUser: this._hass && this._hass.user && this._hass.user.name,
battery_level: this.isFully ? window.fully.getBatteryLevel() : battery ? battery.level*100 : undefined, fullyKiosk: this.isFully,
charging: this.isFully ? window.fully.isPlugged() : battery ? battery.charging : undefined, width: window.innerWidth,
}}); height: window.innerHeight,
}; battery_level: this.isFully
update(); ? window.fully.getBatteryLevel()
: battery
? battery.level * 100
: undefined,
charging: this.isFully
? window.fully.isPlugged()
: battery
? battery.charging
: undefined,
},
});
};
update();
} }
do_navigate(path) { do_navigate(path) {
if (!path) return; if (!path) return;
history.pushState(null, "", path); history.pushState(null, "", path);
fireEvent("location-changed", {}, document.querySelector("home-assistant")); fireEvent(
"location-changed",
{},
document.querySelector("home-assistant")
);
} }
} };

View File

@ -1,46 +1,57 @@
export const BrowserModCameraMixin = (C) => class extends C { export const BrowserModCameraMixin = (C) =>
class extends C {
setup_camera() { setup_camera() {
console.log("Starting camera");
console.log("Starting camera") if (this._video) return;
this._video = document.createElement("video");
this._video.autoplay = true;
this._video.playsInline = true;
this._video.style.display = "none";
if(this._video) return; this._canvas = document.createElement("canvas");
this._video = document.createElement("video"); this._canvas.style.display = "none";
this._video.autoplay = true;
this._video.playsInline = true;
this._video.style.display = "none";
this._canvas = document.createElement("canvas"); document.body.appendChild(this._video);
this._canvas.style.display = "none"; document.body.appendChild(this._canvas);
document.body.appendChild(this._video); if (!navigator.mediaDevices) return;
document.body.appendChild(this._canvas);
if(!navigator.mediaDevices) return; console.log("Starting devices");
navigator.mediaDevices
.getUserMedia({ video: true, audio: false })
.then((stream) => {
this._video.srcObject = stream;
this._video.play();
this.update_camera();
});
console.log("Starting devices") this._camera_framerate = 2;
navigator.mediaDevices.getUserMedia({video: true, audio: false}).then((stream) => {
this._video.srcObject = stream;
this._video.play();
this.update_camera();
})
this._camera_framerate = 2; window.addEventListener("click", () => this._video.play(), {
once: true,
window.addEventListener("click", () => this._video.play(), {once: true}); });
} }
update_camera() { update_camera() {
this._canvas.width = this._video.videoWidth; this._canvas.width = this._video.videoWidth;
this._canvas.height = this._video.videoHeight; this._canvas.height = this._video.videoHeight;
const context = this._canvas.getContext('2d'); const context = this._canvas.getContext("2d");
context.drawImage(this._video, 0, 0, this._video.videoWidth, this._video.videoHeight); context.drawImage(
this._video,
0,
0,
this._video.videoWidth,
this._video.videoHeight
);
this.sendUpdate({ this.sendUpdate({
camera: this._canvas.toDataURL('image/jpeg'), camera: this._canvas.toDataURL("image/jpeg"),
}); });
setTimeout(() => this.update_camera(), Math.round(1000 / this._camera_framerate)); setTimeout(
() => this.update_camera(),
Math.round(1000 / this._camera_framerate)
);
} }
};
}

View File

@ -1,51 +1,47 @@
import { deviceID } from "card-tools/src/deviceId"; import { deviceID } from "card-tools/src/deviceID";
import { hass, provideHass } from "card-tools/src/hass"; import { hass, provideHass } from "card-tools/src/hass";
export class BrowserModConnection{ export class BrowserModConnection {
async connect() {
async connect() { const isCast = document.querySelector("hc-main") !== null;
const isCast = document.querySelector("hc-main") !== null; if (!isCast) {
if(!isCast) { if (!window.hassConnection) {
if(!window.hassConnection) { window.setTimeout(() => this.connect(), 100);
window.setTimeout(() => this.connect(), 100); return;
return; } else {
} else { this._connection = (await window.hassConnection).conn;
this._connection = (await window.hassConnection).conn; }
} } else {
} else { this._connection = hass().connection;
this._connection = hass().connection;
}
this._connection.subscribeMessage((msg) => this.msg_callback(msg), {
type: 'browser_mod/connect',
deviceID: deviceID,
});
this._hass_patched = false;
provideHass(this);
} }
set hass(hass) { this._connection.subscribeMessage((msg) => this.msg_callback(msg), {
this._hass = hass; type: "browser_mod/connect",
} deviceID: deviceID,
});
get connected() { this._hass_patched = false;
return this._connection !== undefined; provideHass(this);
} }
msg_callback(message) { set hass(hass) {
console.log(message); this._hass = hass;
} }
sendUpdate(data) { get connected() {
if(!this.connected) return; return this._connection !== undefined;
this._connection.sendMessage({ }
type: 'browser_mod/update',
deviceID,
data,
}
)
}
msg_callback(message) {
console.log(message);
}
sendUpdate(data) {
if (!this.connected) return;
this._connection.sendMessage({
type: "browser_mod/update",
deviceID,
data,
});
}
} }

View File

@ -1,59 +1,70 @@
export const FullyKioskMixin = (C) => class extends C { export const FullyKioskMixin = (C) =>
class extends C {
get isFully() { get isFully() {
return window.fully !== undefined; return window.fully !== undefined;
} }
constructor() { constructor() {
super(); super();
if (!this.isFully) return; if (!this.isFully) return;
this._fullyMotion = false; this._fullyMotion = false;
this._motionTimeout = undefined; this._motionTimeout = undefined;
for (const ev of ["screenOn", "screenOff", "pluggedAC", "pluggedUSB", "onBatteryLevelChanged", "unplugged", "networkReconnect", "onMotion"]) { for (const ev of [
window.fully.bind(ev, `window.browser_mod.fully_update("${ev}");`); "screenOn",
} "screenOff",
"pluggedAC",
"pluggedUSB",
"onBatteryLevelChanged",
"unplugged",
"networkReconnect",
"onMotion",
]) {
window.fully.bind(ev, `window.browser_mod.fully_update("${ev}");`);
}
this._keepingAlive = false; this._keepingAlive = false;
} }
fully_update(event) { fully_update(event) {
if(!this.isFully) return if (!this.isFully) return;
if(event === "screenOn") { if (event === "screenOn") {
window.clearTimeout(this._keepAliveTimer); window.clearTimeout(this._keepAliveTimer);
if(!this._keepingAlive) if (!this._keepingAlive) this.screen_update();
this.screen_update(); } else if (event === "screenOff") {
} else if (event === "screenOff") { this.screen_update();
this.screen_update(); this._keepingAlive = false;
this._keepingAlive = false; if (this.config.force_stay_awake) {
if(this.config.force_stay_awake) { this._keepAliveTimer = window.setTimeout(() => {
this._keepAliveTimer = window.setTimeout(() => { this._keepingAlive = true;
this._keepingAlive = true; window.fully.turnScreenOn();
window.fully.turnScreenOn(); window.fully.turnScreenOff();
window.fully.turnScreenOff(); }, 270000);
}, 270000);
}
} else if (event === "onMotion") {
this.fullyMotionTriggered();
} }
} else if (event === "onMotion") {
this.fullyMotionTriggered();
}
this.sendUpdate({fully: { this.sendUpdate({
battery: window.fully.getBatteryLevel(), fully: {
charging: window.fully.isPlugged(), battery: window.fully.getBatteryLevel(),
motion: this._fullyMotion, charging: window.fully.isPlugged(),
ip: window.fully.getIp4Address(), motion: this._fullyMotion,
}}) ip: window.fully.getIp4Address(),
},
});
} }
fullyMotionTriggered() { fullyMotionTriggered() {
if(this._keepingAlive) return; if (this._keepingAlive) return;
this._fullyMotion = true; this._fullyMotion = true;
clearTimeout(this._motionTimeout); clearTimeout(this._motionTimeout);
this._motionTimeout = setTimeout(() => { this._motionTimeout = setTimeout(() => {
this._fullyMotion = false; this._fullyMotion = false;
this.fully_update();
}, 5000);
this.fully_update(); this.fully_update();
}, 5000);
this.fully_update();
} }
} };

View File

@ -1,4 +1,4 @@
import { deviceID } from "card-tools/src/deviceId"; import { deviceID } from "card-tools/src/deviceID";
import { lovelace_view } from "card-tools/src/hass"; import { lovelace_view } from "card-tools/src/hass";
import { popUp } from "card-tools/src/popup"; import { popUp } from "card-tools/src/popup";
import { fireEvent } from "card-tools/src/event"; import { fireEvent } from "card-tools/src/event";
@ -12,7 +12,6 @@ import { BrowserModScreensaverMixin } from "./screensaver";
import { BrowserModPopupsMixin } from "./popups"; import { BrowserModPopupsMixin } from "./popups";
import { BrowserModBrowserMixin } from "./browser"; import { BrowserModBrowserMixin } from "./browser";
const ext = (baseClass, mixins) => const ext = (baseClass, mixins) =>
mixins.reduceRight((base, mixin) => mixin(base), baseClass); mixins.reduceRight((base, mixin) => mixin(base), baseClass);
@ -23,9 +22,7 @@ class BrowserMod extends ext(BrowserModConnection, [
BrowserModCameraMixin, BrowserModCameraMixin,
FullyKioskMixin, FullyKioskMixin,
BrowserModMediaPlayerMixin, BrowserModMediaPlayerMixin,
]) { ]) {
constructor() { constructor() {
super(); super();
this.entity_id = deviceID.replace("-", "_"); this.entity_id = deviceID.replace("-", "_");
@ -33,15 +30,18 @@ class BrowserMod extends ext(BrowserModConnection, [
this.connect(); this.connect();
document.body.addEventListener("ll-custom", (ev) => { document.body.addEventListener("ll-custom", (ev) => {
if(ev.detail.browser_mod) { if (ev.detail.browser_mod) {
this.msg_callback(ev.detail.browser_mod); this.msg_callback(ev.detail.browser_mod);
} }
}) });
const pjson = require('../package.json'); const pjson = require("../package.json");
console.info(`%cBROWSER_MOD ${pjson.version} IS INSTALLED console.info(
`%cBROWSER_MOD ${pjson.version} IS INSTALLED
%cDeviceID: ${deviceID}`, %cDeviceID: ${deviceID}`,
"color: green; font-weight: bold", ""); "color: green; font-weight: bold",
""
);
} }
async msg_callback(msg) { async msg_callback(msg) {
@ -65,83 +65,88 @@ class BrowserMod extends ext(BrowserModConnection, [
"lovelace-reload": (msg) => this.lovelace_reload(msg), "lovelace-reload": (msg) => this.lovelace_reload(msg),
"window-reload": () => window.location.reload(), "window-reload": () => window.location.reload(),
blackout: (msg) => this.do_blackout(msg.time ? parseInt(msg.time) : undefined), blackout: (msg) =>
this.do_blackout(msg.time ? parseInt(msg.time) : undefined),
"no-blackout": (msg) => { "no-blackout": (msg) => {
if(msg.brightness && this.isFully) { if (msg.brightness && this.isFully) {
window.fully.setScreenBrightness(msg.brightness); window.fully.setScreenBrightness(msg.brightness);
} }
this.no_blackout() this.no_blackout();
}, },
"call-service": (msg) => this.call_service(msg), "call-service": (msg) => this.call_service(msg),
"commands": async (msg) => { commands: async (msg) => {
for(const m of msg.commands) { for (const m of msg.commands) {
await this.msg_callback(m); await this.msg_callback(m);
} }
}, },
"delay": async (msg) => await new Promise((resolve) => {window.setTimeout(resolve, msg.seconds*1000)}), delay: async (msg) =>
await new Promise((resolve) => {
window.setTimeout(resolve, msg.seconds * 1000);
}),
}; };
await handlers[msg.command.replace("_","-")](msg); await handlers[msg.command.replace("_", "-")](msg);
} }
debug(msg) { debug(msg) {
popUp(`deviceID`, {type: "markdown", content: `# ${deviceID}`}) popUp(`deviceID`, { type: "markdown", content: `# ${deviceID}` });
alert(deviceID); alert(deviceID);
} }
set_theme(msg){ set_theme(msg) {
if(!msg.theme) msg.theme = "default"; if (!msg.theme) msg.theme = "default";
fireEvent("settheme", {theme: msg.theme}, document.querySelector("home-assistant")); fireEvent(
"settheme",
{ theme: msg.theme },
document.querySelector("home-assistant")
);
} }
lovelace_reload(msg) { lovelace_reload(msg) {
const ll = lovelace_view(); const ll = lovelace_view();
if (ll) if (ll) fireEvent("config-refresh", {}, ll);
fireEvent("config-refresh", {}, ll);
} }
call_service(msg) { call_service(msg) {
const _replaceThis = (data) => { const _replaceThis = (data) => {
if (typeof(data) === "string" && data === "this") if (typeof data === "string" && data === "this") return deviceID;
return deviceID; if (Array.isArray(data)) return data.map(_replaceThis);
if (Array.isArray(data))
return data.map(_replaceThis);
if (data.constructor == Object) { if (data.constructor == Object) {
for (const key in data) for (const key in data) data[key] = _replaceThis(data[key]);
data[key] = _replaceThis(data[key]);
} }
return data; return data;
} };
const [domain, service] = msg.service.split(".", 2); const [domain, service] = msg.service.split(".", 2);
let service_data = _replaceThis(JSON.parse(JSON.stringify(msg.service_data))); let service_data = _replaceThis(
JSON.parse(JSON.stringify(msg.service_data))
);
this._hass.callService(domain, service, service_data); this._hass.callService(domain, service, service_data);
} }
update(msg=null) { update(msg = null) {
if(msg) { if (msg) {
if(msg.name) { if (msg.name) {
this.entity_id = msg.name.toLowerCase(); this.entity_id = msg.name.toLowerCase();
} }
if(msg.camera) { if (msg.camera) {
this.setup_camera(); this.setup_camera();
} }
this.config = {...this.config, ...msg}; this.config = { ...this.config, ...msg };
} }
this.player_update(); this.player_update();
this.fully_update(); this.fully_update();
this.screen_update(); this.screen_update();
this.sensor_update(); this.sensor_update();
} }
} }
const bases = [
const bases = [customElements.whenDefined('home-assistant'), customElements.whenDefined('hc-main')]; customElements.whenDefined("home-assistant"),
customElements.whenDefined("hc-main"),
];
Promise.race(bases).then(() => { Promise.race(bases).then(() => {
window.setTimeout(() => { window.setTimeout(() => {
window.browser_mod = window.browser_mod || new BrowserMod(); window.browser_mod = window.browser_mod || new BrowserMod();
}, }, 1000);
1000
);
}); });

View File

@ -1,51 +1,53 @@
export const BrowserModMediaPlayerMixin = (C) => class extends C { export const BrowserModMediaPlayerMixin = (C) =>
class extends C {
constructor() { constructor() {
super(); super();
this.player = new Audio(); this.player = new Audio();
for (const event of ["play", "pause", "ended", "volumechange"]) { for (const event of ["play", "pause", "ended", "volumechange"]) {
this.player.addEventListener(event, () => this.player_update()); this.player.addEventListener(event, () => this.player_update());
} }
window.addEventListener("click", () => this.player.play(), {once: true}); window.addEventListener("click", () => this.player.play(), {
once: true,
});
} }
player_update(ev) { player_update(ev) {
this.sendUpdate({player: { this.sendUpdate({
volume: this.player.volume, player: {
muted: this.player.muted, volume: this.player.volume,
src: this.player.src, muted: this.player.muted,
state: this.player_state, src: this.player.src,
}}) state: this.player_state,
},
});
} }
get player_state() { get player_state() {
if (!this.player.src) return "stopped"; if (!this.player.src) return "stopped";
if (this.player.ended) return "stopped"; if (this.player.ended) return "stopped";
if (this.player.paused) return "paused"; if (this.player.paused) return "paused";
return "playing"; return "playing";
} }
player_play(src) { player_play(src) {
if(src) if (src) this.player.src = src;
this.player.src = src; this.player.play();
this.player.play();
} }
player_pause() { player_pause() {
this.player.pause(); this.player.pause();
} }
player_stop() { player_stop() {
this.player.pause(); this.player.pause();
this.player.src = null; this.player.src = null;
} }
player_set_volume(level) { player_set_volume(level) {
if(level === undefined) return; if (level === undefined) return;
this.player.volume = level; this.player.volume = level;
} }
player_mute(mute) { player_mute(mute) {
if(mute === undefined) if (mute === undefined) mute = !this.player.muted;
mute = !this.player.muted; this.player.muted = Boolean(mute);
this.player.muted = Boolean(mute);
} }
} };

View File

@ -3,77 +3,87 @@ import { load_lovelace, lovelace } from "card-tools/src/hass";
import { moreInfo } from "card-tools/src/more-info"; import { moreInfo } from "card-tools/src/more-info";
import { closePopUp, popUp } from "card-tools/src/popup"; import { closePopUp, popUp } from "card-tools/src/popup";
export const BrowserModPopupsMixin = (C) => class extends C { export const BrowserModPopupsMixin = (C) =>
class extends C {
constructor() { constructor() {
super(); super();
if (document.querySelector("home-assistant")) if (document.querySelector("home-assistant"))
document.querySelector("home-assistant").addEventListener("hass-more-info", (ev) => this._popup_card(ev)); document
.querySelector("home-assistant")
.addEventListener("hass-more-info", (ev) => this._popup_card(ev));
const isCast = document.querySelector("hc-main") !== null; const isCast = document.querySelector("hc-main") !== null;
if(!isCast) if (!isCast) load_lovelace();
load_lovelace();
} }
_popup_card(ev) { _popup_card(ev) {
if(!lovelace()) return; if (!lovelace()) return;
if(!ev.detail || !ev.detail.entityId) return; if (!ev.detail || !ev.detail.entityId) return;
const data = { const data = {
...lovelace().config.popup_cards, ...lovelace().config.popup_cards,
...lovelace().config.views[lovelace().current_view].popup_cards, ...lovelace().config.views[lovelace().current_view].popup_cards,
}; };
const d = data[ev.detail.entityId]; const d = data[ev.detail.entityId];
if(!d) return; if (!d) return;
popUp( this.do_popup(d);
d.title, window.setTimeout(() => {
d.card, fireEvent(
d.large || false, "hass-more-info",
d.style { entityID: "." },
document.querySelector("home-assistant")
); );
window.setTimeout(() => { }, 50);
fireEvent("hass-more-info", {entityID: "."}, document.querySelector("home-assistant"));
}, 50);
} }
do_popup(cfg) { do_popup(cfg) {
if (!(cfg.title || cfg.auto_close || cfg.hide_header)) return; if (!(cfg.title || cfg.auto_close || cfg.hide_header)) {
if (!cfg.card) return; console.error(
"browser_mod: popup: Must specify title, auto_close or hide_header."
);
return;
}
if (!cfg.card) {
console.error("browser_mod: popup: No card specified");
return;
}
const open = () => { const open = () => {
popUp( popUp(
cfg.title, cfg.title,
cfg.card, cfg.card,
cfg.large, cfg.large,
cfg.style, cfg.style,
cfg.auto_close || cfg.hide_header, cfg.auto_close || cfg.hide_header
); );
}; };
if(cfg.auto_close) { if (cfg.auto_close) {
this.screensaver_set(open, closePopUp, cfg.time); this.screensaver_set(open, closePopUp, cfg.time);
} else { } else {
open(); open();
} }
} }
do_close_popup() { do_close_popup() {
this.screensaver_stop(); this.screensaver_stop();
closePopUp(); closePopUp();
} }
do_more_info(entity_id, large) { do_more_info(entity_id, large) {
if (!entity_id) return; if (!entity_id) return;
moreInfo(entity_id, large); moreInfo(entity_id, large);
} }
do_toast(message, duration) { do_toast(message, duration) {
if (!message) return; if (!message) return;
fireEvent("hass-notification", { fireEvent(
message, "hass-notification",
duration: parseInt(duration), {
}, document.querySelector("home-assistant")); message,
duration: parseInt(duration),
},
document.querySelector("home-assistant")
);
} }
};
}

View File

@ -1,22 +1,23 @@
export const BrowserModScreensaverMixin = (C) => class extends C { export const BrowserModScreensaverMixin = (C) =>
class extends C {
constructor() { constructor() {
super(); super();
this._blackout_panel = document.createElement("div"); this._blackout_panel = document.createElement("div");
this._screenSaver = undefined; this._screenSaver = undefined;
this._screenSaverTimer = undefined; this._screenSaverTimer = undefined;
this._screenSaverTimeOut = 0; this._screenSaverTimeOut = 0;
this._screenSaver = { this._screenSaver = {
fn: undefined, fn: undefined,
clearfn: undefined, clearfn: undefined,
timer: undefined, timer: undefined,
timeout: undefined, timeout: undefined,
listeners : {}, listeners: {},
active: false, active: false,
}; };
this._blackout_panel.style.cssText = ` this._blackout_panel.style.cssText = `
position: fixed; position: fixed;
left: 0; left: 0;
top: 0; top: 0;
@ -27,95 +28,100 @@ export const BrowserModScreensaverMixin = (C) => class extends C {
background: black; background: black;
display: none; display: none;
`; `;
document.body.appendChild(this._blackout_panel); document.body.appendChild(this._blackout_panel);
} }
screensaver_set(fn, clearfn, time) { screensaver_set(fn, clearfn, time) {
this._ss_clear(); this._ss_clear();
this._screenSaver = { this._screenSaver = {
fn, fn,
clearfn, clearfn,
timer: undefined, timer: undefined,
timeout: time, timeout: time,
listeners: {}, listeners: {},
active: false, active: false,
} };
const l = () => this.screensaver_update(); const l = () => this.screensaver_update();
for(const event of ["mousemove", "mousedown", "keydown", "touchstart"]) { for (const event of ["mousemove", "mousedown", "keydown", "touchstart"]) {
window.addEventListener(event, l); window.addEventListener(event, l);
this._screenSaver.listeners[event] = l; this._screenSaver.listeners[event] = l;
} }
this._screenSaver.timer = window.setTimeout(() => this._ss_run(), time*1000); this._screenSaver.timer = window.setTimeout(
() => this._ss_run(),
time * 1000
);
} }
screensaver_update() { screensaver_update() {
if (this._screenSaver.active) { if (this._screenSaver.active) {
this.screensaver_stop(); this.screensaver_stop();
} else { } else {
window.clearTimeout(this._screenSaver.timer); window.clearTimeout(this._screenSaver.timer);
this._screenSaver.timer = window.setTimeout(() => this._ss_run(), this._screenSaver.timeout*1000); this._screenSaver.timer = window.setTimeout(
} () => this._ss_run(),
this._screenSaver.timeout * 1000
);
}
} }
screensaver_stop() { screensaver_stop() {
this._ss_clear(); this._ss_clear();
this._screenSaver.active = false; this._screenSaver.active = false;
if(this._screenSaver.clearfn) if (this._screenSaver.clearfn) this._screenSaver.clearfn();
this._screenSaver.clearfn(); if (this._screenSaver.timeout) {
if(this._screenSaver.timeout) { this.screensaver_set(
this.screensaver_set( this._screenSaver.fn,
this._screenSaver.fn, this._screenSaver.clearfn,
this._screenSaver.clearfn, this._screenSaver.timeout
this._screenSaver.timeout, );
); }
}
} }
_ss_clear() { _ss_clear() {
window.clearTimeout(this._screenSaverTimer); window.clearTimeout(this._screenSaverTimer);
for(const [k, v] of Object.entries(this._screenSaver.listeners)) { for (const [k, v] of Object.entries(this._screenSaver.listeners)) {
window.removeEventListener(k, v); window.removeEventListener(k, v);
} }
} }
_ss_run() { _ss_run() {
this._screenSaver.active = true; this._screenSaver.active = true;
this._screenSaver.fn(); this._screenSaver.fn();
} }
do_blackout(timeout) { do_blackout(timeout) {
this.screensaver_set( this.screensaver_set(
() => { () => {
if(this.isFully) if (this.isFully) window.fully.turnScreenOff(true);
window.fully.turnScreenOff(true); else this._blackout_panel.style.display = "block";
else this.screen_update();
this._blackout_panel.style.display = "block"; },
this.screen_update(); () => {
}, if ((this._blackout_panel.style.display = "block"))
() => { this._blackout_panel.style.display = "none";
if(this._blackout_panel.style.display = "block") if (this.isFully && !window.fully.getScreenOn())
this._blackout_panel.style.display = "none" window.fully.turnScreenOn();
if(this.isFully && !window.fully.getScreenOn()) this.screen_update();
window.fully.turnScreenOn(); },
this.screen_update(); timeout || 0
}, );
timeout || 0
);
} }
no_blackout() { no_blackout() {
if(this.isFully) if (this.isFully) window.fully.turnScreenOn();
window.fully.turnScreenOn(); this.screensaver_stop();
this.screensaver_stop();
} }
screen_update() { screen_update() {
this.sendUpdate({screen: { this.sendUpdate({
blackout: this.isFully screen: {
? !window.fully.getScreenOn() blackout: this.isFully
: Boolean(this._blackout_panel.style.display === "block"), ? !window.fully.getScreenOn()
brightness: this.isFully ? window.fully.getScreenBrightness() : undefined, : Boolean(this._blackout_panel.style.display === "block"),
}}) brightness: this.isFully
? window.fully.getScreenBrightness()
: undefined,
},
});
} }
} };

3645
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -12,8 +12,8 @@
"author": "Thomas Lovén", "author": "Thomas Lovén",
"license": "MIT", "license": "MIT",
"devDependencies": { "devDependencies": {
"webpack": "^4.46.0", "webpack": "^5.36.2",
"webpack-cli": "^3.3.12" "webpack-cli": "^4.7.0"
}, },
"dependencies": { "dependencies": {
"card-tools": "github:thomasloven/lovelace-card-tools" "card-tools": "github:thomasloven/lovelace-card-tools"

View File

@ -45,6 +45,8 @@ views:
card: card:
type: markdown type: markdown
content: Local popup for climate.hvac content: Local popup for climate.hvac
light.kitchen_lights:
type: No card
cards: cards:
- type: button - type: button
@ -57,3 +59,8 @@ views:
name: Override global popup-card name: Override global popup-card
tap_action: tap_action:
action: more-info action: more-info
- type: button
entity: light.kitchen_lights
name: No card config
tap_action:
action: more-info