diff --git a/src/components/ha-menu-button.ts b/src/components/ha-menu-button.ts
index ed97a569a8..8a99bafea9 100644
--- a/src/components/ha-menu-button.ts
+++ b/src/components/ha-menu-button.ts
@@ -78,14 +78,25 @@ class HaMenuButton extends LitElement {
protected updated(changedProps) {
super.updated(changedProps);
- if (!changedProps.has("narrow")) {
+ if (!changedProps.has("narrow") && !changedProps.has("hass")) {
+ return;
+ }
+
+ const oldHass = changedProps.get("hass") as HomeAssistant | undefined;
+ const oldNarrow =
+ changedProps.get("narrow") ||
+ (oldHass && oldHass.dockedSidebar === "always_hidden");
+ const newNarrow =
+ this.narrow || this.hass.dockedSidebar === "always_hidden";
+
+ if (oldNarrow === newNarrow) {
return;
}
this.style.visibility =
- this.narrow || this._alwaysVisible ? "initial" : "hidden";
+ newNarrow || this._alwaysVisible ? "initial" : "hidden";
- if (!this.narrow) {
+ if (!newNarrow) {
this._hasNotifications = false;
if (this._unsubNotifications) {
this._unsubNotifications();
diff --git a/src/components/ha-sidebar.ts b/src/components/ha-sidebar.ts
index 0758d1257a..5151e117e8 100644
--- a/src/components/ha-sidebar.ts
+++ b/src/components/ha-sidebar.ts
@@ -134,7 +134,9 @@ class HaSidebar extends LitElement {
? html`
`
@@ -216,7 +218,7 @@ class HaSidebar extends LitElement {
${hass.localize("ui.notification_drawer.title")}
- ${this.expanded
+ ${this.expanded && notificationCount > 0
? html`
${notificationCount}
`
diff --git a/src/fake_data/provide_hass.ts b/src/fake_data/provide_hass.ts
index 3512ec9daa..c14b03111d 100644
--- a/src/fake_data/provide_hass.ts
+++ b/src/fake_data/provide_hass.ts
@@ -159,7 +159,7 @@ export const provideHass = (
localize: () => "",
translationMetadata: translationMetadata as any,
- dockedSidebar: false,
+ dockedSidebar: "auto",
moreInfoEntityId: null as any,
async callService(domain, service, data) {
if (data && "entity_id" in data) {
diff --git a/src/layouts/home-assistant-main.ts b/src/layouts/home-assistant-main.ts
index 480b8cc4f4..6e02734466 100644
--- a/src/layouts/home-assistant-main.ts
+++ b/src/layouts/home-assistant-main.ts
@@ -44,8 +44,11 @@ class HomeAssistantMain extends LitElement {
return;
}
+ const sidebarNarrow =
+ this.narrow || this.hass.dockedSidebar === "always_hidden";
+
const disableSwipe =
- !this.narrow || NON_SWIPABLE_PANELS.indexOf(hass.panelUrl) !== -1;
+ !sidebarNarrow || NON_SWIPABLE_PANELS.indexOf(hass.panelUrl) !== -1;
return html`
@@ -86,7 +91,7 @@ class HomeAssistantMain extends LitElement {
import(/* webpackChunkName: "ha-sidebar" */ "../components/ha-sidebar");
this.addEventListener("hass-toggle-menu", () => {
- if (this.narrow) {
+ if (this.narrow || this.hass.dockedSidebar === "always_hidden") {
if (this.drawer.opened) {
this.drawer.close();
} else {
@@ -94,7 +99,7 @@ class HomeAssistantMain extends LitElement {
}
} else {
fireEvent(this, "hass-dock-sidebar", {
- dock: !this.hass.dockedSidebar,
+ dock: this.hass.dockedSidebar === "auto" ? "docked" : "auto",
});
setTimeout(() => this.appLayout.resetLayout());
}
@@ -110,7 +115,10 @@ class HomeAssistantMain extends LitElement {
protected updated(changedProps: PropertyValues) {
super.updated(changedProps);
- this.toggleAttribute("expanded", this.narrow || this.hass.dockedSidebar);
+ this.toggleAttribute(
+ "expanded",
+ this.narrow || this.hass.dockedSidebar !== "auto"
+ );
if (changedProps.has("route") && this.narrow) {
this.drawer.close();
diff --git a/src/panels/config/ha-panel-config.ts b/src/panels/config/ha-panel-config.ts
index 14a719b93d..9cd3d10155 100644
--- a/src/panels/config/ha-panel-config.ts
+++ b/src/panels/config/ha-panel-config.ts
@@ -146,7 +146,8 @@ class HaPanelConfig extends HassRouterPage {
const showAdvanced = !!(
this._coreUserData && this._coreUserData.showAdvanced
);
- const isWide = this.hass.dockedSidebar ? this._wideSidebar : this._wide;
+ const isWide =
+ this.hass.dockedSidebar === "docked" ? this._wideSidebar : this._wide;
if ("setProperties" in el) {
// As long as we have Polymer panels
diff --git a/src/panels/config/zha/zha-config-panel.ts b/src/panels/config/zha/zha-config-panel.ts
index 114c0f20ff..03fc1fd1cf 100644
--- a/src/panels/config/zha/zha-config-panel.ts
+++ b/src/panels/config/zha/zha-config-panel.ts
@@ -2,7 +2,6 @@ import "../../../layouts/hass-loading-screen";
import { customElement, property } from "lit-element";
-import { listenMediaQuery } from "../../../common/dom/media_query";
import {
HassRouterPage,
RouterOptions,
@@ -12,8 +11,7 @@ import { HomeAssistant } from "../../../types";
@customElement("zha-config-panel")
class ZHAConfigPanel extends HassRouterPage {
@property() public hass!: HomeAssistant;
- @property() public _wideSidebar: boolean = false;
- @property() public _wide: boolean = false;
+ @property() public isWide!: boolean;
protected routerOptions: RouterOptions = {
defaultPage: "configuration",
@@ -33,33 +31,10 @@ class ZHAConfigPanel extends HassRouterPage {
},
};
- private _listeners: Array<() => void> = [];
-
- public connectedCallback(): void {
- super.connectedCallback();
- this._listeners.push(
- listenMediaQuery("(min-width: 1040px)", (matches) => {
- this._wide = matches;
- })
- );
- this._listeners.push(
- listenMediaQuery("(min-width: 1296px)", (matches) => {
- this._wideSidebar = matches;
- })
- );
- }
-
- public disconnectedCallback(): void {
- super.disconnectedCallback();
- while (this._listeners.length) {
- this._listeners.pop()!();
- }
- }
-
protected updatePageEl(el): void {
el.route = this.routeTail;
el.hass = this.hass;
- el.isWide = this.hass.dockedSidebar ? this._wideSidebar : this._wide;
+ el.isWide = this.isWide;
}
}
diff --git a/src/panels/lovelace/ha-panel-lovelace.ts b/src/panels/lovelace/ha-panel-lovelace.ts
index 64f91234e8..bdb5da8399 100644
--- a/src/panels/lovelace/ha-panel-lovelace.ts
+++ b/src/panels/lovelace/ha-panel-lovelace.ts
@@ -178,7 +178,8 @@ class LovelacePanel extends LitElement {
// Do -1 column if the menu is docked and open
this._columns = Math.max(
1,
- matchColumns - Number(!this.narrow && this.hass!.dockedSidebar)
+ matchColumns -
+ Number(!this.narrow && this.hass!.dockedSidebar === "docked")
);
}
diff --git a/src/panels/profile/ha-force-narrow-row.ts b/src/panels/profile/ha-force-narrow-row.ts
new file mode 100644
index 0000000000..f4ff3e9bce
--- /dev/null
+++ b/src/panels/profile/ha-force-narrow-row.ts
@@ -0,0 +1,52 @@
+import {
+ LitElement,
+ TemplateResult,
+ html,
+ property,
+ customElement,
+} from "lit-element";
+import "@polymer/paper-toggle-button/paper-toggle-button";
+
+import "./ha-settings-row";
+import { HomeAssistant } from "../../types";
+import { fireEvent } from "../../common/dom/fire_event";
+import { PolymerChangedEvent } from "../../polymer-types";
+
+@customElement("ha-force-narrow-row")
+class HaPushNotificationsRow extends LitElement {
+ @property() public hass!: HomeAssistant;
+ @property() public narrow!: boolean;
+
+ protected render(): TemplateResult | void {
+ return html`
+
+
+ ${this.hass.localize("ui.panel.profile.force_narrow.header")}
+
+
+ ${this.hass.localize("ui.panel.profile.force_narrow.description")}
+
+
+
+ `;
+ }
+
+ private async _checkedChanged(ev: PolymerChangedEvent) {
+ const newValue = ev.detail.value;
+ if (newValue === (this.hass.dockedSidebar === "always_hidden")) {
+ return;
+ }
+ fireEvent(this, "hass-dock-sidebar", {
+ dock: newValue ? "always_hidden" : "auto",
+ });
+ }
+}
+
+declare global {
+ interface HTMLElementTagNameMap {
+ "ha-force-narrow-row": HaPushNotificationsRow;
+ }
+}
diff --git a/src/panels/profile/ha-panel-profile.js b/src/panels/profile/ha-panel-profile.js
index 47577bc73c..dfd2a3f6c0 100644
--- a/src/panels/profile/ha-panel-profile.js
+++ b/src/panels/profile/ha-panel-profile.js
@@ -25,6 +25,7 @@ import "./ha-long-lived-access-tokens-card";
import "./ha-pick-language-row";
import "./ha-pick-theme-row";
import "./ha-push-notifications-row";
+import "./ha-force-narrow-row";
/*
* @appliesMixin EventsMixin
@@ -83,6 +84,15 @@ class HaPanelProfile extends EventsMixin(LocalizeMixin(PolymerElement)) {
narrow="[[narrow]]"
hass="[[hass]]"
>
+
+
+
"",
translationMetadata,
- dockedSidebar: true,
+ dockedSidebar: "docked",
moreInfoEntityId: null,
callService: async (domain, service, serviceData = {}) => {
if (__DEV__) {
diff --git a/src/state/sidebar-mixin.ts b/src/state/sidebar-mixin.ts
index 507e22c3bf..0432be0014 100644
--- a/src/state/sidebar-mixin.ts
+++ b/src/state/sidebar-mixin.ts
@@ -2,9 +2,10 @@ import { storeState } from "../util/ha-pref-storage";
import { Constructor, LitElement } from "lit-element";
import { HassBaseEl } from "./hass-base-mixin";
import { HASSDomEvent } from "../common/dom/fire_event";
+import { HomeAssistant } from "../types";
interface DockSidebarParams {
- dock: boolean;
+ dock: HomeAssistant["dockedSidebar"];
}
declare global {
diff --git a/src/translations/en.json b/src/translations/en.json
index 3eee344a33..a82d4a580b 100644
--- a/src/translations/en.json
+++ b/src/translations/en.json
@@ -1052,6 +1052,10 @@
"current_user": "You are currently logged in as {fullName}.",
"is_owner": "You are an owner.",
"logout": "Log out",
+ "force_narrow": {
+ "header": "Always hide the sidebar",
+ "description": "This will hide the sidebar by default, similar to the mobile experience."
+ },
"push_notifications": {
"header": "Push Notifications",
"description": "Send notifications to this device.",
diff --git a/src/types.ts b/src/types.ts
index 089e88744e..abe47b9597 100644
--- a/src/types.ts
+++ b/src/types.ts
@@ -139,7 +139,7 @@ export interface HomeAssistant {
localize: LocalizeFunc;
translationMetadata: TranslationMetadata;
- dockedSidebar: boolean;
+ dockedSidebar: "docked" | "always_hidden" | "auto";
moreInfoEntityId: string | null;
user?: CurrentUser;
callService: (
diff --git a/src/util/ha-pref-storage.ts b/src/util/ha-pref-storage.ts
index 3a57320a2b..6d9c681725 100644
--- a/src/util/ha-pref-storage.ts
+++ b/src/util/ha-pref-storage.ts
@@ -19,7 +19,12 @@ export function getState() {
for (const key of STORED_STATE) {
if (key in STORAGE) {
- state[key] = JSON.parse(STORAGE[key]);
+ let value = JSON.parse(STORAGE[key]);
+ // dockedSidebar went from boolean to enum on 20190720
+ if (key === "dockedSidebar" && typeof value === "boolean") {
+ value = value ? "docked" : "auto";
+ }
+ state[key] = value;
}
}