mirror of
https://github.com/home-assistant/frontend.git
synced 2025-07-23 09:16:38 +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) {
|
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();
|
||||||
|
@ -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>
|
||||||
`
|
`
|
||||||
|
@ -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) {
|
||||||
|
@ -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();
|
||||||
|
@ -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
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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")
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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-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);
|
||||||
|
@ -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")
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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__) {
|
||||||
|
@ -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 {
|
||||||
|
@ -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.",
|
||||||
|
@ -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: (
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user