use image selector for view background (#20898)

* use image selector for view background

* make config future proof

* improvements
This commit is contained in:
Bram Kragten 2024-05-29 17:29:09 +02:00 committed by GitHub
parent 5cc08cfe0b
commit d31a777135
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 47 additions and 35 deletions

View File

@ -86,10 +86,17 @@ class HcLovelace extends LitElement {
this.lovelaceConfig.views[index].background ||
this.lovelaceConfig.background;
if (configBackground) {
const backgroundStyle =
typeof configBackground === "string"
? configBackground
: configBackground?.image
? `center / cover no-repeat url('${configBackground.image}')`
: undefined;
if (backgroundStyle) {
this._huiView!.style.setProperty(
"--lovelace-background",
configBackground
backgroundStyle
);
} else {
this._huiView!.style.removeProperty("--lovelace-background");

View File

@ -85,6 +85,8 @@ export class HaImageSelector extends LitElement {
<ha-picture-upload
.hass=${this.hass}
.value=${this.value?.startsWith(URL_PREFIX) ? this.value : null}
.original=${this.selector.image?.original}
.cropOptions=${this.selector.image?.crop}
@change=${this._pictureChanged}
></ha-picture-upload>
`}

View File

@ -7,6 +7,10 @@ export interface ShowViewConfig {
user?: string;
}
interface LovelaceViewBackgroundConfig {
image?: string;
}
export interface LovelaceBaseViewConfig {
index?: number;
title?: string;
@ -14,7 +18,7 @@ export interface LovelaceBaseViewConfig {
icon?: string;
theme?: string;
panel?: boolean;
background?: string;
background?: string | LovelaceViewBackgroundConfig;
visible?: boolean | ShowViewConfig[];
subview?: boolean;
back_path?: string;

View File

@ -14,6 +14,7 @@ import {
} from "./entity_registry";
import { EntitySources } from "./entity_sources";
import { isHelperDomain } from "../panels/config/helpers/const";
import type { CropOptions } from "../dialogs/image-cropper-dialog/show-image-cropper-dialog";
export type Selector =
| ActionSelector
@ -259,7 +260,7 @@ export interface IconSelector {
export interface ImageSelector {
// eslint-disable-next-line @typescript-eslint/ban-types
image: {} | null;
image: { original?: boolean; crop?: CropOptions } | null;
}
export interface LabelSelector {

View File

@ -2,19 +2,11 @@ import "@material/mwc-list/mwc-list-item";
import { CSSResultGroup, LitElement, css, html, nothing } from "lit";
import { customElement, property, state } from "lit/decorators";
import { fireEvent } from "../../../../common/dom/fire_event";
import "../../../../components/user/ha-user-badge";
import "../../../../components/ha-selector/ha-selector-image";
import { LovelaceViewConfig } from "../../../../data/lovelace/config/view";
import { HomeAssistant, ValueChangedEvent } from "../../../../types";
import "../../../../components/ha-picture-upload";
import type { HaPictureUpload } from "../../../../components/ha-picture-upload";
import { CropOptions } from "../../../../dialogs/image-cropper-dialog/show-image-cropper-dialog";
const cropOptions: CropOptions = {
round: false,
type: "image/jpeg",
quality: 0.75,
aspectRatio: 1.78,
};
const SELECTOR = { image: { original: true } };
@customElement("hui-view-background-editor")
export class HuiViewBackgroundEditor extends LitElement {
@ -31,36 +23,35 @@ export class HuiViewBackgroundEditor extends LitElement {
return nothing;
}
const backgroundUrlRegex = /url\(['"]?([^'"]+)['"]?\)/;
const backgroundUrlMatch = backgroundUrlRegex.exec(
this._config?.background || ""
);
const backgroundUrl = backgroundUrlMatch ? backgroundUrlMatch[1] : null;
const background = this._config?.background;
const backgroundUrl =
typeof background === "string"
? background.match(/url\(['"]?([^'"]+)['"]?\)/)?.[1]
: background?.image;
return html`
<p>
${this.hass.localize(
<ha-selector-image
.hass=${this.hass}
.label=${this.hass.localize(
"ui.panel.lovelace.editor.edit_view.background.title"
)}
</p>
<ha-picture-upload
.hass=${this.hass}
.value=${backgroundUrl}
crop
.cropOptions=${cropOptions}
original
@change=${this._backgroundChanged}
></ha-picture-upload>
.selector=${SELECTOR}
@value-changed=${this._backgroundChanged}
></ha-selector-image>
`;
}
private _backgroundChanged(ev: ValueChangedEvent<string | null>) {
const backgroundUrl = (ev.target as HaPictureUpload).value;
const backgroundUrl = ev.detail.value;
const config = {
...this._config,
background: backgroundUrl
? `center / cover no-repeat url('${backgroundUrl}')`
: undefined,
background: {
...(typeof this._config.background === "string"
? {}
: this._config.background),
image: backgroundUrl || undefined,
},
};
fireEvent(this, "view-config-changed", { config });
}

View File

@ -932,8 +932,15 @@ class HUIRoot extends LitElement {
const configBackground = viewConfig.background || this.config.background;
if (configBackground) {
root.style.setProperty("--lovelace-background", configBackground);
const backgroundStyle =
typeof configBackground === "string"
? configBackground
: configBackground?.image
? `center / cover no-repeat url('${configBackground.image}')`
: undefined;
if (backgroundStyle) {
root.style.setProperty("--lovelace-background", backgroundStyle);
} else {
root.style.removeProperty("--lovelace-background");
}