From 4555bd4240f3f06fc79973e3849a9b96e0f4af91 Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Sat, 20 Jul 2019 17:30:25 -0700 Subject: [PATCH] Add a force mobile mode on desktop (#3394) * Add a force mobile mode * Fix columns on LL * Update text * Move it above the push notifications * Hide notification count when sidebar expanded and count=0 --- src/components/ha-menu-button.ts | 17 ++++++-- src/components/ha-sidebar.ts | 6 ++- src/fake_data/provide_hass.ts | 2 +- src/layouts/home-assistant-main.ts | 24 +++++++---- src/panels/config/ha-panel-config.ts | 3 +- src/panels/config/zha/zha-config-panel.ts | 29 +------------ src/panels/lovelace/ha-panel-lovelace.ts | 3 +- src/panels/profile/ha-force-narrow-row.ts | 52 +++++++++++++++++++++++ src/panels/profile/ha-panel-profile.js | 14 ++++++ src/panels/states/ha-panel-states.js | 2 +- src/state/connection-mixin.ts | 2 +- src/state/sidebar-mixin.ts | 3 +- src/translations/en.json | 4 ++ src/types.ts | 2 +- src/util/ha-pref-storage.ts | 7 ++- 15 files changed, 122 insertions(+), 48 deletions(-) create mode 100644 src/panels/profile/ha-force-narrow-row.ts 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; } }