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
This commit is contained in:
Paulus Schoutsen 2019-07-20 17:30:25 -07:00 committed by GitHub
parent 75c7445dd9
commit 4555bd4240
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 122 additions and 48 deletions

View File

@ -78,14 +78,25 @@ class HaMenuButton extends LitElement {
protected updated(changedProps) { protected updated(changedProps) {
super.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; return;
} }
this.style.visibility = this.style.visibility =
this.narrow || this._alwaysVisible ? "initial" : "hidden"; newNarrow || this._alwaysVisible ? "initial" : "hidden";
if (!this.narrow) { if (!newNarrow) {
this._hasNotifications = false; this._hasNotifications = false;
if (this._unsubNotifications) { if (this._unsubNotifications) {
this._unsubNotifications(); this._unsubNotifications();

View File

@ -134,7 +134,9 @@ class HaSidebar extends LitElement {
? html` ? html`
<paper-icon-button <paper-icon-button
aria-label="Sidebar Toggle" aria-label="Sidebar Toggle"
.icon=${hass.dockedSidebar ? "hass:menu-open" : "hass:menu"} .icon=${hass.dockedSidebar === "docked"
? "hass:menu-open"
: "hass:menu"}
@click=${this._toggleSidebar} @click=${this._toggleSidebar}
></paper-icon-button> ></paper-icon-button>
` `
@ -216,7 +218,7 @@ class HaSidebar extends LitElement {
<span class="item-text"> <span class="item-text">
${hass.localize("ui.notification_drawer.title")} ${hass.localize("ui.notification_drawer.title")}
</span> </span>
${this.expanded ${this.expanded && notificationCount > 0
? html` ? html`
<span class="notification-badge">${notificationCount}</span> <span class="notification-badge">${notificationCount}</span>
` `

View File

@ -159,7 +159,7 @@ export const provideHass = (
localize: () => "", localize: () => "",
translationMetadata: translationMetadata as any, translationMetadata: translationMetadata as any,
dockedSidebar: false, dockedSidebar: "auto",
moreInfoEntityId: null as any, moreInfoEntityId: null as any,
async callService(domain, service, data) { async callService(domain, service, data) {
if (data && "entity_id" in data) { if (data && "entity_id" in data) {

View File

@ -44,8 +44,11 @@ class HomeAssistantMain extends LitElement {
return; return;
} }
const sidebarNarrow =
this.narrow || this.hass.dockedSidebar === "always_hidden";
const disableSwipe = const disableSwipe =
!this.narrow || NON_SWIPABLE_PANELS.indexOf(hass.panelUrl) !== -1; !sidebarNarrow || NON_SWIPABLE_PANELS.indexOf(hass.panelUrl) !== -1;
return html` return html`
<iron-media-query <iron-media-query
@ -55,7 +58,7 @@ class HomeAssistantMain extends LitElement {
<app-drawer-layout <app-drawer-layout
fullbleed fullbleed
.forceNarrow=${this.narrow} .forceNarrow=${sidebarNarrow}
responsive-width="0" responsive-width="0"
> >
<app-drawer <app-drawer
@ -64,12 +67,14 @@ class HomeAssistantMain extends LitElement {
slot="drawer" slot="drawer"
.disableSwipe=${disableSwipe} .disableSwipe=${disableSwipe}
.swipeOpen=${!disableSwipe} .swipeOpen=${!disableSwipe}
.persistent=${!this.narrow} .persistent=${!this.narrow &&
this.hass.dockedSidebar !== "always_hidden"}
> >
<ha-sidebar <ha-sidebar
.hass=${hass} .hass=${hass}
.narrow=${this.narrow} .narrow=${sidebarNarrow}
.alwaysExpand=${this.narrow || hass.dockedSidebar} .alwaysExpand=${sidebarNarrow ||
this.hass.dockedSidebar === "docked"}
></ha-sidebar> ></ha-sidebar>
</app-drawer> </app-drawer>
@ -86,7 +91,7 @@ class HomeAssistantMain extends LitElement {
import(/* webpackChunkName: "ha-sidebar" */ "../components/ha-sidebar"); import(/* webpackChunkName: "ha-sidebar" */ "../components/ha-sidebar");
this.addEventListener("hass-toggle-menu", () => { this.addEventListener("hass-toggle-menu", () => {
if (this.narrow) { if (this.narrow || this.hass.dockedSidebar === "always_hidden") {
if (this.drawer.opened) { if (this.drawer.opened) {
this.drawer.close(); this.drawer.close();
} else { } else {
@ -94,7 +99,7 @@ class HomeAssistantMain extends LitElement {
} }
} else { } else {
fireEvent(this, "hass-dock-sidebar", { fireEvent(this, "hass-dock-sidebar", {
dock: !this.hass.dockedSidebar, dock: this.hass.dockedSidebar === "auto" ? "docked" : "auto",
}); });
setTimeout(() => this.appLayout.resetLayout()); setTimeout(() => this.appLayout.resetLayout());
} }
@ -110,7 +115,10 @@ class HomeAssistantMain extends LitElement {
protected updated(changedProps: PropertyValues) { protected updated(changedProps: PropertyValues) {
super.updated(changedProps); 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) { if (changedProps.has("route") && this.narrow) {
this.drawer.close(); this.drawer.close();

View File

@ -146,7 +146,8 @@ class HaPanelConfig extends HassRouterPage {
const showAdvanced = !!( const showAdvanced = !!(
this._coreUserData && this._coreUserData.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) { if ("setProperties" in el) {
// As long as we have Polymer panels // As long as we have Polymer panels

View File

@ -2,7 +2,6 @@ import "../../../layouts/hass-loading-screen";
import { customElement, property } from "lit-element"; import { customElement, property } from "lit-element";
import { listenMediaQuery } from "../../../common/dom/media_query";
import { import {
HassRouterPage, HassRouterPage,
RouterOptions, RouterOptions,
@ -12,8 +11,7 @@ import { HomeAssistant } from "../../../types";
@customElement("zha-config-panel") @customElement("zha-config-panel")
class ZHAConfigPanel extends HassRouterPage { class ZHAConfigPanel extends HassRouterPage {
@property() public hass!: HomeAssistant; @property() public hass!: HomeAssistant;
@property() public _wideSidebar: boolean = false; @property() public isWide!: boolean;
@property() public _wide: boolean = false;
protected routerOptions: RouterOptions = { protected routerOptions: RouterOptions = {
defaultPage: "configuration", 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 { protected updatePageEl(el): void {
el.route = this.routeTail; el.route = this.routeTail;
el.hass = this.hass; el.hass = this.hass;
el.isWide = this.hass.dockedSidebar ? this._wideSidebar : this._wide; el.isWide = this.isWide;
} }
} }

View File

@ -178,7 +178,8 @@ class LovelacePanel extends LitElement {
// Do -1 column if the menu is docked and open // Do -1 column if the menu is docked and open
this._columns = Math.max( this._columns = Math.max(
1, 1,
matchColumns - Number(!this.narrow && this.hass!.dockedSidebar) matchColumns -
Number(!this.narrow && this.hass!.dockedSidebar === "docked")
); );
} }

View File

@ -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`
<ha-settings-row .narrow=${this.narrow}>
<span slot="heading">
${this.hass.localize("ui.panel.profile.force_narrow.header")}
</span>
<span slot="description">
${this.hass.localize("ui.panel.profile.force_narrow.description")}
</span>
<paper-toggle-button
.checked=${this.hass.dockedSidebar === "always_hidden"}
@checked-changed=${this._checkedChanged}
></paper-toggle-button>
</ha-settings-row>
`;
}
private async _checkedChanged(ev: PolymerChangedEvent<boolean>) {
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;
}
}

View File

@ -25,6 +25,7 @@ import "./ha-long-lived-access-tokens-card";
import "./ha-pick-language-row"; import "./ha-pick-language-row";
import "./ha-pick-theme-row"; import "./ha-pick-theme-row";
import "./ha-push-notifications-row"; import "./ha-push-notifications-row";
import "./ha-force-narrow-row";
/* /*
* @appliesMixin EventsMixin * @appliesMixin EventsMixin
@ -83,6 +84,15 @@ class HaPanelProfile extends EventsMixin(LocalizeMixin(PolymerElement)) {
narrow="[[narrow]]" narrow="[[narrow]]"
hass="[[hass]]" hass="[[hass]]"
></ha-pick-theme-row> ></ha-pick-theme-row>
<template
is="dom-if"
if="[[_showNarrowRow(hass.dockedSidebar, narrow)]]"
>
<ha-force-narrow-row
narrow="[[narrow]]"
hass="[[hass]]"
></ha-force-narrow-row>
</template>
<ha-push-notifications-row <ha-push-notifications-row
narrow="[[narrow]]" narrow="[[narrow]]"
hass="[[hass]]" hass="[[hass]]"
@ -174,6 +184,10 @@ class HaPanelProfile extends EventsMixin(LocalizeMixin(PolymerElement)) {
_isAdmin(user) { _isAdmin(user) {
return user.is_admin; return user.is_admin;
} }
_showNarrowRow(dockedSidebar, narrow) {
return dockedSidebar === "auto" ? !narrow : true;
}
} }
customElements.define("ha-panel-profile", HaPanelProfile); customElements.define("ha-panel-profile", HaPanelProfile);

View File

@ -237,7 +237,7 @@ class PartialCards extends EventsMixin(NavigateMixin(PolymerElement)) {
// Do -1 column if the menu is docked and open // Do -1 column if the menu is docked and open
this._columns = Math.max( this._columns = Math.max(
1, 1,
matchColumns - (!this.narrow && this.hass.dockedSidebar) matchColumns - (!this.narrow && this.hass.dockedSidebar === "docked")
); );
} }

View File

@ -44,7 +44,7 @@ export const connectionMixin = (
localize: () => "", localize: () => "",
translationMetadata, translationMetadata,
dockedSidebar: true, dockedSidebar: "docked",
moreInfoEntityId: null, moreInfoEntityId: null,
callService: async (domain, service, serviceData = {}) => { callService: async (domain, service, serviceData = {}) => {
if (__DEV__) { if (__DEV__) {

View File

@ -2,9 +2,10 @@ import { storeState } from "../util/ha-pref-storage";
import { Constructor, LitElement } from "lit-element"; import { Constructor, LitElement } from "lit-element";
import { HassBaseEl } from "./hass-base-mixin"; import { HassBaseEl } from "./hass-base-mixin";
import { HASSDomEvent } from "../common/dom/fire_event"; import { HASSDomEvent } from "../common/dom/fire_event";
import { HomeAssistant } from "../types";
interface DockSidebarParams { interface DockSidebarParams {
dock: boolean; dock: HomeAssistant["dockedSidebar"];
} }
declare global { declare global {

View File

@ -1052,6 +1052,10 @@
"current_user": "You are currently logged in as {fullName}.", "current_user": "You are currently logged in as {fullName}.",
"is_owner": "You are an owner.", "is_owner": "You are an owner.",
"logout": "Log out", "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": { "push_notifications": {
"header": "Push Notifications", "header": "Push Notifications",
"description": "Send notifications to this device.", "description": "Send notifications to this device.",

View File

@ -139,7 +139,7 @@ export interface HomeAssistant {
localize: LocalizeFunc; localize: LocalizeFunc;
translationMetadata: TranslationMetadata; translationMetadata: TranslationMetadata;
dockedSidebar: boolean; dockedSidebar: "docked" | "always_hidden" | "auto";
moreInfoEntityId: string | null; moreInfoEntityId: string | null;
user?: CurrentUser; user?: CurrentUser;
callService: ( callService: (

View File

@ -19,7 +19,12 @@ export function getState() {
for (const key of STORED_STATE) { for (const key of STORED_STATE) {
if (key in STORAGE) { 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;
} }
} }