Compare commits
	
		
			4 Commits
		
	
	
		
			1dddaa9bcc
			...
			6e5a1c18a3
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 6e5a1c18a3 | |||
| df745e7f3b | |||
| 18eec919a0 | |||
| 0ecfe402ea | 
@ -1,6 +1,6 @@
 | 
				
			|||||||
from homeassistant.components.binary_sensor import BinarySensorEntity
 | 
					from homeassistant.components.binary_sensor import BinarySensorEntity
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from .const import DATA_BROWSERS, DOMAIN, DATA_ADDERS
 | 
					from .const import DOMAIN, DATA_ADDERS
 | 
				
			||||||
from .entities import BrowserModEntity
 | 
					from .entities import BrowserModEntity
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -15,14 +15,14 @@ async def async_setup_entry(hass, config_entry, async_add_entities):
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class BrowserBinarySensor(BrowserModEntity, BinarySensorEntity):
 | 
					class BrowserBinarySensor(BrowserModEntity, BinarySensorEntity):
 | 
				
			||||||
    def __init__(self, coordinator, browserID, parameter, name):
 | 
					    def __init__(self, coordinator, browserID, parameter, name, icon=None):
 | 
				
			||||||
        BrowserModEntity.__init__(self, coordinator, browserID, name)
 | 
					        BrowserModEntity.__init__(self, coordinator, browserID, name, icon)
 | 
				
			||||||
        BinarySensorEntity.__init__(self)
 | 
					        BinarySensorEntity.__init__(self)
 | 
				
			||||||
        self.parameter = parameter
 | 
					        self.parameter = parameter
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @property
 | 
					    @property
 | 
				
			||||||
    def is_on(self):
 | 
					    def is_on(self):
 | 
				
			||||||
        return self._data.get(DATA_BROWSERS, {}).get(self.parameter, None)
 | 
					        return self._data.get("browser", {}).get(self.parameter, None)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class ActivityBinarySensor(BrowserModEntity, BinarySensorEntity):
 | 
					class ActivityBinarySensor(BrowserModEntity, BinarySensorEntity):
 | 
				
			||||||
 | 
				
			|||||||
@ -57,33 +57,50 @@ class BrowserModBrowser:
 | 
				
			|||||||
        coordinator = self.coordinator
 | 
					        coordinator = self.coordinator
 | 
				
			||||||
        browserID = self.browserID
 | 
					        browserID = self.browserID
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        def _assert_browser_sensor(type, name, *properties):
 | 
					        def _assert_browser_sensor(type, name, *properties, **kwarg):
 | 
				
			||||||
            """Create a browser state sensor if it does not already exist"""
 | 
					            """Create a browser state sensor if it does not already exist"""
 | 
				
			||||||
            if name in self.entities:
 | 
					            if name in self.entities:
 | 
				
			||||||
                return
 | 
					                return
 | 
				
			||||||
            adder = hass.data[DOMAIN][DATA_ADDERS][type]
 | 
					            adder = hass.data[DOMAIN][DATA_ADDERS][type]
 | 
				
			||||||
            cls = {"sensor": BrowserSensor, "binary_sensor": BrowserBinarySensor}[type]
 | 
					            cls = {"sensor": BrowserSensor, "binary_sensor": BrowserBinarySensor}[type]
 | 
				
			||||||
            new = cls(coordinator, browserID, name, *properties)
 | 
					            new = cls(coordinator, browserID, name, *properties, **kwarg)
 | 
				
			||||||
            adder([new])
 | 
					            adder([new])
 | 
				
			||||||
            self.entities[name] = new
 | 
					            self.entities[name] = new
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        _assert_browser_sensor("sensor", "path", "Browser path")
 | 
					        _assert_browser_sensor("sensor", "path", "Browser path", icon="mdi:web")
 | 
				
			||||||
        _assert_browser_sensor("sensor", "visibility", "Browser visibility")
 | 
					        _assert_browser_sensor("sensor", "visibility", "Browser visibility")
 | 
				
			||||||
        _assert_browser_sensor("sensor", "userAgent", "Browser userAgent")
 | 
					        _assert_browser_sensor(
 | 
				
			||||||
        _assert_browser_sensor("sensor", "currentUser", "Browser user")
 | 
					            "sensor", "userAgent", "Browser userAgent", icon="mdi:account-details"
 | 
				
			||||||
        _assert_browser_sensor("sensor", "width", "Browser width", "px")
 | 
					        )
 | 
				
			||||||
        _assert_browser_sensor("sensor", "height", "Browser height", "px")
 | 
					        _assert_browser_sensor(
 | 
				
			||||||
 | 
					            "sensor", "currentUser", "Browser user", icon="mdi:account"
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					        _assert_browser_sensor(
 | 
				
			||||||
 | 
					            "sensor", "width", "Browser width", "px", icon="mdi:arrow-left-right"
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					        _assert_browser_sensor(
 | 
				
			||||||
 | 
					            "sensor", "height", "Browser height", "px", icon="mdi:arrow-up-down"
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
        # Don't create battery sensor unless battery level is reported
 | 
					        # Don't create battery sensor unless battery level is reported
 | 
				
			||||||
        if self.data.get("browser", {}).get("battery_level", None) is not None:
 | 
					        if self.data.get("browser", {}).get("battery_level", None) is not None:
 | 
				
			||||||
            _assert_browser_sensor(
 | 
					            _assert_browser_sensor(
 | 
				
			||||||
                "sensor", "battery_level", "Browser battery", "%", "battery"
 | 
					                "sensor", "battery_level", "Browser battery", "%", "battery"
 | 
				
			||||||
            )
 | 
					            )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        _assert_browser_sensor("binary_sensor", "darkMode", "Browser dark mode")
 | 
					        _assert_browser_sensor(
 | 
				
			||||||
        _assert_browser_sensor("binary_sensor", "fullyKiosk", "Browser FullyKiosk")
 | 
					            "binary_sensor",
 | 
				
			||||||
 | 
					            "darkMode",
 | 
				
			||||||
 | 
					            "Browser dark mode",
 | 
				
			||||||
 | 
					            icon="mdi:theme-light-dark",
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					        _assert_browser_sensor(
 | 
				
			||||||
 | 
					            "binary_sensor", "fullyKiosk", "Browser FullyKiosk", icon="mdi:alpha-f"
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
        # Don't create a charging sensor unless charging state is reported
 | 
					        # Don't create a charging sensor unless charging state is reported
 | 
				
			||||||
        if self.data.get("browser", {}).get("charging", None) is not None:
 | 
					        if self.data.get("browser", {}).get("charging", None) is not None:
 | 
				
			||||||
            _assert_browser_sensor("binary_sensor", "charging", "Browser charging")
 | 
					            _assert_browser_sensor(
 | 
				
			||||||
 | 
					                "binary_sensor", "charging", "Browser charging", icon="mdi:power-plug"
 | 
				
			||||||
 | 
					            )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if "activity" not in self.entities:
 | 
					        if "activity" not in self.entities:
 | 
				
			||||||
            adder = hass.data[DOMAIN][DATA_ADDERS]["binary_sensor"]
 | 
					            adder = hass.data[DOMAIN][DATA_ADDERS]["binary_sensor"]
 | 
				
			||||||
 | 
				
			|||||||
@ -619,10 +619,19 @@ const MediaPlayerMixin = (SuperClass) => {
 | 
				
			|||||||
    return class MediaPlayerMixinClass extends SuperClass {
 | 
					    return class MediaPlayerMixinClass extends SuperClass {
 | 
				
			||||||
        constructor() {
 | 
					        constructor() {
 | 
				
			||||||
            super();
 | 
					            super();
 | 
				
			||||||
            this.player = new Audio();
 | 
					            this._audio_player = new Audio();
 | 
				
			||||||
 | 
					            this._video_player = document.createElement("video");
 | 
				
			||||||
 | 
					            this._video_player.controls = true;
 | 
				
			||||||
 | 
					            this._video_player.style.setProperty("width", "100%");
 | 
				
			||||||
 | 
					            this.player = this._audio_player;
 | 
				
			||||||
            this._player_enabled = false;
 | 
					            this._player_enabled = false;
 | 
				
			||||||
            for (const ev of ["play", "pause", "ended", "volumechange"]) {
 | 
					            for (const ev of ["play", "pause", "ended", "volumechange"]) {
 | 
				
			||||||
                this.player.addEventListener(ev, () => this._player_update());
 | 
					                this._audio_player.addEventListener(ev, () => this._player_update());
 | 
				
			||||||
 | 
					                this._video_player.addEventListener(ev, () => this._player_update());
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            for (const ev of ["timeupdate"]) {
 | 
				
			||||||
 | 
					                this._audio_player.addEventListener(ev, () => this._player_update_choked());
 | 
				
			||||||
 | 
					                this._video_player.addEventListener(ev, () => this._player_update_choked());
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            this.firstInteraction.then(() => {
 | 
					            this.firstInteraction.then(() => {
 | 
				
			||||||
                this._player_enabled = true;
 | 
					                this._player_enabled = true;
 | 
				
			||||||
@ -630,10 +639,18 @@ const MediaPlayerMixin = (SuperClass) => {
 | 
				
			|||||||
                    this.player.play();
 | 
					                    this.player.play();
 | 
				
			||||||
            });
 | 
					            });
 | 
				
			||||||
            this.addEventListener("command-player-play", (ev) => {
 | 
					            this.addEventListener("command-player-play", (ev) => {
 | 
				
			||||||
                var _a;
 | 
					                var _a, _b, _c;
 | 
				
			||||||
                if ((_a = ev.detail) === null || _a === void 0 ? void 0 : _a.media_content_id)
 | 
					                if (this.player.src)
 | 
				
			||||||
 | 
					                    this.player.pause();
 | 
				
			||||||
 | 
					                if ((_a = ev.detail) === null || _a === void 0 ? void 0 : _a.media_type)
 | 
				
			||||||
 | 
					                    if ((_b = ev.detail) === null || _b === void 0 ? void 0 : _b.media_type.startsWith("video"))
 | 
				
			||||||
 | 
					                        this.player = this._video_player;
 | 
				
			||||||
 | 
					                    else
 | 
				
			||||||
 | 
					                        this.player = this._audio_player;
 | 
				
			||||||
 | 
					                if ((_c = ev.detail) === null || _c === void 0 ? void 0 : _c.media_content_id)
 | 
				
			||||||
                    this.player.src = ev.detail.media_content_id;
 | 
					                    this.player.src = ev.detail.media_content_id;
 | 
				
			||||||
                this.player.play();
 | 
					                this.player.play();
 | 
				
			||||||
 | 
					                this._show_video_player();
 | 
				
			||||||
            });
 | 
					            });
 | 
				
			||||||
            this.addEventListener("command-player-pause", (ev) => this.player.pause());
 | 
					            this.addEventListener("command-player-pause", (ev) => this.player.pause());
 | 
				
			||||||
            this.addEventListener("command-player-stop", (ev) => {
 | 
					            this.addEventListener("command-player-stop", (ev) => {
 | 
				
			||||||
@ -653,17 +670,49 @@ const MediaPlayerMixin = (SuperClass) => {
 | 
				
			|||||||
                else
 | 
					                else
 | 
				
			||||||
                    this.player.muted = !this.player.muted;
 | 
					                    this.player.muted = !this.player.muted;
 | 
				
			||||||
            });
 | 
					            });
 | 
				
			||||||
 | 
					            this.addEventListener("command-player-seek", (ev) => {
 | 
				
			||||||
 | 
					                this.player.currentTime = ev.detail.position;
 | 
				
			||||||
 | 
					                setTimeout(() => this._player_update(), 10);
 | 
				
			||||||
 | 
					            });
 | 
				
			||||||
 | 
					            this.addEventListener("command-player-turn-off", (ev) => {
 | 
				
			||||||
 | 
					                if (this.player === this._video_player &&
 | 
				
			||||||
 | 
					                    this._video_player.isConnected)
 | 
				
			||||||
 | 
					                    this.closePopup();
 | 
				
			||||||
 | 
					                else if (this.player.src)
 | 
				
			||||||
 | 
					                    this.player.pause();
 | 
				
			||||||
 | 
					                this.player.src = "";
 | 
				
			||||||
 | 
					                this._player_update();
 | 
				
			||||||
 | 
					            });
 | 
				
			||||||
            this.connectionPromise.then(() => this._player_update());
 | 
					            this.connectionPromise.then(() => this._player_update());
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					        _show_video_player() {
 | 
				
			||||||
 | 
					            if (this.player === this._video_player && this.player.src) {
 | 
				
			||||||
 | 
					                selectTree(document, "home-assistant $ dialog-media-player-browse").then((el) => el === null || el === void 0 ? void 0 : el.closeDialog());
 | 
				
			||||||
 | 
					                this.showPopup(undefined, this._video_player, {
 | 
				
			||||||
 | 
					                    dismiss_action: () => this._video_player.pause(),
 | 
				
			||||||
 | 
					                    size: "wide",
 | 
				
			||||||
 | 
					                });
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            else if (this.player !== this._video_player &&
 | 
				
			||||||
 | 
					                this._video_player.isConnected) {
 | 
				
			||||||
 | 
					                this.closePopup();
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        _player_update_choked() {
 | 
				
			||||||
 | 
					            if (this._player_update_cooldown)
 | 
				
			||||||
 | 
					                return;
 | 
				
			||||||
 | 
					            this._player_update_cooldown = window.setTimeout(() => (this._player_update_cooldown = undefined), 3000);
 | 
				
			||||||
 | 
					            this._player_update();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
        _player_update() {
 | 
					        _player_update() {
 | 
				
			||||||
            const state = this._player_enabled
 | 
					            const state = this._player_enabled
 | 
				
			||||||
                ? this.player.src
 | 
					                ? !this.player.src || this.player.src === window.location.href
 | 
				
			||||||
                    ? this.player.ended
 | 
					                    ? "off"
 | 
				
			||||||
 | 
					                    : this.player.ended
 | 
				
			||||||
                        ? "stopped"
 | 
					                        ? "stopped"
 | 
				
			||||||
                        : this.player.paused
 | 
					                        : this.player.paused
 | 
				
			||||||
                            ? "paused"
 | 
					                            ? "paused"
 | 
				
			||||||
                            : "playing"
 | 
					                            : "playing"
 | 
				
			||||||
                    : "stopped"
 | 
					 | 
				
			||||||
                : "unavailable";
 | 
					                : "unavailable";
 | 
				
			||||||
            this.sendUpdate({
 | 
					            this.sendUpdate({
 | 
				
			||||||
                player: {
 | 
					                player: {
 | 
				
			||||||
@ -671,6 +720,8 @@ const MediaPlayerMixin = (SuperClass) => {
 | 
				
			|||||||
                    muted: this.player.muted,
 | 
					                    muted: this.player.muted,
 | 
				
			||||||
                    src: this.player.src,
 | 
					                    src: this.player.src,
 | 
				
			||||||
                    state,
 | 
					                    state,
 | 
				
			||||||
 | 
					                    media_duration: this.player.duration,
 | 
				
			||||||
 | 
					                    media_position: this.player.currentTime,
 | 
				
			||||||
                },
 | 
					                },
 | 
				
			||||||
            });
 | 
					            });
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
@ -1152,13 +1203,17 @@ class BrowserModPopup extends s {
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
        this._autocloseListener = undefined;
 | 
					        this._autocloseListener = undefined;
 | 
				
			||||||
        if (this._autoclose) {
 | 
					        if (this._autoclose) {
 | 
				
			||||||
            this._autocloseListener = this._dismiss.bind(this);
 | 
					            this._autocloseListener = () => this.dialog.close();
 | 
				
			||||||
            window.browser_mod.addEventListener("browser-mod-activity", this._autocloseListener);
 | 
					            window.browser_mod.addEventListener("browser-mod-activity", this._autocloseListener, { once: true });
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    async setupDialog(title, content, { right_button = undefined, right_button_action = undefined, left_button = undefined, left_button_action = undefined, dismissable = true, dismiss_action = undefined, timeout = undefined, timeout_action = undefined, size = undefined, style = undefined, autoclose = false, } = {}) {
 | 
					    async setupDialog(title, content, { right_button = undefined, right_button_action = undefined, left_button = undefined, left_button_action = undefined, dismissable = true, dismiss_action = undefined, timeout = undefined, timeout_action = undefined, size = undefined, style = undefined, autoclose = false, } = {}) {
 | 
				
			||||||
        this.title = title;
 | 
					        this.title = title;
 | 
				
			||||||
        if (content && typeof content === "object") {
 | 
					        if (content && content instanceof HTMLElement) {
 | 
				
			||||||
 | 
					            this.card = undefined;
 | 
				
			||||||
 | 
					            this.content = content;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        else if (content && typeof content === "object") {
 | 
				
			||||||
            // Create a card from config in content
 | 
					            // Create a card from config in content
 | 
				
			||||||
            this.card = true;
 | 
					            this.card = true;
 | 
				
			||||||
            const helpers = await window.loadCardHelpers();
 | 
					            const helpers = await window.loadCardHelpers();
 | 
				
			||||||
@ -1189,30 +1244,30 @@ class BrowserModPopup extends s {
 | 
				
			|||||||
        this._autoclose = autoclose;
 | 
					        this._autoclose = autoclose;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    async _primary() {
 | 
					    async _primary() {
 | 
				
			||||||
        var _a, _b, _c;
 | 
					        var _a, _b, _c, _d;
 | 
				
			||||||
        if ((_a = this._actions) === null || _a === void 0 ? void 0 : _a.dismiss_action)
 | 
					        if ((_a = this._actions) === null || _a === void 0 ? void 0 : _a.dismiss_action)
 | 
				
			||||||
            this._actions.dismiss_action = undefined;
 | 
					            this._actions.dismiss_action = undefined;
 | 
				
			||||||
        await this.closeDialog();
 | 
					        (_b = this.dialog) === null || _b === void 0 ? void 0 : _b.close();
 | 
				
			||||||
        (_c = (_b = this._actions) === null || _b === void 0 ? void 0 : _b.right_button_action) === null || _c === void 0 ? void 0 : _c.call(_b);
 | 
					        (_d = (_c = this._actions) === null || _c === void 0 ? void 0 : _c.right_button_action) === null || _d === void 0 ? void 0 : _d.call(_c);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    async _secondary() {
 | 
					    async _secondary() {
 | 
				
			||||||
        var _a, _b, _c;
 | 
					        var _a, _b, _c, _d;
 | 
				
			||||||
        if ((_a = this._actions) === null || _a === void 0 ? void 0 : _a.dismiss_action)
 | 
					        if ((_a = this._actions) === null || _a === void 0 ? void 0 : _a.dismiss_action)
 | 
				
			||||||
            this._actions.dismiss_action = undefined;
 | 
					            this._actions.dismiss_action = undefined;
 | 
				
			||||||
        await this.closeDialog();
 | 
					        (_b = this.dialog) === null || _b === void 0 ? void 0 : _b.close();
 | 
				
			||||||
        (_c = (_b = this._actions) === null || _b === void 0 ? void 0 : _b.left_button_action) === null || _c === void 0 ? void 0 : _c.call(_b);
 | 
					        (_d = (_c = this._actions) === null || _c === void 0 ? void 0 : _c.left_button_action) === null || _d === void 0 ? void 0 : _d.call(_c);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    async _dismiss() {
 | 
					    async _dismiss(ev) {
 | 
				
			||||||
        var _a, _b;
 | 
					        var _a, _b, _c;
 | 
				
			||||||
        await this.closeDialog();
 | 
					        (_a = this.dialog) === null || _a === void 0 ? void 0 : _a.close();
 | 
				
			||||||
        (_b = (_a = this._actions) === null || _a === void 0 ? void 0 : _a.dismiss_action) === null || _b === void 0 ? void 0 : _b.call(_a);
 | 
					        (_c = (_b = this._actions) === null || _b === void 0 ? void 0 : _b.dismiss_action) === null || _c === void 0 ? void 0 : _c.call(_b);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    async _timeout() {
 | 
					    async _timeout() {
 | 
				
			||||||
        var _a, _b, _c;
 | 
					        var _a, _b, _c, _d;
 | 
				
			||||||
        if ((_a = this._actions) === null || _a === void 0 ? void 0 : _a.dismiss_action)
 | 
					        if ((_a = this._actions) === null || _a === void 0 ? void 0 : _a.dismiss_action)
 | 
				
			||||||
            this._actions.dismiss_action = undefined;
 | 
					            this._actions.dismiss_action = undefined;
 | 
				
			||||||
        await this.closeDialog();
 | 
					        (_b = this.dialog) === null || _b === void 0 ? void 0 : _b.close();
 | 
				
			||||||
        (_c = (_b = this._actions) === null || _b === void 0 ? void 0 : _b.timeout_action) === null || _c === void 0 ? void 0 : _c.call(_b);
 | 
					        (_d = (_c = this._actions) === null || _c === void 0 ? void 0 : _c.timeout_action) === null || _d === void 0 ? void 0 : _d.call(_c);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    render() {
 | 
					    render() {
 | 
				
			||||||
        if (!this.open)
 | 
					        if (!this.open)
 | 
				
			||||||
@ -1220,10 +1275,12 @@ class BrowserModPopup extends s {
 | 
				
			|||||||
        return $ `
 | 
					        return $ `
 | 
				
			||||||
      <ha-dialog
 | 
					      <ha-dialog
 | 
				
			||||||
        open
 | 
					        open
 | 
				
			||||||
 | 
					        @closed=${this.closeDialog}
 | 
				
			||||||
 | 
					        @closing=${this._dismiss}
 | 
				
			||||||
        .heading=${this.title !== undefined}
 | 
					        .heading=${this.title !== undefined}
 | 
				
			||||||
        ?hideActions=${this.actions === undefined}
 | 
					        ?hideActions=${this.actions === undefined}
 | 
				
			||||||
        .scrimClickAction=${this.dismissable ? this._dismiss : ""}
 | 
					        .scrimClickAction=${this.dismissable ? "close" : ""}
 | 
				
			||||||
        .escapeKeyAction=${this.dismissable ? this._dismiss : ""}
 | 
					        .escapeKeyAction=${this.dismissable ? "close" : ""}
 | 
				
			||||||
      >
 | 
					      >
 | 
				
			||||||
        ${this.timeout
 | 
					        ${this.timeout
 | 
				
			||||||
            ? $ ` <div slot="heading" class="progress"></div> `
 | 
					            ? $ ` <div slot="heading" class="progress"></div> `
 | 
				
			||||||
@ -1274,6 +1331,7 @@ class BrowserModPopup extends s {
 | 
				
			|||||||
    static get styles() {
 | 
					    static get styles() {
 | 
				
			||||||
        return r$2 `
 | 
					        return r$2 `
 | 
				
			||||||
      ha-dialog {
 | 
					      ha-dialog {
 | 
				
			||||||
 | 
					        z-index: 10;
 | 
				
			||||||
        --mdc-dialog-min-width: var(--popup-min-width, 400px);
 | 
					        --mdc-dialog-min-width: var(--popup-min-width, 400px);
 | 
				
			||||||
        --mdc-dialog-max-width: var(--popup-max-width, 600px);
 | 
					        --mdc-dialog-max-width: var(--popup-max-width, 600px);
 | 
				
			||||||
        --mdc-dialog-heading-ink-color: var(--primary-text-color);
 | 
					        --mdc-dialog-heading-ink-color: var(--primary-text-color);
 | 
				
			||||||
@ -2165,8 +2223,8 @@ const BrowserIDMixin = (SuperClass) => {
 | 
				
			|||||||
  - Tweaks
 | 
					  - Tweaks
 | 
				
			||||||
    - Quickbar tweaks (ctrl+enter)?
 | 
					    - Quickbar tweaks (ctrl+enter)?
 | 
				
			||||||
    x Card-mod preload
 | 
					    x Card-mod preload
 | 
				
			||||||
  - Video player?
 | 
					  x Video player?
 | 
				
			||||||
  - Media_seek
 | 
					  x Media_seek
 | 
				
			||||||
  - Screensavers
 | 
					  - Screensavers
 | 
				
			||||||
  x IMPORTANT: FIX DEFAULT HIDING OF ENTITIES
 | 
					  x IMPORTANT: FIX DEFAULT HIDING OF ENTITIES
 | 
				
			||||||
    - NOFIX. Home Assistant bug
 | 
					    - NOFIX. Home Assistant bug
 | 
				
			||||||
 | 
				
			|||||||
@ -11,10 +11,11 @@ _LOGGER = logging.getLogger(__name__)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class BrowserModEntity(CoordinatorEntity):
 | 
					class BrowserModEntity(CoordinatorEntity):
 | 
				
			||||||
    def __init__(self, coordinator, browserID, name):
 | 
					    def __init__(self, coordinator, browserID, name, icon=None):
 | 
				
			||||||
        super().__init__(coordinator)
 | 
					        super().__init__(coordinator)
 | 
				
			||||||
        self.browserID = browserID
 | 
					        self.browserID = browserID
 | 
				
			||||||
        self._name = name
 | 
					        self._name = name
 | 
				
			||||||
 | 
					        self._icon = icon
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @property
 | 
					    @property
 | 
				
			||||||
    def _data(self):
 | 
					    def _data(self):
 | 
				
			||||||
@ -54,3 +55,7 @@ class BrowserModEntity(CoordinatorEntity):
 | 
				
			|||||||
    @property
 | 
					    @property
 | 
				
			||||||
    def unique_id(self):
 | 
					    def unique_id(self):
 | 
				
			||||||
        return f"{self.browserID}-{self._name.replace(' ','_')}"
 | 
					        return f"{self.browserID}-{self._name.replace(' ','_')}"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @property
 | 
				
			||||||
 | 
					    def icon(self):
 | 
				
			||||||
 | 
					        return self._icon
 | 
				
			||||||
 | 
				
			|||||||
@ -15,6 +15,9 @@ from homeassistant.components.media_player.const import (
 | 
				
			|||||||
    MEDIA_TYPE_MUSIC,
 | 
					    MEDIA_TYPE_MUSIC,
 | 
				
			||||||
    MEDIA_TYPE_URL,
 | 
					    MEDIA_TYPE_URL,
 | 
				
			||||||
    SUPPORT_BROWSE_MEDIA,
 | 
					    SUPPORT_BROWSE_MEDIA,
 | 
				
			||||||
 | 
					    SUPPORT_SEEK,
 | 
				
			||||||
 | 
					    SUPPORT_TURN_OFF,
 | 
				
			||||||
 | 
					    SUPPORT_TURN_ON,
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
from homeassistant.const import (
 | 
					from homeassistant.const import (
 | 
				
			||||||
    STATE_UNAVAILABLE,
 | 
					    STATE_UNAVAILABLE,
 | 
				
			||||||
@ -22,8 +25,12 @@ from homeassistant.const import (
 | 
				
			|||||||
    STATE_PLAYING,
 | 
					    STATE_PLAYING,
 | 
				
			||||||
    STATE_IDLE,
 | 
					    STATE_IDLE,
 | 
				
			||||||
    STATE_UNKNOWN,
 | 
					    STATE_UNKNOWN,
 | 
				
			||||||
 | 
					    STATE_ON,
 | 
				
			||||||
 | 
					    STATE_OFF,
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					from homeassistant.util import dt
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from .entities import BrowserModEntity
 | 
					from .entities import BrowserModEntity
 | 
				
			||||||
from .const import DOMAIN, DATA_ADDERS
 | 
					from .const import DOMAIN, DATA_ADDERS
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -60,6 +67,8 @@ class BrowserModPlayer(BrowserModEntity, MediaPlayerEntity):
 | 
				
			|||||||
            "paused": STATE_PAUSED,
 | 
					            "paused": STATE_PAUSED,
 | 
				
			||||||
            "stopped": STATE_IDLE,
 | 
					            "stopped": STATE_IDLE,
 | 
				
			||||||
            "unavailable": STATE_UNAVAILABLE,
 | 
					            "unavailable": STATE_UNAVAILABLE,
 | 
				
			||||||
 | 
					            "on": STATE_ON,
 | 
				
			||||||
 | 
					            "off": STATE_OFF,
 | 
				
			||||||
        }.get(state, STATE_UNKNOWN)
 | 
					        }.get(state, STATE_UNKNOWN)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @property
 | 
					    @property
 | 
				
			||||||
@ -72,6 +81,9 @@ class BrowserModPlayer(BrowserModEntity, MediaPlayerEntity):
 | 
				
			|||||||
            | SUPPORT_VOLUME_SET
 | 
					            | SUPPORT_VOLUME_SET
 | 
				
			||||||
            | SUPPORT_VOLUME_MUTE
 | 
					            | SUPPORT_VOLUME_MUTE
 | 
				
			||||||
            | SUPPORT_BROWSE_MEDIA
 | 
					            | SUPPORT_BROWSE_MEDIA
 | 
				
			||||||
 | 
					            | SUPPORT_SEEK
 | 
				
			||||||
 | 
					            | SUPPORT_TURN_OFF
 | 
				
			||||||
 | 
					            | SUPPORT_TURN_ON
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @property
 | 
					    @property
 | 
				
			||||||
@ -82,6 +94,20 @@ class BrowserModPlayer(BrowserModEntity, MediaPlayerEntity):
 | 
				
			|||||||
    def is_volume_muted(self):
 | 
					    def is_volume_muted(self):
 | 
				
			||||||
        return self._data.get("player", {}).get("muted", False)
 | 
					        return self._data.get("player", {}).get("muted", False)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @property
 | 
				
			||||||
 | 
					    def media_duration(self):
 | 
				
			||||||
 | 
					        duration = self._data.get("player", {}).get("media_duration", None)
 | 
				
			||||||
 | 
					        return float(duration) if duration is not None else None
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @property
 | 
				
			||||||
 | 
					    def media_position(self):
 | 
				
			||||||
 | 
					        position = self._data.get("player", {}).get("media_position", None)
 | 
				
			||||||
 | 
					        return float(position) if position is not None else None
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @property
 | 
				
			||||||
 | 
					    def media_position_updated_at(self):
 | 
				
			||||||
 | 
					        return dt.utcnow()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def set_volume_level(self, volume):
 | 
					    def set_volume_level(self, volume):
 | 
				
			||||||
        self.browser.send("player-set-volume", volume_level=volume)
 | 
					        self.browser.send("player-set-volume", volume_level=volume)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -90,21 +116,24 @@ class BrowserModPlayer(BrowserModEntity, MediaPlayerEntity):
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    async def async_play_media(self, media_type, media_id, **kwargs):
 | 
					    async def async_play_media(self, media_type, media_id, **kwargs):
 | 
				
			||||||
        if media_source.is_media_source_id(media_id):
 | 
					        if media_source.is_media_source_id(media_id):
 | 
				
			||||||
            media_type = MEDIA_TYPE_URL
 | 
					 | 
				
			||||||
            play_item = await media_source.async_resolve_media(
 | 
					            play_item = await media_source.async_resolve_media(
 | 
				
			||||||
                self.hass, media_id, self.entity_id
 | 
					                self.hass, media_id, self.entity_id
 | 
				
			||||||
            )
 | 
					            )
 | 
				
			||||||
 | 
					            media_type = play_item.mime_type
 | 
				
			||||||
            media_id = play_item.url
 | 
					            media_id = play_item.url
 | 
				
			||||||
 | 
					            media_id = async_process_play_media_url(self.hass, media_id)
 | 
				
			||||||
        if media_type in (MEDIA_TYPE_URL, MEDIA_TYPE_MUSIC):
 | 
					        if media_type in (MEDIA_TYPE_URL, MEDIA_TYPE_MUSIC):
 | 
				
			||||||
            media_id = async_process_play_media_url(self.hass, media_id)
 | 
					            media_id = async_process_play_media_url(self.hass, media_id)
 | 
				
			||||||
        self.browser.send("player-play", media_content_id=media_id)
 | 
					        self.browser.send(
 | 
				
			||||||
 | 
					            "player-play", media_content_id=media_id, media_type=media_type, **kwargs
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    async def async_browse_media(self, media_content_type=None, media_content_id=None):
 | 
					    async def async_browse_media(self, media_content_type=None, media_content_id=None):
 | 
				
			||||||
        """Implement the websocket media browsing helper."""
 | 
					        """Implement the websocket media browsing helper."""
 | 
				
			||||||
        return await media_source.async_browse_media(
 | 
					        return await media_source.async_browse_media(
 | 
				
			||||||
            self.hass,
 | 
					            self.hass,
 | 
				
			||||||
            media_content_id,
 | 
					            media_content_id,
 | 
				
			||||||
            content_filter=lambda item: item.media_content_type.startswith("audio/"),
 | 
					            # content_filter=lambda item: item.media_content_type.startswith("audio/"),
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def media_play(self):
 | 
					    def media_play(self):
 | 
				
			||||||
@ -115,3 +144,12 @@ class BrowserModPlayer(BrowserModEntity, MediaPlayerEntity):
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    def media_stop(self):
 | 
					    def media_stop(self):
 | 
				
			||||||
        self.browser.send("player-stop")
 | 
					        self.browser.send("player-stop")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def media_seek(self, position):
 | 
				
			||||||
 | 
					        self.browser.send("player-seek", position=position)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def turn_off(self):
 | 
				
			||||||
 | 
					        self.browser.send("player-turn-off")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def turn_on(self, **kwargs):
 | 
				
			||||||
 | 
					        self.browser.send("player-turn-on", **kwargs)
 | 
				
			||||||
 | 
				
			|||||||
@ -23,8 +23,9 @@ class BrowserSensor(BrowserModEntity, SensorEntity):
 | 
				
			|||||||
        name,
 | 
					        name,
 | 
				
			||||||
        unit_of_measurement=None,
 | 
					        unit_of_measurement=None,
 | 
				
			||||||
        device_class=None,
 | 
					        device_class=None,
 | 
				
			||||||
 | 
					        icon=None,
 | 
				
			||||||
    ):
 | 
					    ):
 | 
				
			||||||
        BrowserModEntity.__init__(self, coordinator, browserID, name)
 | 
					        BrowserModEntity.__init__(self, coordinator, browserID, name, icon)
 | 
				
			||||||
        SensorEntity.__init__(self)
 | 
					        SensorEntity.__init__(self)
 | 
				
			||||||
        self.parameter = parameter
 | 
					        self.parameter = parameter
 | 
				
			||||||
        self._device_class = device_class
 | 
					        self._device_class = device_class
 | 
				
			||||||
@ -32,10 +33,7 @@ class BrowserSensor(BrowserModEntity, SensorEntity):
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    @property
 | 
					    @property
 | 
				
			||||||
    def native_value(self):
 | 
					    def native_value(self):
 | 
				
			||||||
        data = self._data
 | 
					        return self._data.get("browser", {}).get(self.parameter, None)
 | 
				
			||||||
        data = data.get("browser", {})
 | 
					 | 
				
			||||||
        data = data.get(self.parameter, None)
 | 
					 | 
				
			||||||
        return data
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @property
 | 
					    @property
 | 
				
			||||||
    def device_class(self):
 | 
					    def device_class(self):
 | 
				
			||||||
 | 
				
			|||||||
@ -67,8 +67,8 @@ import { BrowserIDMixin } from "./browserID";
 | 
				
			|||||||
  - Tweaks
 | 
					  - Tweaks
 | 
				
			||||||
    - Quickbar tweaks (ctrl+enter)?
 | 
					    - Quickbar tweaks (ctrl+enter)?
 | 
				
			||||||
    x Card-mod preload
 | 
					    x Card-mod preload
 | 
				
			||||||
  - Video player?
 | 
					  x Video player?
 | 
				
			||||||
  - Media_seek
 | 
					  x Media_seek
 | 
				
			||||||
  - Screensavers
 | 
					  - Screensavers
 | 
				
			||||||
  x IMPORTANT: FIX DEFAULT HIDING OF ENTITIES
 | 
					  x IMPORTANT: FIX DEFAULT HIDING OF ENTITIES
 | 
				
			||||||
    - NOFIX. Home Assistant bug
 | 
					    - NOFIX. Home Assistant bug
 | 
				
			||||||
 | 
				
			|||||||
@ -1,16 +1,34 @@
 | 
				
			|||||||
 | 
					import { selectTree } from "../helpers";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export const MediaPlayerMixin = (SuperClass) => {
 | 
					export const MediaPlayerMixin = (SuperClass) => {
 | 
				
			||||||
  return class MediaPlayerMixinClass extends SuperClass {
 | 
					  return class MediaPlayerMixinClass extends SuperClass {
 | 
				
			||||||
    public player;
 | 
					    public player;
 | 
				
			||||||
 | 
					    private _audio_player;
 | 
				
			||||||
 | 
					    private _video_player;
 | 
				
			||||||
    private _player_enabled;
 | 
					    private _player_enabled;
 | 
				
			||||||
 | 
					    private _player_update_cooldown;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    constructor() {
 | 
					    constructor() {
 | 
				
			||||||
      super();
 | 
					      super();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      this.player = new Audio();
 | 
					      this._audio_player = new Audio();
 | 
				
			||||||
 | 
					      this._video_player = document.createElement("video");
 | 
				
			||||||
 | 
					      this._video_player.controls = true;
 | 
				
			||||||
 | 
					      this._video_player.style.setProperty("width", "100%");
 | 
				
			||||||
 | 
					      this.player = this._audio_player;
 | 
				
			||||||
      this._player_enabled = false;
 | 
					      this._player_enabled = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      for (const ev of ["play", "pause", "ended", "volumechange"]) {
 | 
					      for (const ev of ["play", "pause", "ended", "volumechange"]) {
 | 
				
			||||||
        this.player.addEventListener(ev, () => this._player_update());
 | 
					        this._audio_player.addEventListener(ev, () => this._player_update());
 | 
				
			||||||
 | 
					        this._video_player.addEventListener(ev, () => this._player_update());
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					      for (const ev of ["timeupdate"]) {
 | 
				
			||||||
 | 
					        this._audio_player.addEventListener(ev, () =>
 | 
				
			||||||
 | 
					          this._player_update_choked()
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
 | 
					        this._video_player.addEventListener(ev, () =>
 | 
				
			||||||
 | 
					          this._player_update_choked()
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      this.firstInteraction.then(() => {
 | 
					      this.firstInteraction.then(() => {
 | 
				
			||||||
@ -19,9 +37,15 @@ export const MediaPlayerMixin = (SuperClass) => {
 | 
				
			|||||||
      });
 | 
					      });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      this.addEventListener("command-player-play", (ev) => {
 | 
					      this.addEventListener("command-player-play", (ev) => {
 | 
				
			||||||
 | 
					        if (this.player.src) this.player.pause();
 | 
				
			||||||
 | 
					        if (ev.detail?.media_type)
 | 
				
			||||||
 | 
					          if (ev.detail?.media_type.startsWith("video"))
 | 
				
			||||||
 | 
					            this.player = this._video_player;
 | 
				
			||||||
 | 
					          else this.player = this._audio_player;
 | 
				
			||||||
        if (ev.detail?.media_content_id)
 | 
					        if (ev.detail?.media_content_id)
 | 
				
			||||||
          this.player.src = ev.detail.media_content_id;
 | 
					          this.player.src = ev.detail.media_content_id;
 | 
				
			||||||
        this.player.play();
 | 
					        this.player.play();
 | 
				
			||||||
 | 
					        this._show_video_player();
 | 
				
			||||||
      });
 | 
					      });
 | 
				
			||||||
      this.addEventListener("command-player-pause", (ev) =>
 | 
					      this.addEventListener("command-player-pause", (ev) =>
 | 
				
			||||||
        this.player.pause()
 | 
					        this.player.pause()
 | 
				
			||||||
@ -39,19 +63,60 @@ export const MediaPlayerMixin = (SuperClass) => {
 | 
				
			|||||||
          this.player.muted = Boolean(ev.detail.mute);
 | 
					          this.player.muted = Boolean(ev.detail.mute);
 | 
				
			||||||
        else this.player.muted = !this.player.muted;
 | 
					        else this.player.muted = !this.player.muted;
 | 
				
			||||||
      });
 | 
					      });
 | 
				
			||||||
 | 
					      this.addEventListener("command-player-seek", (ev) => {
 | 
				
			||||||
 | 
					        this.player.currentTime = ev.detail.position;
 | 
				
			||||||
 | 
					        setTimeout(() => this._player_update(), 10);
 | 
				
			||||||
 | 
					      });
 | 
				
			||||||
 | 
					      this.addEventListener("command-player-turn-off", (ev) => {
 | 
				
			||||||
 | 
					        if (
 | 
				
			||||||
 | 
					          this.player === this._video_player &&
 | 
				
			||||||
 | 
					          this._video_player.isConnected
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					          this.closePopup();
 | 
				
			||||||
 | 
					        else if (this.player.src) this.player.pause();
 | 
				
			||||||
 | 
					        this.player.src = "";
 | 
				
			||||||
 | 
					        this._player_update();
 | 
				
			||||||
 | 
					      });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      this.connectionPromise.then(() => this._player_update());
 | 
					      this.connectionPromise.then(() => this._player_update());
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private _show_video_player() {
 | 
				
			||||||
 | 
					      if (this.player === this._video_player && this.player.src) {
 | 
				
			||||||
 | 
					        selectTree(
 | 
				
			||||||
 | 
					          document,
 | 
				
			||||||
 | 
					          "home-assistant $ dialog-media-player-browse"
 | 
				
			||||||
 | 
					        ).then((el) => el?.closeDialog());
 | 
				
			||||||
 | 
					        this.showPopup(undefined, this._video_player, {
 | 
				
			||||||
 | 
					          dismiss_action: () => this._video_player.pause(),
 | 
				
			||||||
 | 
					          size: "wide",
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					      } else if (
 | 
				
			||||||
 | 
					        this.player !== this._video_player &&
 | 
				
			||||||
 | 
					        this._video_player.isConnected
 | 
				
			||||||
 | 
					      ) {
 | 
				
			||||||
 | 
					        this.closePopup();
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private _player_update_choked() {
 | 
				
			||||||
 | 
					      if (this._player_update_cooldown) return;
 | 
				
			||||||
 | 
					      this._player_update_cooldown = window.setTimeout(
 | 
				
			||||||
 | 
					        () => (this._player_update_cooldown = undefined),
 | 
				
			||||||
 | 
					        3000
 | 
				
			||||||
 | 
					      );
 | 
				
			||||||
 | 
					      this._player_update();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private _player_update() {
 | 
					    private _player_update() {
 | 
				
			||||||
      const state = this._player_enabled
 | 
					      const state = this._player_enabled
 | 
				
			||||||
        ? this.player.src
 | 
					        ? !this.player.src || this.player.src === window.location.href
 | 
				
			||||||
          ? this.player.ended
 | 
					          ? "off"
 | 
				
			||||||
 | 
					          : this.player.ended
 | 
				
			||||||
          ? "stopped"
 | 
					          ? "stopped"
 | 
				
			||||||
          : this.player.paused
 | 
					          : this.player.paused
 | 
				
			||||||
          ? "paused"
 | 
					          ? "paused"
 | 
				
			||||||
          : "playing"
 | 
					          : "playing"
 | 
				
			||||||
          : "stopped"
 | 
					 | 
				
			||||||
        : "unavailable";
 | 
					        : "unavailable";
 | 
				
			||||||
      this.sendUpdate({
 | 
					      this.sendUpdate({
 | 
				
			||||||
        player: {
 | 
					        player: {
 | 
				
			||||||
@ -59,6 +124,8 @@ export const MediaPlayerMixin = (SuperClass) => {
 | 
				
			|||||||
          muted: this.player.muted,
 | 
					          muted: this.player.muted,
 | 
				
			||||||
          src: this.player.src,
 | 
					          src: this.player.src,
 | 
				
			||||||
          state,
 | 
					          state,
 | 
				
			||||||
 | 
					          media_duration: this.player.duration,
 | 
				
			||||||
 | 
					          media_position: this.player.currentTime,
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
      });
 | 
					      });
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
				
			|||||||
@ -3,8 +3,6 @@ import { property, query } from "lit/decorators.js";
 | 
				
			|||||||
import { unsafeHTML } from "lit/directives/unsafe-html.js";
 | 
					import { unsafeHTML } from "lit/directives/unsafe-html.js";
 | 
				
			||||||
import { provideHass, loadLoadCardHelpers, hass_base_el } from "../helpers";
 | 
					import { provideHass, loadLoadCardHelpers, hass_base_el } from "../helpers";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
let aaa = 0;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class BrowserModPopup extends LitElement {
 | 
					class BrowserModPopup extends LitElement {
 | 
				
			||||||
  @property() open;
 | 
					  @property() open;
 | 
				
			||||||
  @property() content;
 | 
					  @property() content;
 | 
				
			||||||
@ -52,10 +50,11 @@ class BrowserModPopup extends LitElement {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
    this._autocloseListener = undefined;
 | 
					    this._autocloseListener = undefined;
 | 
				
			||||||
    if (this._autoclose) {
 | 
					    if (this._autoclose) {
 | 
				
			||||||
      this._autocloseListener = this._dismiss.bind(this);
 | 
					      this._autocloseListener = () => this.dialog.close();
 | 
				
			||||||
      window.browser_mod.addEventListener(
 | 
					      window.browser_mod.addEventListener(
 | 
				
			||||||
        "browser-mod-activity",
 | 
					        "browser-mod-activity",
 | 
				
			||||||
        this._autocloseListener
 | 
					        this._autocloseListener,
 | 
				
			||||||
 | 
					        { once: true }
 | 
				
			||||||
      );
 | 
					      );
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
@ -78,7 +77,10 @@ class BrowserModPopup extends LitElement {
 | 
				
			|||||||
    } = {}
 | 
					    } = {}
 | 
				
			||||||
  ) {
 | 
					  ) {
 | 
				
			||||||
    this.title = title;
 | 
					    this.title = title;
 | 
				
			||||||
    if (content && typeof content === "object") {
 | 
					    if (content && content instanceof HTMLElement) {
 | 
				
			||||||
 | 
					      this.card = undefined;
 | 
				
			||||||
 | 
					      this.content = content;
 | 
				
			||||||
 | 
					    } else if (content && typeof content === "object") {
 | 
				
			||||||
      // Create a card from config in content
 | 
					      // Create a card from config in content
 | 
				
			||||||
      this.card = true;
 | 
					      this.card = true;
 | 
				
			||||||
      const helpers = await window.loadCardHelpers();
 | 
					      const helpers = await window.loadCardHelpers();
 | 
				
			||||||
@ -112,21 +114,21 @@ class BrowserModPopup extends LitElement {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  async _primary() {
 | 
					  async _primary() {
 | 
				
			||||||
    if (this._actions?.dismiss_action) this._actions.dismiss_action = undefined;
 | 
					    if (this._actions?.dismiss_action) this._actions.dismiss_action = undefined;
 | 
				
			||||||
    await this.closeDialog();
 | 
					    this.dialog?.close();
 | 
				
			||||||
    this._actions?.right_button_action?.();
 | 
					    this._actions?.right_button_action?.();
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  async _secondary() {
 | 
					  async _secondary() {
 | 
				
			||||||
    if (this._actions?.dismiss_action) this._actions.dismiss_action = undefined;
 | 
					    if (this._actions?.dismiss_action) this._actions.dismiss_action = undefined;
 | 
				
			||||||
    await this.closeDialog();
 | 
					    this.dialog?.close();
 | 
				
			||||||
    this._actions?.left_button_action?.();
 | 
					    this._actions?.left_button_action?.();
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  async _dismiss() {
 | 
					  async _dismiss(ev?) {
 | 
				
			||||||
    await this.closeDialog();
 | 
					    this.dialog?.close();
 | 
				
			||||||
    this._actions?.dismiss_action?.();
 | 
					    this._actions?.dismiss_action?.();
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  async _timeout() {
 | 
					  async _timeout() {
 | 
				
			||||||
    if (this._actions?.dismiss_action) this._actions.dismiss_action = undefined;
 | 
					    if (this._actions?.dismiss_action) this._actions.dismiss_action = undefined;
 | 
				
			||||||
    await this.closeDialog();
 | 
					    this.dialog?.close();
 | 
				
			||||||
    this._actions?.timeout_action?.();
 | 
					    this._actions?.timeout_action?.();
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -136,10 +138,12 @@ class BrowserModPopup extends LitElement {
 | 
				
			|||||||
    return html`
 | 
					    return html`
 | 
				
			||||||
      <ha-dialog
 | 
					      <ha-dialog
 | 
				
			||||||
        open
 | 
					        open
 | 
				
			||||||
 | 
					        @closed=${this.closeDialog}
 | 
				
			||||||
 | 
					        @closing=${this._dismiss}
 | 
				
			||||||
        .heading=${this.title !== undefined}
 | 
					        .heading=${this.title !== undefined}
 | 
				
			||||||
        ?hideActions=${this.actions === undefined}
 | 
					        ?hideActions=${this.actions === undefined}
 | 
				
			||||||
        .scrimClickAction=${this.dismissable ? this._dismiss : ""}
 | 
					        .scrimClickAction=${this.dismissable ? "close" : ""}
 | 
				
			||||||
        .escapeKeyAction=${this.dismissable ? this._dismiss : ""}
 | 
					        .escapeKeyAction=${this.dismissable ? "close" : ""}
 | 
				
			||||||
      >
 | 
					      >
 | 
				
			||||||
        ${this.timeout
 | 
					        ${this.timeout
 | 
				
			||||||
          ? html` <div slot="heading" class="progress"></div> `
 | 
					          ? html` <div slot="heading" class="progress"></div> `
 | 
				
			||||||
@ -191,6 +195,7 @@ class BrowserModPopup extends LitElement {
 | 
				
			|||||||
  static get styles() {
 | 
					  static get styles() {
 | 
				
			||||||
    return css`
 | 
					    return css`
 | 
				
			||||||
      ha-dialog {
 | 
					      ha-dialog {
 | 
				
			||||||
 | 
					        z-index: 10;
 | 
				
			||||||
        --mdc-dialog-min-width: var(--popup-min-width, 400px);
 | 
					        --mdc-dialog-min-width: var(--popup-min-width, 400px);
 | 
				
			||||||
        --mdc-dialog-max-width: var(--popup-max-width, 600px);
 | 
					        --mdc-dialog-max-width: var(--popup-max-width, 600px);
 | 
				
			||||||
        --mdc-dialog-heading-ink-color: var(--primary-text-color);
 | 
					        --mdc-dialog-heading-ink-color: var(--primary-text-color);
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user