Add UI for setting view background (#20708)

* Add UI for setting view background

* Update eslint-plugin-unused-imports to fix parse failure

* Changes from review
This commit is contained in:
Adam Kapos 2024-05-29 13:23:54 +03:00 committed by GitHub
parent 2921161336
commit ff9c794659
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 120 additions and 3 deletions

View File

@ -31,6 +31,8 @@ export class HaPictureUpload extends LitElement {
@property({ attribute: false }) public cropOptions?: CropOptions;
@property({ type: Boolean }) public original = false;
@property({ type: Number }) public size = 512;
@state() private _uploading = false;
@ -122,7 +124,11 @@ export class HaPictureUpload extends LitElement {
this._uploading = true;
try {
const media = await createImage(this.hass, file);
this.value = generateImageThumbnailUrl(media.id, this.size);
this.value = generateImageThumbnailUrl(
media.id,
this.size,
this.original
);
fireEvent(this, "change");
} catch (err: any) {
showAlertDialog(this, {

View File

@ -12,8 +12,19 @@ export interface ImageMutableParams {
name: string;
}
export const generateImageThumbnailUrl = (mediaId: string, size: number) =>
`/api/image/serve/${mediaId}/${size}x${size}`;
export const generateImageThumbnailUrl = (
mediaId: string,
size?: number,
original: boolean = false
) => {
if (!original && !size) {
throw new Error("Size must be provided if original is false");
}
return original
? `/api/image/serve/${mediaId}/original`
: `/api/image/serve/${mediaId}/${size}x${size}`;
};
export const fetchImages = (hass: HomeAssistant) =>
hass.callWS<Image[]>({ type: "image/list" });

View File

@ -49,6 +49,7 @@ import {
ViewVisibilityChangeEvent,
} from "../types";
import "./hui-view-editor";
import "./hui-view-background-editor";
import "./hui-view-visibility-editor";
import { EditViewDialogParams } from "./show-edit-view-dialog";
@ -155,6 +156,15 @@ export class HuiDialogEditView extends LitElement {
></hui-view-editor>
`;
break;
case "tab-background":
content = html`
<hui-view-background-editor
.hass=${this.hass}
.config=${this._config}
@view-config-changed=${this._viewConfigChanged}
></hui-view-background-editor>
`;
break;
case "tab-badges":
content = html`
${this._config?.badges?.length
@ -292,6 +302,11 @@ export class HuiDialogEditView extends LitElement {
"ui.panel.lovelace.editor.edit_view.tab_settings"
)}</paper-tab
>
<paper-tab id="tab-background"
>${this.hass!.localize(
"ui.panel.lovelace.editor.edit_view.tab_background"
)}</paper-tab
>
<paper-tab id="tab-badges"
>${this.hass!.localize(
"ui.panel.lovelace.editor.edit_view.tab_badges"

View File

@ -0,0 +1,81 @@
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 { 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,
};
@customElement("hui-view-background-editor")
export class HuiViewBackgroundEditor extends LitElement {
@property({ attribute: false }) public hass!: HomeAssistant;
@state() private _config!: LovelaceViewConfig;
set config(config: LovelaceViewConfig) {
this._config = config;
}
protected render() {
if (!this.hass) {
return nothing;
}
const backgroundUrlRegex = /url\(['"]?([^'"]+)['"]?\)/;
const backgroundUrlMatch = backgroundUrlRegex.exec(
this._config?.background || ""
);
const backgroundUrl = backgroundUrlMatch ? backgroundUrlMatch[1] : null;
return html`
<p>
${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>
`;
}
private _backgroundChanged(ev: ValueChangedEvent<string | null>) {
const backgroundUrl = (ev.target as HaPictureUpload).value;
const config = {
...this._config,
background: backgroundUrl
? `center / cover no-repeat url('${backgroundUrl}')`
: undefined,
};
fireEvent(this, "view-config-changed", { config });
}
static get styles(): CSSResultGroup {
return css`
:host {
display: block;
}
`;
}
}
declare global {
interface HTMLElementTagNameMap {
"hui-view-background-editor": HuiViewBackgroundEditor;
}
}

View File

@ -5445,11 +5445,15 @@
"header": "View configuration",
"header_name": "{name} View Configuration",
"add": "Add view",
"background": {
"title": "Add a background to the view"
},
"edit": "Edit view",
"delete": "Delete view",
"move_left": "Move view left",
"move_right": "Move view right",
"tab_settings": "Settings",
"tab_background": "Background",
"tab_badges": "Badges",
"tab_visibility": "Visibility",
"visibility": {