Skip to content

Commit

Permalink
Merge pull request #5 from igor-panteleev/develop
Browse files Browse the repository at this point in the history
Release 1.1.0
  • Loading branch information
igor-panteleev authored Jul 23, 2024
2 parents fe8a57b + 25e44c6 commit 5453b58
Show file tree
Hide file tree
Showing 7 changed files with 144 additions and 8,194 deletions.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
/node_modules/
/.rpt2_cache/
/dist
.idea
.idea
package-lock.json
8,088 changes: 0 additions & 8,088 deletions package-lock.json

This file was deleted.

15 changes: 8 additions & 7 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "qr-code-card",
"version": "v1.0.2",
"version": "v1.1.0",
"description": "QR code card",
"keywords": [
"home-assistant",
Expand All @@ -15,10 +15,11 @@
"@polymer/paper-dropdown-menu": "^3.2.0",
"@polymer/paper-item": "^3.0.1",
"@polymer/paper-listbox": "^3.0.1",
"compare-versions": "^4.0.1",
"custom-card-helpers": "^1.7.2",
"lit": "^2.0.0-rc.2",
"qrcode": "^1.4.4"
"@mdi/js": "7.4.47",
"compare-versions": "^6.1.1",
"custom-card-helpers": "^1.9.0",
"lit": "^2.0.0",
"qrcode": "^1.5.3"
},
"devDependencies": {
"@babel/core": "^7.15.0",
Expand All @@ -39,7 +40,7 @@
"rollup-plugin-node-resolve": "^5.2.0",
"rollup-plugin-serve": "^1.1.0",
"rollup-plugin-terser": "^7.0.2",
"rollup-plugin-typescript2": "^0.30.0",
"rollup-plugin-typescript2": "^0.31.0",
"typescript": "^4.4.3"
},
"scripts": {
Expand All @@ -48,4 +49,4 @@
"lint": "eslint src/*.ts",
"rollup": "rollup -c"
}
}
}
153 changes: 76 additions & 77 deletions src/editor.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { mdiEye, mdiEyeOff } from "@mdi/js";
import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit";
import { customElement, property, state } from "lit/decorators";
import { fireEvent, HomeAssistant, LovelaceCardEditor } from "custom-card-helpers";
Expand Down Expand Up @@ -85,80 +86,76 @@ export class QRCodeCardEditor extends LitElement implements LovelaceCardEditor {
return html`
<div class="card-config">
<div class="values">
<paper-input
<ha-textfield
label=${this._localize("editor.label.title")}
.value=${this._title}
.configValue=${"title"}
@value-changed=${this._valueChanged}></paper-input>
@input=${this._valueChanged}></ha-textfield>
</div>
<div class="values">
<paper-dropdown-menu
label=${this._localize("editor.label.source")}
@iron-select=${this._selectionChanged}
.configValue=${"source"}>
<paper-listbox
slot="dropdown-content"
attr-for-selected="value"
.selected=${this._source}>
${Object.values(SourceType).map(source => {
return html`<paper-item .value=${source}>${this._localize(`editor.options.source.${source}`)}</paper-item>`;
})}
</paper-listbox>
</paper-dropdown-menu>
<ha-select
naturalMenuWidth
fixedMenuPosition
label="${this._localize("editor.label.source")}"
@selected="${this._valueChanged}"
@closed="${ev => ev.stopPropagation()}"
.configValue="${"source"}"
.value="${this._source}">
${Object.values(SourceType).map(source => {
return html` <mwc-list-item .value="${source}">${this._localize(`editor.options.source.${source}`)}</mwc-list-item> `;
})}
</ha-select>
</div>
${this._config?.source == SourceType.TEXT ? html`
<div class="values">
<paper-input
label=${this._localize("editor.label.text")}
.value=${this._text}
.configValue=${"text"}
@value-changed=${this._valueChanged}></paper-input>
<ha-textfield
label="${this._localize("editor.label.text")}"
.value="${this._text}"
.configValue="${"text"}"
@input="${this._valueChanged}"></ha-textfield>
</div>` : ""}
${this._config?.source == SourceType.WIFI ? html`
<div class="values">
<paper-dropdown-menu
label=${this._localize("editor.label.auth_type")}
@iron-select=${this._selectionChanged}
.configValue=${"auth_type"}>
<paper-listbox
slot="dropdown-content"
attr-for-selected="value"
.selected=${this._auth_type}>
${Object.values(AuthenticationType).map(auth_type => {
return html`<paper-item .value=${auth_type}>${this._localize(`editor.options.auth_type.${auth_type}`)}</paper-item>`;
})}
</paper-listbox>
</paper-dropdown-menu>
<ha-select
naturalMenuWidth
fixedMenuPosition
label="${this._localize("editor.label.auth_type")}"
@selected="${this._valueChanged}"
@closed="${ev => ev.stopPropagation()}"
.configValue="${"auth_type"}"
.value="${this._auth_type}">
${Object.values(AuthenticationType).map(auth_type => {
return html` <mwc-list-item .value="${auth_type}">${this._localize(`editor.options.auth_type.${auth_type}`)}</mwc-list-item> `;
})}
</ha-select>
</div>
<div class="values">
<paper-input
<ha-textfield
label=${this._localize("editor.label.ssid")}
.value=${this._ssid}
.configValue=${"ssid"}
@value-changed=${this._valueChanged}></paper-input>
@input=${this._valueChanged}></ha-textfield>
</div>
${is_password_protected(this._auth_type) ? html`
<div class="values">
<paper-input
type=${this._unmaskedPassword ? "text" : "password"}
label=${this._localize("editor.label.password")}
<ha-textfield
.type=${this._unmaskedPassword ? "text" : "password"}
.label=${this._localize("editor.label.password")}
.value=${this._password}
.configValue=${"password"}
@value-changed=${this._valueChanged}>
<ha-icon-button
toggles
.active=${this._unmaskedPassword}
title=${this._unmaskedPassword ? this._localize("editor.title.hide_password") : this._localize("editor.title.show_password")}
slot="suffix"
@click=${this._toggleUnmaskedPassword}>
<ha-icon
.icon=${this._unmaskedPassword ? "hass:eye-off" : "hass:eye"}>
</ha-icon>
</ha-icon-button>
</paper-input>
.suffix="${html`<div style="width: 24px"></div>`}"
@input=${this._valueChanged}>
</ha-textfield>
<ha-icon-button
toggles
.label=${this._unmaskedPassword ? this._localize("editor.title.hide_password") : this._localize("editor.title.show_password")}
@click=${this._toggleUnmaskedPassword}
.path=${this._unmaskedPassword ? mdiEyeOff : mdiEye}
></ha-icon-button>
</div>
` : ""}
<div class="values">
Expand All @@ -173,18 +170,19 @@ export class QRCodeCardEditor extends LitElement implements LovelaceCardEditor {
${this._config?.source == SourceType.ENTITY ? html`
<div class="values">
<paper-dropdown-menu
label=${this._localize("editor.label.entity")}
@value-changed=${this._valueChanged}
.configValue=${"entity"}>
<paper-listbox slot="dropdown-content" .selected=${entities.indexOf(this._entity)}>
${entities.map(entity => {
return html` <paper-item>${entity}</paper-item> `;
})}
</paper-listbox>
</paper-dropdown-menu>
<ha-select
naturalMenuWidth
fixedMenuPosition
label="${this._localize("editor.label.entity")}"
@selected="${this._valueChanged}"
@closed="${ev => ev.stopPropagation()}"
.configValue="${"entity"}"
.value="${this._entity}">
${entities.map(entity => {
return html` <mwc-list-item .value="${entity}">${entity}</mwc-list-item>`;
})}
</ha-select>
</div>` : ""}
</div>
`;
}
Expand All @@ -195,11 +193,6 @@ export class QRCodeCardEditor extends LitElement implements LovelaceCardEditor {
this._initialized = true;
}

private _selectionChanged(ev): void {
ev.stopPropagation();
this._updateConfig(ev.currentTarget.configValue, ev.detail.item.value);
}

private _valueChanged(ev): void {
ev.stopPropagation();
const value = ev.target.checked !== undefined ? ev.target.checked : ev.target.value;
Expand Down Expand Up @@ -235,21 +228,27 @@ export class QRCodeCardEditor extends LitElement implements LovelaceCardEditor {
static get styles(): CSSResultGroup {
return css`
.values {
padding-left: 16px;
margin: 8px;
display: grid;
margin-top: 8px;
margin-bottom: 16px;
display: block;
position: relative;
}
.values ha-icon-button {
flex-direction: column;
width: 24px;
height: 24px;
--mdc-icon-button-size: 24px;
color: var(--secondary-text-color);
ha-textfield,
ha-select {
width: 100%;
}
.values ha-icon {
display: flex;
ha-icon-button {
position: absolute;
top: 8px;
right: 8px;
inset-inline-start: initial;
inset-inline-end: 8px;
--mdc-icon-button-size: 40px;
--mdc-icon-size: 20px;
color: var(--secondary-text-color);
direction: var(--direction);
}
`;
}
Expand Down
2 changes: 1 addition & 1 deletion src/localize/languages/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
"auth_type": "Authentication type (required)",
"ssid": "SSID (required)",
"password": "Password (required)",
"is_hidden": "Hidden (optional)"
"is_hidden": "Hidden SSID"
},
"title": {
"show_password": "Show password",
Expand Down
43 changes: 23 additions & 20 deletions src/qr-code-card.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,10 @@ import { PropertyValues } from "@lit/reactive-element";
import { HomeAssistant, LovelaceCard, LovelaceCardEditor } from "custom-card-helpers";

import "./editor";
import type { DataUrl, QRCodeCardConfig, TranslatableString } from "./types/types";
import type {QRCodeCardConfig, TranslatableString } from "./types/types";

import { localize, localizeWithHass } from "./localize/localize";
import { getWatchedEntities, hasConfigOrAnyEntityChanged } from "./utils"
import { version } from '../package.json';
import { generateQR } from "./models/generator";
import { validateConfig } from "./validators";
Expand Down Expand Up @@ -44,6 +45,7 @@ export class QRCodeCard extends LitElement {
}

private config!: QRCodeCardConfig;
private watchedEntities: string[] = [];
@property({ attribute: false }) public _hass!: HomeAssistant;
@state() private errors: string[] = [];
@state() private dataUrl = "";
Expand All @@ -67,37 +69,38 @@ export class QRCodeCard extends LitElement {
return;
}

this._generateQR();
this.watchedEntities = getWatchedEntities(this.config)
this.requestUpdate("config");
}

private _generateQR(): void {
generateQR(this.hass, this.config)
.then((data_url: DataUrl) => {
this.dataUrl = data_url;
}).catch((e: Error) => {
this.errors = [e.message];
})
private async _updateQR(): Promise<void> {
try {
this.dataUrl = await generateQR(this.hass, this.config);
} catch (e: unknown) {
if (e instanceof Error) {
this.errors = [e.message]
} else {
this.errors = ['An unknown error occurred'];
}
}
}

private _localize(ts: TranslatableString): string {
return localizeWithHass(ts, this.hass, this.config);
}

protected shouldUpdate(changedProperties: PropertyValues): boolean {
if (changedProperties.has('dataUrl') || changedProperties.has('errors')) return true;

if (this.config?.entity) {
const oldHass = changedProperties.get('_hass') as HomeAssistant | undefined;
if (oldHass) {
return (
oldHass.states[this.config.entity] !== this.hass.states[this.config.entity]
);
}
if (!this.config) {
return false;
}

return false;
return hasConfigOrAnyEntityChanged(this.watchedEntities, changedProperties, false, this.hass);
}

protected async update(changedProperties: PropertyValues): Promise<void> {
await this._updateQR();
super.update(changedProperties);
}

protected render(): TemplateResult {
if (this.errors.length > 0) {
return this._showErrors(this.errors);
Expand Down
34 changes: 34 additions & 0 deletions src/utils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import { PropertyValues } from "@lit/reactive-element";
import { HomeAssistant } from "custom-card-helpers";
import { QRCodeCardConfig } from "./types/types"
import { SourceType } from "./models/source-type";

export function hasConfigOrAnyEntityChanged(
watchedEntities: string[],
changedProps: PropertyValues,
forceUpdate: boolean,
hass?: HomeAssistant,
): boolean {
if (changedProps.has("config") || forceUpdate) {
return true;
}
const oldHass = changedProps.get("_hass") as HomeAssistant | undefined;
return !oldHass || watchedEntities.some(entity => oldHass.states[entity] !== hass?.states[entity]);
}

export function getWatchedEntities(config: QRCodeCardConfig): string[] {
const watchedEntities = new Set<string>();

switch (config.source) {
case SourceType.ENTITY:
watchedEntities.add(config.entity);
break;

// TODO: add support to use entities for WIFI QR code
// case SourceType.WIFI:
// if (config.ssid.hasOwnProperty("entity")) watchedEntities.add(config.ssid["entity"]);
// if (config.password.hasOwnProperty("entity")) watchedEntities.add(config.password["entity"]);
}

return [...watchedEntities];
}

0 comments on commit 5453b58

Please sign in to comment.