mirror of
https://github.com/home-assistant/frontend.git
synced 2025-07-23 01:06:35 +00:00
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:
parent
75c7445dd9
commit
4555bd4240
@ -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();
|
||||
|
@ -134,7 +134,9 @@ class HaSidebar extends LitElement {
|
||||
? html`
|
||||
<paper-icon-button
|
||||
aria-label="Sidebar Toggle"
|
||||
.icon=${hass.dockedSidebar ? "hass:menu-open" : "hass:menu"}
|
||||
.icon=${hass.dockedSidebar === "docked"
|
||||
? "hass:menu-open"
|
||||
: "hass:menu"}
|
||||
@click=${this._toggleSidebar}
|
||||
></paper-icon-button>
|
||||
`
|
||||
@ -216,7 +218,7 @@ class HaSidebar extends LitElement {
|
||||
<span class="item-text">
|
||||
${hass.localize("ui.notification_drawer.title")}
|
||||
</span>
|
||||
${this.expanded
|
||||
${this.expanded && notificationCount > 0
|
||||
? html`
|
||||
<span class="notification-badge">${notificationCount}</span>
|
||||
`
|
||||
|
@ -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) {
|
||||
|
@ -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`
|
||||
<iron-media-query
|
||||
@ -55,7 +58,7 @@ class HomeAssistantMain extends LitElement {
|
||||
|
||||
<app-drawer-layout
|
||||
fullbleed
|
||||
.forceNarrow=${this.narrow}
|
||||
.forceNarrow=${sidebarNarrow}
|
||||
responsive-width="0"
|
||||
>
|
||||
<app-drawer
|
||||
@ -64,12 +67,14 @@ class HomeAssistantMain extends LitElement {
|
||||
slot="drawer"
|
||||
.disableSwipe=${disableSwipe}
|
||||
.swipeOpen=${!disableSwipe}
|
||||
.persistent=${!this.narrow}
|
||||
.persistent=${!this.narrow &&
|
||||
this.hass.dockedSidebar !== "always_hidden"}
|
||||
>
|
||||
<ha-sidebar
|
||||
.hass=${hass}
|
||||
.narrow=${this.narrow}
|
||||
.alwaysExpand=${this.narrow || hass.dockedSidebar}
|
||||
.narrow=${sidebarNarrow}
|
||||
.alwaysExpand=${sidebarNarrow ||
|
||||
this.hass.dockedSidebar === "docked"}
|
||||
></ha-sidebar>
|
||||
</app-drawer>
|
||||
|
||||
@ -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();
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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")
|
||||
);
|
||||
}
|
||||
|
||||
|
52
src/panels/profile/ha-force-narrow-row.ts
Normal file
52
src/panels/profile/ha-force-narrow-row.ts
Normal 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;
|
||||
}
|
||||
}
|
@ -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]]"
|
||||
></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
|
||||
narrow="[[narrow]]"
|
||||
hass="[[hass]]"
|
||||
@ -174,6 +184,10 @@ class HaPanelProfile extends EventsMixin(LocalizeMixin(PolymerElement)) {
|
||||
_isAdmin(user) {
|
||||
return user.is_admin;
|
||||
}
|
||||
|
||||
_showNarrowRow(dockedSidebar, narrow) {
|
||||
return dockedSidebar === "auto" ? !narrow : true;
|
||||
}
|
||||
}
|
||||
|
||||
customElements.define("ha-panel-profile", HaPanelProfile);
|
||||
|
@ -237,7 +237,7 @@ class PartialCards extends EventsMixin(NavigateMixin(PolymerElement)) {
|
||||
// Do -1 column if the menu is docked and open
|
||||
this._columns = Math.max(
|
||||
1,
|
||||
matchColumns - (!this.narrow && this.hass.dockedSidebar)
|
||||
matchColumns - (!this.narrow && this.hass.dockedSidebar === "docked")
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -44,7 +44,7 @@ export const connectionMixin = (
|
||||
localize: () => "",
|
||||
|
||||
translationMetadata,
|
||||
dockedSidebar: true,
|
||||
dockedSidebar: "docked",
|
||||
moreInfoEntityId: null,
|
||||
callService: async (domain, service, serviceData = {}) => {
|
||||
if (__DEV__) {
|
||||
|
@ -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 {
|
||||
|
@ -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.",
|
||||
|
@ -139,7 +139,7 @@ export interface HomeAssistant {
|
||||
localize: LocalizeFunc;
|
||||
translationMetadata: TranslationMetadata;
|
||||
|
||||
dockedSidebar: boolean;
|
||||
dockedSidebar: "docked" | "always_hidden" | "auto";
|
||||
moreInfoEntityId: string | null;
|
||||
user?: CurrentUser;
|
||||
callService: (
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user