Favicon templates

This commit is contained in:
Thomas Lovén 2022-07-22 21:40:59 +00:00
parent 5f2e7d7bfa
commit b82da219ce
8 changed files with 447 additions and 236 deletions

View File

@ -1864,20 +1864,24 @@ const AutoSettingsMixin = (SuperClass) => {
constructor() { constructor() {
super(); super();
this._auto_settings_setup(); this._auto_settings_setup();
this.addEventListener("browser-mod-config-update", () => this._auto_settings_setup());
} }
async _auto_settings_setup() { async _auto_settings_setup() {
await this.connectionPromise; await this.connectionPromise;
const settings = this.settings; const settings = this.settings;
// Sidebar panel order and hiding
if (settings.sidebarPanelOrder) { if (settings.sidebarPanelOrder) {
localStorage.setItem("sidebarPanelOrder", settings.sidebarPanelOrder); localStorage.setItem("sidebarPanelOrder", settings.sidebarPanelOrder);
} }
if (settings.sidebarHiddenPanels) { if (settings.sidebarHiddenPanels) {
localStorage.setItem("sidebarHiddenPanels", settings.sidebarHiddenPanels); localStorage.setItem("sidebarHiddenPanels", settings.sidebarHiddenPanels);
} }
// Hide sidebar
if (settings.hideSidebar === true) { if (settings.hideSidebar === true) {
selectTree(document.body, "home-assistant$home-assistant-main$app-drawer-layout").then((el) => el.style.setProperty("--app-drawer-width", "0px")); selectTree(document.body, "home-assistant$home-assistant-main$app-drawer-layout").then((el) => el.style.setProperty("--app-drawer-width", "0px"));
selectTree(document.body, "home-assistant$home-assistant-main$app-drawer-layout app-drawer").then((el) => el.remove()); selectTree(document.body, "home-assistant$home-assistant-main$app-drawer-layout app-drawer").then((el) => el.remove());
} }
// Hide header
if (settings.hideHeader === true) { if (settings.hideHeader === true) {
customElements.whenDefined("app-header-layout").then(() => { customElements.whenDefined("app-header-layout").then(() => {
const appHeader = customElements.get("app-header").prototype; const appHeader = customElements.get("app-header").prototype;
@ -1888,6 +1892,40 @@ const AutoSettingsMixin = (SuperClass) => {
}; };
}); });
} }
// Favicon template
if (settings.faviconTemplate !== undefined) {
(async () => {
if (this._faviconTemplateSubscription) {
this._faviconTemplateSubscription();
}
this._faviconTemplateSubscription = undefined;
this._faviconTemplateSubscription =
await this.connection.subscribeMessage(this._updateFavicon, {
type: "render_template",
template: settings.faviconTemplate,
variables: {},
});
})();
}
// Title template
if (settings.titleTemplate !== undefined) ;
}
get _currentFavicon() {
const link = document.head.querySelector("link[rel~='icon']");
return link === null || link === void 0 ? void 0 : link.href;
}
_updateFavicon({ result }) {
// TEMP: Template for testing
/*
{% if is_state("light.bed_light", "on") %}
/local/workspace/test/icons/green.png
{% else %}
/local/workspace/test/icons/red.png
{% endif %}
*/
const link = document.head.querySelector("link[rel~='icon']");
link.href = result;
window.browser_mod.fireEvent("browser-mod-favicon-update");
} }
}; };
}; };
@ -1931,9 +1969,9 @@ const AutoSettingsMixin = (SuperClass) => {
x Kiosk mode x Kiosk mode
- Default panel? - Default panel?
- Screensaver? - Screensaver?
- Tweaks x Favicon templates
- Favicon templates
- Title templates - Title templates
- Tweaks
- Quickbar tweaks (ctrl+enter)? - Quickbar tweaks (ctrl+enter)?
- Video player? - Video player?
- Media_seek - Media_seek

View File

@ -67,7 +67,7 @@ const i=(i,e)=>"method"===e.kind&&e.descriptor&&!("value"in e.descriptor)?{...e,
// 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 // Also provides ha-settings-row
const loadDevTools = async () => { const loadConfigDashboard = 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;
await customElements.whenDefined("partial-panel-resolver"); await customElements.whenDefined("partial-panel-resolver");
const ppResolver = document.createElement("partial-panel-resolver"); const ppResolver = document.createElement("partial-panel-resolver");
@ -84,7 +84,24 @@ const loadDevTools = async () => {
await ((_l = (_k = (_j = (_h = configRouter === null || configRouter === void 0 ? void 0 : configRouter.routerOptions) === null || _h === void 0 ? void 0 : _h.routes) === null || _j === void 0 ? void 0 : _j.cloud) === null || _k === void 0 ? void 0 : _k.load) === null || _l === void 0 ? void 0 : _l.call(_k)); // Load ha-settings-row await ((_l = (_k = (_j = (_h = configRouter === null || configRouter === void 0 ? void 0 : configRouter.routerOptions) === null || _h === void 0 ? void 0 : _h.routes) === null || _j === void 0 ? void 0 : _j.cloud) === null || _k === void 0 ? void 0 : _k.load) === null || _l === void 0 ? void 0 : _l.call(_k)); // Load ha-settings-row
await customElements.whenDefined("ha-config-dashboard"); await customElements.whenDefined("ha-config-dashboard");
}; };
const loadDeveloperToolsTemplate = async () => {
var _a, _b, _c, _d, _e, _f, _g;
await customElements.whenDefined("partial-panel-resolver");
await customElements.whenDefined("partial-panel-resolver");
const ppResolver = document.createElement("partial-panel-resolver");
const routes = ppResolver.getRoutes([
{
component_name: "developer-tools",
url_path: "a",
},
]);
await ((_c = (_b = (_a = routes === null || routes === void 0 ? void 0 : routes.routes) === null || _a === void 0 ? void 0 : _a.a) === null || _b === void 0 ? void 0 : _b.load) === null || _c === void 0 ? void 0 : _c.call(_b));
const dtRouter = document.createElement("developer-tools-router");
await ((_g = (_f = (_e = (_d = dtRouter === null || dtRouter === void 0 ? void 0 : dtRouter.routerOptions) === null || _d === void 0 ? void 0 : _d.routes) === null || _e === void 0 ? void 0 : _e.template) === null || _f === void 0 ? void 0 : _f.load) === null || _g === void 0 ? void 0 : _g.call(_f));
await customElements.whenDefined("developer-tools-template");
};
loadDeveloperToolsTemplate();
class BrowserModSettingsCard extends s { class BrowserModSettingsCard extends s {
constructor() { constructor() {
super(...arguments); super(...arguments);
@ -92,6 +109,7 @@ class BrowserModSettingsCard extends s {
} }
firstUpdated() { firstUpdated() {
window.browser_mod.addEventListener("browser-mod-config-update", () => this.requestUpdate()); window.browser_mod.addEventListener("browser-mod-config-update", () => this.requestUpdate());
window.browser_mod.addEventListener("browser-mod-favicon-update", () => this.requestUpdate());
} }
_handleSwitchTab(ev) { _handleSwitchTab(ev) {
this._selectedTab = parseInt(ev.detail.index, 10); this._selectedTab = parseInt(ev.detail.index, 10);
@ -101,12 +119,30 @@ class BrowserModSettingsCard extends s {
return $ ` return $ `
<ha-card header="Frontend settings" outlined> <ha-card header="Frontend settings" outlined>
<div class="card-content"> <div class="card-content">
<p>
Please note: Those settings severely change the way the Home
Assistant frontend works and looks. It is very easy to forget that
you made a setting here when you switch devices or user.
</p>
<p>
Do not report any issues to Home Assistant before clearing
<b>EVERY</b> setting here and thouroghly clearing all your browser
caches. Failure to do so means you risk wasting a lot of peoples
time, and you will be severly and rightfully ridiculed.
</p>
<p>
Global settings are applied for all users and browsers.</br>
User settings are applied to the current user and overrides any Global settings.</br>
Browser settings are applied for the current browser and overrides any User or Global settings.
</p>
<mwc-tab-bar <mwc-tab-bar
.activeIndex=${this._selectedTab} .activeIndex=${this._selectedTab}
@MDCTabBar:activated=${this._handleSwitchTab} @MDCTabBar:activated=${this._handleSwitchTab}
> >
<mwc-tab .label=${"Browser"}></mwc-tab> <mwc-tab .label=${"Browser"}></mwc-tab>
<ha-icon .icon=${"mdi:chevron-double-right"}></ha-icon>
<mwc-tab .label=${"User (" + this.hass.user.name + ")"}></mwc-tab> <mwc-tab .label=${"User (" + this.hass.user.name + ")"}></mwc-tab>
<ha-icon .icon=${"mdi:chevron-double-right"}></ha-icon>
<mwc-tab .label=${"Global"}></mwc-tab> <mwc-tab .label=${"Global"}></mwc-tab>
</mwc-tab-bar> </mwc-tab-bar>
@ -120,7 +156,7 @@ class BrowserModSettingsCard extends s {
const user = window.browser_mod.user_settings; const user = window.browser_mod.user_settings;
const browser = window.browser_mod.browser_settings; const browser = window.browser_mod.browser_settings;
const current = { global, user, browser }[level]; const current = { global, user, browser }[level];
const DESC_BOOLEAN = (val) => ({ true: "Enabled", false: "Disabled", undefined: "unset" }[String(val)]); const DESC_BOOLEAN = (val) => ({ true: "Enabled", false: "Disabled", undefined: "Unset" }[String(val)]);
const DESC_SET_UNSET = (val) => (val === undefined ? "Unset" : "Set"); const DESC_SET_UNSET = (val) => (val === undefined ? "Unset" : "Set");
const OVERRIDDEN = (key) => { const OVERRIDDEN = (key) => {
if (level !== "browser" && browser[key] !== undefined) if (level !== "browser" && browser[key] !== undefined)
@ -129,112 +165,133 @@ class BrowserModSettingsCard extends s {
return $ `<br />Overridden by user setting`; return $ `<br />Overridden by user setting`;
}; };
return $ ` return $ `
<ha-settings-row> <div class="box">
<span slot="heading">Hide Sidebar</span> <ha-settings-row>
<span slot="description">Hide the sidebar and hamburger menu</span> <span slot="heading">Favicon template</span>
Currenty: ${DESC_BOOLEAN(current.hideSidebar)} ${OVERRIDDEN("faviconTemplate")}
${OVERRIDDEN("hideSidebar")} <img src="${window.browser_mod._currentFavicon}" class="favicon" />
</ha-settings-row> </ha-settings-row>
<ha-settings-row> <ha-code-editor
<mwc-button .hass=${this.hass}
@click=${() => window.browser_mod.set_setting("hideSidebar", true, level)} .value=${current.faviconTemplate}
> @value-changed=${(ev) => {
Enable const tpl = ev.detail.value || undefined;
</mwc-button> window.browser_mod.set_setting("faviconTemplate", tpl, level);
<mwc-button }}
@click=${() => window.browser_mod.set_setting("hideSidebar", false, level)} ></ha-code-editor>
> <ha-settings-row>
Disable <mwc-button
</mwc-button> @click=${() => window.browser_mod.set_setting("faviconTemplate", undefined, level)}
<mwc-button >
@click=${() => window.browser_mod.set_setting("hideSidebar", undefined, level)} Clear
> </mwc-button>
Clear </ha-settings-row>
</mwc-button>
</ha-settings-row>
<ha-settings-row> <div class="separator"></div>
<span slot="heading">Hide Header</span>
<span slot="description">Hide the header on all pages</span>
Currenty: ${DESC_BOOLEAN(current.hideHeader)}
${OVERRIDDEN("hideHeader")}
</ha-settings-row>
<ha-settings-row>
<mwc-button
@click=${() => window.browser_mod.set_setting("hideHeader", true, level)}
>
Enable
</mwc-button>
<mwc-button
@click=${() => window.browser_mod.set_setting("hideHeader", false, level)}
>
Disable
</mwc-button>
<mwc-button
@click=${() => window.browser_mod.set_setting("hideHeader", undefined, level)}
>
Clear
</mwc-button>
</ha-settings-row>
<ha-settings-row> <ha-settings-row>
<span slot="heading">Sidebar order</span> <span slot="heading">Hide Sidebar</span>
<span slot="description">Order and visibility of sidebar buttons</span> <span slot="description">Hide the sidebar and hamburger menu</span>
Currenty: ${DESC_SET_UNSET(current.sidebarPanelOrder)} Currenty: ${DESC_BOOLEAN(current.hideSidebar)}
${OVERRIDDEN("sidebarPanelOrder")} ${OVERRIDDEN("hideSidebar")}
</ha-settings-row> </ha-settings-row>
<ha-settings-row> <ha-settings-row>
<mwc-button <mwc-button
@click=${() => { @click=${() => window.browser_mod.set_setting("hideSidebar", true, level)}
>
Enable
</mwc-button>
<mwc-button
@click=${() => window.browser_mod.set_setting("hideSidebar", false, level)}
>
Disable
</mwc-button>
<mwc-button
@click=${() => window.browser_mod.set_setting("hideSidebar", undefined, level)}
>
Clear
</mwc-button>
</ha-settings-row>
<div class="separator"></div>
<ha-settings-row>
<span slot="heading">Hide Header</span>
<span slot="description">Hide the header on all pages</span>
Currenty: ${DESC_BOOLEAN(current.hideHeader)}
${OVERRIDDEN("hideHeader")}
</ha-settings-row>
<ha-settings-row>
<mwc-button
@click=${() => window.browser_mod.set_setting("hideHeader", true, level)}
>
Enable
</mwc-button>
<mwc-button
@click=${() => window.browser_mod.set_setting("hideHeader", false, level)}
>
Disable
</mwc-button>
<mwc-button
@click=${() => window.browser_mod.set_setting("hideHeader", undefined, level)}
>
Clear
</mwc-button>
</ha-settings-row>
<div class="separator"></div>
<ha-settings-row>
<span slot="heading">Sidebar order</span>
<span slot="description"
>Order and visibility of sidebar buttons</span
>
Currenty: ${DESC_SET_UNSET(current.sidebarPanelOrder)}
${OVERRIDDEN("sidebarPanelOrder")}
</ha-settings-row>
<ha-settings-row>
<span slot="description">
Clearing this does NOT restore the original button order.
</span>
<mwc-button
@click=${() => {
window.browser_mod.set_setting("sidebarPanelOrder", localStorage.getItem("sidebarPanelOrder"), level); window.browser_mod.set_setting("sidebarPanelOrder", localStorage.getItem("sidebarPanelOrder"), level);
window.browser_mod.set_setting("sidebarHiddenPanels", localStorage.getItem("sidebarHiddenPanels"), level); window.browser_mod.set_setting("sidebarHiddenPanels", localStorage.getItem("sidebarHiddenPanels"), level);
}} }}
> >
Set Set
</mwc-button> </mwc-button>
<mwc-button <mwc-button
@click=${() => { @click=${() => {
window.browser_mod.set_setting("sidebarPanelOrder", undefined, level); window.browser_mod.set_setting("sidebarPanelOrder", undefined, level);
window.browser_mod.set_setting("sidebarHiddenPanels", undefined, level); window.browser_mod.set_setting("sidebarHiddenPanels", undefined, level);
}} }}
> >
Clear Clear
</mwc-button> </mwc-button>
</ha-settings-row> </ha-settings-row>
</div>
`; `;
} }
_render_user() { static get styles() {
return $ ` return r$2 `
User .box {
<ha-settings-row> border: 1px solid var(--divider-color);
<span slot="heading">Kiosk mode</span> padding: 8px;
<span slot="description"> Hide sidebar and header </span> }
Currenty: Overridden .separator {
</ha-settings-row> border-bottom: 1px solid var(--divider-color);
<ha-settings-row> margin: 0 -8px;
<span slot="heading">Set screensaver</span> }
<span slot="description"> Set screensaver card </span> img.favicon {
<mwc-button>Enable</mwc-button> width: 64px;
<mwc-button>Disable</mwc-button> height: 64px;
<mwc-button>Clear</mwc-button> margin-left: 16px;
</ha-settings-row> }
`; mwc-tab-bar ha-icon {
} display: flex;
_render_browser() { align-items: center;
return $ ` }
Browser
<ha-settings-row>
<span slot="heading">Kiosk mode</span>
<span slot="description"> Hide sidebar and header </span>
Currenty: Overridden
</ha-settings-row>
<ha-settings-row>
<span slot="heading">Set screensaver</span>
<span slot="description"> Set screensaver card </span>
<mwc-button>Enable</mwc-button>
<mwc-button>Disable</mwc-button>
<mwc-button>Clear</mwc-button>
</ha-settings-row>
`; `;
} }
} }
@ -247,7 +304,7 @@ __decorate([
customElements.define("browser-mod-settings-card", BrowserModSettingsCard); customElements.define("browser-mod-settings-card", BrowserModSettingsCard);
const bmWindow = window; const bmWindow = window;
loadDevTools().then(() => { loadConfigDashboard().then(() => {
class BrowserModPanel extends s { class BrowserModPanel extends s {
constructor() { constructor() {
super(...arguments); super(...arguments);

View File

@ -16,6 +16,8 @@ class Settings:
defaultPanel = attr.ib(type=str, default=None) defaultPanel = attr.ib(type=str, default=None)
sidebarPanelOrder = attr.ib(type=list, default=None) sidebarPanelOrder = attr.ib(type=list, default=None)
sidebarHiddenPanels = attr.ib(type=list, default=None) sidebarHiddenPanels = attr.ib(type=list, default=None)
faviconTemplate = attr.ib(type=str, default=None)
titleTemplate = attr.ib(type=str, default=None)
@classmethod @classmethod
def from_dict(cls, data): def from_dict(cls, data):

View File

@ -1,13 +1,13 @@
import { LitElement, html, css } from "lit"; import { LitElement, html, css } from "lit";
import { property } from "lit/decorators.js"; import { property } from "lit/decorators.js";
import { loadDevTools } from "../helpers"; import { loadConfigDashboard } from "../helpers";
import { loadHaForm } from "../helpers"; import { loadHaForm } from "../helpers";
import "./settings-card"; import "./settings-card";
const bmWindow = window as any; const bmWindow = window as any;
loadDevTools().then(() => { loadConfigDashboard().then(() => {
class BrowserModPanel extends LitElement { class BrowserModPanel extends LitElement {
@property() hass; @property() hass;
@property() narrow; @property() narrow;

View File

@ -1,5 +1,8 @@
import { LitElement, html, css } from "lit"; import { LitElement, html, css } from "lit";
import { property, state } from "lit/decorators.js"; import { property, state } from "lit/decorators.js";
import { loadDeveloperToolsTemplate } from "../helpers";
loadDeveloperToolsTemplate();
class BrowserModSettingsCard extends LitElement { class BrowserModSettingsCard extends LitElement {
@property() hass; @property() hass;
@ -10,6 +13,9 @@ class BrowserModSettingsCard extends LitElement {
window.browser_mod.addEventListener("browser-mod-config-update", () => window.browser_mod.addEventListener("browser-mod-config-update", () =>
this.requestUpdate() this.requestUpdate()
); );
window.browser_mod.addEventListener("browser-mod-favicon-update", () =>
this.requestUpdate()
);
} }
_handleSwitchTab(ev: CustomEvent) { _handleSwitchTab(ev: CustomEvent) {
@ -21,12 +27,30 @@ class BrowserModSettingsCard extends LitElement {
return html` return html`
<ha-card header="Frontend settings" outlined> <ha-card header="Frontend settings" outlined>
<div class="card-content"> <div class="card-content">
<p>
Please note: Those settings severely change the way the Home
Assistant frontend works and looks. It is very easy to forget that
you made a setting here when you switch devices or user.
</p>
<p>
Do not report any issues to Home Assistant before clearing
<b>EVERY</b> setting here and thouroghly clearing all your browser
caches. Failure to do so means you risk wasting a lot of peoples
time, and you will be severly and rightfully ridiculed.
</p>
<p>
Global settings are applied for all users and browsers.</br>
User settings are applied to the current user and overrides any Global settings.</br>
Browser settings are applied for the current browser and overrides any User or Global settings.
</p>
<mwc-tab-bar <mwc-tab-bar
.activeIndex=${this._selectedTab} .activeIndex=${this._selectedTab}
@MDCTabBar:activated=${this._handleSwitchTab} @MDCTabBar:activated=${this._handleSwitchTab}
> >
<mwc-tab .label=${"Browser"}></mwc-tab> <mwc-tab .label=${"Browser"}></mwc-tab>
<ha-icon .icon=${"mdi:chevron-double-right"}></ha-icon>
<mwc-tab .label=${"User (" + this.hass.user.name + ")"}></mwc-tab> <mwc-tab .label=${"User (" + this.hass.user.name + ")"}></mwc-tab>
<ha-icon .icon=${"mdi:chevron-double-right"}></ha-icon>
<mwc-tab .label=${"Global"}></mwc-tab> <mwc-tab .label=${"Global"}></mwc-tab>
</mwc-tab-bar> </mwc-tab-bar>
@ -43,7 +67,7 @@ class BrowserModSettingsCard extends LitElement {
const current = { global, user, browser }[level]; const current = { global, user, browser }[level];
const DESC_BOOLEAN = (val) => const DESC_BOOLEAN = (val) =>
({ true: "Enabled", false: "Disabled", undefined: "unset" }[String(val)]); ({ true: "Enabled", false: "Disabled", undefined: "Unset" }[String(val)]);
const DESC_SET_UNSET = (val) => (val === undefined ? "Unset" : "Set"); const DESC_SET_UNSET = (val) => (val === undefined ? "Unset" : "Set");
const OVERRIDDEN = (key) => { const OVERRIDDEN = (key) => {
if (level !== "browser" && browser[key] !== undefined) if (level !== "browser" && browser[key] !== undefined)
@ -53,136 +77,161 @@ class BrowserModSettingsCard extends LitElement {
}; };
return html` return html`
<ha-settings-row> <div class="box">
<span slot="heading">Hide Sidebar</span> <ha-settings-row>
<span slot="description">Hide the sidebar and hamburger menu</span> <span slot="heading">Favicon template</span>
Currenty: ${DESC_BOOLEAN(current.hideSidebar)} ${OVERRIDDEN("faviconTemplate")}
${OVERRIDDEN("hideSidebar")} <img src="${window.browser_mod._currentFavicon}" class="favicon" />
</ha-settings-row> </ha-settings-row>
<ha-settings-row> <ha-code-editor
<mwc-button .hass=${this.hass}
@click=${() => .value=${current.faviconTemplate}
window.browser_mod.set_setting("hideSidebar", true, level)} @value-changed=${(ev) => {
> const tpl = ev.detail.value || undefined;
Enable window.browser_mod.set_setting("faviconTemplate", tpl, level);
</mwc-button>
<mwc-button
@click=${() =>
window.browser_mod.set_setting("hideSidebar", false, level)}
>
Disable
</mwc-button>
<mwc-button
@click=${() =>
window.browser_mod.set_setting("hideSidebar", undefined, level)}
>
Clear
</mwc-button>
</ha-settings-row>
<ha-settings-row>
<span slot="heading">Hide Header</span>
<span slot="description">Hide the header on all pages</span>
Currenty: ${DESC_BOOLEAN(current.hideHeader)}
${OVERRIDDEN("hideHeader")}
</ha-settings-row>
<ha-settings-row>
<mwc-button
@click=${() =>
window.browser_mod.set_setting("hideHeader", true, level)}
>
Enable
</mwc-button>
<mwc-button
@click=${() =>
window.browser_mod.set_setting("hideHeader", false, level)}
>
Disable
</mwc-button>
<mwc-button
@click=${() =>
window.browser_mod.set_setting("hideHeader", undefined, level)}
>
Clear
</mwc-button>
</ha-settings-row>
<ha-settings-row>
<span slot="heading">Sidebar order</span>
<span slot="description">Order and visibility of sidebar buttons</span>
Currenty: ${DESC_SET_UNSET(current.sidebarPanelOrder)}
${OVERRIDDEN("sidebarPanelOrder")}
</ha-settings-row>
<ha-settings-row>
<mwc-button
@click=${() => {
window.browser_mod.set_setting(
"sidebarPanelOrder",
localStorage.getItem("sidebarPanelOrder"),
level
);
window.browser_mod.set_setting(
"sidebarHiddenPanels",
localStorage.getItem("sidebarHiddenPanels"),
level
);
}} }}
> ></ha-code-editor>
Set <ha-settings-row>
</mwc-button> <mwc-button
<mwc-button @click=${() =>
@click=${() => { window.browser_mod.set_setting(
window.browser_mod.set_setting( "faviconTemplate",
"sidebarPanelOrder", undefined,
undefined, level
level )}
); >
window.browser_mod.set_setting( Clear
"sidebarHiddenPanels", </mwc-button>
undefined, </ha-settings-row>
level
); <div class="separator"></div>
}}
> <ha-settings-row>
Clear <span slot="heading">Hide Sidebar</span>
</mwc-button> <span slot="description">Hide the sidebar and hamburger menu</span>
</ha-settings-row> Currenty: ${DESC_BOOLEAN(current.hideSidebar)}
${OVERRIDDEN("hideSidebar")}
</ha-settings-row>
<ha-settings-row>
<mwc-button
@click=${() =>
window.browser_mod.set_setting("hideSidebar", true, level)}
>
Enable
</mwc-button>
<mwc-button
@click=${() =>
window.browser_mod.set_setting("hideSidebar", false, level)}
>
Disable
</mwc-button>
<mwc-button
@click=${() =>
window.browser_mod.set_setting("hideSidebar", undefined, level)}
>
Clear
</mwc-button>
</ha-settings-row>
<div class="separator"></div>
<ha-settings-row>
<span slot="heading">Hide Header</span>
<span slot="description">Hide the header on all pages</span>
Currenty: ${DESC_BOOLEAN(current.hideHeader)}
${OVERRIDDEN("hideHeader")}
</ha-settings-row>
<ha-settings-row>
<mwc-button
@click=${() =>
window.browser_mod.set_setting("hideHeader", true, level)}
>
Enable
</mwc-button>
<mwc-button
@click=${() =>
window.browser_mod.set_setting("hideHeader", false, level)}
>
Disable
</mwc-button>
<mwc-button
@click=${() =>
window.browser_mod.set_setting("hideHeader", undefined, level)}
>
Clear
</mwc-button>
</ha-settings-row>
<div class="separator"></div>
<ha-settings-row>
<span slot="heading">Sidebar order</span>
<span slot="description"
>Order and visibility of sidebar buttons</span
>
Currenty: ${DESC_SET_UNSET(current.sidebarPanelOrder)}
${OVERRIDDEN("sidebarPanelOrder")}
</ha-settings-row>
<ha-settings-row>
<span slot="description">
Clearing this does NOT restore the original button order.
</span>
<mwc-button
@click=${() => {
window.browser_mod.set_setting(
"sidebarPanelOrder",
localStorage.getItem("sidebarPanelOrder"),
level
);
window.browser_mod.set_setting(
"sidebarHiddenPanels",
localStorage.getItem("sidebarHiddenPanels"),
level
);
}}
>
Set
</mwc-button>
<mwc-button
@click=${() => {
window.browser_mod.set_setting(
"sidebarPanelOrder",
undefined,
level
);
window.browser_mod.set_setting(
"sidebarHiddenPanels",
undefined,
level
);
}}
>
Clear
</mwc-button>
</ha-settings-row>
</div>
`; `;
} }
_render_user() { static get styles() {
return html` return css`
User .box {
<ha-settings-row> border: 1px solid var(--divider-color);
<span slot="heading">Kiosk mode</span> padding: 8px;
<span slot="description"> Hide sidebar and header </span> }
Currenty: Overridden .separator {
</ha-settings-row> border-bottom: 1px solid var(--divider-color);
<ha-settings-row> margin: 0 -8px;
<span slot="heading">Set screensaver</span> }
<span slot="description"> Set screensaver card </span> img.favicon {
<mwc-button>Enable</mwc-button> width: 64px;
<mwc-button>Disable</mwc-button> height: 64px;
<mwc-button>Clear</mwc-button> margin-left: 16px;
</ha-settings-row> }
`; mwc-tab-bar ha-icon {
} display: flex;
align-items: center;
_render_browser() { }
return html`
Browser
<ha-settings-row>
<span slot="heading">Kiosk mode</span>
<span slot="description"> Hide sidebar and header </span>
Currenty: Overridden
</ha-settings-row>
<ha-settings-row>
<span slot="heading">Set screensaver</span>
<span slot="description"> Set screensaver card </span>
<mwc-button>Enable</mwc-button>
<mwc-button>Disable</mwc-button>
<mwc-button>Clear</mwc-button>
</ha-settings-row>
`; `;
} }
} }

View File

@ -88,7 +88,7 @@ export const loadHaForm = async () => {
// 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 // Also provides ha-settings-row
export const loadDevTools = async () => { export const loadConfigDashboard = async () => {
await customElements.whenDefined("partial-panel-resolver"); await customElements.whenDefined("partial-panel-resolver");
const ppResolver = document.createElement("partial-panel-resolver"); const ppResolver = document.createElement("partial-panel-resolver");
const routes = (ppResolver as any).getRoutes([ const routes = (ppResolver as any).getRoutes([
@ -99,8 +99,24 @@ export const loadDevTools = async () => {
]); ]);
await routes?.routes?.a?.load?.(); await routes?.routes?.a?.load?.();
await customElements.whenDefined("ha-panel-config"); await customElements.whenDefined("ha-panel-config");
const configRouter = document.createElement("ha-panel-config"); const configRouter: any = document.createElement("ha-panel-config");
await (configRouter as any)?.routerOptions?.routes?.dashboard?.load?.(); // Load ha-config-dashboard await configRouter?.routerOptions?.routes?.dashboard?.load?.(); // Load ha-config-dashboard
await (configRouter as any)?.routerOptions?.routes?.cloud?.load?.(); // Load ha-settings-row await configRouter?.routerOptions?.routes?.cloud?.load?.(); // Load ha-settings-row
await customElements.whenDefined("ha-config-dashboard"); await customElements.whenDefined("ha-config-dashboard");
}; };
export const loadDeveloperToolsTemplate = async () => {
await customElements.whenDefined("partial-panel-resolver");
await customElements.whenDefined("partial-panel-resolver");
const ppResolver = document.createElement("partial-panel-resolver");
const routes = (ppResolver as any).getRoutes([
{
component_name: "developer-tools",
url_path: "a",
},
]);
await routes?.routes?.a?.load?.();
const dtRouter: any = document.createElement("developer-tools-router");
await dtRouter?.routerOptions?.routes?.template?.load?.();
await customElements.whenDefined("developer-tools-template");
};

View File

@ -2,10 +2,16 @@ import { selectTree } from "../helpers";
export const AutoSettingsMixin = (SuperClass) => { export const AutoSettingsMixin = (SuperClass) => {
return class AutoSettingsMixinClass extends SuperClass { return class AutoSettingsMixinClass extends SuperClass {
_faviconTemplateSubscription;
_titleTemplateSubscription;
constructor() { constructor() {
super(); super();
this._auto_settings_setup(); this._auto_settings_setup();
this.addEventListener("browser-mod-config-update", () =>
this._auto_settings_setup()
);
} }
async _auto_settings_setup() { async _auto_settings_setup() {
@ -13,6 +19,7 @@ export const AutoSettingsMixin = (SuperClass) => {
const settings = this.settings; const settings = this.settings;
// Sidebar panel order and hiding
if (settings.sidebarPanelOrder) { if (settings.sidebarPanelOrder) {
localStorage.setItem("sidebarPanelOrder", settings.sidebarPanelOrder); localStorage.setItem("sidebarPanelOrder", settings.sidebarPanelOrder);
} }
@ -23,6 +30,7 @@ export const AutoSettingsMixin = (SuperClass) => {
); );
} }
// Hide sidebar
if (settings.hideSidebar === true) { if (settings.hideSidebar === true) {
selectTree( selectTree(
document.body, document.body,
@ -33,6 +41,8 @@ export const AutoSettingsMixin = (SuperClass) => {
"home-assistant$home-assistant-main$app-drawer-layout app-drawer" "home-assistant$home-assistant-main$app-drawer-layout app-drawer"
).then((el) => el.remove()); ).then((el) => el.remove());
} }
// Hide header
if (settings.hideHeader === true) { if (settings.hideHeader === true) {
customElements.whenDefined("app-header-layout").then(() => { customElements.whenDefined("app-header-layout").then(() => {
const appHeader = customElements.get("app-header").prototype; const appHeader = customElements.get("app-header").prototype;
@ -43,6 +53,45 @@ export const AutoSettingsMixin = (SuperClass) => {
}; };
}); });
} }
// Favicon template
if (settings.faviconTemplate !== undefined) {
(async () => {
if (this._faviconTemplateSubscription) {
this._faviconTemplateSubscription();
}
this._faviconTemplateSubscription = undefined;
this._faviconTemplateSubscription =
await this.connection.subscribeMessage(this._updateFavicon, {
type: "render_template",
template: settings.faviconTemplate,
variables: {},
});
})();
}
// Title template
if (settings.titleTemplate !== undefined) {
}
}
get _currentFavicon() {
const link: any = document.head.querySelector("link[rel~='icon']");
return link?.href;
}
_updateFavicon({ result }) {
// TEMP: Template for testing
/*
{% if is_state("light.bed_light", "on") %}
/local/workspace/test/icons/green.png
{% else %}
/local/workspace/test/icons/red.png
{% endif %}
*/
const link: any = document.head.querySelector("link[rel~='icon']");
link.href = result;
window.browser_mod.fireEvent("browser-mod-favicon-update");
} }
}; };
}; };

View File

@ -55,9 +55,9 @@ import { AutoSettingsMixin } from "./auto-settings";
x Kiosk mode x Kiosk mode
- Default panel? - Default panel?
- Screensaver? - Screensaver?
- Tweaks x Favicon templates
- Favicon templates
- Title templates - Title templates
- Tweaks
- Quickbar tweaks (ctrl+enter)? - Quickbar tweaks (ctrl+enter)?
- Video player? - Video player?
- Media_seek - Media_seek