diff --git a/src/components/ha-picture-upload.ts b/src/components/ha-picture-upload.ts index 7a23a3b0939f..748da3917265 100644 --- a/src/components/ha-picture-upload.ts +++ b/src/components/ha-picture-upload.ts @@ -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, { diff --git a/src/data/image_upload.ts b/src/data/image_upload.ts index 94198de6dc87..e6ffc1ac7eba 100644 --- a/src/data/image_upload.ts +++ b/src/data/image_upload.ts @@ -12,8 +12,14 @@ 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 +) => + original + ? `/api/image/serve/${mediaId}/original` + : `/api/image/serve/${mediaId}/${size}x${size}`; export const fetchImages = (hass: HomeAssistant) => hass.callWS({ type: "image/list" }); diff --git a/src/panels/lovelace/editor/view-editor/hui-dialog-edit-view.ts b/src/panels/lovelace/editor/view-editor/hui-dialog-edit-view.ts index 78517e3bae85..e08e70a383d8 100644 --- a/src/panels/lovelace/editor/view-editor/hui-dialog-edit-view.ts +++ b/src/panels/lovelace/editor/view-editor/hui-dialog-edit-view.ts @@ -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 { > `; break; + case "tab-background": + content = html` + + `; + 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" )} + ${this.hass!.localize( + "ui.panel.lovelace.editor.edit_view.tab_background" + )} ${this.hass!.localize( "ui.panel.lovelace.editor.edit_view.tab_badges" diff --git a/src/panels/lovelace/editor/view-editor/hui-view-background-editor.ts b/src/panels/lovelace/editor/view-editor/hui-view-background-editor.ts new file mode 100644 index 000000000000..87d02d2399e4 --- /dev/null +++ b/src/panels/lovelace/editor/view-editor/hui-view-background-editor.ts @@ -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` +

+ ${this.hass.localize( + "ui.panel.lovelace.editor.edit_view.background.title" + )} +

+ + `; + } + + private _backgroundChanged(ev: ValueChangedEvent) { + 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; + } +} diff --git a/src/translations/en.json b/src/translations/en.json index f28231447e1e..b6958a4cfe74 100644 --- a/src/translations/en.json +++ b/src/translations/en.json @@ -5439,11 +5439,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": {